Alias support in progress
diff --git a/bundles/org.eclipse.core.resources/.project b/bundles/org.eclipse.core.resources/.project index 26047c9..fb58441 100644 --- a/bundles/org.eclipse.core.resources/.project +++ b/bundles/org.eclipse.core.resources/.project
@@ -14,39 +14,6 @@ <arguments> </arguments> </buildCommand> - <buildCommand> - <name>org.eclipse.ui.externaltools.ExternalToolBuilder</name> - <arguments> - <dictionary> - <key>!{tool_args}</key> - <value>-DbuildType=${build_type}</value> - </dictionary> - <dictionary> - <key>!{tool_loc}</key> - <value>${workspace_loc:/org.eclipse.core.resources/scripts/buildExtraJAR.xml}</value> - </dictionary> - <dictionary> - <key>!{tool_dir}</key> - <value></value> - </dictionary> - <dictionary> - <key>!{tool_refresh}</key> - <value>${none}</value> - </dictionary> - <dictionary> - <key>!{tool_name}</key> - <value>org.eclipse.core.resources extra builder</value> - </dictionary> - <dictionary> - <key>!{tool_type}</key> - <value>org.eclipse.ui.externaltools.type.ant</value> - </dictionary> - <dictionary> - <key>!{tool_show_log}</key> - <value>true</value> - </dictionary> - </arguments> - </buildCommand> </buildSpec> <natures> <nature>org.eclipse.jdt.core.javanature</nature>
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/events/BuildManager.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/events/BuildManager.java index 120433e..421d377 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/events/BuildManager.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/events/BuildManager.java
@@ -19,7 +19,7 @@ import org.eclipse.core.resources.*; import org.eclipse.core.runtime.*; -public class BuildManager implements ICoreConstants, IManager { +public class BuildManager implements ICoreConstants, IManager, ILifecycleListener { protected Workspace workspace; protected boolean building = false; @@ -261,10 +261,6 @@ protected boolean canRun(int trigger) { return !building; } -public void changing(IProject project) { -} -public void closing(IProject project) { -} /** * Creates and returns a Map mapping String(builder name) -> BuilderPersistentInfo. * The table includes entries for all builders that are @@ -315,11 +311,6 @@ return "<no project>"; //$NON-NLS-1$ return currentBuilder.getProject().getFullPath().toString(); } -public void deleting(IProject project) { - //make sure the builder persistent info is deleted for the project move case - if (project.isAccessible()) - setBuildersPersistentInfo(project, null); -} protected IncrementalProjectBuilder getBuilder(String builderName, IProject project, MultiStatus status) throws CoreException { Hashtable builders = getBuilders(project); IncrementalProjectBuilder result = (IncrementalProjectBuilder) builders.get(builderName); @@ -412,6 +403,17 @@ } }; } +public void handleEvent(LifecycleEvent event) { + IProject project = null; + switch (event.kind) { + case LifecycleEvent.PRE_PROJECT_DELETE: + case LifecycleEvent.PRE_PROJECT_MOVE: + project = (IProject)event.resource; + //make sure the builder persistent info is deleted for the project move case + if (project.isAccessible()) + setBuildersPersistentInfo(project, null); + } +} /** * Hook for adding trace options and debug information at the start of a build. */ @@ -546,8 +548,6 @@ } return false; } -public void opening(IProject project) { -} /** * Removes all builders with the given ID from the build spec. * Does nothing if there were no such builders in the spec @@ -598,6 +598,7 @@ public void shutdown(IProgressMonitor monitor) { } public void startup(IProgressMonitor monitor) { + workspace.addLifecycleListener(this); } /** * Returns a string representation of the given builder. @@ -636,4 +637,6 @@ } return project.isNatureEnabled(nature); } + + } \ No newline at end of file
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/events/ILifecycleListener.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/events/ILifecycleListener.java new file mode 100644 index 0000000..87fe5b8 --- /dev/null +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/events/ILifecycleListener.java
@@ -0,0 +1,21 @@ +/********************************************************************** + * Copyright (c) 2002 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.core.internal.events; + +import org.eclipse.core.runtime.CoreException; + +/** + * Interface for clients interested in receiving notification of workspace + * lifecycle events. + */ +public interface ILifecycleListener { + public void handleEvent(LifecycleEvent event) throws CoreException; +}
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/events/LifecycleEvent.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/events/LifecycleEvent.java new file mode 100644 index 0000000..12d8876 --- /dev/null +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/events/LifecycleEvent.java
@@ -0,0 +1,68 @@ +/********************************************************************** + * Copyright (c) 2002 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.core.internal.events; + +import org.eclipse.core.resources.IResource; + +/** + * Class used for broadcasting internal workspace lifecycle events. There is a + * singleton instance, so no listener is allowed to keep references to the event + * after the notification is finished. + */ +public class LifecycleEvent { + //constants for kinds of internal workspace lifecycle events + public static final int PRE_PROJECT_CLOSE = 0x01; + public static final int PRE_PROJECT_DELETE = 0x02; + public static final int PRE_PROJECT_OPEN = 0x04; + public static final int PRE_PROJECT_MOVE = 0x08; + public static final int POST_LINK_CREATE = 0x10; + public static final int PRE_LINK_DELETE = 0x20; + public static final int PRE_LINK_MOVE = 0x40; + + /** + * The kind of event + */ + public int kind; + /** + * For events that only involve one resource, this is it. More + * specifically, this is used for all non-move events. For move events, this + * resource represents the source of the move. + */ + public IResource resource; + /** + * For move events, this resource represents the destination of the move. + */ + public IResource newResource; + + /** + * The update flags for the event. + */ + public int updateFlags; + + private static final LifecycleEvent instance = new LifecycleEvent(); + private LifecycleEvent() { + super(); + } + public LifecycleEvent newEvent(int kind, IResource resource) { + this.kind = kind; + this.resource = resource; + this.newResource = null; + this.updateFlags = 0; + return this; + } + public LifecycleEvent newEvent(int kind, IResource oldResource, IResource newResource, int updateFlags) { + this.kind = kind; + this.resource = oldResource; + this.newResource = null; + this.updateFlags = 0; + return this; + } +} \ No newline at end of file
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/events/NotificationManager.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/events/NotificationManager.java index d9c4bcf..2db4929 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/events/NotificationManager.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/events/NotificationManager.java
@@ -17,7 +17,7 @@ import org.eclipse.core.resources.*; import org.eclipse.core.runtime.*; -public class NotificationManager implements IManager { +public class NotificationManager implements IManager, ILifecycleListener { protected ResourceChangeListenerList listeners; protected Workspace workspace; protected ElementTree oldState; @@ -80,19 +80,6 @@ } } -public void changing(IProject project) { -} - -public void closing(IProject project) { - if (!listeners.hasListenerFor(IResourceChangeEvent.PRE_CLOSE)) - return; - notify(getListeners(), new ResourceChangeEvent(workspace, IResourceChangeEvent.PRE_CLOSE, project), true); -} -public void deleting(IProject project) { - if (!listeners.hasListenerFor(IResourceChangeEvent.PRE_DELETE)) - return; - notify(getListeners(), new ResourceChangeEvent(workspace, IResourceChangeEvent.PRE_DELETE, project), true); -} protected ResourceDelta getDelta(ElementTree tree) { long id = workspace.getMarkerManager().getChangeId(); // if we have a delta from last time and no resources have changed since then, we @@ -117,6 +104,23 @@ } return result; } +public void handleEvent(LifecycleEvent event) { + switch (event.kind) { + case LifecycleEvent.PRE_PROJECT_CLOSE: + if (!listeners.hasListenerFor(IResourceChangeEvent.PRE_CLOSE)) + return; + IProject project = (IProject)event.resource; + notify(getListeners(), new ResourceChangeEvent(workspace, IResourceChangeEvent.PRE_CLOSE, project), true); + break; + + case LifecycleEvent.PRE_PROJECT_DELETE: + if (!listeners.hasListenerFor(IResourceChangeEvent.PRE_DELETE)) + return; + project = (IProject)event.resource; + notify(getListeners(), new ResourceChangeEvent(workspace, IResourceChangeEvent.PRE_DELETE, project), true); + break; + } +} private void notify(ResourceChangeListenerList.ListenerEntry[] resourceListeners, final IResourceChangeEvent event, boolean lockTree) { int type = event.getType(); for (int i = 0; i < resourceListeners.length; i++) { @@ -154,8 +158,6 @@ } } } -public void opening(IProject project) { -} public void removeListener(IResourceChangeListener listener) { synchronized (listeners) { listeners.remove(listener); @@ -169,5 +171,8 @@ // tell the workspace to track changes from there. This gives the // notificaiton manager an initial basis for comparison. oldState = workspace.getElementTree(); + workspace.addLifecycleListener(this); } + + }
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/properties/PropertyManager.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/properties/PropertyManager.java index f10fe29..5c3abae 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/properties/PropertyManager.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/properties/PropertyManager.java
@@ -13,6 +13,8 @@ import java.util.Enumeration; import java.util.List; +import org.eclipse.core.internal.events.ILifecycleListener; +import org.eclipse.core.internal.events.LifecycleEvent; import org.eclipse.core.internal.resources.*; import org.eclipse.core.internal.utils.Assert; import org.eclipse.core.internal.utils.Policy; @@ -21,13 +23,11 @@ /** * */ -public class PropertyManager implements IManager { +public class PropertyManager implements IManager, ILifecycleListener { protected Workspace workspace; public PropertyManager(Workspace workspace) { this.workspace = workspace; } -public void changing(IProject target) { -} public void closePropertyStore(IResource target) throws CoreException { Resource host = (Resource) getPropertyHost(target); ResourceInfo info = (ResourceInfo) host.getResourceInfo(false, false); @@ -41,9 +41,6 @@ setPropertyStore(target, null); } } -public void closing(IProject target) throws CoreException { - closePropertyStore(target); -} /** * Copy all the properties of one resource to another. Both resources * must have a property store available. @@ -101,8 +98,6 @@ closePropertyStore(target); workspace.getMetaArea().getPropertyStoreLocation(target).toFile().delete(); } -public void deleting(IProject project) { -} /** * Returns the value of the identified property on the given resource as * maintained by this store. @@ -152,7 +147,9 @@ throw new ResourceException(IResourceStatus.FAILED_READ_LOCAL, target.getFullPath(), message, e); } } -public void opening(IProject target) throws CoreException { +public void handleEvent(LifecycleEvent event) throws CoreException { + if (event.kind == LifecycleEvent.PRE_PROJECT_CLOSE) + closePropertyStore(event.resource); } protected PropertyStore openPropertyStore(IResource target) { int type = target.getType(); @@ -190,5 +187,8 @@ closePropertyStore(workspace.getRoot()); } public void startup(IProgressMonitor monitor) throws CoreException { + workspace.addLifecycleListener(this); } + + }
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/AliasManager.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/AliasManager.java index 3d543a0..8bf2a92 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/AliasManager.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/AliasManager.java
@@ -12,7 +12,8 @@ import java.util.*; -import org.eclipse.core.internal.utils.Assert; +import org.eclipse.core.internal.events.ILifecycleListener; +import org.eclipse.core.internal.events.LifecycleEvent; import org.eclipse.core.internal.utils.Policy; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -38,10 +39,10 @@ * that it's better to incur this cost on startup than on the first attempt to * modify a resource. After startup, the state is updated incrementally on the * following occasions: - * - when projects are created, deleted, opened, closed, or moved + * - when projects are deleted, opened, closed, or moved * - when linked resources are created, deleted, or moved. */ -public class AliasManager implements IManager { +public class AliasManager implements IManager, ILifecycleListener { /** * Maintains a mapping of IPath->IResource, such that multiple resources * mapped from the same path are tolerated. @@ -176,23 +177,22 @@ IPath location = project.getLocation(); if (location != null) locationsMap.add(location, project); - IResource[] members = null; try { - members = project.members(); + IResource[] members = project.members(); + if (members != null) + //look for linked resources + for (int i = 0; i < members.length; i++) + if (members[i].isLinked()) + addToLocationsMap(members[i]); } catch (CoreException e) { //skip inaccessible projects } - if (members != null) { - //look for linked resources - for (int j = 0; j < members.length; j++) { - if (members[j].isLinked()) { - location = members[j].getLocation(); - if (location != null) - if (locationsMap.add(location, members[j])) - linkedResourceCount++; - } - } - } + } + private void addToLocationsMap(IResource linkedResource) { + IPath location = linkedResource.getLocation(); + if (location != null) + if (locationsMap.add(location, linkedResource)) + linkedResourceCount++; } /** @@ -203,7 +203,7 @@ //if there are no linked resources then there can't be any aliased projects if (linkedResourceCount <= 0) { //paranoid check -- count should never be below zero - Assert.isTrue(linkedResourceCount == 0, "Linked resource count below zero");//$NON-NLS-1$ +// Assert.isTrue(linkedResourceCount == 0, "Linked resource count below zero");//$NON-NLS-1$ return; } //for every resource that overlaps another, marked its project as aliased @@ -226,13 +226,7 @@ addToLocationsMap(projects[i]); } } - public void changing(IProject project) { - } - public void closing(IProject project) { - //same as deleting for purposes of alias data - deleting(project); - } - public void deleting(IProject project) { + public void removeFromLocationsMap(IProject project) { //remove this project and all linked children from the location table IPath location = project.getLocation(); if (location != null) @@ -246,14 +240,12 @@ if (children != null) { for (int i = 0; i < children.length; i++) { if (children[i].isLinked()) { - deleting(children[i]); + removeFromLocationsMap(children[i]); } } } - //rebuild the set of aliased projects from scratch - buildAliasedProjectsSet(); } - public void deleting(IResource linkedResource) { + public void removeFromLocationsMap(IResource linkedResource) { //this linked resource is being deleted IPath location = linkedResource.getLocation(); if (location != null) @@ -286,10 +278,33 @@ } }; } - public void opening(IProject project) { - addToLocationsMap(project); + public void handleEvent(LifecycleEvent event) throws CoreException { + switch (event.kind) { + case LifecycleEvent.PRE_PROJECT_CLOSE: + case LifecycleEvent.PRE_PROJECT_DELETE: + removeFromLocationsMap((IProject)event.resource); + break; + case LifecycleEvent.PRE_PROJECT_MOVE: + case LifecycleEvent.PRE_PROJECT_OPEN: + addToLocationsMap((IProject)event.resource); + buildAliasedProjectsSet(); + break; + case LifecycleEvent.PRE_LINK_DELETE: + case LifecycleEvent.PRE_LINK_MOVE: + case LifecycleEvent.POST_LINK_CREATE: + } + //rebuild the set of aliased projects from scratch buildAliasedProjectsSet(); } + /** + * Method moving. + * @param source + * @param destination + * @param updateFlags + */ + public void moving(IResource source, IResource destination, int updateFlags) { + // todo + } /** * @see IManager#shutdown @@ -301,9 +316,11 @@ * @see IManager#startup */ public void startup(IProgressMonitor monitor) throws CoreException { + workspace.addLifecycleListener(this); buildLocationsMap(); buildAliasedProjectsSet(); } + /** * The file underlying the given resource has changed on disk. Compute all * aliases for this resource and update them. This method will not attempt @@ -330,4 +347,11 @@ // todo return null; } + /** + * Notification of creation of a linked reousr.cds + */ + public void creating(IResource linkedResource) { + addToLocationsMap(linkedResource); + buildAliasedProjectsSet(); + } } \ No newline at end of file
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Container.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Container.java index 5e73fd6..2761163 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Container.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Container.java
@@ -69,11 +69,9 @@ /** */ protected void fixupAfterMoveSource() throws CoreException { - if (!synchronizing(getResourceInfo(false, false)) || getType() == PROJECT) { - workspace.deleteResource(this); - return; - } super.fixupAfterMoveSource(); + if (!synchronizing(getResourceInfo(false, false))) + return; IResource[] members = members(IContainer.INCLUDE_PHANTOMS | IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS); for (int i = 0; i < members.length; i++) ((Resource) members[i]).fixupAfterMoveSource();
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/MarkerManager.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/MarkerManager.java index 65163b6..a64a78f 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/MarkerManager.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/MarkerManager.java
@@ -197,22 +197,6 @@ info.incrementMarkerGenerationCount(); } /** - * Internal workspace lifecycle event - */ -public void changing(IProject project) { -} -/** - * Internal workspace lifecycle event - */ -public void closing(IProject project) { -} -/** - * Internal workspace lifecycle event - */ -public void deleting(IProject project) { -} - -/** * Returns the marker with the given id or <code>null</code> if none is found. */ public IMarker findMarker(IResource resource, long id) { @@ -332,11 +316,6 @@ destination.accept(visitor, depth, false); } /** - * Internal workspace lifecycle event - */ -public void opening(IProject project) { -} -/** * Adds the markers for a subtree of resources to the list. */ private void recursiveFindMarkers(IPath path, ArrayList list, String type, boolean includeSubtypes, int depth) { @@ -483,4 +462,6 @@ */ public void startup(IProgressMonitor monitor) throws CoreException { } + + }
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/NatureManager.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/NatureManager.java index 32e23b6..69b11b4 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/NatureManager.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/NatureManager.java Binary files differ
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Project.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Project.java index 2c54395..9d5a29f 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Project.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Project.java Binary files differ
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Resource.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Resource.java index 08a522e..0313600 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Resource.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Resource.java
@@ -475,7 +475,8 @@ new LinkDescription(this,localLocation)); project.writeDescription(IResource.NONE); monitor.worked(Policy.opWork * 5 / 100); - + //notify internal infrastructure that link has been created + workspace.creating(this); //refresh to discover any new resources below this linked location if (getType() != IResource.FILE) refreshLocal(DEPTH_INFINITE, Policy.subMonitorFor(monitor, Policy.opWork * 90 / 100)); @@ -625,6 +626,8 @@ getMarkerManager().removeMarkers(this, IResource.DEPTH_INFINITE); // if this is a linked resource, remove the entry from the project description if (isLinked()) { + //pre-delete notification to internal infrastructure + workspace.deleting(this); Project project = (Project)getProject(); ProjectDescription description = project.internalGetDescription(); description.setLinkLocation(getName(), null); @@ -681,6 +684,13 @@ } protected void fixupAfterMoveSource() throws CoreException { ResourceInfo info = getResourceInfo(true, true); + //if a linked resource is moved, we need to remove the location info from the .project + if (isLinked()) { + Project project = (Project)getProject(); + project.internalGetDescription().setLinkLocation(getName(), null); + project.writeDescription(IResource.NONE); + } + if (!synchronizing(info)) { workspace.deleteResource(this); return; @@ -984,20 +994,19 @@ } /** - * @see IResource#move - */ -public void move(IPath destination, boolean force, IProgressMonitor monitor) throws CoreException { - move(destination, force ? IResource.FORCE : IResource.NONE, monitor); -} - -/** - * @see IResource#move + * @see IFolder#move and IFile#move */ public void move(IPath destination, boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException { int updateFlags = force ? IResource.FORCE : IResource.NONE; updateFlags |= keepHistory ? IResource.KEEP_HISTORY : IResource.NONE; move(destination, updateFlags, monitor); } +/** + * @see IResource#move + */ +public void move(IPath destination, boolean force, IProgressMonitor monitor) throws CoreException { + move(destination, force ? IResource.FORCE : IResource.NONE, monitor); +} /** * @see IResource#move @@ -1031,14 +1040,13 @@ break; case IResource.PROJECT: IProject project = (IProject) this; - // if there is a change in name, then we are deleting the source project so notify. - // else there is nothing to do so return. + // if there is no change in name, there is nothing to do so return. if (getName().equals(path.lastSegment())) { return; - } else { - workspace.changing(project); - workspace.deleting(project); } + //we are deleting the source project so notify. + workspace.changing(project); + workspace.deleting(project); IProjectDescription description = project.getDescription(); description.setName(path.lastSegment()); if (!hook.moveProject(tree, project, description, updateFlags, Policy.subMonitorFor(monitor, Policy.opWork/2)))
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Workspace.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Workspace.java index d12b7bb..d093a1f 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Workspace.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Workspace.java
@@ -26,6 +26,7 @@ public class Workspace extends PlatformObject implements IWorkspace, ICoreConstants { + protected WorkspaceDescription description; protected LocalMetaArea localMetaArea; protected boolean openFlag = false; @@ -39,13 +40,16 @@ protected PathVariableManager pathVariableManager; protected PropertyManager propertyManager; protected MarkerManager markerManager; + protected WorkManager workManager; + protected AliasManager aliasManager; protected long nextNodeId = 0; protected long nextModificationStamp = 0; protected long nextMarkerId = 0; protected Synchronizer synchronizer; - protected WorkManager workManager; protected IProject[] buildOrder = null; protected IWorkspaceRoot defaultRoot = new WorkspaceRoot(Path.ROOT, this); + + protected final ArrayList lifecycleListeners = new ArrayList(10); protected static final String REFRESH_ON_STARTUP = "-refresh"; //$NON-NLS-1$ @@ -95,6 +99,13 @@ tree.setTreeData(newElement(IResource.ROOT)); } /** + * Adds a listener for internal workspace lifecycle events. There is no way to + * remove lifecycle listeners. + */ +public void addLifecycleListener(ILifecycleListener listener) { + lifecycleListeners.add(listener); +} +/** * @see IWorkspace */ public void addResourceChangeListener(IResourceChangeListener listener) { @@ -140,6 +151,14 @@ monitor.subTask(Policy.bind("resources.updating")); //$NON-NLS-1$ notificationManager.broadcastChanges(currentTree, type, lockTree, updateState); } +/** + * Broadcasts an internal workspace lifecycle event to interested + * internal listeners. + */ +protected void broadcastEvent(LifecycleEvent event) throws CoreException { + +} + public void build(int trigger, IProgressMonitor monitor) throws CoreException { monitor = Policy.monitorFor(monitor); try { @@ -168,6 +187,7 @@ notificationManager.changing(project); propertyManager.changing(project); markerManager.changing(project); + aliasManager.changing(project); } /** * @see IWorkspace#checkpoint @@ -281,6 +301,7 @@ notificationManager.closing(project); propertyManager.closing(project); markerManager.closing(project); + aliasManager.closing(project); } /** @@ -690,6 +711,15 @@ } return info; } +/** + * Notify relevant infrastructure pieces that a linked resource is being + * created. + */ +public void creating(IResource linkedResource) { + aliasManager.creating(linkedResource); +} + + /* * Creates the given resource in the tree and returns the new resource info object. * If phantom is true, the created element is marked as a phantom. @@ -814,8 +844,18 @@ notificationManager.deleting(project); propertyManager.deleting(project); markerManager.deleting(project); + aliasManager.deleting(project); } /** + * Notify relevant infrastructure pieces that a linked resources is being + * deleted. This is needed because the linked resource location is no longer + * available after the operation is completed. + */ +protected void deleting(IResource linkedResource) throws CoreException { + aliasManager.deleting(linkedResource); +} + +/** * For debugging purposes only. Dumps plugin stats to console */ public void dumpStats() { @@ -1388,6 +1428,23 @@ source.fixupAfterMoveSource(); } /** + * Notify the relevant infrastructure pieces that the given project or linked + * resource is being moved. + */ +protected void moving(IResource source, IResource destination, int updateFlags) { + //most infrastructure only cares about project deletion + if (source.getType() == IResource.PROJECT) { + IProject project = (IProject)source; + buildManager.deleting(project); + natureManager.deleting(project); + notificationManager.deleting(project); + propertyManager.deleting(project); + markerManager.deleting(project); + } + aliasManager.moving(source, destination, updateFlags); +} + +/** * Create and return a new tree element of the given type. */ protected ResourceInfo newElement(int type) { @@ -1533,6 +1590,7 @@ notificationManager.opening(project); propertyManager.opening(project); markerManager.opening(project); + aliasManager.opening(project); } /** * Called before checking the pre-conditions of an operation. @@ -1696,6 +1754,7 @@ pathVariableManager = new PathVariableManager(this); pathVariableManager.startup(null); natureManager = new NatureManager(); + natureManager.startup(null); buildManager = new BuildManager(this); buildManager.startup(null); notificationManager = new NotificationManager(this); @@ -1705,6 +1764,10 @@ synchronizer = new Synchronizer(this); saveManager = new SaveManager(this); saveManager.startup(null); + //must start after save manager, because (read) access to tree is needed + aliasManager = new AliasManager(this); + aliasManager.startup(null); + treeLocked = false; // unlock the tree. } /**
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/messages.properties b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/messages.properties index f888a9e..907e2a7 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/messages.properties +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/messages.properties
@@ -83,6 +83,7 @@ links.moveNotProject = Cannot move {0} to {1}. Linked resources must have a project as their parent. links.natureVeto = Linking is not allowed because project nature \"{0}\" does not allow it. links.overlappingResource = Location {0} may overlap the location of another resource in the same workspace. This is permitted, but may have unexpected side-effects because changing one resource may now cause several resources to change. +links.updatingDuplicate = Updating duplicate resource: {0}. links.parentNotProject = Cannot create linked resource {0}. Linked resources must have a project as their parent. links.vetoNature = Cannot add nature because project {0} contains linked resources, and nature \"{1}\" does not allow it. links.wrongLocalType = Cannot create linked resource {0}. Files cannot be linked to folders.