### Eclipse Workspace Patch 1.0 #P org.eclipse.core.resources Index: src/org/eclipse/core/internal/properties/IPropertyManager.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/properties/IPropertyManager.java,v retrieving revision 1.6 diff -u -r1.6 IPropertyManager.java --- src/org/eclipse/core/internal/properties/IPropertyManager.java 19 Jan 2006 19:20:51 -0000 1.6 +++ src/org/eclipse/core/internal/properties/IPropertyManager.java 29 Jan 2008 10:26:28 -0000 @@ -72,4 +72,8 @@ * be found, returns an empty map. */ public Map getProperties(IResource resource) throws CoreException; + + public void restorePropertiesFromDeleted(IResource target) throws CoreException; + public void savePropertiesAsDeleted(IResource resource) throws CoreException; + public void removeDeletedProperties(IResource resource) throws CoreException; } Index: src/org/eclipse/core/internal/properties/PropertyManager2.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/properties/PropertyManager2.java,v retrieving revision 1.11 diff -u -r1.11 PropertyManager2.java --- src/org/eclipse/core/internal/properties/PropertyManager2.java 22 Nov 2005 22:23:22 -0000 1.11 +++ src/org/eclipse/core/internal/properties/PropertyManager2.java 29 Jan 2008 10:26:28 -0000 @@ -65,9 +65,11 @@ } BucketTree tree; + BucketTree deletedTree; public PropertyManager2(Workspace workspace) { this.tree = new BucketTree(workspace, new PropertyBucket()); + this.deletedTree = new BucketTree(workspace, new DeletedPropertyBucket()); } public void closePropertyStore(IResource target) throws CoreException { @@ -96,7 +98,11 @@ } public synchronized void deleteProperties(IResource target, int depth) throws CoreException { - tree.accept(new PropertyBucket.Visitor() { + deleteProperties(target, depth, tree); + } + + public synchronized void deleteProperties(IResource target, int depth, BucketTree treeToUse) throws CoreException { + treeToUse.accept(new PropertyBucket.Visitor() { public int visit(Entry entry) { entry.delete(); return CONTINUE; @@ -109,8 +115,12 @@ } public synchronized Map getProperties(IResource target) throws CoreException { + return getProperties(target, tree); + } + + protected synchronized Map getProperties(IResource target, BucketTree treeToUse) throws CoreException { final Map result = new HashMap(); - tree.accept(new PropertyBucket.Visitor() { + treeToUse.accept(new PropertyBucket.Visitor() { public int visit(Entry entry) { PropertyEntry propertyEntry = (PropertyEntry) entry; int propertyCount = propertyEntry.getOccurrences(); @@ -141,7 +151,37 @@ return tree.getVersionFile(); } + public void removeDeletedProperties(IResource target) throws CoreException { + deleteProperties(target, IResource.DEPTH_INFINITE, deletedTree); + } + + public void restorePropertiesFromDeleted(IResource target) throws CoreException + { + Map properties = getProperties(target, deletedTree); + Iterator keys = properties.keySet().iterator(); + while (keys.hasNext()) { + QualifiedName key = (QualifiedName) keys.next(); + String value = (String) properties.get(key); + setProperty(target, key, value); + } + } + + public void savePropertiesAsDeleted(IResource target) throws CoreException + { + Map properties = getProperties(target); + Iterator keys = properties.keySet().iterator(); + while (keys.hasNext()) { + QualifiedName key = (QualifiedName) keys.next(); + String value = (String) properties.get(key); + setProperty(target, key, value, deletedTree); + } + } + public synchronized void setProperty(IResource target, QualifiedName name, String value) throws CoreException { + setProperty(target, name, value, this.tree); + } + + protected synchronized void setProperty(IResource target, QualifiedName name, String value, BucketTree treeToUse) throws CoreException { //resource may have been deleted concurrently //must check for existence within synchronized method Resource resource = (Resource) target; @@ -159,8 +199,8 @@ } IPath resourcePath = target.getFullPath(); - tree.loadBucketFor(resourcePath); - PropertyBucket current = (PropertyBucket) tree.getCurrent(); + treeToUse.loadBucketFor(resourcePath); + PropertyBucket current = (PropertyBucket) treeToUse.getCurrent(); current.setProperty(resourcePath, name, value); current.save(); } Index: src/org/eclipse/core/internal/resources/Resource.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Resource.java,v retrieving revision 1.155 diff -u -r1.155 Resource.java --- src/org/eclipse/core/internal/resources/Resource.java 6 Dec 2007 20:38:15 -0000 1.155 +++ src/org/eclipse/core/internal/resources/Resource.java 29 Jan 2008 10:26:29 -0000 @@ -192,6 +192,14 @@ checkExists(flags, true); } + protected ResourceInfo checkAccessibleAndLocal(int depth) throws CoreException { + ResourceInfo info = getResourceInfo(false, false); + int flags = getFlags(info); + checkAccessible(flags); + checkLocal(flags, depth); + return info; + } + /** * This method reports errors in two different ways. It can throw a * CoreException or return a status. CoreExceptions are used according to the @@ -218,11 +226,9 @@ } checkValidPath(destination, destinationType, false); - ResourceInfo info = getResourceInfo(false, false); - int flags = getFlags(info); - checkAccessible(flags); - checkLocal(flags, DEPTH_INFINITE); - + ResourceInfo info; + checkAccessibleAndLocal(DEPTH_INFINITE); + Resource dest = workspace.newResource(destination, destinationType); dest.checkDoesNotExist(); @@ -350,10 +356,8 @@ } checkValidPath(destination, destinationType, false); - ResourceInfo info = getResourceInfo(false, false); - int flags = getFlags(info); - checkAccessible(flags); - checkLocal(flags, DEPTH_INFINITE); + ResourceInfo info; + checkAccessibleAndLocal(DEPTH_INFINITE); Resource dest = workspace.newResource(destination, destinationType); @@ -1008,10 +1012,7 @@ * @see IResource#getPersistentProperty(QualifiedName) */ public String getPersistentProperty(QualifiedName key) throws CoreException { - ResourceInfo info = getResourceInfo(false, false); - int flags = getFlags(info); - checkAccessible(flags); - checkLocal(flags, DEPTH_ZERO); + checkAccessibleAndLocal(DEPTH_ZERO); return getPropertyManager().getProperty(this, key); } @@ -1073,10 +1074,7 @@ * @see IResource#getSessionProperty(QualifiedName) */ public Object getSessionProperty(QualifiedName key) throws CoreException { - ResourceInfo info = getResourceInfo(false, false); - int flags = getFlags(info); - checkAccessible(flags); - checkLocal(flags, DEPTH_ZERO); + ResourceInfo info = checkAccessibleAndLocal(DEPTH_ZERO); return info.getSessionProperty(key); } @@ -1450,6 +1448,14 @@ } /* (non-Javadoc) + * @see IResource#removeDeletedPersistentProperties + */ + public void removeDeletedPersistentProperties() throws CoreException { + // The resource is deleted when this is called + getPropertyManager().removeDeletedProperties(this); + } + + /* (non-Javadoc) * Method declared on {@link IPathRequestor}. */ public String requestName() { @@ -1464,6 +1470,14 @@ } /* (non-Javadoc) + * @see IResource#restorePersistentPropertiesFromDeleted() + */ + public void restorePersistentPropertiesFromDeleted() throws CoreException { + checkAccessibleAndLocal(DEPTH_ZERO); + getPropertyManager().restorePropertiesFromDeleted(this); + } + + /* (non-Javadoc) * @see IResource#revertModificationStamp */ public void revertModificationStamp(long value) throws CoreException { @@ -1471,14 +1485,19 @@ throw new IllegalArgumentException("Illegal value: " + value); //$NON-NLS-1$ // fetch the info but don't bother making it mutable even though we are going // to modify it. It really doesn't matter as the change we are doing does not show up in deltas. - ResourceInfo info = getResourceInfo(false, false); - int flags = getFlags(info); - checkAccessible(flags); - checkLocal(flags, DEPTH_ZERO); + ResourceInfo info = checkAccessibleAndLocal(DEPTH_ZERO); info.setModificationStamp(value); } /* (non-Javadoc) + * @see IResource#savePersistentPropertiesAsDeleted() + */ + public void savePersistentPropertiesAsDeleted() throws CoreException { + checkAccessibleAndLocal(DEPTH_ZERO); + getPropertyManager().savePropertiesAsDeleted(this); + } + + /* (non-Javadoc) * @see IResource#setDerived(boolean) */ public void setDerived(boolean isDerived) throws CoreException { @@ -1545,10 +1564,7 @@ throw new IllegalArgumentException("Illegal value: " + value); //$NON-NLS-1$ // fetch the info but don't bother making it mutable even though we are going // to modify it. It really doesn't matter as the change we are doing does not show up in deltas. - ResourceInfo info = getResourceInfo(false, false); - int flags = getFlags(info); - checkAccessible(flags); - checkLocal(flags, DEPTH_ZERO); + ResourceInfo info = checkAccessibleAndLocal(DEPTH_ZERO); return getLocalManager().setLocalTimeStamp(this, info, value); } @@ -1556,10 +1572,7 @@ * @see IResource#setPersistentProperty(QualifiedName, String) */ public void setPersistentProperty(QualifiedName key, String value) throws CoreException { - ResourceInfo info = getResourceInfo(false, false); - int flags = getFlags(info); - checkAccessible(flags); - checkLocal(flags, DEPTH_ZERO); + checkAccessibleAndLocal(DEPTH_ZERO); getPropertyManager().setProperty(this, key, value); } @@ -1583,10 +1596,7 @@ * @see org.eclipse.core.resources.IResource#setResourceAttributes(org.eclipse.core.resources.ResourceAttributes) */ public void setResourceAttributes(ResourceAttributes attributes) throws CoreException { - ResourceInfo info = getResourceInfo(false, false); - int flags = getFlags(info); - checkAccessible(flags); - checkLocal(flags, DEPTH_ZERO); + checkAccessibleAndLocal(DEPTH_ZERO); getLocalManager().setResourceAttributes(this, attributes); } @@ -1597,10 +1607,7 @@ // fetch the info but don't bother making it mutable even though we are going // to modify it. We don't know whether or not the tree is open and it really doesn't // matter as the change we are doing does not show up in deltas. - ResourceInfo info = getResourceInfo(false, false); - int flags = getFlags(info); - checkAccessible(flags); - checkLocal(flags, DEPTH_ZERO); + ResourceInfo info = checkAccessibleAndLocal(DEPTH_ZERO); info.setSessionProperty(key, value); } @@ -1650,10 +1657,7 @@ final ISchedulingRule rule = workspace.getRuleFactory().modifyRule(this); try { workspace.prepareOperation(rule, monitor); - ResourceInfo info = getResourceInfo(false, false); - int flags = getFlags(info); - checkAccessible(flags); - checkLocal(flags, DEPTH_ZERO); + ResourceInfo info = checkAccessibleAndLocal(DEPTH_ZERO); workspace.beginOperation(true); // fake a change by incrementing the content ID Index: src/org/eclipse/core/resources/IResource.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.core.resources/src/org/eclipse/core/resources/IResource.java,v retrieving revision 1.97 diff -u -r1.97 IResource.java --- src/org/eclipse/core/resources/IResource.java 6 Dec 2007 20:38:15 -0000 1.97 +++ src/org/eclipse/core/resources/IResource.java 29 Jan 2008 10:26:31 -0000 @@ -270,7 +270,7 @@ * @since 3.2 */ public static final int TEAM_PRIVATE = 0x800; - + /** * Update flag constant (bit mask value 0x1000) indicating that a * resource should be marked as a hidden resource. @@ -1582,7 +1582,7 @@ * @since 2.0 */ public boolean isDerived(); - + /** * Returns whether this resource subtree is marked as derived. Returns * false if this resource does not exist. @@ -2504,6 +2504,42 @@ * @see IResourceDelta#DESCRIPTION */ public void touch(IProgressMonitor monitor) throws CoreException; + + // Note to Committers (from Francis): These comments below are minimal, and these + // methods are not in the correct place. I will take care of making this + // right if you indicate you want the patch. + /** + * Removes the previously saved persistent properties. + * + * This is used to support saving persistent properties when a resource + * has been deleted so that the properties can be restored is the delete is undone. + * @throws CoreException + */ + public void removeDeletedPersistentProperties() throws CoreException; + + /** + * Sets this resource's persistent properties to be those previously + * saved when the using the savePersistentPropertiesAsDeleted() method. + * + * This is used to support saving persistent properties when a + * resource has been deleted so that the properties can be restored is the delete is undone. + * @throws CoreException + */ + public void restorePersistentPropertiesFromDeleted() throws CoreException; + + /** + * Saves this resource's persistent properties so they persist after the + * resource has been deleted. This must be followed either by a + * restorePersistentPropertiesFromDeleted() call (if the delete is undone) + * or a removeDeletedPersistentProperties (if the delete can never + * be undone. + * + * This is used to support saving persistent properties when a resource + * has been deleted so that the properties can be restored is the delete is undone. + * @throws CoreException + */ + public void savePersistentPropertiesAsDeleted() throws CoreException; + } Index: src/org/eclipse/core/internal/properties/DeletedPropertyBucket.java =================================================================== RCS file: src/org/eclipse/core/internal/properties/DeletedPropertyBucket.java diff -N src/org/eclipse/core/internal/properties/DeletedPropertyBucket.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/core/internal/properties/DeletedPropertyBucket.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2008 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.internal.properties; + +/** + * Used to store properties associated with deleted resources. + */ +public class DeletedPropertyBucket extends PropertyBucket { + + /* (non-Javadoc) + * @see org.eclipse.core.internal.localstore.Bucket#getIndexFileName() + */ + protected String getIndexFileName() { + return "deletedProperties.index"; //$NON-NLS-1$ + } + + +}