diff options
author | Eduard Bartsch | 2012-04-04 15:43:05 +0000 |
---|---|---|
committer | Eduard Bartsch | 2012-04-04 15:43:05 +0000 |
commit | 4b368db281e0df461ec403aa53da72d1088cb0c6 (patch) | |
tree | 519574e2ab3f5fa5b686a120bec22dcc584a9866 | |
parent | ab7c1aeab1984b66986f15a1ea3417b9cad3b3bb (diff) | |
download | org.eclipse.e4.resources-4b368db281e0df461ec403aa53da72d1088cb0c6.tar.gz org.eclipse.e4.resources-4b368db281e0df461ec403aa53da72d1088cb0c6.tar.xz org.eclipse.e4.resources-4b368db281e0df461ec403aa53da72d1088cb0c6.zip |
Bug 375973 - [sfs] Implement move operation for SFS file resources
23 files changed, 660 insertions, 50 deletions
diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ISemanticFileStoreInternal.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ISemanticFileStoreInternal.java index b43322f..16869b7 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ISemanticFileStoreInternal.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/ISemanticFileStoreInternal.java @@ -18,6 +18,7 @@ import java.util.Map; import org.eclipse.core.resources.semantic.ISemanticProperties; import org.eclipse.core.resources.semantic.ISemanticResourceInfo; import org.eclipse.core.resources.semantic.SyncDirection; +import org.eclipse.core.resources.semantic.spi.ISemanticFileStore; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; @@ -95,4 +96,8 @@ interface ISemanticFileStoreInternal extends ISemanticProperties { public void forceRemoveFromWorkspace(int options, IProgressMonitor monitor) throws CoreException; + public boolean supportsMove(ISemanticFileStore targetParent, String targetName, IProgressMonitor monitor) throws CoreException; + + public void moveTo(ISemanticFileStore targetParent, String targetName, IProgressMonitor monitor) throws CoreException; + } diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/Messages.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/Messages.java index d53db1e..d6332ad 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/Messages.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/Messages.java @@ -15,6 +15,7 @@ import org.eclipse.osgi.util.NLS; public class Messages extends NLS { private static final String BUNDLE_NAME = "org.eclipse.core.internal.resources.semantic.messages"; //$NON-NLS-1$ + public static String SemanticFileStore_SupportsMove_XMSG; public static String SemanticFileStore_AddChildFile_XMSG; public static String SemanticFileStore_AddChildFolder_XMSG; public static String SemanticFileStore_AddContentProviderRootFile_XMSG; diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticFileAdapterImpl.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticFileAdapterImpl.java index 32fde39..d7ad6fb 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticFileAdapterImpl.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticFileAdapterImpl.java @@ -12,11 +12,15 @@ package org.eclipse.core.internal.resources.semantic; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.semantic.ISemanticFile; import org.eclipse.core.resources.semantic.ISemanticFileSystem; +import org.eclipse.core.resources.semantic.ISemanticFolder; +import org.eclipse.core.resources.semantic.spi.ISemanticFileStore; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; /** * The {@link ISemanticFile} implementation. @@ -81,4 +85,51 @@ public class SemanticFileAdapterImpl extends SemanticResourceAdapterImpl impleme refreshLocalIfNeeded(RuleType.MODIFY, getRuleForType(RuleType.MODIFY, this.file), options, monitor); } + + /** + * @param targetFolder + * @param targetName + * @param monitor + * a progress monitor, or <code>null</code> if progress reporting + * is not desired + * @return true if resource move is supported + * @throws CoreException + * @since 0.6.0 + */ + public boolean supportsMoveInternal(ISemanticFolder targetFolder, String targetName, IProgressMonitor monitor) throws CoreException { + ISemanticFileStoreInternal store = getOwnStore(); + ISemanticFileStore targetParent = (ISemanticFileStore) getStoreForResource(targetFolder.getAdaptedResource()); + + return store.supportsMove(targetParent, targetName, monitor); + } + + /** + * Moves the current file to the target folder using the specified name + * + * @param targetFolder + * must exist + * @param targetName + * @param options + * @param monitor + * a progress monitor, or <code>null</code> if progress reporting + * is not desired + * @throws CoreException + * in case of operation failure, e.g. the target file already + * exists, content can not be copied. + * + * @see IFile#move(org.eclipse.core.runtime.IPath, int, IProgressMonitor) + * + * @since 0.6.0 + */ + public void moveToInternal(ISemanticFolder targetFolder, String targetName, int options, IProgressMonitor monitor) throws CoreException { + IResource destination = targetFolder.getAdaptedContainer().getFile(new Path(targetName)); + + checkCurrentMoveRule(destination); + + ISemanticFileStoreInternal store = getOwnStore(); + + ISemanticFileStore targetParent = (ISemanticFileStore) getStoreForResource(targetFolder.getAdaptedResource()); + + store.moveTo(targetParent, targetName, monitor); + } } diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticFileStore.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticFileStore.java index 67b6307..b632b32 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticFileStore.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticFileStore.java @@ -788,6 +788,63 @@ public class SemanticFileStore extends SemanticProperties implements ISemanticFi // // 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(); + + this.node.setParent(((SemanticFileStore) targetParent).node); + this.node.setName(targetName); + } 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()) { diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticFolderAdapterImpl.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticFolderAdapterImpl.java index 31661a8..a8ca39a 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticFolderAdapterImpl.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticFolderAdapterImpl.java @@ -213,6 +213,13 @@ public class SemanticFolderAdapterImpl extends SemanticResourceAdapterImpl imple } + public boolean supportsMove(ISemanticFolder targetFolder, String targetName, IProgressMonitor monitor) throws CoreException { + ISemanticFileStoreInternal store = getOwnStore(); + ISemanticFileStore targetParent = (ISemanticFileStore) getStoreForResource(targetFolder.getAdaptedResource()); + + return store.supportsMove(targetParent, targetName, monitor); + } + /** * @param name * @param childStore @@ -263,8 +270,8 @@ public class SemanticFolderAdapterImpl extends SemanticResourceAdapterImpl imple private void validateName(String name, int type) throws CoreException { IStatus test = this.container.getWorkspace().validateName(name, type); if (!test.isOK()) { - throw new SemanticResourceException(SemanticResourceStatusCode.INVALID_RESOURCE_NAME, this.container.getFullPath(), test - .getMessage()); + throw new SemanticResourceException(SemanticResourceStatusCode.INVALID_RESOURCE_NAME, this.container.getFullPath(), + test.getMessage()); } } diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticResourceAdapterImpl.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticResourceAdapterImpl.java index a3f3d3b..642d4d8 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticResourceAdapterImpl.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticResourceAdapterImpl.java @@ -92,6 +92,35 @@ public abstract class SemanticResourceAdapterImpl implements ISemanticResource { } } + /** + * + * @return store instance + * @throws CoreException + * if store can not be determined + */ + protected static ISemanticFileStoreInternal getStoreForResource(IResource someResource) throws CoreException { + // TODO trace + URI uri = someResource.getLocationURI(); + + try { + IFileStore store = EFS.getStore(uri); + + if (store instanceof ISemanticFileStoreInternal) { + return (ISemanticFileStoreInternal) store; + } else if (store.getFileSystem() == EFS.getNullFileSystem()) { + throw new SemanticResourceException(SemanticResourceStatusCode.STORE_NOT_FOUND, someResource.getFullPath(), + Messages.SemanticResourceAdapterImpl_NullFile_XMSG); + } else { + // quite unlikely (the URI was changed on the resource, e.g. on + // a project or symbolic link) + throw new SemanticResourceException(SemanticResourceStatusCode.STORE_NOT_FOUND, someResource.getFullPath(), NLS.bind( + Messages.SemanticResourceAdapterImpl_NoSemanticStore_XMSG, uri.toString())); + } + } catch (CoreException e) { + throw new SemanticResourceException(SemanticResourceStatusCode.STORE_NOT_FOUND, someResource.getFullPath(), null, e); + } + } + protected ISchedulingRule checkCurrentRule(RuleType ruleType) throws CoreException { Job job = Job.getJobManager().currentJob(); @@ -99,24 +128,23 @@ public abstract class SemanticResourceAdapterImpl implements ISemanticResource { ISchedulingRule checkRule = getRuleForType(ruleType, this.resource); - ISchedulingRule rule = job.getRule(); - if (rule != null) { + return validateCurrentRule(job, checkRule); - if (!rule.contains(checkRule)) { - throw new SemanticResourceException(SemanticResourceStatusCode.LOCK_CONFLICT, this.resource.getFullPath(), - Messages.SemanticResourceAdapterImpl_OperationNotCoveredByRule_XMSG); - } - } else { - // TODO 0.1: we need to investigate again what to do when rule - // is null - if (SfsTraceLocation.CORE.isActive()) { - SfsTraceLocation.getTrace().trace(SfsTraceLocation.CORE.getLocation(), - Messages.SemanticResourceAdapterImpl_JobNoRule_XMSG); - SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE.getLocation()); - } + } - } - return checkRule; + throw new SemanticResourceException(SemanticResourceStatusCode.CALLED_OUTSIDE_OF_SCHEDULING_RULE, this.resource.getFullPath(), + Messages.SemanticResourceAdapterImpl_CalledOutsideRule_XMSG); + + } + + protected ISchedulingRule checkCurrentMoveRule(IResource destination) throws CoreException { + Job job = Job.getJobManager().currentJob(); + + if (job != null) { + + ISchedulingRule checkRule = getMoveRule(this.resource, destination); + + return validateCurrentRule(job, checkRule); } @@ -125,37 +153,67 @@ public abstract class SemanticResourceAdapterImpl implements ISemanticResource { } - ISchedulingRule getRuleForType(RuleType ruleType, IResource actResource) throws SemanticResourceException { + ISchedulingRule getMoveRule(IResource source, IResource destination) throws SemanticResourceException { + IResourceRuleFactory rf = getResourceRuleFactory(source); + return rf.moveRule(source, destination); + } + + private ISchedulingRule validateCurrentRule(Job job, ISchedulingRule checkRule) throws SemanticResourceException { + ISchedulingRule rule = job.getRule(); + if (rule != null) { + + if (!rule.contains(checkRule)) { + throw new SemanticResourceException(SemanticResourceStatusCode.LOCK_CONFLICT, this.resource.getFullPath(), + Messages.SemanticResourceAdapterImpl_OperationNotCoveredByRule_XMSG); + } + } else { + // TODO 0.1: we need to investigate again what to do when rule + // is null + if (SfsTraceLocation.CORE.isActive()) { + SfsTraceLocation.getTrace().trace(SfsTraceLocation.CORE.getLocation(), Messages.SemanticResourceAdapterImpl_JobNoRule_XMSG); + SfsTraceLocation.getTrace().traceDumpStack(SfsTraceLocation.CORE.getLocation()); + } - if (actResource instanceof IWorkspaceRoot) { - return actResource; } + return checkRule; + } + + private IResourceRuleFactory getResourceRuleFactory(IResource source) throws SemanticResourceException { // TODO 0.1: check life cycle issues with project close/delete - IProject project = actResource.getProject(); + IProject project = source.getProject(); if (!project.isAccessible()) { // project closed or deleted - throw new SemanticResourceException(SemanticResourceStatusCode.PROJECT_NOT_ACCESSIBLE, actResource.getFullPath(), NLS.bind( + throw new SemanticResourceException(SemanticResourceStatusCode.PROJECT_NOT_ACCESSIBLE, source.getFullPath(), NLS.bind( Messages.SemanticResourceAdapterImpl_ProjectNotAccessible_XMSG, project.getName())); } IResourceRuleFactory rf; - if (actResource.isLinked()) { + if (source.isLinked()) { // fallback to default factory - rf = actResource.getWorkspace().getRuleFactory(); + rf = source.getWorkspace().getRuleFactory(); } else { // we obtain the "expected" rule from the content provider RepositoryProvider provider = RepositoryProvider.getProvider(project, ISemanticFileSystem.SFS_REPOSITORY_PROVIDER); if (provider != null) { rf = provider.getRuleFactory(); } else { - if (actResource.getType() == IResource.PROJECT) { - rf = actResource.getWorkspace().getRuleFactory(); + if (source.getType() == IResource.PROJECT) { + rf = source.getWorkspace().getRuleFactory(); } else { rf = new DelegatingResourceRuleFactory(this.fs); } } } + return rf; + } + + ISchedulingRule getRuleForType(RuleType ruleType, IResource actResource) throws SemanticResourceException { + + if (actResource instanceof IWorkspaceRoot) { + return actResource; + } + IResourceRuleFactory rf = getResourceRuleFactory(actResource); ISchedulingRule checkRule; diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/cacheservice/CacheService.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/cacheservice/CacheService.java index 3aa84f7..7529493 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/cacheservice/CacheService.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/cacheservice/CacheService.java @@ -124,6 +124,40 @@ public class CacheService implements ICacheService { } } + public void moveContent(IPath path, IPath targetPath, IProgressMonitor monitor) throws CoreException { + if (SfsSpiTraceLocation.CACHESERVICE.isActive()) { + SfsSpiTraceLocation.getTrace().traceEntry(SfsSpiTraceLocation.CACHESERVICE.getLocation(), path.toString()); + } + + try { + lockForWrite(); + + InputStream input = getContent(path); + + if (input != null) { + try { + addContent(targetPath, input, 0, monitor); + } finally { + if (input != null) { + try { + input.close(); + } catch (IOException e) { + // ignore + } + } + } + } + + ICachedContentHandle cacheFile = createCacheContentHandle(path); + + if (cacheFile.exists()) { + cacheFile.delete(); + } + } finally { + unlockForWrite(); + } + } + public boolean hasContent(IPath path) throws CoreException { if (SfsSpiTraceLocation.CACHESERVICE.isActive()) { diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/messages.properties b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/messages.properties index e8cc905..b6d0fc6 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/messages.properties +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/messages.properties @@ -49,6 +49,7 @@ SemanticFileStore_ValidateRemoteCreate_XMSG=Validate remote create for {0} on pr SemanticFileStore_ValidateRemoteDelete_XMSG=Validate remote delete for {0} on provider {1} SemanticFileStore_ValidateRemove_XMSG=Validate remove for {0} on provider {1} SemanticFileStore_ValidateSave_XMSG=Validating save on provider {0} for path {1} +SemanticFileStore_SupportsMove_XMSG=SupportsMove called for path {0} SemanticFileSystem_NotInitialized_XMSG=Semantic File System was not initialized SemanticFileSystem_SFSInitError_XMSG=Semantic File System Initialization Error SemanticFileSystem_SFSUpdateError_XMSG=Error when updating Sematnic File System metadata diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/provider/DefaultContentProvider.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/provider/DefaultContentProvider.java index 3f68ff5..452104e 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/provider/DefaultContentProvider.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/provider/DefaultContentProvider.java @@ -32,6 +32,7 @@ import org.eclipse.core.resources.semantic.SyncDirection; import org.eclipse.core.resources.semantic.spi.CachingContentProvider; import org.eclipse.core.resources.semantic.spi.DefaultMinimalSemanticResourceRuleFactory; import org.eclipse.core.resources.semantic.spi.FileCacheServiceFactory; +import org.eclipse.core.resources.semantic.spi.ICacheService; import org.eclipse.core.resources.semantic.spi.ICacheServiceFactory; import org.eclipse.core.resources.semantic.spi.ISemanticContentProviderFederation; import org.eclipse.core.resources.semantic.spi.ISemanticContentProviderREST; @@ -62,6 +63,10 @@ import org.eclipse.osgi.util.NLS; public class DefaultContentProvider extends CachingContentProvider implements ISemanticContentProviderFederation, ISemanticContentProviderREST { + /** + * + */ + private static final String DEFAULT_CONTENT_PROVIDER_ID = "org.eclipse.core.resources.semantic.provider.DefaultContentProvider"; //$NON-NLS-1$ private static final String TRUE = "true"; //$NON-NLS-1$ private static final QualifiedName RESOURCE_NOT_ACCESSIBLE = new QualifiedName(SemanticResourcesPlugin.PLUGIN_ID, "ResourceNotAccessible"); //$NON-NLS-1$ @@ -194,8 +199,8 @@ public class DefaultContentProvider extends CachingContentProvider implements IS String remoteURI = this.getURIString(childStore); if (childStore.getPersistentProperty(RESOURCE_NOT_ACCESSIBLE) != null) { - throw new SemanticResourceException(SemanticResourceStatusCode.REMOTE_CONNECT_EXCEPTION, childStore.getPath(), childStore - .getPersistentProperty(RESOURCE_NOT_ACCESSIBLE_MESSAGE)); + throw new SemanticResourceException(SemanticResourceStatusCode.REMOTE_CONNECT_EXCEPTION, childStore.getPath(), + childStore.getPersistentProperty(RESOURCE_NOT_ACCESSIBLE_MESSAGE)); } if (remoteURI == null) { @@ -418,12 +423,42 @@ public class DefaultContentProvider extends CachingContentProvider implements IS } } + @Override + public boolean isMoveSupportedForStore(ISemanticFileStore semanticFileStore, ISemanticFileStore targetParent, String targetName, + IProgressMonitor monitor) throws CoreException { + if (semanticFileStore.getEffectiveContentProviderID().equals(DEFAULT_CONTENT_PROVIDER_ID)) { + if (targetParent.getEffectiveContentProviderID().equals(DEFAULT_CONTENT_PROVIDER_ID)) { + return true; + } + } + return false; + } + + @Override + public void detachMovingStore(ISemanticFileStore semanticFileStore, ISemanticFileStore targetParent, String targetName, + IProgressMonitor monitor) throws CoreException { + ICacheService cacheService = this.getCacheService(); + IPath path = semanticFileStore.getPath(); + + if (cacheService.hasContent(path)) { + IPath targetPath = targetParent.getPath().append(targetName); + + cacheService.moveContent(path, targetPath, monitor); + } + } + + @Override + public void attachMovingStore(ISemanticFileStore semanticFileStore, ISemanticFileStore targetParent, String targetName, + IProgressMonitor monitor) { + // nothing to do + } + private void setStateResourceNotAccessible(ISemanticFileStore childStore, Exception e) throws CoreException { childStore.setPersistentProperty(RESOURCE_NOT_ACCESSIBLE, TRUE); if (e instanceof UnknownHostException) { - childStore.setPersistentProperty(RESOURCE_NOT_ACCESSIBLE_MESSAGE, NLS.bind(Messages.DefaultContentProvider_UnknownHostError_XMSG, e - .getMessage())); + childStore.setPersistentProperty(RESOURCE_NOT_ACCESSIBLE_MESSAGE, + NLS.bind(Messages.DefaultContentProvider_UnknownHostError_XMSG, e.getMessage())); } else { childStore.setPersistentProperty(RESOURCE_NOT_ACCESSIBLE_MESSAGE, e.getMessage()); } diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/provider/Messages.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/provider/Messages.java index 2575833..f95ab70 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/provider/Messages.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/provider/Messages.java @@ -15,6 +15,7 @@ import org.eclipse.osgi.util.NLS; public class Messages extends NLS { private static final String BUNDLE_NAME = "org.eclipse.core.internal.resources.semantic.provider.messages"; //$NON-NLS-1$ + public static String ContentProvider_NotSupported_XMSG; public static String DefaultContentProvider_CacheFillError_XMSG; public static String DefaultContentProvider_NoRemoteEdit_XMSG; public static String DefaultContentProvider_NotSupported_XMSG; diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/provider/messages.properties b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/provider/messages.properties index 25ce99b..92566f8 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/provider/messages.properties +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/provider/messages.properties @@ -9,6 +9,7 @@ # Eduard Bartsch (SAP AG) - initial API and implementation # Mathias Kinzler (SAP AG) - initial API and implementation ############################################################################### +ContentProvider_NotSupported_XMSG=A Content Provider (class {0}) does not support this method DefaultContentProvider_CacheFillError_XMSG=Cache could not be filled for URI {0} DefaultContentProvider_NoRemoteEdit_XMSG=Can not edit non-local resources DefaultContentProvider_NotSupported_XMSG=Default Content Provider does not support this method diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/team/DelegatingResourceRuleFactory.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/team/DelegatingResourceRuleFactory.java index fcd86c0..6d1a9f0 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/team/DelegatingResourceRuleFactory.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/team/DelegatingResourceRuleFactory.java @@ -223,8 +223,8 @@ public class DelegatingResourceRuleFactory extends ResourceRuleFactory { if (sres != null) { ISemanticFileStore sfs = (ISemanticFileStore) EFS.getStore(resource.getLocationURI()); - result = toRule(new IResource[] {resource}, RuleType.MODIFY, sfs.getEffectiveContentProvider().getRuleFactory().modifyRule( - sfs)); + result = toRule(new IResource[] {resource}, RuleType.MODIFY, + sfs.getEffectiveContentProvider().getRuleFactory().modifyRule(sfs)); } else { if (SfsTraceLocation.RULEFACTORY.isActive()) { SfsTraceLocation.getTrace().trace(SfsTraceLocation.RULEFACTORY.getLocation(), @@ -264,6 +264,12 @@ public class DelegatingResourceRuleFactory extends ResourceRuleFactory { new Object[] {source.getFullPath().toString(), destination.getFullPath().toString()}); } + // when a resource is moved across project, the projects are locked as a + // whole + if (!source.getFullPath().segment(0).equals(destination.getFullPath().segment(0))) { + return new MultiRule(new ISchedulingRule[] {modifyRule(source.getProject()), modifyRule(destination.getProject())}); + } + ISchedulingRule result; try { ISemanticResource sourceres = (ISemanticResource) source.getAdapter(ISemanticResource.class); @@ -274,8 +280,8 @@ public class DelegatingResourceRuleFactory extends ResourceRuleFactory { ISemanticFileStore destinationStore = (ISemanticFileStore) EFS.getStore(destination.getLocationURI()); // if source and target come from different providers, return // root - if (sourceStore.getEffectiveContentProvider().getClass().getName().equals( - destinationStore.getEffectiveContentProvider().getClass().getName())) { + if (sourceStore.getEffectiveContentProvider().getClass().getName() + .equals(destinationStore.getEffectiveContentProvider().getClass().getName())) { result = toRule(new IResource[] {source}, RuleType.MOVE, sourceStore.getEffectiveContentProvider().getRuleFactory() .moveRule(sourceStore, destinationStore)); } else { @@ -392,8 +398,8 @@ public class DelegatingResourceRuleFactory extends ResourceRuleFactory { IFileStore fs = EFS.getStore(res.getLocationURI()); if (fs instanceof ISemanticFileStore) { ISemanticFileStore sfs = (ISemanticFileStore) fs; - ISemanticFileStore ruleStore = sfs.getEffectiveContentProvider().getRuleFactory().validateEditRule( - new ISemanticFileStore[] {sfs}); + ISemanticFileStore ruleStore = sfs.getEffectiveContentProvider().getRuleFactory() + .validateEditRule(new ISemanticFileStore[] {sfs}); if (ruleStore != null) { ruleStores.add(ruleStore); } else { @@ -476,8 +482,9 @@ public class DelegatingResourceRuleFactory extends ResourceRuleFactory { rule = this.root.findMember(path); } if (rule == null || !rule.exists()) { - throw new SemanticResourceException(SemanticResourceStatusCode.RESOURCE_FOR_STORE_NOT_FOUND, store.getPath(), MessageFormat - .format(Messages.DelegatingResourceRuleFactory_NoExistingParentFound_XMSG, stores[0].getPath().toString())); + throw new SemanticResourceException(SemanticResourceStatusCode.RESOURCE_FOR_STORE_NOT_FOUND, store.getPath(), + MessageFormat.format(Messages.DelegatingResourceRuleFactory_NoExistingParentFound_XMSG, stores[0].getPath() + .toString())); } rules[i] = rule; } @@ -511,6 +518,7 @@ public class DelegatingResourceRuleFactory extends ResourceRuleFactory { case REFRESH : case CREATE : case DELETE : + case MOVE : rule = resource.getParent(); break; case MODIFY : diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/team/MoveDeleteHook.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/team/MoveDeleteHook.java index 59e3e5d..d425752 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/team/MoveDeleteHook.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/team/MoveDeleteHook.java @@ -11,6 +11,7 @@ *******************************************************************************/ package org.eclipse.core.internal.resources.semantic.team; +import org.eclipse.core.internal.resources.semantic.SemanticFileAdapterImpl; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; @@ -118,9 +119,23 @@ public class MoveDeleteHook implements IMoveDeleteHook { } if (!localOnly) { + ISemanticFolder targetParent = (ISemanticFolder) destination.getParent().getAdapter(ISemanticFolder.class); + + if (targetParent != null) { + try { + SemanticFileAdapterImpl sFileImpl = (SemanticFileAdapterImpl) sFile; + if (sFileImpl.supportsMoveInternal(targetParent, destination.getName(), monitor)) { + sFileImpl.moveToInternal(targetParent, destination.getName(), ISemanticFileSystem.SUPPRESS_REFRESH, monitor); + tree.movedFile(source, destination); + return true; + } + } catch (CoreException e) { + // Fall back to exception + } + } // TODO 0.1: no file move for the time being - SemanticResourceException ex = new SemanticResourceException(SemanticResourceStatusCode.METHOD_NOT_SUPPORTED, source - .getFullPath(), Messages.MoveDeleteHook_MoveRenameNotSupported_XMSG); + SemanticResourceException ex = new SemanticResourceException(SemanticResourceStatusCode.METHOD_NOT_SUPPORTED, + source.getFullPath(), Messages.MoveDeleteHook_MoveRenameNotSupported_XMSG); this.sfs.getLog().log(ex); // the message is not transported to the client anyway, so we leave // it empty @@ -150,8 +165,8 @@ public class MoveDeleteHook implements IMoveDeleteHook { IProgressMonitor monitor) { // TODO 0.1: no project move for the time being if (source.getAdapter(ISemanticProject.class) != null) { - SemanticResourceException ex = new SemanticResourceException(SemanticResourceStatusCode.METHOD_NOT_SUPPORTED, source - .getFullPath(), Messages.MoveDeleteHook_MoveRenameNotSupported_XMSG); + SemanticResourceException ex = new SemanticResourceException(SemanticResourceStatusCode.METHOD_NOT_SUPPORTED, + source.getFullPath(), Messages.MoveDeleteHook_MoveRenameNotSupported_XMSG); this.sfs.getLog().log(ex); // the message is not transported to the client anyway, so we leave // it empty diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/resources/semantic/spi/ContentProvider.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/resources/semantic/spi/ContentProvider.java index e13cc08..b343515 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/resources/semantic/spi/ContentProvider.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/resources/semantic/spi/ContentProvider.java @@ -12,11 +12,15 @@ package org.eclipse.core.resources.semantic.spi; import org.eclipse.core.internal.resources.semantic.SemanticResourcesPlugin; +import org.eclipse.core.internal.resources.semantic.provider.Messages; +import org.eclipse.core.resources.semantic.SemanticResourceException; +import org.eclipse.core.resources.semantic.SemanticResourceStatusCode; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.core.runtime.Status; +import org.eclipse.osgi.util.NLS; /** * This class implements the base class for SPI contract of @@ -191,4 +195,22 @@ public abstract class ContentProvider implements ISemanticContentProvider { return new Status(IStatus.OK, SemanticResourcesPlugin.PLUGIN_ID, ""); //$NON-NLS-1$ } + /** + * @throws CoreException + */ + public boolean isMoveSupportedForStore(ISemanticFileStore semanticFileStore, ISemanticFileStore targetParent, String targetName, + IProgressMonitor monitor) throws CoreException { + return false; + } + + public void detachMovingStore(ISemanticFileStore semanticFileStore, ISemanticFileStore targetParent, String targetName, + IProgressMonitor monitor) throws CoreException { + throw new SemanticResourceException(SemanticResourceStatusCode.METHOD_NOT_SUPPORTED, semanticFileStore.getPath(), NLS.bind( + Messages.ContentProvider_NotSupported_XMSG, this.getClass().getName())); + } + + public void attachMovingStore(ISemanticFileStore semanticFileStore, ISemanticFileStore targetParent, String targetName, + IProgressMonitor monitor) { + // do nothing + } } diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/resources/semantic/spi/DefaultMinimalSemanticResourceRuleFactory.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/resources/semantic/spi/DefaultMinimalSemanticResourceRuleFactory.java index 027553a..e6b8b7e 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/resources/semantic/spi/DefaultMinimalSemanticResourceRuleFactory.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/resources/semantic/spi/DefaultMinimalSemanticResourceRuleFactory.java @@ -11,6 +11,8 @@ *******************************************************************************/ package org.eclipse.core.resources.semantic.spi; +import org.eclipse.core.runtime.IPath; + /** * The default implementation for the {@link ISemanticResourceRuleFactory} that * provides fine-grained locks. @@ -48,7 +50,33 @@ public class DefaultMinimalSemanticResourceRuleFactory implements ISemanticResou } public ISemanticFileStore moveRule(ISemanticFileStore source, ISemanticFileStore destination) { - return null; + IPath sourcePath = source.getPath(); + IPath destinationPath = destination.getPath(); + IPath rootPath = rootStore.getPath(); + + if (rootPath.equals(sourcePath)) { + return getParent(rootStore); + } else if (rootPath.equals(destinationPath)) { + return getParent(rootStore); + } else { + int matchingSegments = sourcePath.matchingFirstSegments(destinationPath); + if (matchingSegments < rootPath.segmentCount()) { + // either source or destination is outside of this content + // provider + return null; + } + if (matchingSegments == rootPath.segmentCount()) { + return rootStore; + } + // find common parent + int segmentsToRemove = sourcePath.segmentCount() - matchingSegments; + ISemanticFileStore store = source; + + for (int i = 0; i < segmentsToRemove; i++) { + store = (ISemanticFileStore) store.getParent(); + } + return store; + } } public ISemanticFileStore refreshRule(ISemanticFileStore store) { diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/resources/semantic/spi/DefaultSemanticResourceRuleFactory.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/resources/semantic/spi/DefaultSemanticResourceRuleFactory.java index be7fb61..d2554f4 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/resources/semantic/spi/DefaultSemanticResourceRuleFactory.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/resources/semantic/spi/DefaultSemanticResourceRuleFactory.java @@ -11,6 +11,8 @@ *******************************************************************************/ package org.eclipse.core.resources.semantic.spi; +import org.eclipse.core.runtime.IPath; + /** * The default implementation for the {@link ISemanticResourceRuleFactory}. * <p> @@ -61,6 +63,15 @@ public class DefaultSemanticResourceRuleFactory implements ISemanticResourceRule } public ISemanticFileStore moveRule(ISemanticFileStore source, ISemanticFileStore destination) { + IPath sourcePath = source.getPath(); + IPath destinationPath = destination.getPath(); + + int matchingSegments = sourcePath.matchingFirstSegments(destinationPath); + if (matchingSegments < rootStore.getPath().segmentCount()) { + // either source or destination is outside of this content + // provider + return null; + } return (ISemanticFileStore) this.rootStore.getParent(); } diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/resources/semantic/spi/ICacheService.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/resources/semantic/spi/ICacheService.java index 2ecc7c7..79bf33a 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/resources/semantic/spi/ICacheService.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/resources/semantic/spi/ICacheService.java @@ -105,4 +105,20 @@ public interface ICacheService { public OutputStream wrapOutputStream(IPath path, boolean append, ICacheUpdateCallback callback, IProgressMonitor monitor) throws CoreException; + /** + * Moves content of a file specified by <code>path</code> to a location + * specified by <code>targetPath<code> + * + * @param path + * must point to a file + * @param targetPath + * must point to a non-existing file + * @param monitor + * may be null + * @throws CoreException + * + * @since 0.6.0 + */ + public void moveContent(IPath path, IPath targetPath, IProgressMonitor monitor) throws CoreException; + } diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/resources/semantic/spi/ISemanticContentProvider.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/resources/semantic/spi/ISemanticContentProvider.java index 29fdfc5..b95f6e8 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/resources/semantic/spi/ISemanticContentProvider.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/resources/semantic/spi/ISemanticContentProvider.java @@ -470,4 +470,51 @@ public interface ISemanticContentProvider extends ISemanticContentProviderBase, */ public ISemanticResourceRuleFactory getRuleFactory(); + /** + * Notifies the source content provider the store is about to be moved. + * + * @param semanticFileStore + * @param targetParent + * @param targetName + * @param monitor + * @throws CoreException + * in case an error happened during detach + * + */ + public void detachMovingStore(ISemanticFileStore semanticFileStore, ISemanticFileStore targetParent, String targetName, + IProgressMonitor monitor) throws CoreException; + + /** + * Notifies the target content provider that the store has been moved. + * + * The content provider is not allowed to throw any exception in this + * method. + * + * @param semanticFileStore + * @param targetParent + * @param targetName + * @param monitor + */ + public void attachMovingStore(ISemanticFileStore semanticFileStore, ISemanticFileStore targetParent, String targetName, + IProgressMonitor monitor); + + /** + * Checks whether the content providers that are source and target of the + * move are capable of doing the move. + * + * The method is called on both content providers with the same parameters. + * + * The move is only executed if both content providers return + * <code>true</code>. + * + * @param semanticFileStore + * @param targetParent + * @param targetName + * @param monitor + * @return true if move is supported/allowed + * @throws CoreException + */ + public boolean isMoveSupportedForStore(ISemanticFileStore semanticFileStore, ISemanticFileStore targetParent, String targetName, + IProgressMonitor monitor) throws CoreException; + } diff --git a/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/TestCacheService.java b/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/TestCacheService.java index 1f76123..14d4b15 100644 --- a/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/TestCacheService.java +++ b/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/TestCacheService.java @@ -361,6 +361,56 @@ public class TestCacheService { } /** + * @throws Exception + */ + @Test + public void testFileMoveSameFolder() throws Exception { + ICacheService service = new FileCacheServiceFactory().getCacheService(); + + IPath path = new Path("/test3/file.txt"); + String content = "test"; + InputStream input = new ByteArrayInputStream(content.getBytes("UTF-8")); + + writeToCache(service, path, input); + + IPath targetPath = new Path("/test3/file2.txt"); + + service.moveContent(path, targetPath, null); + + File cacheFile = new File(SemanticFileCache.getCache().getCacheDir(), path.toString()); + + Assert.assertFalse(cacheFile.exists()); + Assert.assertTrue(service.hasContent(targetPath)); + + readFromCache(service, targetPath, content); + } + + /** + * @throws Exception + */ + @Test + public void testFileMoveAnotherFolder() throws Exception { + ICacheService service = new FileCacheServiceFactory().getCacheService(); + + IPath path = new Path("/test3/folder1/file.txt"); + String content = "test"; + InputStream input = new ByteArrayInputStream(content.getBytes("UTF-8")); + + writeToCache(service, path, input); + + IPath targetPath = new Path("/test3/folder2/file2.txt"); + + service.moveContent(path, targetPath, null); + + File cacheFile = new File(SemanticFileCache.getCache().getCacheDir(), path.toString()); + + Assert.assertFalse(cacheFile.exists()); + Assert.assertTrue(service.hasContent(targetPath)); + + readFromCache(service, targetPath, content); + } + + /** * @param service * @param path * @throws CoreException diff --git a/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/TestsContentProviderBase.java b/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/TestsContentProviderBase.java index d1da435..3e66f74 100644 --- a/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/TestsContentProviderBase.java +++ b/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/TestsContentProviderBase.java @@ -641,8 +641,8 @@ public abstract class TestsContentProviderBase extends TestsContentProviderUtil .existsRemotely()); sf = (ISemanticFile) nofile.getAdapter(ISemanticFile.class); - Assert.assertFalse("Should not exist remotely", sf.fetchResourceInfo(ISemanticFileSystem.RESOURCE_INFO_EXISTS_REMOTELY, - monitor).existsRemotely()); + Assert.assertFalse("Should not exist remotely", + sf.fetchResourceInfo(ISemanticFileSystem.RESOURCE_INFO_EXISTS_REMOTELY, monitor).existsRemotely()); } }; @@ -1189,8 +1189,8 @@ public abstract class TestsContentProviderBase extends TestsContentProviderUtil info.setAttribute(EFS.ATTRIBUTE_READ_ONLY, false); store.putInfo(info, EFS.SET_ATTRIBUTES, null); - Assert.assertFalse("File should not be read-only", sfile.fetchResourceInfo(ISemanticFileSystem.RESOURCE_INFO_READ_ONLY, - null).isReadOnly()); + Assert.assertFalse("File should not be read-only", + sfile.fetchResourceInfo(ISemanticFileSystem.RESOURCE_INFO_READ_ONLY, null).isReadOnly()); } }; diff --git a/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/TestsDefaultContentProvider.java b/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/TestsDefaultContentProvider.java index e6bad52..53b0ffb 100644 --- a/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/TestsDefaultContentProvider.java +++ b/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/TestsDefaultContentProvider.java @@ -35,6 +35,7 @@ import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.resources.semantic.ISemanticFile; import org.eclipse.core.resources.semantic.ISemanticFileSystem; import org.eclipse.core.resources.semantic.ISemanticFolder; +import org.eclipse.core.resources.semantic.SemanticResourceException; import org.eclipse.core.resources.semantic.SyncDirection; import org.eclipse.core.resources.semantic.examples.remote.RemoteFolder; import org.eclipse.core.resources.semantic.examples.remote.RemoteStoreTransient; @@ -358,6 +359,167 @@ public class TestsDefaultContentProvider extends TestsContentProviderUtil { } }; + workspace.run(runnable, TestsDefaultContentProvider.this.testProject, IWorkspace.AVOID_UPDATE, new NullProgressMonitor()); + } + + /** + * + * @throws Exception + */ + @Test + public void testAddRemoteFileAndMove() throws Exception { + final IFolder parent = TestsDefaultContentProvider.this.testProject.getFolder("someFolder"); + final IFolder folder = parent.getFolder("someChild1"); + final IFolder targetFolder = parent.getFolder("someChild2"); + parent.create(true, false, null); + folder.create(true, false, null); + targetFolder.create(true, false, null); + + IWorkspaceRunnable runnable = new IWorkspaceRunnable() { + + public void run(IProgressMonitor monitor) throws CoreException { + try { + ISemanticFolder sFolder = (ISemanticFolder) folder.getAdapter(ISemanticFolder.class); + + File testfile = createTestFile("test.txt"); + boolean created = testfile.createNewFile(); + if (!created) { + new FileOutputStream(testfile).close(); + } + + writeContentsToFile(testfile, "Hello World", "UTF-8"); + + ISemanticFile sfile = sFolder.addFile("SomeFile", createURI4File(testfile), TestsDefaultContentProvider.this.options, + monitor); + if (TestsDefaultContentProvider.this.options == ISemanticFileSystem.SUPPRESS_REFRESH) { + testProject.refreshLocal(IResource.DEPTH_INFINITE, monitor); + } + + IFile file = sfile.getAdaptedFile(); + + IFile targetFile = targetFolder.getFile(file.getName()); + + file.move(targetFolder.getFile(file.getName()).getFullPath(), false, monitor); + + Assert.assertEquals("File existence", false, file.exists()); + Assert.assertEquals("File existence", true, targetFile.exists()); + + assertContentsEqual(targetFile, "Hello World"); + + } catch (URISyntaxException e) { + throw new CoreException(new Status(IStatus.ERROR, TestPlugin.PLUGIN_ID, e.getMessage(), e)); + } catch (IOException e) { + throw new CoreException(new Status(IStatus.ERROR, TestPlugin.PLUGIN_ID, e.getMessage(), e)); + } + } + }; + workspace.run(runnable, parent, IWorkspace.AVOID_UPDATE, new NullProgressMonitor()); + } + + @Test(expected = SemanticResourceException.class) + public void testAddRemoteFileAndMoveWithWrongSchedulingRule() throws Exception { + final IFolder folder = TestsDefaultContentProvider.this.testProject.getFolder("someFolder/someChild1"); + + IWorkspaceRunnable runnable = new IWorkspaceRunnable() { + + public void run(IProgressMonitor monitor) throws CoreException { + try { + ISemanticFolder sFolder = (ISemanticFolder) folder.getAdapter(ISemanticFolder.class); + + File testfile = createTestFile("test.txt"); + boolean created = testfile.createNewFile(); + if (!created) { + new FileOutputStream(testfile).close(); + } + + writeContentsToFile(testfile, "Hello World", "UTF-8"); + + ISemanticFile sfile = sFolder.addFile("SomeFile", createURI4File(testfile), TestsDefaultContentProvider.this.options, + monitor); + if (TestsDefaultContentProvider.this.options == ISemanticFileSystem.SUPPRESS_REFRESH) { + testProject.refreshLocal(IResource.DEPTH_INFINITE, monitor); + } + + IFile file = sfile.getAdaptedFile(); + + IFolder targetFolder = TestsDefaultContentProvider.this.testProject.getFolder("someFolder/someChild2"); + targetFolder.create(false, false, monitor); + + IFile targetFile = targetFolder.getFile(file.getName()); + + file.move(targetFolder.getFile(file.getName()).getFullPath(), false, monitor); + + Assert.assertEquals("File existence", false, file.exists()); + Assert.assertEquals("File existence", true, targetFile.exists()); + + assertContentsEqual(targetFile, "Hello World"); + + } catch (URISyntaxException e) { + throw new CoreException(new Status(IStatus.ERROR, TestPlugin.PLUGIN_ID, e.getMessage(), e)); + } catch (IOException e) { + throw new CoreException(new Status(IStatus.ERROR, TestPlugin.PLUGIN_ID, e.getMessage(), e)); + } + } + }; + workspace.run(runnable, folder, IWorkspace.AVOID_UPDATE, new NullProgressMonitor()); + } + + /** + * + * @throws Exception + */ + @Test(expected = CoreException.class) + public void testAddRemoteFileAndMoveToExistingLocation() throws Exception { + final IFolder folder = TestsDefaultContentProvider.this.testProject.getFolder("someFolder"); + + IWorkspaceRunnable runnable = new IWorkspaceRunnable() { + + public void run(IProgressMonitor monitor) throws CoreException { + try { + ISemanticFolder sFolder = (ISemanticFolder) folder.getAdapter(ISemanticFolder.class); + + File testfile = createTestFile("test.txt"); + boolean created = testfile.createNewFile(); + if (!created) { + new FileOutputStream(testfile).close(); + } + + writeContentsToFile(testfile, "Hello World", "UTF-8"); + + ISemanticFile sfile = sFolder.addFile("SomeFile", createURI4File(testfile), TestsDefaultContentProvider.this.options, + monitor); + if (TestsDefaultContentProvider.this.options == ISemanticFileSystem.SUPPRESS_REFRESH) { + testProject.refreshLocal(IResource.DEPTH_INFINITE, monitor); + } + + IFile file = sfile.getAdaptedFile(); + + IFolder targetFolder = TestsDefaultContentProvider.this.testProject.getFolder("target"); + targetFolder.create(false, false, monitor); + + IFile targetFile = targetFolder.getFile(file.getName()); + + Assert.assertEquals("File existence", false, targetFile.exists()); + ByteArrayInputStream is; + try { + is = new ByteArrayInputStream("Hello World".getBytes("UTF-8")); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + targetFile.create(is, false, monitor); + Util.safeClose(targetFile.getContents()); + Assert.assertEquals("File existence", true, targetFile.exists()); + + file.move(targetFolder.getFile(file.getName()).getFullPath(), false, monitor); + + Assert.assertTrue("file.move() should have failed.", false); + } catch (URISyntaxException e) { + throw new CoreException(new Status(IStatus.ERROR, TestPlugin.PLUGIN_ID, e.getMessage(), e)); + } catch (IOException e) { + throw new CoreException(new Status(IStatus.ERROR, TestPlugin.PLUGIN_ID, e.getMessage(), e)); + } + } + }; workspace.run(runnable, workspace.getRoot(), IWorkspace.AVOID_UPDATE, new NullProgressMonitor()); } diff --git a/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/provider/CachingTestContentProvider.java b/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/provider/CachingTestContentProvider.java index 9ca3b3f..b1a5e84 100644 --- a/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/provider/CachingTestContentProvider.java +++ b/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/provider/CachingTestContentProvider.java @@ -135,7 +135,7 @@ public class CachingTestContentProvider extends CachingTestContentProviderBase i } public ITag[] getBranches() { - return new ITag[0]; + return null; } }; diff --git a/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/provider/MemoryCachingTestContentProvider.java b/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/provider/MemoryCachingTestContentProvider.java index f792be3..76bb35e 100644 --- a/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/provider/MemoryCachingTestContentProvider.java +++ b/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/provider/MemoryCachingTestContentProvider.java @@ -131,7 +131,7 @@ public class MemoryCachingTestContentProvider extends CachingTestContentProvider } public ITag[] getBranches() { - return new ITag[0]; + return null; } }; |