| /******************************************************************************* |
| * Copyright (c) 2009 SAP AG. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Eduard Bartsch (SAP AG) - initial API and implementation |
| * Mathias Kinzler (SAP AG) - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.core.internal.resources.semantic; |
| |
| import java.io.File; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.net.URI; |
| import java.net.URISyntaxException; |
| import java.text.MessageFormat; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.core.filesystem.EFS; |
| import org.eclipse.core.filesystem.IFileInfo; |
| import org.eclipse.core.filesystem.IFileStore; |
| import org.eclipse.core.filesystem.provider.FileInfo; |
| import org.eclipse.core.filesystem.provider.FileStore; |
| import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.ResourceTreeNode; |
| import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.SemanticResourceDBFactory; |
| import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.TreeNodeType; |
| import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.TreeRoot; |
| import org.eclipse.core.internal.resources.semantic.util.ISemanticFileSystemLog; |
| import org.eclipse.core.resources.semantic.ISemanticFileSystem; |
| import org.eclipse.core.resources.semantic.ISemanticResourceInfo; |
| import org.eclipse.core.resources.semantic.SemanticResourceException; |
| import org.eclipse.core.resources.semantic.SemanticResourceStatusCode; |
| import org.eclipse.core.resources.semantic.SyncDirection; |
| import org.eclipse.core.resources.semantic.spi.FileCacheServiceFactory; |
| import org.eclipse.core.resources.semantic.spi.ISemanticContentProvider; |
| import org.eclipse.core.resources.semantic.spi.ISemanticContentProviderFederation; |
| import org.eclipse.core.resources.semantic.spi.ISemanticContentProviderFederation2; |
| import org.eclipse.core.resources.semantic.spi.ISemanticContentProviderFederation2.FederatedProviderInfo; |
| import org.eclipse.core.resources.semantic.spi.ISemanticContentProviderLocal; |
| import org.eclipse.core.resources.semantic.spi.ISemanticContentProviderLocking; |
| import org.eclipse.core.resources.semantic.spi.ISemanticContentProviderREST; |
| import org.eclipse.core.resources.semantic.spi.ISemanticContentProviderRemote; |
| import org.eclipse.core.resources.semantic.spi.ISemanticFileStore; |
| import org.eclipse.core.resources.semantic.spi.ISemanticSpiResourceInfo; |
| import org.eclipse.core.resources.semantic.spi.MemoryCacheServiceFactory; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.MultiStatus; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.QualifiedName; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.osgi.util.NLS; |
| |
| /** |
| * The Semantic File Store implementation. |
| * |
| */ |
| public class SemanticFileStore extends SemanticProperties implements ISemanticFileStore, ISemanticFileStoreInternal { |
| |
| // we can't use the class name, since we don't have it in the class loader |
| private final static String DEFAULT_CONTENT_PROVIDER_ID = "org.eclipse.core.resources.semantic.provider.DefaultContentProvider"; //$NON-NLS-1$ |
| |
| private final ISemanticFileSystemLog log; |
| private ISemanticContentProvider provider; |
| |
| SemanticFileStore(SemanticFileSystem fs, ResourceTreeNode node) { |
| super(fs, node); |
| this.log = fs.getLog(); |
| } |
| |
| // |
| // IFileStore/FileStore |
| // |
| /** |
| * @throws CoreException |
| */ |
| @Override |
| public String[] childNames(int options, IProgressMonitor monitor) throws CoreException { |
| |
| try { |
| this.fs.lockForRead(); |
| |
| this.checkAndJoinTreeIfAnotherEntryExists(); |
| |
| EList<ResourceTreeNode> children = this.node.getChildren(); |
| int counter = children.size(); |
| |
| String[] names = new String[counter]; |
| int i = 0; |
| |
| for (ResourceTreeNode resourceTreeNode : children) { |
| if (resourceTreeNode.isExists()) { |
| names[i] = resourceTreeNode.getName(); |
| i++; |
| } |
| } |
| return names; |
| } finally { |
| this.fs.unlockForRead(); |
| } |
| } |
| |
| @Override |
| public IFileInfo fetchInfo(int options, IProgressMonitor monitor) throws CoreException { |
| FileInfo info; |
| |
| this.checkAndJoinTreeIfAnotherEntryExists(); |
| |
| ISemanticContentProvider effectiveProvider = getEffectiveContentProvider(); |
| boolean askContentProviderForReadonly = false; |
| boolean askContentProviderForTimestamp = false; |
| |
| try { |
| this.fs.lockForRead(); |
| |
| info = new SemanticFileInfo(); |
| |
| info.setName(this.node.getName()); |
| info.setExists(this.node.isExists()); |
| TreeNodeType actType = this.node.getType(); |
| info.setDirectory(actType.equals(TreeNodeType.FOLDER) || actType.equals(TreeNodeType.PROJECT)); |
| |
| if (info.isDirectory() || !this.node.isExists() || actType.equals(TreeNodeType.UNKNOWN)) { |
| // see IFileInfo.getLastModified() |
| info.setLastModified(EFS.NONE); |
| // false is the fall back for non-existing resources, |
| info.setAttribute(EFS.ATTRIBUTE_READ_ONLY, false); |
| } else { |
| askContentProviderForTimestamp = true; |
| |
| // local-only resources are always writable (for the time being) |
| if (!this.node.isLocalOnly()) { |
| askContentProviderForReadonly = true; |
| } else { |
| info.setAttribute(EFS.ATTRIBUTE_READ_ONLY, false); |
| } |
| } |
| } finally { |
| this.fs.unlockForRead(); |
| } |
| |
| // communicate with content providers outside of our lock to avoid |
| // deadlocks |
| if (askContentProviderForReadonly) { |
| boolean readOnly = true; |
| try { |
| readOnly = effectiveProvider.fetchResourceInfo(this, ISemanticFileSystem.RESOURCE_INFO_READ_ONLY, monitor).isReadOnly(); |
| } catch (CoreException e) { |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| SfsTraceLocation.getTrace().trace(SfsTraceLocation.CONTENTPROVIDER.getLocation(), e.getMessage(), e); |
| } |
| |
| } |
| info.setAttribute(EFS.ATTRIBUTE_READ_ONLY, readOnly); |
| } |
| |
| if (askContentProviderForTimestamp) { |
| try { |
| info.setLastModified(effectiveProvider.getResourceTimestamp(this, monitor)); |
| } catch (CoreException e) { |
| // we don't want to crash everything if the resource is not |
| // accessible |
| info.setLastModified(EFS.NONE); |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| SfsTraceLocation.getTrace().trace(SfsTraceLocation.CONTENTPROVIDER.getLocation(), e.getMessage(), e); |
| } |
| } |
| } |
| |
| return info; |
| } |
| |
| @Override |
| public void putInfo(IFileInfo info, int options, IProgressMonitor monitor) throws CoreException { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| if (SfsTraceLocation.CORE.isActive()) { |
| SfsTraceLocation.getTrace().trace(SfsTraceLocation.CORE.getLocation(), |
| NLS.bind(Messages.SemanticFileStore_UpdateFileInfo_XMSG, getPath().toString())); |
| } |
| |
| checkAccessible(); |
| |
| if ((options & EFS.SET_ATTRIBUTES) != 0) { |
| // we ignore Archive, Hidden, and Executable here |
| getEffectiveContentProvider().setReadOnly(this, info.getAttribute(EFS.ATTRIBUTE_READ_ONLY), monitor); |
| } |
| if ((options & EFS.SET_LAST_MODIFIED) != 0) { |
| long timestamp = info.getLastModified(); |
| getEffectiveContentProvider().setResourceTimestamp(this, timestamp, monitor); |
| } |
| } |
| |
| private static ISemanticContentProvider initProvider(String contentProviderID, ISemanticFileStore store) throws CoreException { |
| |
| ISemanticContentProvider actProvider = SemanticFileSystemCore.getInstance().getContentProviderFactory(contentProviderID) |
| .createContentProvider(); |
| |
| actProvider.setRootStore(store); |
| |
| ((SemanticFileStore) store).setProvider(actProvider); |
| |
| return actProvider; |
| } |
| |
| public String getEffectiveContentProviderID() throws CoreException { |
| try { |
| this.fs.lockForWrite(); |
| |
| if (this.getContentProviderID() != null) { |
| return this.getContentProviderID(); |
| } |
| |
| ContentProviderData effectiveProviderData = getEffectiveContentProviderInternal(); |
| |
| if (effectiveProviderData.provider instanceof ISemanticContentProviderFederation2) { |
| IPath thisPath = this.getPath(); |
| |
| return findFederatedContentProvider(thisPath, this.fs, this.node, effectiveProviderData).providerID; |
| } |
| |
| return effectiveProviderData.providerID; |
| } finally { |
| this.fs.unlockForWrite(); |
| } |
| } |
| |
| public ISemanticContentProvider getEffectiveContentProvider() throws CoreException { |
| try { |
| this.fs.lockForWrite(); |
| // TODO 0.1: check if we can use more fine grained locks here |
| if (this.provider != null) { |
| return this.provider; |
| } |
| |
| ContentProviderData effectiveProviderData = getEffectiveContentProviderInternal(); |
| |
| if (effectiveProviderData.provider instanceof ISemanticContentProviderFederation2) { |
| IPath thisPath = this.getPath(); |
| |
| return findFederatedContentProvider(thisPath, this.fs, this.node, effectiveProviderData).provider; |
| } |
| |
| return effectiveProviderData.provider; |
| } finally { |
| this.fs.unlockForWrite(); |
| } |
| } |
| |
| private static ContentProviderData findFederatedContentProvider(IPath path, SemanticFileSystem fs, ResourceTreeNode node, |
| ContentProviderData parentProviderData) throws CoreException { |
| |
| int relativePathLength = path.segmentCount() - parentProviderData.provider.getRootStore().getPath().segmentCount(); |
| |
| if (relativePathLength > 0) { |
| ISemanticContentProviderFederation2 federatingProvider = (ISemanticContentProviderFederation2) parentProviderData.provider; |
| |
| FederatedProviderInfo info = federatingProvider.getFederatedProviderInfoForPath(path); |
| if (info != null) { |
| if (info.contentProviderID == null) { |
| throw new SemanticResourceException(SemanticResourceStatusCode.FEDERATION_EMPTY_FEDERATED_PROVIDER_ID, path, NLS.bind( |
| Messages.SemanticFileStore_FederatingContentProviderReturnedNull_XMSG, federatingProvider.getClass().getName(), |
| path.toString())); |
| } |
| |
| if (info.rootNodePosition <= 0 || info.rootNodePosition > relativePathLength) { |
| throw new SemanticResourceException(SemanticResourceStatusCode.FEDERATION_INVALID_ROOT_NODE_POSITION, path, NLS.bind( |
| Messages.SemanticFileStore_FederatingContentProviderReturnedInvalidRootNodePosition_XMSG, federatingProvider |
| .getClass().getName(), path.toString())); |
| } |
| |
| ResourceTreeNode parent = node; |
| |
| for (int i = 0; i < (relativePathLength - info.rootNodePosition); i++) { |
| if (parent != null) { |
| parent = parent.getParent(); |
| } |
| } |
| |
| if (parent != null) { |
| parent.setDynamicContentProviderID(info.contentProviderID); |
| } else { |
| String pathString = path.removeLastSegments(relativePathLength - info.rootNodePosition).toString(); |
| parent = fs.getNodeByPath(pathString); |
| } |
| |
| ISemanticContentProvider nestedProvider = initProvider(info.contentProviderID, fs.getStore(parent)); |
| |
| ContentProviderData nestedProviderData = new ContentProviderData(nestedProvider, info.contentProviderID); |
| if (nestedProvider instanceof ISemanticContentProviderFederation2) { |
| return findFederatedContentProvider(path, fs, node, nestedProviderData); |
| } |
| return nestedProviderData; |
| } |
| } |
| return parentProviderData; |
| } |
| |
| private static class ContentProviderData { |
| ContentProviderData(ISemanticContentProvider provider, String providerID) { |
| this.provider = provider; |
| this.providerID = providerID; |
| } |
| |
| ISemanticContentProvider provider; |
| String providerID; |
| } |
| |
| private ContentProviderData getEffectiveContentProviderInternal() throws CoreException { |
| ISemanticFileStore parentStore; |
| String parentContentProviderId = SemanticFileStore.DEFAULT_CONTENT_PROVIDER_ID; |
| ResourceTreeNode parent = null; |
| ResourceTreeNode cpRootParent; |
| |
| this.checkAndJoinTreeIfAnotherEntryExists(); |
| |
| if (this.node.getTemplateID() != null) { |
| String contentProviderID = this.node.getTemplateID(); |
| // TODO move outside of lock |
| initProvider(contentProviderID, this); |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceExit(SfsTraceLocation.CORE_VERBOSE.getLocation(), contentProviderID); |
| } |
| |
| return new ContentProviderData(this.provider, contentProviderID); |
| } |
| |
| if (this.node.getDynamicContentProviderID() != null) { |
| String contentProviderID = this.node.getDynamicContentProviderID(); |
| // TODO move outside of lock |
| initProvider(contentProviderID, this); |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceExit(SfsTraceLocation.CORE_VERBOSE.getLocation(), contentProviderID); |
| } |
| |
| return new ContentProviderData(this.provider, contentProviderID); |
| } |
| |
| if (!this.node.isExists()) { |
| List<ResourceTreeNode> nodes = this.fs.getNodesByPath(this.node.getPath()); |
| // go down to find a contentProviderID |
| cpRootParent = nodes.get(0); |
| int counter = 0; |
| |
| // scan the existing part where CP IDs are already assigned |
| for (ResourceTreeNode resourceTreeNode : nodes) { |
| if (resourceTreeNode.isExists()) { |
| if (resourceTreeNode.getTemplateID() != null) { |
| parentContentProviderId = resourceTreeNode.getTemplateID(); |
| cpRootParent = resourceTreeNode; |
| } |
| counter++; |
| } else { |
| break; |
| } |
| } |
| |
| // construct the root parent |
| parentStore = this.fs.getStore(cpRootParent); |
| |
| // TODO move outside of lock? |
| ISemanticContentProvider parentProvider = initProvider(parentContentProviderId, parentStore); |
| |
| // scan through non existing part |
| for (int i = counter; i < nodes.size(); i++) { |
| ResourceTreeNode resourceTreeNode = nodes.get(i); |
| |
| if (parentProvider instanceof ISemanticContentProviderFederation) { |
| String federatedContentProviderId = ((ISemanticContentProviderFederation) parentProvider) |
| .getFederatedProviderIDForPath(new Path(resourceTreeNode.getPath())); |
| |
| if (federatedContentProviderId != null) { |
| parentContentProviderId = federatedContentProviderId; |
| cpRootParent = resourceTreeNode; |
| parentStore = this.fs.getStore(cpRootParent); |
| // TODO move outside of lock? |
| parentProvider = initProvider(parentContentProviderId, parentStore); |
| } |
| } |
| } |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceExit(SfsTraceLocation.CORE_VERBOSE.getLocation(), parentContentProviderId); |
| } |
| |
| return new ContentProviderData(parentProvider, parentContentProviderId); |
| } |
| |
| // walk up to find a contentProviderID |
| parent = this.node.getParent(); |
| |
| if (parent == null) { |
| // this is a root store with default content provider |
| ISemanticContentProvider parentProvider = initProvider(parentContentProviderId, this); |
| |
| return new ContentProviderData(parentProvider, parentContentProviderId); |
| } |
| |
| ResourceTreeNode oldParent = this.node; |
| |
| while (parent != null) { |
| parentContentProviderId = parent.getTemplateID(); |
| if (parentContentProviderId != null) { |
| break; |
| } |
| oldParent = parent; |
| |
| parent = parent.getParent(); |
| } |
| |
| if (parentContentProviderId == null) { |
| parentContentProviderId = SemanticFileStore.DEFAULT_CONTENT_PROVIDER_ID; |
| parent = oldParent; |
| } |
| |
| // construct the parent |
| parentStore = this.fs.getStore(parent); |
| |
| // TODO move outside of lock? |
| // the first parent with a provider ID |
| ISemanticContentProvider parentProvider = initProvider(parentContentProviderId, parentStore); |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceExit(SfsTraceLocation.CORE_VERBOSE.getLocation(), parentContentProviderId); |
| } |
| |
| return new ContentProviderData(parentProvider, parentContentProviderId); |
| } |
| |
| @Override |
| public File toLocalFile(int options, IProgressMonitor monitor) throws CoreException { |
| // some tools are operating directly on the file system; this enables |
| // these tools |
| // for content providers that have a file system cache by delegating to |
| // this cache |
| // non-caching content providers can not support this |
| // TODO 0.1: think of a more generic solution |
| |
| this.checkAndJoinTreeIfAnotherEntryExists(); |
| |
| if (options != EFS.CACHE && this.node.isExists()) { |
| ISemanticContentProvider effectiveProvider = getEffectiveContentProvider(); |
| if (effectiveProvider instanceof ISemanticContentProviderLocal) { |
| return ((ISemanticContentProviderLocal) effectiveProvider).toLocalFile(this); |
| } |
| // TODO 0.1: check exception handling in tools, adjust error message |
| return null; |
| |
| } |
| |
| IFileStore store = new FileStore() { |
| |
| @Override |
| public URI toURI() { |
| return SemanticFileStore.this.toURI(); |
| } |
| |
| @Override |
| public InputStream openInputStream(int options1, IProgressMonitor monitor1) throws CoreException { |
| return SemanticFileStore.this.openInputStream(options1, monitor1); |
| } |
| |
| @Override |
| public IFileStore getParent() { |
| return SemanticFileStore.this.getParent(); |
| } |
| |
| @Override |
| public String getName() { |
| return SemanticFileStore.this.getName(); |
| } |
| |
| @Override |
| public IFileStore getChild(String name) { |
| return SemanticFileStore.this.getChild(name); |
| } |
| |
| @Override |
| public IFileInfo fetchInfo(int options1, IProgressMonitor monitor1) throws CoreException { |
| IFileInfo info = SemanticFileStore.this.fetchInfo(options1, monitor1); |
| |
| if (info != null && info.exists()) { |
| // clear the read-only flag in order to temporarily fix the |
| // bug 323833 on MacOS |
| if (info.getAttribute(EFS.ATTRIBUTE_READ_ONLY)) { |
| info.setAttribute(EFS.ATTRIBUTE_READ_ONLY, false); |
| } |
| } |
| return info; |
| } |
| |
| @Override |
| public String[] childNames(int options1, IProgressMonitor monitor1) throws CoreException { |
| return SemanticFileStore.this.childNames(options1, monitor1); |
| } |
| }; |
| |
| return store.toLocalFile(options, monitor); |
| } |
| |
| @Override |
| public IFileStore getChild(String name) { |
| |
| IFileStore store = findChild(name); |
| |
| if (store != null) { |
| return store; |
| } |
| |
| ISemanticContentProvider effectiveProvider; |
| |
| try { |
| effectiveProvider = getEffectiveContentProvider(); |
| } catch (CoreException ce) { |
| this.log.log(ce); |
| return EFS.getNullFileSystem().getStore(getPath().append(name)); |
| } |
| // no child found, let's check whether child can be created |
| |
| // TODO 0.1: concurrency we need to detect and handle broken parent |
| // hierarchy |
| // situations |
| // due to concurrency (e.g. parent was deleted in another thread) |
| |
| // check if there is federation |
| |
| String federatedContentProviderId = null; |
| |
| if (effectiveProvider instanceof ISemanticContentProviderFederation) { |
| federatedContentProviderId = ((ISemanticContentProviderFederation) effectiveProvider).getFederatedProviderIDForPath(getPath() |
| .append(name)); |
| } |
| |
| ISemanticFileStore result; |
| try { |
| this.fs.lockForWrite(); |
| |
| this.checkAndJoinTreeIfAnotherEntryExists(); |
| |
| store = findChild(name); |
| |
| if (store != null) { |
| return store; |
| } |
| |
| IPath childPath = this.getPath().append(name); |
| |
| ResourceTreeNode newnode = createLocalChildNode(name, childPath, federatedContentProviderId); |
| |
| result = this.fs.getStore(newnode); |
| } finally { |
| this.fs.unlockForWrite(); |
| } |
| |
| if (result != null) { |
| // notify the content provider |
| effectiveProvider.onImplicitStoreCreate(result); |
| |
| if (federatedContentProviderId != null) { |
| // federation |
| try { |
| result.getEffectiveContentProvider().onImplicitStoreCreate(result); |
| } catch (CoreException e) { |
| // $JL-EXC$ ignore and just trace |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| SfsTraceLocation.getTrace().trace(SfsTraceLocation.CONTENTPROVIDER.getLocation(), e.getMessage(), e); |
| } |
| } |
| } |
| } |
| |
| return result; |
| |
| } |
| |
| @Override |
| public String getName() { |
| try { |
| this.fs.lockForRead(); |
| |
| this.checkAndJoinTreeIfAnotherEntryExists(); |
| |
| return this.node.getName(); |
| } finally { |
| this.fs.unlockForRead(); |
| } |
| } |
| |
| @Override |
| public IFileStore getParent() { |
| try { |
| this.fs.lockForRead(); |
| |
| this.checkAndJoinTreeIfAnotherEntryExists(); |
| |
| ResourceTreeNode parentNode = this.fs.getParentNode(this.node); |
| if (parentNode != null) { |
| return this.fs.getStore(parentNode); |
| } |
| return null; |
| |
| } finally { |
| this.fs.unlockForRead(); |
| } |
| } |
| |
| @Override |
| public InputStream openInputStream(int options, IProgressMonitor monitor) throws CoreException { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| checkAccessible(); |
| |
| try { |
| this.fs.lockForRead(); |
| TreeNodeType type = this.node.getType(); |
| if (type != TreeNodeType.FILE) { |
| throw new SemanticResourceException(SemanticResourceStatusCode.INVALID_RESOURCE_TYPE, getPath(), |
| Messages.SemanticFileStore_OpenInputOnlyOnFiles_XMSG); |
| } |
| } finally { |
| this.fs.unlockForRead(); |
| } |
| |
| final ISemanticContentProvider effectiveProvider = getEffectiveContentProvider(); |
| |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| |
| SfsTraceLocation.getTrace() |
| .trace(SfsTraceLocation.CONTENTPROVIDER.getLocation(), |
| NLS.bind(Messages.SemanticFileStore_OpeningInputInfo_XMSG, effectiveProvider.getClass().getName(), getPath() |
| .toString())); |
| |
| } |
| |
| return effectiveProvider.openInputStream(this, monitor); |
| } |
| |
| @Override |
| public OutputStream openOutputStream(int options, IProgressMonitor monitor) throws CoreException { |
| // TODO 0.1: concurrency/race condition with IFile.getContent() |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| this.checkAndJoinTreeIfAnotherEntryExists(); |
| |
| try { |
| this.fs.lockForRead(); |
| TreeNodeType type = this.node.getType(); |
| if (type != TreeNodeType.FILE && type != TreeNodeType.UNKNOWN) { |
| throw new SemanticResourceException(SemanticResourceStatusCode.INVALID_RESOURCE_TYPE, getPath(), |
| Messages.SemanticFileStore_OpenOutputNotOnFolders_XMSG); |
| } |
| } finally { |
| this.fs.unlockForRead(); |
| } |
| |
| ISemanticContentProvider effectiveProvider = getEffectiveContentProvider(); |
| boolean append = (options & EFS.APPEND) != 0; |
| |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| String message; |
| if (append) { |
| message = NLS.bind(Messages.SemanticFileStore_AppendingInfo_XMSG, effectiveProvider.getClass().getName(), getPath() |
| .toString()); |
| } else { |
| message = NLS.bind(Messages.SemanticFileStore_OpeningInfo_XMSG, effectiveProvider.getClass().getName(), getPath() |
| .toString()); |
| } |
| SfsTraceLocation.getTrace().trace(SfsTraceLocation.CONTENTPROVIDER.getLocation(), message); |
| } |
| |
| ISemanticSpiResourceInfo info = effectiveProvider.fetchResourceInfo(this, ISemanticFileSystem.RESOURCE_INFO_READ_ONLY, monitor); |
| if (info.isReadOnly()) { |
| IStatus status = effectiveProvider.validateSave(this); |
| if (!status.isOK()) { |
| throw new CoreException(status); |
| } |
| } |
| |
| int actOptions = ISemanticFileSystem.NONE; |
| if (append) { |
| actOptions = ISemanticFileSystem.CONTENT_APPEND; |
| } |
| OutputStream os = effectiveProvider.openOutputStream(this, actOptions, monitor); |
| |
| try { |
| this.fs.lockForWrite(); |
| |
| boolean changeRequired = !this.node.isExists() || this.node.getType() != TreeNodeType.FILE; |
| if (changeRequired) { |
| this.fs.switchToExists(this.node, this.fs.getParentNode(this.node)); |
| this.node.setType(TreeNodeType.FILE); |
| try { |
| this.fs.requestFlush(false, this.node); |
| } catch (CoreException e) { |
| Util.safeClose(os); |
| throw e; |
| } |
| } |
| } finally { |
| this.fs.unlockForWrite(); |
| } |
| |
| return os; |
| } |
| |
| @Override |
| public URI toURI() { |
| try { |
| this.fs.lockForRead(); |
| try { |
| return new URI(ISemanticFileSystem.SCHEME, null, null, -1, getPath().toString(), node.getQueryPart(), null); |
| } catch (URISyntaxException e) { |
| throw new RuntimeException(e); |
| } |
| } finally { |
| this.fs.unlockForRead(); |
| } |
| } |
| |
| @Override |
| public SemanticFileSystem getFileSystem() { |
| return this.fs; |
| } |
| |
| @Override |
| public IFileStore mkdir(int options, IProgressMonitor monitor) throws CoreException { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().trace(SfsTraceLocation.CORE_VERBOSE.getLocation(), |
| NLS.bind(Messages.SemanticFileStore_MkDir_XMSG, getPath().toString())); |
| } |
| |
| try { |
| this.fs.lockForWrite(); |
| |
| this.checkAndJoinTreeIfAnotherEntryExists(); |
| |
| ResourceTreeNode parent = this.fs.getParentNode(this.node); |
| ISemanticContentProvider parentProvider = null; |
| |
| if ((options & EFS.SHALLOW) != 0) { |
| if (parent != null && !parent.isExists()) { |
| throw new SemanticResourceException(SemanticResourceStatusCode.RESOURCE_PARENT_DOESNT_EXIST, getPath(), |
| Messages.SemanticFileStore_ShallowMkDirFailed_XMSG); |
| } else if (parent != null) { // and exists |
| parentProvider = fs.getStore(parent).getEffectiveContentProvider(); |
| } else { // parent == null |
| parentProvider = getEffectiveContentProvider(); |
| } |
| } else { |
| if (parent != null && !parent.isExists()) { |
| parentProvider = this.fs.mkdir(parent, this.fs.getParentNode(parent)); |
| } else if (parent != null) { // and exists |
| parentProvider = fs.getStore(parent).getEffectiveContentProvider(); |
| } else { // parent == null |
| parentProvider = getEffectiveContentProvider(); |
| } |
| } |
| this.fs.makeFolder(this.node, parent, parentProvider); |
| |
| } finally { |
| this.fs.unlockForWrite(); |
| } |
| |
| return this; |
| } |
| |
| // |
| // ISemantiFileStoreInternal |
| // |
| public boolean supportsMove(ISemanticFileStore targetParent, String targetName, IProgressMonitor monitor) throws CoreException { |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| final ISemanticContentProvider effectiveProvider = getEffectiveContentProvider(); |
| |
| checkAccessible(); |
| |
| if (targetParent.hasChild(targetName)) { |
| return false; |
| } |
| |
| if (effectiveProvider.isMoveSupportedForStore(this, targetParent, targetName, monitor)) { |
| final ISemanticContentProvider targetProvider = targetParent.getEffectiveContentProvider(); |
| if (targetProvider.isMoveSupportedForStore(this, targetParent, targetName, monitor)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| public void moveTo(ISemanticFileStore targetParent, String targetName, IProgressMonitor monitor) throws CoreException { |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| final ISemanticContentProvider effectiveProvider = getEffectiveContentProvider(); |
| final ISemanticContentProvider targetProvider = targetParent.getEffectiveContentProvider(); |
| |
| checkAccessible(); |
| |
| if (targetParent.hasChild(targetName)) { |
| IPath newPath = targetParent.getPath().append(targetName); |
| throw new SemanticResourceException(SemanticResourceStatusCode.RESOURCE_ALREADY_EXISTS, newPath, NLS.bind( |
| Messages.SemanticFileStore_ResourceWithPathExists_XMSG, newPath.toString())); |
| } |
| |
| targetParent.mkdir(0, monitor); |
| |
| effectiveProvider.detachMovingStore(this, targetParent, targetName, monitor); |
| |
| try { |
| this.fs.lockForWrite(); |
| |
| checkAccessible(); |
| ((SemanticFileStore) targetParent).checkAccessible(); |
| |
| ResourceTreeNode currentParent = this.node.getParent(); |
| |
| this.node.setParent(((SemanticFileStore) targetParent).node); |
| this.node.setName(targetName); |
| |
| this.fs.requestFlush(true, currentParent); |
| this.fs.requestFlush(true, ((SemanticFileStore) targetParent).node); |
| } finally { |
| this.fs.unlockForWrite(); |
| } |
| |
| targetProvider.attachMovingStore(this, targetParent, targetName, monitor); |
| } |
| |
| public void createFileRemotely(String name, InputStream source, Object context, IProgressMonitor monitor) throws CoreException { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| this.mkdir(EFS.NONE, monitor); |
| final ISemanticContentProvider effectiveProvider = getEffectiveContentProvider(); |
| |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| SfsTraceLocation.getTrace().trace( |
| SfsTraceLocation.CONTENTPROVIDER.getLocation(), |
| MessageFormat.format(Messages.SemanticFileStore_CreateFileRemote_XMSG, name, effectiveProvider.getClass().getName(), |
| getPath().toString())); |
| } |
| |
| if (effectiveProvider instanceof ISemanticContentProviderRemote) { |
| ((ISemanticContentProviderRemote) effectiveProvider).createFileRemotely(this, name, source, context, monitor); |
| } else { |
| throw new SemanticResourceException(SemanticResourceStatusCode.METHOD_NOT_SUPPORTED, getPath(), NLS.bind( |
| Messages.SemanticFileStore_IntefaceNotImplemented_XMSG, effectiveProvider.getClass().getName(), |
| ISemanticContentProviderRemote.class.getName())); |
| } |
| |
| } |
| |
| public ISemanticFileStoreInternal createResourceRemotely(String name, Object context, IProgressMonitor monitor) throws CoreException { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| this.mkdir(EFS.NONE, monitor); |
| final ISemanticContentProvider effectiveProvider = getEffectiveContentProvider(); |
| |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| |
| SfsTraceLocation.getTrace().trace( |
| SfsTraceLocation.CONTENTPROVIDER.getLocation(), |
| MessageFormat.format(Messages.SemanticFileStore_CreateResourceRemtoe_XMSG, name, |
| effectiveProvider.getClass().getName(), getPath().toString())); |
| |
| } |
| |
| if (effectiveProvider instanceof ISemanticContentProviderRemote) { |
| ((ISemanticContentProviderRemote) effectiveProvider).createResourceRemotely(this, name, context, monitor); |
| } else { |
| throw new SemanticResourceException(SemanticResourceStatusCode.METHOD_NOT_SUPPORTED, getPath(), NLS.bind( |
| Messages.SemanticFileStore_IntefaceNotImplemented_XMSG, effectiveProvider.getClass().getName(), |
| ISemanticContentProviderRemote.class.getName())); |
| } |
| |
| return findChild(name); |
| } |
| |
| public void addFileFromRemote(String name, IProgressMonitor monitor) throws CoreException { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| this.mkdir(EFS.NONE, monitor); |
| ISemanticContentProvider effectiveProvider = getEffectiveContentProvider(); |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| |
| SfsTraceLocation.getTrace().trace( |
| SfsTraceLocation.CONTENTPROVIDER.getLocation(), |
| MessageFormat.format(Messages.SemanticFileStore_AddFileRemote_XMSG, name, effectiveProvider.getClass().getName(), |
| getPath().toString())); |
| } |
| |
| // delegate to content provider |
| effectiveProvider.addResource(this, name, ResourceType.FILE_TYPE, monitor); |
| |
| } |
| |
| public void addFileFromRemoteByURI(String name, URI uri, IProgressMonitor monitor) throws CoreException { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| this.mkdir(EFS.NONE, monitor); |
| ISemanticContentProvider effectiveProvider = getEffectiveContentProvider(); |
| |
| // delegate to content provider |
| if (effectiveProvider instanceof ISemanticContentProviderREST) { |
| |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| |
| SfsTraceLocation.getTrace().trace( |
| SfsTraceLocation.CONTENTPROVIDER.getLocation(), |
| MessageFormat.format(Messages.SemanticFileStore_AddFileRemoteURI_XMSG, name, uri.toString(), effectiveProvider |
| .getClass().getName(), getPath().toString())); |
| |
| } |
| |
| ((ISemanticContentProviderREST) effectiveProvider).addFileFromRemoteByURI(this, name, uri, monitor); |
| |
| } else { |
| throw new SemanticResourceException(SemanticResourceStatusCode.METHOD_NOT_SUPPORTED, getPath(), NLS.bind( |
| Messages.SemanticFileStore_IntefaceNotImplemented_XMSG, effectiveProvider.getClass().getName(), |
| ISemanticContentProviderREST.class.getName())); |
| } |
| |
| } |
| |
| public void addFolderFromRemoteByURI(String name, URI uri, IProgressMonitor monitor) throws CoreException { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| this.mkdir(EFS.NONE, monitor); |
| ISemanticContentProvider effectiveProvider = getEffectiveContentProvider(); |
| |
| // delegate to content provider |
| if (effectiveProvider instanceof ISemanticContentProviderREST) { |
| |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| |
| SfsTraceLocation.getTrace().trace( |
| SfsTraceLocation.CONTENTPROVIDER.getLocation(), |
| MessageFormat.format(Messages.SemanticFileStore_AddFileRemoteURI_XMSG, name, uri.toString(), effectiveProvider |
| .getClass().getName(), getPath().toString())); |
| } |
| |
| ((ISemanticContentProviderREST) effectiveProvider).addFolderFromRemoteByURI(this, name, uri, monitor); |
| |
| } else { |
| throw new SemanticResourceException(SemanticResourceStatusCode.METHOD_NOT_SUPPORTED, getPath(), NLS.bind( |
| Messages.SemanticFileStore_IntefaceNotImplemented_XMSG, effectiveProvider.getClass().getName(), |
| ISemanticContentProviderREST.class.getName())); |
| } |
| |
| } |
| |
| public void addFolderFromRemote(String name, IProgressMonitor monitor) throws CoreException { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| this.mkdir(EFS.NONE, monitor); |
| final ISemanticContentProvider effectiveProvider = getEffectiveContentProvider(); |
| |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| |
| SfsTraceLocation.getTrace().trace( |
| SfsTraceLocation.CONTENTPROVIDER.getLocation(), |
| MessageFormat.format(Messages.SemanticFileStore_AddFolderRemote_XMSG, name, effectiveProvider.getClass().getName(), |
| getPath().toString())); |
| } |
| |
| // delegate to content provider |
| effectiveProvider.addResource(this, name, ResourceType.FOLDER_TYPE, monitor); |
| |
| } |
| |
| public ISemanticFileStoreInternal addResourceFromRemote(String name, IProgressMonitor monitor) throws CoreException { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| this.mkdir(EFS.NONE, monitor); |
| final ISemanticContentProvider effectiveProvider = getEffectiveContentProvider(); |
| |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| |
| SfsTraceLocation.getTrace().trace( |
| SfsTraceLocation.CONTENTPROVIDER.getLocation(), |
| MessageFormat.format(Messages.SemanticFileStore_AddResourceRemote_XMSG, name, effectiveProvider.getClass().getName(), |
| getPath().toString())); |
| } |
| |
| // delegate to content provider |
| effectiveProvider.addResource(this, name, ResourceType.UNKNOWN_TYPE, monitor); |
| |
| return findChild(name); |
| } |
| |
| public void addResource(String name, boolean asFolder, String contentProviderID, Map<QualifiedName, String> properties, |
| IProgressMonitor monitor) throws CoreException { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| this.mkdir(EFS.NONE, monitor); |
| final ISemanticContentProvider effectiveProvider = getEffectiveContentProvider(); |
| |
| if (effectiveProvider instanceof ISemanticContentProviderFederation) { |
| ((ISemanticContentProviderFederation) effectiveProvider).addResource(this, name, asFolder ? ResourceType.FOLDER_TYPE |
| : ResourceType.FILE_TYPE, contentProviderID, properties); |
| } else { |
| throw new SemanticResourceException(SemanticResourceStatusCode.METHOD_NOT_SUPPORTED, getPath(), NLS.bind( |
| Messages.SemanticFileStore_IntefaceNotImplemented_XMSG, effectiveProvider.getClass().getName(), |
| ISemanticContentProviderFederation.class.getName())); |
| } |
| |
| } |
| |
| @Override |
| public void delete(int options, IProgressMonitor monitor) throws CoreException { |
| // this will be called instead of delete hook if no team provider is |
| // found |
| // or if resource is marked as derived |
| // TODO 0.1: review this behavior e.g. with respect to linked resources |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| removeFromWorkspace(monitor); |
| |
| } |
| |
| public void deleteRemotely(IProgressMonitor monitor) throws CoreException { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| this.checkAndJoinTreeIfAnotherEntryExists(); |
| |
| final ISemanticContentProvider effectiveProvider = getEffectiveContentProvider(); |
| |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| SfsTraceLocation.getTrace().trace( |
| SfsTraceLocation.CONTENTPROVIDER.getLocation(), |
| NLS.bind(Messages.SemanticFileStore_DeleteResourceRemote_XMSG, getPath().toString(), effectiveProvider.getClass() |
| .getName())); |
| } |
| |
| if (effectiveProvider instanceof ISemanticContentProviderRemote) { |
| ((ISemanticContentProviderRemote) effectiveProvider).deleteRemotely(this, monitor); |
| } else { |
| throw new SemanticResourceException(SemanticResourceStatusCode.METHOD_NOT_SUPPORTED, getPath(), NLS.bind( |
| Messages.SemanticFileStore_IntefaceNotImplemented_XMSG, effectiveProvider.getClass().getName(), |
| ISemanticContentProviderRemote.class.getName())); |
| } |
| } |
| |
| public void removeFromWorkspace(IProgressMonitor monitor) throws CoreException { |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| final ISemanticContentProvider effectiveProvider = getEffectiveContentProvider(); |
| |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| |
| SfsTraceLocation.getTrace().trace( |
| SfsTraceLocation.CONTENTPROVIDER.getLocation(), |
| NLS.bind(Messages.SemanticFileStore_RemoveResourceRemote_XMSG, getPath().toString(), effectiveProvider.getClass() |
| .getName())); |
| } |
| |
| checkAccessible(); |
| |
| effectiveProvider.removeResource(this, monitor); |
| } |
| |
| public void forceRemoveFromWorkspace(int options, IProgressMonitor monitor) throws CoreException { |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| checkAccessible(); |
| |
| new FileCacheServiceFactory().getCacheService().removeContentRecursive(getPath(), monitor); |
| new MemoryCacheServiceFactory().getCacheService().removeContentRecursive(getPath(), monitor); |
| |
| this.remove(monitor); |
| } |
| |
| public void forceRemove(int options, IProgressMonitor monitor) throws CoreException { |
| forceRemoveFromWorkspace(options, monitor); |
| } |
| |
| public void synchronizeContentWithRemote(SyncDirection direction, IProgressMonitor monitor) throws CoreException { |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| final ISemanticContentProvider effectiveProvider = getEffectiveContentProvider(); |
| |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| SfsTraceLocation.getTrace().trace(SfsTraceLocation.CONTENTPROVIDER.getLocation(), |
| NLS.bind(Messages.SemanticFileStore_SynchContent_XMSG, effectiveProvider.getClass().getName(), getPath().toString())); |
| |
| } |
| |
| checkAccessible(); |
| |
| MultiStatus status = new MultiStatus(SemanticResourcesPlugin.PLUGIN_ID, IStatus.OK, NLS.bind( |
| Messages.SemanticFileStore_SyncContent_XGRP, getPath().toString()), null); |
| effectiveProvider.synchronizeContentWithRemote(this, direction, monitor, status); |
| if (!status.isOK()) { |
| throw new CoreException(status); |
| } |
| } |
| |
| public void setRemoteURI(URI uri, IProgressMonitor monitor) throws CoreException { |
| |
| final ISemanticContentProvider effectiveProvider = getEffectiveContentProvider(); |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| checkAccessible(); |
| |
| // delegate to content provider |
| if (effectiveProvider instanceof ISemanticContentProviderREST) { |
| |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| |
| SfsTraceLocation.getTrace().trace( |
| SfsTraceLocation.CONTENTPROVIDER.getLocation(), |
| MessageFormat.format(Messages.SemanticFileStore_SettingURI_XMSG, uri.toString(), effectiveProvider.getClass() |
| .getName(), getPath().toString())); |
| } |
| |
| ((ISemanticContentProviderREST) effectiveProvider).setURIString(this, uri, monitor); |
| |
| } else { |
| throw new SemanticResourceException(SemanticResourceStatusCode.METHOD_NOT_SUPPORTED, getPath(), NLS.bind( |
| Messages.SemanticFileStore_IntefaceNotImplemented_XMSG, effectiveProvider.getClass().getName(), |
| ISemanticContentProviderREST.class.getName())); |
| } |
| } |
| |
| public void revertChanges(IProgressMonitor monitor) throws CoreException { |
| |
| final ISemanticContentProvider effectiveProvider = getEffectiveContentProvider(); |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| |
| SfsTraceLocation.getTrace().trace(SfsTraceLocation.CONTENTPROVIDER.getLocation(), |
| NLS.bind(Messages.SemanticFileStore_Revert_XMSG, getPath().toString(), effectiveProvider.getClass().getName())); |
| } |
| |
| checkAccessible(); |
| |
| effectiveProvider.revertChanges(this, monitor); |
| } |
| |
| public IStatus lockResource(IProgressMonitor monitor) throws CoreException { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| final ISemanticContentProvider effectiveProvider = getEffectiveContentProvider(); |
| |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| |
| SfsTraceLocation.getTrace().trace(SfsTraceLocation.CONTENTPROVIDER.getLocation(), |
| NLS.bind(Messages.SemanticFileStore_Locking_XMSG, getPath().toString(), effectiveProvider.getClass().getName())); |
| } |
| |
| checkAccessible(); |
| |
| if (effectiveProvider instanceof ISemanticContentProviderLocking) { |
| return ((ISemanticContentProviderLocking) effectiveProvider).lockResource(this, monitor); |
| } |
| |
| return new Status(IStatus.ERROR, SemanticResourcesPlugin.PLUGIN_ID, NLS.bind( |
| Messages.SemanticFileStore_IntefaceNotImplemented_XMSG, effectiveProvider.getClass().getName(), |
| ISemanticContentProviderLocking.class.getName())); |
| } |
| |
| public IStatus unlockResource(IProgressMonitor monitor) throws CoreException { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| final ISemanticContentProvider effectiveProvider = getEffectiveContentProvider(); |
| |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| |
| SfsTraceLocation.getTrace().trace(SfsTraceLocation.CONTENTPROVIDER.getLocation(), |
| NLS.bind(Messages.SemanticFileStore_Unlocking_XMSG, getPath().toString(), effectiveProvider.getClass().getName())); |
| } |
| |
| checkAccessible(); |
| |
| if (effectiveProvider instanceof ISemanticContentProviderLocking) { |
| return ((ISemanticContentProviderLocking) effectiveProvider).unlockResource(this, monitor); |
| } |
| |
| return new Status(IStatus.ERROR, SemanticResourcesPlugin.PLUGIN_ID, NLS.bind( |
| Messages.SemanticFileStore_IntefaceNotImplemented_XMSG, effectiveProvider.getClass().getName(), |
| ISemanticContentProviderLocking.class.getName())); |
| } |
| |
| public IStatus validateRemoteCreate(String name, Object shell) { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| ISemanticContentProvider effectiveProvider; |
| try { |
| checkAccessible(); |
| effectiveProvider = getEffectiveContentProvider(); |
| } catch (CoreException ce) { |
| this.log.log(ce); |
| return ce.getStatus(); |
| } |
| |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| |
| SfsTraceLocation.getTrace().trace( |
| SfsTraceLocation.CONTENTPROVIDER.getLocation(), |
| MessageFormat.format(Messages.SemanticFileStore_ValidateRemoteCreate_XMSG, name, |
| effectiveProvider.getClass().getName(), getPath().toString())); |
| } |
| |
| if (effectiveProvider instanceof ISemanticContentProviderRemote) { |
| return ((ISemanticContentProviderRemote) effectiveProvider).validateRemoteCreate(this, name, shell); |
| } |
| |
| return new Status(IStatus.ERROR, SemanticResourcesPlugin.PLUGIN_ID, NLS.bind( |
| Messages.SemanticFileStore_IntefaceNotImplemented_XMSG, effectiveProvider.getClass().getName(), |
| ISemanticContentProviderRemote.class.getName())); |
| } |
| |
| public IStatus validateRemoteDelete(Object shell) { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| try { |
| checkAccessible(); |
| } catch (CoreException e) { |
| return e.getStatus(); |
| } |
| |
| boolean canBeDeleted; |
| ISemanticContentProvider effectiveProvider; |
| try { |
| effectiveProvider = getEffectiveContentProvider(); |
| |
| } catch (CoreException e) { |
| this.log.log(e); |
| return e.getStatus(); |
| } |
| |
| try { |
| this.fs.lockForRead(); |
| canBeDeleted = this.node.isExists(); |
| |
| } finally { |
| this.fs.unlockForRead(); |
| } |
| |
| if (canBeDeleted) { |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| |
| SfsTraceLocation.getTrace().trace( |
| SfsTraceLocation.CONTENTPROVIDER.getLocation(), |
| MessageFormat.format(Messages.SemanticFileStore_ValidateRemoteDelete_XMSG, getPath().toString(), effectiveProvider |
| .getClass().getName())); |
| } |
| |
| if (effectiveProvider instanceof ISemanticContentProviderRemote) { |
| return ((ISemanticContentProviderRemote) effectiveProvider).validateRemoteDelete(this, shell); |
| } |
| |
| return new Status(IStatus.ERROR, SemanticResourcesPlugin.PLUGIN_ID, NLS.bind( |
| Messages.SemanticFileStore_IntefaceNotImplemented_XMSG, effectiveProvider.getClass().getName(), |
| ISemanticContentProviderRemote.class.getName())); |
| } |
| return new Status(IStatus.CANCEL, SemanticResourcesPlugin.PLUGIN_ID, null); |
| } |
| |
| public IStatus validateRemove(int options, IProgressMonitor monitor) { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| try { |
| checkAccessible(); |
| } catch (CoreException e) { |
| return e.getStatus(); |
| } |
| |
| boolean canBeDeleted; |
| ISemanticContentProvider effectiveProvider; |
| try { |
| |
| effectiveProvider = getEffectiveContentProvider(); |
| |
| } catch (CoreException e) { |
| this.log.log(e); |
| return e.getStatus(); |
| } |
| |
| try { |
| this.fs.lockForRead(); |
| canBeDeleted = this.node.isExists(); |
| |
| } finally { |
| this.fs.unlockForRead(); |
| } |
| |
| if (canBeDeleted) { |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| SfsTraceLocation.getTrace().trace( |
| SfsTraceLocation.CONTENTPROVIDER.getLocation(), |
| NLS.bind(Messages.SemanticFileStore_ValidateRemove_XMSG, getPath().toString(), effectiveProvider.getClass() |
| .getName())); |
| } |
| try { |
| return effectiveProvider.validateRemove(this, options, monitor); |
| } catch (CoreException e) { |
| this.log.log(e); |
| return e.getStatus(); |
| } |
| |
| } |
| return new Status(IStatus.CANCEL, SemanticResourcesPlugin.PLUGIN_ID, null); |
| } |
| |
| public void addChildFolder(String name) throws CoreException { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| if (SfsTraceLocation.CORE.isActive()) { |
| |
| SfsTraceLocation.getTrace().trace(SfsTraceLocation.CORE.getLocation(), |
| NLS.bind(Messages.SemanticFileStore_AddChildFolder_XMSG, name, getPath().toString())); |
| } |
| |
| try { |
| this.fs.lockForWrite(); |
| |
| checkAccessible(); |
| |
| checkChildExists(name); |
| |
| createChildNode(name, true, null); |
| |
| this.fs.requestFlush(false, this.node); |
| } finally { |
| this.fs.unlockForWrite(); |
| } |
| } |
| |
| public void addChildResource(String name, boolean asFolder, String contentProviderID, Map<QualifiedName, String> properties) |
| throws CoreException { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| if (SfsTraceLocation.CORE.isActive()) { |
| String message; |
| if (asFolder) { |
| message = NLS.bind(Messages.SemanticFileStore_AddContentProviderRootFolder_XMSG, name, getPath().toString()); |
| } else { |
| message = NLS.bind(Messages.SemanticFileStore_AddContentProviderRootFile_XMSG, name, getPath().toString()); |
| } |
| |
| SfsTraceLocation.getTrace().trace(SfsTraceLocation.CORE.getLocation(), message); |
| |
| } |
| |
| ResourceTreeNode child; |
| try { |
| this.fs.lockForWrite(); |
| |
| checkAccessible(); |
| |
| checkChildExists(name); |
| |
| child = createChildNode(name, asFolder, contentProviderID); |
| |
| HashMap<String, String> propsMap = new HashMap<String, String>(); |
| if (properties != null && !properties.isEmpty()) { |
| for (Map.Entry<QualifiedName, String> entry : properties.entrySet()) { |
| propsMap.put(Util.qualifiedNameToString(entry.getKey()), entry.getValue()); |
| } |
| child.setPersistentProperties(propsMap); |
| } else { |
| // we don't use an empty map, but null |
| child.setPersistentProperties(null); |
| } |
| this.fs.requestFlush(false, this.node); |
| |
| } finally { |
| this.fs.unlockForWrite(); |
| } |
| |
| if (contentProviderID != null) { |
| ISemanticFileStore store = this.fs.getStore(child); |
| |
| store.getEffectiveContentProvider().onRootStoreCreate(store); |
| } |
| } |
| |
| public void addChildFile(String name) throws CoreException { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| if (SfsTraceLocation.CORE.isActive()) { |
| |
| SfsTraceLocation.getTrace().trace(SfsTraceLocation.CORE.getLocation(), |
| NLS.bind(Messages.SemanticFileStore_AddChildFile_XMSG, name, getPath().toString())); |
| } |
| |
| try { |
| this.fs.lockForWrite(); |
| |
| checkAccessible(); |
| |
| checkChildExists(name); |
| |
| createChildNode(name, false, null); |
| |
| this.fs.requestFlush(false, this.node); |
| } finally { |
| this.fs.unlockForWrite(); |
| } |
| } |
| |
| public void addLocalChildResource(String name, String contentProviderID) throws CoreException { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| if (SfsTraceLocation.CORE.isActive()) { |
| |
| SfsTraceLocation.getTrace().trace(SfsTraceLocation.CORE.getLocation(), |
| NLS.bind(Messages.SemanticFileStore_AddLocalChild_XMSG, name, getPath().toString())); |
| } |
| |
| try { |
| this.fs.lockForWrite(); |
| |
| checkAccessible(); |
| |
| checkChildExists(name); |
| |
| createLocalChildNode(name, this.getPath().append(name), contentProviderID); |
| |
| this.fs.requestFlush(false, this.node); |
| } finally { |
| this.fs.unlockForWrite(); |
| } |
| } |
| |
| public boolean hasResource(String name) { |
| |
| try { |
| this.fs.lockForRead(); |
| |
| this.checkAndJoinTreeIfAnotherEntryExists(); |
| |
| EList<ResourceTreeNode> children = this.node.getChildren(); |
| for (ResourceTreeNode resourceTreeNode : children) { |
| if (resourceTreeNode.getName().equals(name)) { |
| return resourceTreeNode.isExists(); |
| } |
| } |
| return false; |
| } finally { |
| this.fs.unlockForRead(); |
| } |
| } |
| |
| public boolean hasChild(String name) { |
| return hasResource(name); |
| } |
| |
| public String getContentProviderID() { |
| try { |
| this.fs.lockForRead(); |
| |
| this.checkAndJoinTreeIfAnotherEntryExists(); |
| |
| return this.node.getTemplateID(); |
| } finally { |
| this.fs.unlockForRead(); |
| } |
| } |
| |
| public URI getRemoteURI() throws CoreException { |
| |
| checkAccessible(); |
| |
| final ISemanticContentProvider effectiveProvider = getEffectiveContentProvider(); |
| |
| if (effectiveProvider instanceof ISemanticContentProviderREST) { |
| try { |
| String uriString = ((ISemanticContentProviderREST) effectiveProvider).getURIString(this); |
| |
| return new URI(uriString); |
| } catch (URISyntaxException e) { |
| throw new SemanticResourceException(SemanticResourceStatusCode.INVALID_URI_SYNTAX, getPath(), NLS.bind( |
| Messages.SemanticFileStore_InvalidURISyntax_XMSG, effectiveProvider.getClass().getName(), |
| ISemanticContentProviderREST.class.getName())); |
| } |
| } |
| throw new SemanticResourceException(SemanticResourceStatusCode.METHOD_NOT_SUPPORTED, getPath(), NLS.bind( |
| Messages.SemanticFileStore_IntefaceNotImplemented_XMSG, effectiveProvider.getClass().getName(), |
| ISemanticContentProviderREST.class.getName())); |
| |
| } |
| |
| public boolean isExists() { |
| try { |
| this.fs.lockForRead(); |
| |
| this.checkAndJoinTreeIfAnotherEntryExists(); |
| |
| return this.node.isExists(); |
| } finally { |
| this.fs.unlockForRead(); |
| } |
| } |
| |
| public boolean isLocalOnly() { |
| try { |
| this.fs.lockForRead(); |
| |
| this.checkAndJoinTreeIfAnotherEntryExists(); |
| |
| return this.node.isLocalOnly(); |
| } finally { |
| this.fs.unlockForRead(); |
| } |
| } |
| |
| public void setLocalOnly(boolean isLocalOnly) { |
| try { |
| this.fs.lockForWrite(); |
| |
| this.checkAndJoinTreeIfAnotherEntryExists(); |
| |
| this.node.setLocalOnly(isLocalOnly); |
| } finally { |
| this.fs.unlockForWrite(); |
| } |
| } |
| |
| // |
| // private section |
| // |
| /** |
| * @param name |
| */ |
| private SemanticFileStore findChild(String name) { |
| try { |
| this.fs.lockForRead(); |
| |
| this.checkAndJoinTreeIfAnotherEntryExists(); |
| |
| EList<ResourceTreeNode> children = this.node.getChildren(); |
| |
| for (ResourceTreeNode resourceTreeNode : children) { |
| if (resourceTreeNode.getName().equals(name)) { |
| return (SemanticFileStore) this.fs.getStore(resourceTreeNode); |
| } |
| } |
| } finally { |
| this.fs.unlockForRead(); |
| } |
| return null; |
| } |
| |
| private ResourceTreeNode createChildNode(String name, boolean isFolder, String contentProviderID) { |
| // all callers have a lock, so we don't lock here |
| ResourceTreeNode child = SemanticResourceDBFactory.eINSTANCE.createResourceTreeNode(); |
| |
| child.setName(name); |
| child.setTemplateID(contentProviderID); |
| |
| if (isFolder) { |
| child.setType(TreeNodeType.FOLDER); |
| // folders are always local-only |
| child.setLocalOnly(true); |
| } else { |
| child.setType(TreeNodeType.FILE); |
| child.setLocalOnly(false); |
| } |
| |
| child.setExists(true); |
| child.setParent(this.node); |
| |
| return child; |
| } |
| |
| private ResourceTreeNode createLocalChildNode(String name, IPath childPath, String contentProviderID) { |
| // all callers have a lock, so we don't lock here |
| ResourceTreeNode child = SemanticResourceDBFactory.eINSTANCE.createResourceTreeNode(); |
| |
| child.setName(name); |
| child.setTemplateID(contentProviderID); |
| child.setType(TreeNodeType.UNKNOWN); |
| child.setExists(false); // needed to comply with resource creation |
| // behavior |
| child.setPath(childPath.toString()); |
| child.setLocalOnly(true); |
| |
| return child; |
| } |
| |
| /* |
| * private ResourceTreeNode createPhantomNode(String name, boolean |
| * isDirectory, URI uri) { ResourceTreeNode child = |
| * SemanticResourceDBFactory.eINSTANCE.createResourceTreeNode(); |
| * |
| * child.setName(name); child.setIsDirectory(isDirectory); |
| * child.setExists(false); child.setPhantom(true); child.setReadOnly(false); |
| * child.setParent(node); child.setLastModified(System.currentTimeMillis()); |
| * |
| * if ( uri != null ) { child.setRemoteURI(uri.toString()); } return child; |
| * } |
| */ |
| /** |
| * throws exception if child exists |
| */ |
| private void checkChildExists(String name) throws CoreException { |
| // all callers have obtained a lock, so we don't lock here |
| EList<ResourceTreeNode> children = this.node.getChildren(); |
| |
| for (ResourceTreeNode resourceTreeNode : children) { |
| if (resourceTreeNode.getName().equals(name)) { |
| if (resourceTreeNode.isExists()) { |
| IPath newPath = getPath().append(name); |
| throw new SemanticResourceException(SemanticResourceStatusCode.RESOURCE_ALREADY_EXISTS, newPath, NLS.bind( |
| Messages.SemanticFileStore_ResourceWithPathExists_XMSG, newPath.toString())); |
| } |
| } |
| } |
| } |
| |
| private static void cleanupNodeAndChildren(ResourceTreeNode node, IPath path) { |
| EList<ResourceTreeNode> children = node.getChildren(); |
| |
| for (ResourceTreeNode resourceTreeNode : children) { |
| cleanupNodeAndChildren(resourceTreeNode, path.append(resourceTreeNode.getName())); |
| } |
| |
| // keep the last path so that getPath returns something meaningful after |
| // remove |
| node.setPath(path.toString()); |
| node.setExists(false); |
| |
| node.setPersistentProperties(null); |
| node.setSessionProperties(null); |
| |
| children.clear(); |
| } |
| |
| public IStatus validateEdit(Object shell) { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| try { |
| checkAccessible(); |
| } catch (CoreException e) { |
| return e.getStatus(); |
| } |
| |
| boolean canBeEdited; |
| ISemanticContentProvider effectiveProvider; |
| try { |
| effectiveProvider = getEffectiveContentProvider(); |
| } catch (CoreException e) { |
| this.log.log(e); |
| return e.getStatus(); |
| } |
| |
| try { |
| this.fs.lockForRead(); |
| // exist could be false if node was created, but no content was |
| // written yet |
| canBeEdited = this.node.isExists() && this.node.getType().equals(TreeNodeType.FILE); |
| |
| } finally { |
| this.fs.unlockForRead(); |
| } |
| |
| if (canBeEdited) { |
| |
| boolean readOnly; |
| |
| try { |
| readOnly = effectiveProvider.fetchResourceInfo(this, ISemanticFileSystem.RESOURCE_INFO_READ_ONLY, null).isReadOnly(); |
| } catch (CoreException e) { |
| this.log.log(e); |
| return e.getStatus(); |
| } |
| |
| if (readOnly) { |
| |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| SfsTraceLocation.getTrace().trace( |
| SfsTraceLocation.CONTENTPROVIDER.getLocation(), |
| NLS.bind(Messages.SemanticFileStore_ValidateEdit_XMSG, effectiveProvider.getClass().getName(), getPath() |
| .toString())); |
| |
| } |
| |
| return effectiveProvider.validateEdit(new ISemanticFileStore[] {this}, shell); |
| } |
| // already checked out |
| return new Status(IStatus.OK, SemanticResourcesPlugin.PLUGIN_ID, null); |
| |
| } |
| return new Status(IStatus.CANCEL, SemanticResourcesPlugin.PLUGIN_ID, null); |
| |
| } |
| |
| public IStatus validateSave() { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| try { |
| checkAccessible(); |
| } catch (CoreException e) { |
| return e.getStatus(); |
| } |
| |
| boolean canBeSaved; |
| ISemanticContentProvider effectiveProvider; |
| try { |
| effectiveProvider = getEffectiveContentProvider(); |
| } catch (CoreException e) { |
| this.log.log(e); |
| return e.getStatus(); |
| } |
| |
| try { |
| this.fs.lockForRead(); |
| canBeSaved = this.node.isExists() && this.node.getType().equals(TreeNodeType.FILE); |
| |
| } finally { |
| this.fs.unlockForRead(); |
| } |
| |
| if (canBeSaved) { |
| boolean readOnly; |
| try { |
| readOnly = effectiveProvider.fetchResourceInfo(this, ISemanticFileSystem.RESOURCE_INFO_READ_ONLY, null).isReadOnly(); |
| } catch (CoreException e) { |
| this.log.log(e); |
| return e.getStatus(); |
| } |
| if (!readOnly) { |
| if (SfsTraceLocation.CONTENTPROVIDER.isActive()) { |
| |
| SfsTraceLocation.getTrace().trace( |
| SfsTraceLocation.CONTENTPROVIDER.getLocation(), |
| NLS.bind(Messages.SemanticFileStore_ValidateSave_XMSG, effectiveProvider.getClass().getName(), getPath() |
| .toString())); |
| } |
| return effectiveProvider.validateSave(this); |
| } |
| // not checked out |
| return new Status(IStatus.CANCEL, SemanticResourcesPlugin.PLUGIN_ID, NLS.bind(Messages.SemanticFileStore_NotWritable_XMSG, |
| getPath().toString())); |
| } |
| return new Status(IStatus.CANCEL, SemanticResourcesPlugin.PLUGIN_ID, null); |
| |
| } |
| |
| public IPath getPath() { |
| |
| try { |
| this.fs.lockForRead(); |
| |
| this.checkAndJoinTreeIfAnotherEntryExists(); |
| |
| return this.fs.getPathForNode(this.node); |
| } finally { |
| this.fs.unlockForRead(); |
| } |
| |
| } |
| |
| public void remove(IProgressMonitor monitor) throws CoreException { |
| |
| if (SfsTraceLocation.CORE_VERBOSE.isActive()) { |
| SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE_VERBOSE.getLocation()); |
| } |
| |
| if (SfsTraceLocation.CORE.isActive()) { |
| |
| SfsTraceLocation.getTrace().trace(SfsTraceLocation.CORE.getLocation(), |
| NLS.bind(Messages.SemanticFileStore_RemovingResource_XMSG, getPath().toString())); |
| } |
| |
| try { |
| this.fs.lockForWrite(); |
| |
| this.checkAccessible(); |
| |
| SemanticFileStore.cleanupNodeAndChildren(node, getPath()); |
| |
| ResourceTreeNode topParent = this.fs.getHighestParent(this.node); |
| |
| if (this.node instanceof TreeRoot) { |
| ((TreeRoot) this.node).setParentDB(null); |
| } else { |
| this.node.setParent(null); |
| } |
| |
| this.fs.requestFlush(false, topParent); |
| |
| this.fs.requestURILocatorRebuild(); |
| } finally { |
| this.fs.unlockForWrite(); |
| } |
| } |
| |
| public ISemanticResourceInfo fetchResourceInfo(int options, IProgressMonitor monitor) throws CoreException { |
| // checkAccessible(); |
| |
| ISemanticSpiResourceInfo providerInfo = getEffectiveContentProvider().fetchResourceInfo(this, options, getNotNullMonitor(monitor)); |
| return new SemanticResourceInfo(options, providerInfo, isLocalOnly()); |
| } |
| |
| public int getType() { |
| try { |
| this.fs.lockForRead(); |
| |
| this.checkAndJoinTreeIfAnotherEntryExists(); |
| |
| return this.node.getType().getValue(); |
| } finally { |
| this.fs.unlockForRead(); |
| } |
| |
| } |
| |
| public ISemanticFileStoreInternal getChildResource(String name) { |
| // TODO checkAccessible()?? |
| return findChild(name); |
| } |
| |
| /** |
| * This is called during initialization of this class |
| * |
| * @param contentProvider |
| * the responsible content provider |
| */ |
| public void setProvider(ISemanticContentProvider contentProvider) { |
| this.provider = contentProvider; |
| } |
| |
| /** |
| * @throws CoreException |
| */ |
| @Override |
| protected void notifyPersistentPropertySet(String keyString, String oldValue, String newValue) throws CoreException { |
| // nothing to do for now |
| } |
| |
| public IPath[] findURI(URI uri, IProgressMonitor monitor) throws CoreException { |
| return this.fs.getURILocatorService(monitor).locateURI(uri, getPath()); |
| } |
| |
| public String getRemoteURIString() { |
| return node.getRemoteURI(); |
| } |
| |
| public void setRemoteURIString(String uriString) { |
| String oldValue = node.getRemoteURI(); |
| |
| node.setRemoteURI(uriString); |
| |
| if (this.fs.getURILocator() != null) { |
| if ((oldValue == null && uriString != null) || (oldValue != null && !oldValue.equals(uriString))) { |
| IPath path = getPath(); |
| if (oldValue != null) { |
| this.fs.getURILocator().removeURI(path, oldValue); |
| } |
| if (uriString != null) { |
| this.fs.getURILocator().addURI(path, uriString); |
| } |
| } |
| } |
| } |
| |
| private IProgressMonitor getNotNullMonitor(IProgressMonitor monitor) { |
| if (monitor == null) { |
| return new NullProgressMonitor(); |
| } |
| return monitor; |
| } |
| |
| } |