Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 170061
Collapse All | Expand All

(-)core refactoring/org/eclipse/jdt/internal/corext/refactoring/changes/undo/MarkerDescription.java (-108 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jdt.internal.corext.refactoring.changes.undo;
13
14
import java.util.Map;
15
16
import org.eclipse.core.resources.IMarker;
17
import org.eclipse.core.resources.IResource;
18
import org.eclipse.core.runtime.CoreException;
19
20
/**
21
 * MarkerDescription is a lightweight description of a marker that can be used
22
 * to describe a marker to be created or updated.
23
 * 
24
 * This class is not intended to be instantiated or used by clients.
25
 * 
26
 * @since 3.3
27
 * 
28
 */
29
public class MarkerDescription {
30
	String type;
31
32
	Map attributes;
33
34
	IResource resource;
35
36
	/**
37
	 * 
38
	 * Create a marker description from the specified marker.
39
	 * 
40
	 * @param marker
41
	 *            the marker to be described
42
	 * @throws CoreException
43
	 */
44
	public MarkerDescription(IMarker marker) throws CoreException {
45
		this.type = marker.getType();
46
		this.attributes = marker.getAttributes();
47
		this.resource = marker.getResource();
48
49
	}
50
51
	/**
52
	 * Create a marker description from the specified marker type, attributes,
53
	 * and resource.
54
	 * 
55
	 * @param type
56
	 *            the type of marker to be created.
57
	 * @param attributes
58
	 *            the attributes to be assigned to the marker
59
	 * @param resource
60
	 *            the resource on which the marker should be created
61
	 */
62
	public MarkerDescription(String type, Map attributes, IResource resource) {
63
		this.type = type;
64
		this.attributes = attributes;
65
		this.resource = resource;
66
	}
67
68
	/**
69
	 * Create a marker from the marker description.
70
	 * 
71
	 * @return the created marker
72
	 * @throws CoreException
73
	 */
74
	public IMarker createMarker() throws CoreException {
75
		IMarker marker = resource.createMarker(type);
76
		marker.setAttributes(attributes);
77
		return marker;
78
	}
79
80
	/**
81
	 * Update an existing marker using the attributes in the marker description.
82
	 * 
83
	 * @param marker
84
	 *            the marker to be updated
85
	 * @throws CoreException
86
	 */
87
	public void updateMarker(IMarker marker) throws CoreException {
88
		marker.setAttributes(attributes);
89
	}
90
91
	/**
92
	 * Return the resource associated with this marker.
93
	 * 
94
	 * @return the resource associated with this marker
95
	 */
96
	public IResource getResource() {
97
		return resource;
98
	}
99
100
	/**
101
	 * Return the marker type associated with this marker.
102
	 * 
103
	 * @return the string marker type of this marker
104
	 */
105
	public String getType() {
106
		return type;
107
	}
108
}
(-)core refactoring/org/eclipse/jdt/internal/corext/refactoring/changes/undo/messages.properties (-55 lines)
Removed Link Here
1
###############################################################################
2
# Copyright (c) 2006 IBM Corporation and others.
3
# All rights reserved. This program and the accompanying materials
4
# are made available under the terms of the Eclipse Public License v1.0
5
# which accompanies this distribution, and is available at
6
# http://www.eclipse.org/legal/epl-v10.html
7
#
8
# Contributors:
9
#     IBM Corporation - initial API and implementation
10
###############################################################################
11
12
AbstractWorkspaceOperation_ExecuteErrorTitle=Error while executing the "{0}" operation
13
AbstractWorkspaceOperation_ErrorInvalidMessage=The operation {0} is no longer valid.
14
AbstractWorkspaceOperation_GenericWarningMessage=The operation {0} may not complete as expected. 
15
AbstractWorkspaceOperation_RedoErrorTitle=Error while redoing the "{0}" operation
16
AbstractWorkspaceOperation_UndoErrorTitle=Error while undoing the "{0}" operation
17
18
AbstractWorkspaceOperation_SideEffectsWarningTitle=Side effects
19
AbstractWorkspaceOperation_ExecuteSideEffectsWarningMessage=Executing "{0}" may have undesirable side effects.
20
AbstractWorkspaceOperation_UndoSideEffectsWarningMessage=Undoing "{0}" may have undesirable side effects.
21
AbstractWorkspaceOperation_RedoSideEffectsWarningMessage=Redoing "{0}" may have undesirable side effects.
22
23
AbstractResourcesOperation_ResourcesDoNotExist=Cannot complete operation because resources no longer exist.
24
AbstractResourcesOperation_ResourcesAlreadyExist=Cannot create or restore resource because it already exists.
25
AbstractResourcesOperation_NotEnoughInfo=There is not enough information to complete the resource operation.
26
AbstractResourcesOperation_InvalidRestoreInfo=There is not enough information to create or restore the resource.
27
AbstractResourcesOperation_DeleteResourcesProgress=Deleting resources...
28
AbstractResourcesOperation_CreateResourcesProgress=Creating resources...
29
AbstractResourcesOperation_CopyingResourcesProgress=Copying resources...
30
AbstractResourcesOperation_MovingResources=Moving resources...
31
AbstractResourcesOperation_outOfSyncError = Resource is out of sync with the file system. Refresh and try again.
32
AbstractResourcesOperation_outOfSyncQuestion = Resource ''{0}'' is out of sync with the file system. Do you want to delete it anyway?
33
AbstractResourcesOperation_deletionMessageTitle = Problems deleting
34
AbstractResourcesOperation_deletionExceptionMessage=Multiple problems occurred while deleting resources.
35
36
AbstractCopyOrMoveResourcesOperation_SameNameOrLocation=Resource cannot be moved or copied to the same location and name.
37
AbstractCopyOrMoveResourcesOperation_ResourceDoesNotExist=Resource no longer exists in the workspace.
38
AbstractCopyOrMoveResourcesOperation_copyProjectProgress=Copying project...
39
AbstractCopyOrMoveResourcesOperation_moveProjectProgress=Moving project...
40
41
CopyResourcesOperation_NotAllowedDueToDataLoss=The original resources that were copied no longer exist.  Undoing the copy is no longer valid, since data could be lost.
42
43
ProjectDescription_NewProjectProgress=Creating new project...
44
FileDescription_NewFileProgress=Creating new file...
45
FileDescription_ContentsCouldNotBeRestored=Unexpected error.  File contents could not be restored from local history during undo/redo.
46
FileDescription_SavingUndoInfoProgress=Saving file info...
47
FolderDescription_NewFolderProgress=Creating new folder...
48
FolderDescription_SavingUndoInfoProgress=Saving folder info...
49
	
50
MarkerOperation_ResourceDoesNotExist=Cannot complete operation because resource no longer exists.
51
MarkerOperation_MarkerDoesNotExist=Cannot complete operation because marker no longer exists.
52
MarkerOperation_NotEnoughInfo=There is not enough information to perform the marker operation.
53
MarkerOperation_CreateProgress=Creating markers...
54
MarkerOperation_DeleteProgress=Deleting markers...
55
MarkerOperation_UpdateProgress= Updating markers...
(-)core refactoring/org/eclipse/jdt/internal/corext/refactoring/changes/undo/UndoMessages.java (-74 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.jdt.internal.corext.refactoring.changes.undo;
13
14
import org.eclipse.osgi.util.NLS;
15
16
/**
17
 * UndoMessages is the class that handles the messages for performing workspace
18
 * undo and redo.
19
 * 
20
 */
21
public class UndoMessages extends NLS {
22
23
	private static final String BUNDLE_NAME = "org.eclipse.ui.internal.ide.undo.messages"; //$NON-NLS-1$
24
25
	static {
26
		// load message values from bundle file
27
		NLS.initializeMessages(BUNDLE_NAME, UndoMessages.class);
28
	}
29
30
	public static String AbstractWorkspaceOperation_ExecuteErrorTitle;
31
	public static String AbstractWorkspaceOperation_RedoErrorTitle;
32
	public static String AbstractWorkspaceOperation_UndoErrorTitle;
33
	public static String AbstractWorkspaceOperation_SideEffectsWarningTitle;
34
	public static String AbstractWorkspaceOperation_ExecuteSideEffectsWarningMessage;
35
	public static String AbstractWorkspaceOperation_UndoSideEffectsWarningMessage;
36
	public static String AbstractWorkspaceOperation_RedoSideEffectsWarningMessage;
37
	public static String AbstractWorkspaceOperation_ErrorInvalidMessage;
38
	public static String AbstractWorkspaceOperation_GenericWarningMessage;
39
	
40
	public static String AbstractResourcesOperation_ResourcesDoNotExist;
41
	public static String AbstractResourcesOperation_ResourcesAlreadyExist;
42
	public static String AbstractResourcesOperation_NotEnoughInfo;
43
	public static String AbstractResourcesOperation_InvalidRestoreInfo;
44
	public static String AbstractResourcesOperation_DeleteResourcesProgress;
45
	public static String AbstractResourcesOperation_CreateResourcesProgress;
46
	public static String AbstractResourcesOperation_CopyingResourcesProgress;
47
	public static String AbstractResourcesOperation_MovingResources;
48
	public static String AbstractResourcesOperation_outOfSyncError;
49
	public static String AbstractResourcesOperation_outOfSyncQuestion;
50
	public static String AbstractResourcesOperation_deletionMessageTitle;
51
	public static String AbstractResourcesOperation_deletionExceptionMessage;
52
	
53
	public static String AbstractCopyOrMoveResourcesOperation_SameNameOrLocation;
54
	public static String AbstractCopyOrMoveResourcesOperation_ResourceDoesNotExist;
55
	public static String AbstractCopyOrMoveResourcesOperation_copyProjectProgress;
56
	public static String AbstractCopyOrMoveResourcesOperation_moveProjectProgress;
57
	
58
	public static String CopyResourcesOperation_NotAllowedDueToDataLoss;
59
	
60
	public static String ProjectDescription_NewProjectProgress;
61
	public static String FileDescription_NewFileProgress;
62
	public static String FileDescription_SavingUndoInfoProgress;
63
	public static String FileDescription_ContentsCouldNotBeRestored;
64
	public static String FolderDescription_NewFolderProgress;
65
	public static String FolderDescription_SavingUndoInfoProgress;
66
	
67
68
	public static String MarkerOperation_ResourceDoesNotExist;
69
	public static String MarkerOperation_MarkerDoesNotExist;
70
	public static String MarkerOperation_NotEnoughInfo;	
71
	public static String MarkerOperation_CreateProgress;
72
	public static String MarkerOperation_DeleteProgress;
73
	public static String MarkerOperation_UpdateProgress;
74
}
(-)core refactoring/org/eclipse/jdt/internal/corext/refactoring/changes/undo/package.html (-16 lines)
Removed Link Here
1
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
2
<html>
3
<head>
4
   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
5
   <meta name="Author" content="IBM">
6
   <title>Package-level Javadoc</title>
7
</head>
8
<body>
9
10
This package is a copy of org.eclipse.ui.internal.ide.undo, see
11
<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=166763">bug 166763</a>.
12
<p>
13
It will be removed shortly.
14
15
</body>
16
</html>
(-)core refactoring/org/eclipse/jdt/internal/corext/refactoring/changes/undo/IFileContentDescription.java (-57 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jdt.internal.corext.refactoring.changes.undo;
12
13
import java.io.InputStream;
14
15
import org.eclipse.core.runtime.CoreException;
16
17
/**
18
 * IFileContentDescription is a description of a file's content.
19
 * 
20
 * This class is not intended to be instantiated or used by clients.
21
 * 
22
 * @since 3.3
23
 * 
24
 */
25
public interface IFileContentDescription {
26
	/**
27
	 * Returns an open input stream on the contents of the file described. The
28
	 * client is responsible for closing the stream when finished.
29
	 * 
30
	 * @return an input stream containing the contents of the file
31
	 * @throws CoreException
32
	 *             any CoreException encountered retrieving the contents
33
	 */
34
	public InputStream getContents() throws CoreException;
35
36
	/**
37
	 * Returns whether this file content description still exists. If it does
38
	 * not exist, it will be unable to produce the contents.
39
	 * 
40
	 * @return <code>true</code> if this description exists, and
41
	 *         <code>false</code> if it does not
42
	 */
43
	public boolean exists();
44
45
	/**
46
	 * Returns the name of a charset encoding to be used when decoding the
47
	 * contents into characters. Returns <code>null</code> if a charset
48
	 * has not been explicitly specified.
49
	 * 
50
	 * @return the name of a charset, or <code>null</code>
51
	 * @throws CoreException
52
	 *             any CoreException encountered while determining the character
53
	 *             set
54
	 * 
55
	 */
56
	public String getCharset() throws CoreException;
57
}
(-)core refactoring/org/eclipse/jdt/internal/corext/refactoring/changes/undo/ProjectDescription.java (-140 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jdt.internal.corext.refactoring.changes.undo;
13
14
import org.eclipse.core.resources.IProject;
15
import org.eclipse.core.resources.IProjectDescription;
16
import org.eclipse.core.resources.IResource;
17
import org.eclipse.core.resources.ResourcesPlugin;
18
import org.eclipse.core.runtime.Assert;
19
import org.eclipse.core.runtime.CoreException;
20
import org.eclipse.core.runtime.IProgressMonitor;
21
import org.eclipse.core.runtime.OperationCanceledException;
22
import org.eclipse.core.runtime.SubProgressMonitor;
23
24
/**
25
 * ProjectDescription is a lightweight description that describes a project to
26
 * be created.
27
 * 
28
 * This class is not intended to be instantiated or used by clients.
29
 * 
30
 * @since 3.3
31
 * 
32
 */
33
public class ProjectDescription extends ContainerDescription {
34
35
	private IProjectDescription projectDescription;
36
	private boolean openOnCreate = true;
37
38
	/**
39
	 * Create a project description from a specified project.
40
	 * 
41
	 * @param project
42
	 *            The project to be described. The project must exist.
43
	 */
44
	public ProjectDescription(IProject project) {
45
		super(project);
46
		Assert.isLegal(project.exists());
47
		if (project.isOpen()) {
48
			try {
49
				this.projectDescription = project.getDescription();
50
			} catch (CoreException e) {
51
				// Eat this exception because it only occurs when the project
52
				// is not accessible and we have already checked this. We
53
				// don't want to propagate the CoreException into the
54
				// constructor
55
				// API.
56
			}
57
		} else {
58
			openOnCreate = false;
59
		}
60
	}
61
62
	/**
63
	 * Create a project description from a specified IProjectDescription. Used
64
	 * when the project does not yet exist.
65
	 * 
66
	 * @param projectDescription
67
	 *            the project description for the future project
68
	 */
69
	public ProjectDescription(IProjectDescription projectDescription) {
70
		super();
71
		this.projectDescription = projectDescription;
72
	}
73
74
	/*
75
	 * (non-Javadoc)
76
	 * 
77
	 * @see org.eclipse.ui.internal.ide.undo.ContainerDescription#createResourceHandle()
78
	 */
79
	public IResource createResourceHandle() {
80
		return ResourcesPlugin.getWorkspace().getRoot().getProject(getName());
81
	}
82
83
	/*
84
	 * (non-Javadoc)
85
	 * 
86
	 * @see org.eclipse.ui.internal.ide.undo.ResourceDescription#createExistentResourceFromHandle(org.eclipse.core.resources.IResource,
87
	 *      org.eclipse.core.runtime.IProgressMonitor)
88
	 */
89
	public void createExistentResourceFromHandle(IResource resource,
90
			IProgressMonitor monitor) throws CoreException {
91
		Assert.isLegal(resource instanceof IProject);
92
		if (resource.exists()) {
93
			return;
94
		}
95
		IProject projectHandle = (IProject) resource;
96
		monitor.beginTask("", 200); //$NON-NLS-1$
97
		monitor.setTaskName(UndoMessages.FolderDescription_NewFolderProgress);
98
		if (projectDescription == null) {
99
			projectHandle.create(new SubProgressMonitor(monitor, 100));
100
		} else {
101
			projectHandle.create(projectDescription, new SubProgressMonitor(
102
					monitor, 100));
103
		}
104
105
		if (monitor.isCanceled()) {
106
			throw new OperationCanceledException();
107
		}
108
		if (openOnCreate) {
109
			projectHandle.open(IResource.BACKGROUND_REFRESH,
110
					new SubProgressMonitor(monitor, 100));
111
		}
112
		monitor.done();
113
	}
114
115
	/*
116
	 * (non-Javadoc)
117
	 * 
118
	 * @see org.eclipse.ui.internal.ide.undo.ContainerDescription#getName()
119
	 */
120
	public String getName() {
121
		if (projectDescription != null) {
122
			return projectDescription.getName();
123
		}
124
		return super.getName();
125
	}
126
127
	/*
128
	 * (non-Javadoc)
129
	 * 
130
	 * @see org.eclipse.ui.internal.ide.undo.ResourceDescription#verifyExistence(boolean)
131
	 */
132
	public boolean verifyExistence(boolean checkMembers) {
133
		// We can only check members if the project is open.
134
		IProject projectHandle = (IProject) createResourceHandle();
135
		if (projectHandle.isAccessible()) {
136
			return super.verifyExistence(checkMembers);
137
		}
138
		return super.verifyExistence(false);
139
	}
140
}
(-)core refactoring/org/eclipse/jdt/internal/corext/refactoring/changes/undo/ResourceDescription.java (-227 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jdt.internal.corext.refactoring.changes.undo;
13
14
import org.eclipse.core.resources.IContainer;
15
import org.eclipse.core.resources.IFile;
16
import org.eclipse.core.resources.IFolder;
17
import org.eclipse.core.resources.IMarker;
18
import org.eclipse.core.resources.IProject;
19
import org.eclipse.core.resources.IResource;
20
import org.eclipse.core.resources.IWorkspace;
21
import org.eclipse.core.resources.ResourceAttributes;
22
import org.eclipse.core.resources.ResourcesPlugin;
23
import org.eclipse.core.runtime.CoreException;
24
import org.eclipse.core.runtime.IProgressMonitor;
25
26
/**
27
 * ResourceDescription is a lightweight description that describes the common
28
 * attributes of a resource to be created.
29
 * 
30
 * This class is not intended to be instantiated or used by clients.
31
 * 
32
 * @since 3.3
33
 * 
34
 */
35
public abstract class ResourceDescription {
36
	IContainer parent;
37
38
	long modificationStamp = IResource.NULL_STAMP;
39
40
	long localTimeStamp = IResource.NULL_STAMP;
41
42
	ResourceAttributes resourceAttributes;
43
44
	MarkerDescription[] markerDescriptions;
45
46
	/**
47
	 * Create a resource description given the specified resource. The resource
48
	 * is assumed to exist.
49
	 * 
50
	 * @param resource
51
	 *            the resource from which a description should be created
52
	 * @return the resource description
53
	 */
54
	public static ResourceDescription fromResource(IResource resource) {
55
		if (resource.getType() == IResource.PROJECT) {
56
			return new ProjectDescription((IProject) resource);
57
		} else if (resource.getType() == IResource.FOLDER) {
58
			return new FolderDescription((IFolder) resource);
59
		} else if (resource.getType() == IResource.FILE) {
60
			return new FileDescription((IFile) resource);
61
		} else {
62
			throw new IllegalArgumentException();
63
		}
64
	}
65
66
	/**
67
	 * Create a resource description with no initial attributes
68
	 */
69
	protected ResourceDescription() {
70
		super();
71
	}
72
73
	/**
74
	 * Create a resource description from the specified resource.
75
	 * 
76
	 * @param resource
77
	 *            the resource to be described
78
	 */
79
	protected ResourceDescription(IResource resource) {
80
		super();
81
		parent = resource.getParent();
82
		if (resource.isAccessible()) {
83
			modificationStamp = resource.getModificationStamp();
84
			localTimeStamp = resource.getLocalTimeStamp();
85
			resourceAttributes = resource.getResourceAttributes();
86
			try {
87
				IMarker[] markers = resource.findMarkers(null, true,
88
						IResource.DEPTH_INFINITE);
89
				markerDescriptions = new MarkerDescription[markers.length];
90
				for (int i = 0; i < markers.length; i++) {
91
					markerDescriptions[i] = new MarkerDescription(markers[i]);
92
				}
93
			} catch (CoreException e) {
94
				// Eat this exception because it only occurs when the resource
95
				// does not exist and we have already checked this.
96
				// We do not want to throw exceptions on the simple constructor,
97
				// as no one has actually tried to do anything yet.
98
			}
99
		}
100
	}
101
102
	/**
103
	 * Create a resource handle that can be used to create a resource from this
104
	 * resource description. This handle can be used to create the actual
105
	 * resource, or to describe the creation to a resource delta factory.
106
	 * 
107
	 * @return the resource handle that can be used to create a resource from
108
	 *         this description
109
	 */
110
	public abstract IResource createResourceHandle();
111
112
	/**
113
	 * Get the name of this resource.
114
	 * 
115
	 * @return the name of the Resource
116
	 */
117
	public abstract String getName();
118
119
	/**
120
	 * Create an existent resource from this resource description.
121
	 * 
122
	 * @param monitor
123
	 *            the progress monitor to use
124
	 * @return a resource that has the attributes of this resource description
125
	 * @throws CoreException
126
	 */
127
	public IResource createResource(IProgressMonitor monitor)
128
			throws CoreException {
129
		IResource resource = createResourceHandle();
130
		createExistentResourceFromHandle(resource, monitor);
131
		restoreResourceAttributes(resource);
132
		return resource;
133
	}
134
135
	/**
136
	 * Given a resource handle, create an actual resource with the attributes of
137
	 * the receiver resource description.
138
	 * 
139
	 * @param resource
140
	 *            the resource handle
141
	 * @param monitor
142
	 *            the progress monitor to be used when creating the resource
143
	 * @throws CoreException
144
	 */
145
	public abstract void createExistentResourceFromHandle(IResource resource,
146
			IProgressMonitor monitor) throws CoreException;
147
148
	/**
149
	 * Return a boolean indicating whether this resource description has enough
150
	 * information to create a resource.
151
	 * 
152
	 * @return <code>true</code> if the resource can be created, and
153
	 *         <code>false</code> if it does not have enough information
154
	 */
155
	public boolean isValid() {
156
		return parent == null || parent.exists();
157
	}
158
159
	/**
160
	 * Record the appropriate state of this resource description using
161
	 * any available resource history.
162
	 * 
163
	 * @param resource
164
	 *            the resource whose state is to be recorded.
165
	 * @param monitor
166
	 *            the progress monitor to be used
167
	 * @throws CoreException
168
	 */
169
	public abstract void recordStateFromHistory(IResource resource,
170
			IProgressMonitor monitor) throws CoreException;
171
172
	/**
173
	 * Restore any saved attributed of the specified resource. This method is
174
	 * called after the existent resource represented by the receiver has been
175
	 * created.
176
	 * 
177
	 * @param resource
178
	 *            the newly created resource
179
	 * @throws CoreException
180
	 */
181
	protected void restoreResourceAttributes(IResource resource) throws CoreException {
182
		if (modificationStamp != IResource.NULL_STAMP) {
183
			resource.revertModificationStamp(modificationStamp);
184
		}
185
		if (localTimeStamp != IResource.NULL_STAMP) {
186
			resource.setLocalTimeStamp(localTimeStamp);
187
		}
188
		if (resourceAttributes != null) {
189
			resource.setResourceAttributes(resourceAttributes);
190
		}
191
		if (markerDescriptions != null) {
192
			for (int i = 0; i < markerDescriptions.length; i++) {
193
				markerDescriptions[i].resource = resource;
194
				markerDescriptions[i].createMarker();
195
			}
196
		}
197
	}
198
199
	/*
200
	 * Return the workspace.
201
	 */
202
	IWorkspace getWorkspace() {
203
		return ResourcesPlugin.getWorkspace();
204
	}
205
206
	/**
207
	 * Return a boolean indicating whether this description represents an
208
	 * existent resource.
209
	 * 
210
	 * @param checkMembers
211
	 *            Use <code>true</code> if members should also exist in order
212
	 *            for this description to be considered existent. A value of
213
	 *            <code>false</code> indicates that the existence of members
214
	 *            does not matter.
215
	 * 
216
	 * @return a boolean indicating whether this description represents an
217
	 *         existent resource.
218
	 */
219
	public boolean verifyExistence(boolean checkMembers) {
220
		IContainer p = parent;
221
		if (p == null) {
222
			p = getWorkspace().getRoot();
223
		}
224
		IResource handle = p.findMember(getName());
225
		return handle != null;
226
	}
227
}
(-)core refactoring/org/eclipse/jdt/internal/corext/refactoring/changes/undo/FileDescription.java (-252 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jdt.internal.corext.refactoring.changes.undo;
13
14
import java.io.ByteArrayInputStream;
15
import java.io.InputStream;
16
import java.net.URI;
17
18
import org.eclipse.core.resources.IFile;
19
import org.eclipse.core.resources.IFileState;
20
import org.eclipse.core.resources.IResource;
21
import org.eclipse.core.resources.IResourceStatus;
22
import org.eclipse.core.resources.IWorkspaceRoot;
23
import org.eclipse.core.runtime.Assert;
24
import org.eclipse.core.runtime.CoreException;
25
import org.eclipse.core.runtime.IPath;
26
import org.eclipse.core.runtime.IProgressMonitor;
27
import org.eclipse.core.runtime.OperationCanceledException;
28
import org.eclipse.core.runtime.SubProgressMonitor;
29
30
/**
31
 * FileDescription is a lightweight description that describes a file to be
32
 * created.
33
 * 
34
 * This class is not intended to be instantiated or used by clients.
35
 * 
36
 * @since 3.3
37
 * 
38
 */
39
public class FileDescription extends ResourceDescription {
40
41
	String name;
42
43
	URI location;
44
45
	String charset;
46
47
	private IFileContentDescription fileContentDescription;
48
49
	/**
50
	 * Create a FileDescription that can be used to later restore the given
51
	 * file. The file typically already exists, but this constructor will not
52
	 * fail if the file does not exist.
53
	 * 
54
	 * @param file
55
	 *            the file to be restored.
56
	 */
57
	public FileDescription(IFile file) {
58
		super(file);
59
		this.name = file.getName();
60
		try {
61
			this.charset = file.getCharset(false);
62
		} catch (CoreException e) {
63
			// we don't care, a null charset is fine.
64
		}
65
		if (file.isLinked()) {
66
			location = file.getLocationURI();
67
		}
68
69
	}
70
71
	/**
72
	 * Create a file description from the specified file handle. The handle does
73
	 * not exist, so no information should be derived from it. If a location
74
	 * path is specified, this file should represent a link to another location.
75
	 * The content description describes any state that should be used when the
76
	 * file resource is created.
77
	 * 
78
	 * @param file
79
	 *            the file to be described
80
	 * @param linkLocation
81
	 *            the location of the file's link, or <code>null</code> if the
82
	 *            file is not linked
83
	 * @param fileContentDescription
84
	 *            the file content description that can be used to get
85
	 *            information about the file, such as its initial content
86
	 */
87
	public FileDescription(IFile file, URI linkLocation,
88
			IFileContentDescription fileContentDescription) {
89
		super(file);
90
		this.name = file.getName();
91
		this.location = linkLocation;
92
		this.charset = null;
93
		this.fileContentDescription = fileContentDescription;
94
	}
95
96
	/*
97
	 * (non-Javadoc)
98
	 * 
99
	 * @see org.eclipse.ui.internal.ide.undo.ResourceDescription#recordStateFromHistory(org.eclipse.core.resources.IResource,
100
	 *      org.eclipse.core.runtime.IProgressMonitor)
101
	 */
102
	public void recordStateFromHistory(IResource resource,
103
			IProgressMonitor monitor) throws CoreException {
104
		Assert.isLegal(resource.getType() == IResource.FILE);
105
106
		if (location != null) {
107
			// file is linked, no need to record any history
108
			return;
109
		}
110
		IFileState[] states = ((IFile) resource).getHistory(monitor);
111
		if (states.length > 0) {
112
			final IFileState state = getMatchingFileState(states);
113
			this.fileContentDescription = new IFileContentDescription() {
114
				/*
115
				 * (non-Javadoc)
116
				 * 
117
				 * @see org.eclipse.ui.internal.ide.undo.IFileContentDescription#exists()
118
				 */
119
				public boolean exists() {
120
					return state.exists();
121
				}
122
123
				/*
124
				 * (non-Javadoc)
125
				 * 
126
				 * @see org.eclipse.ui.internal.ide.undo.IFileContentDescription#getContents()
127
				 */
128
				public InputStream getContents() throws CoreException {
129
					return state.getContents();
130
				}
131
132
				/*
133
				 * (non-Javadoc)
134
				 * 
135
				 * @see org.eclipse.ui.internal.ide.undo.IFileContentDescription#getCharset()
136
				 */
137
				public String getCharset() throws CoreException {
138
					return state.getCharset();
139
				}
140
			};
141
		}
142
	}
143
144
	/*
145
	 * (non-Javadoc)
146
	 * 
147
	 * @see org.eclipse.ui.internal.ide.undo.ResourceDescription#createResourceHandle()
148
	 */
149
	public IResource createResourceHandle() {
150
		IWorkspaceRoot workspaceRoot = parent.getWorkspace().getRoot();
151
		IPath fullPath = parent.getFullPath().append(name);
152
		return workspaceRoot.getFile(fullPath);
153
	}
154
155
	/*
156
	 * (non-Javadoc)
157
	 * 
158
	 * @see org.eclipse.ui.internal.ide.undo.ResourceDescription#createExistentResourceFromHandle(org.eclipse.core.resources.IResource,
159
	 *      org.eclipse.core.runtime.IProgressMonitor)
160
	 */
161
	public void createExistentResourceFromHandle(IResource resource,
162
			IProgressMonitor monitor) throws CoreException {
163
164
		Assert.isLegal(resource instanceof IFile);
165
		if (resource.exists()) {
166
			return;
167
		}
168
		IFile fileHandle = (IFile) resource;
169
		monitor.beginTask("", 200); //$NON-NLS-1$
170
		monitor.setTaskName(UndoMessages.FileDescription_NewFileProgress);
171
		try {
172
			if (monitor.isCanceled()) {
173
				throw new OperationCanceledException();
174
			}
175
			if (location != null) {
176
				fileHandle.createLink(location, IResource.ALLOW_MISSING_LOCAL,
177
						new SubProgressMonitor(monitor, 200));
178
			} else {
179
				InputStream contents = new ByteArrayInputStream(
180
						UndoMessages.FileDescription_ContentsCouldNotBeRestored
181
								.getBytes());
182
				// Retrieve the contents and charset from the file content
183
				// description. Other file state attributes, such as timestamps,
184
				// have already been retrieved from the original IResource
185
				// object and are restored in the superclass.
186
				if (fileContentDescription != null
187
						&& fileContentDescription.exists()) {
188
					contents = fileContentDescription.getContents();
189
					// If the charset was explicitly recorded from the file
190
					// handle,
191
					// use it. But if it is null, get it from the
192
					// fileContentDescription.
193
					if (charset == null) {
194
						charset = fileContentDescription.getCharset();
195
					}
196
				}
197
				fileHandle.create(contents, false, new SubProgressMonitor(
198
						monitor, 100));
199
				fileHandle.setCharset(charset, new SubProgressMonitor(monitor,
200
						100));
201
			}
202
			if (monitor.isCanceled()) {
203
				throw new OperationCanceledException();
204
			}
205
		} catch (CoreException e) {
206
			if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED) {
207
				fileHandle.refreshLocal(IResource.DEPTH_ZERO, null);
208
			} else {
209
				throw e;
210
			}
211
		} finally {
212
			monitor.done();
213
		}
214
	}
215
216
	/*
217
	 * (non-Javadoc)
218
	 * 
219
	 * @see org.eclipse.ui.internal.ide.undo.ResourceDescription#isValid()
220
	 */
221
	public boolean isValid() {
222
		if (location != null) {
223
			return super.isValid();
224
		}
225
		return super.isValid() && fileContentDescription != null
226
				&& fileContentDescription.exists();
227
	}
228
229
	/*
230
	 * (non-Javadoc)
231
	 * 
232
	 * @see org.eclipse.ui.internal.ide.undo.ResourceDescription#getName()
233
	 */
234
	public String getName() {
235
		return name;
236
	}
237
238
	/*
239
	 * Get the file state that matches this file description. The local time
240
	 * stamp is used to try to find a matching file state. If none can be found,
241
	 * the most recent copy of the file state is used.
242
	 */
243
	private IFileState getMatchingFileState(IFileState[] states) {
244
		for (int i = 0; i < states.length; i++) {
245
			if (localTimeStamp == states[i].getModificationTime()) {
246
				return states[i];
247
			}
248
		}
249
		return states[0];
250
251
	}
252
}
(-)core refactoring/org/eclipse/jdt/internal/corext/refactoring/changes/undo/ContainerDescription.java (-298 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jdt.internal.corext.refactoring.changes.undo;
13
14
import java.net.URI;
15
16
import org.eclipse.core.resources.IContainer;
17
import org.eclipse.core.resources.IFile;
18
import org.eclipse.core.resources.IFolder;
19
import org.eclipse.core.resources.IResource;
20
import org.eclipse.core.resources.IWorkspaceRoot;
21
import org.eclipse.core.resources.ResourcesPlugin;
22
import org.eclipse.core.runtime.Assert;
23
import org.eclipse.core.runtime.CoreException;
24
import org.eclipse.core.runtime.IPath;
25
import org.eclipse.core.runtime.IProgressMonitor;
26
import org.eclipse.core.runtime.Path;
27
import org.eclipse.core.runtime.SubProgressMonitor;
28
29
/**
30
 * ContainerDescription is a lightweight description that describes a container
31
 * to be created.
32
 * 
33
 * This class is not intended to be instantiated or used by clients.
34
 * 
35
 * @since 3.3
36
 * 
37
 */
38
public abstract class ContainerDescription extends ResourceDescription {
39
40
	String name;
41
42
	URI location;
43
44
	String defaultCharSet;
45
46
	ResourceDescription[] members;
47
48
	/**
49
	 * Create a container description from the specified container handle that
50
	 * can be used to create the container. The returned ContainerDescription
51
	 * should represent any non-existing parents in addition to the specified
52
	 * container.
53
	 * 
54
	 * @param container
55
	 *            the handle of the container to be described
56
	 * @return a container description describing the container and any
57
	 *         non-existing parents.
58
	 */
59
60
	public static ContainerDescription fromContainer(IContainer container) {
61
		IPath fullPath = container.getFullPath();
62
		ContainerDescription firstCreatedParent = null;
63
		ContainerDescription currentContainerDescription = null;
64
65
		// Does the container exist already? If so, then the parent exists and
66
		// we use the normal creation constructor.
67
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
68
		IContainer currentContainer = (IContainer) root.findMember(fullPath);
69
		if (currentContainer != null) {
70
			return (ContainerDescription) ResourceDescription
71
					.fromResource(container);
72
		}
73
74
		// Create container descriptions for any uncreated parents in the given
75
		// path.
76
		currentContainer = root;
77
		for (int i = 0; i < fullPath.segmentCount(); i++) {
78
			String currentSegment = fullPath.segment(i);
79
			IResource resource = currentContainer.findMember(currentSegment);
80
			if (resource != null) {
81
				// parent already exists, no need to create a description for it
82
				currentContainer = (IContainer) resource;
83
			} else {
84
				if (i == 0) {
85
					// parent does not exist and it is a project
86
					firstCreatedParent = new ProjectDescription(root
87
							.getProject(currentSegment));
88
					currentContainerDescription = firstCreatedParent;
89
				} else {
90
					IFolder folderHandle = currentContainer.getFolder(new Path(
91
							currentSegment));
92
					ContainerDescription currentFolder = new FolderDescription(
93
							folderHandle);
94
					currentContainer = folderHandle;
95
					if (currentContainerDescription != null) {
96
						currentContainerDescription.addMember(currentFolder);
97
					}
98
					currentContainerDescription = currentFolder;
99
					if (firstCreatedParent == null) {
100
						firstCreatedParent = currentFolder;
101
					}
102
				}
103
			}
104
		}
105
		return firstCreatedParent;
106
	}
107
108
	/**
109
	 * Create a ContainerDescription with no state.
110
	 */
111
	public ContainerDescription() {
112
113
	}
114
115
	/**
116
	 * Create a ContainerDescription from the specified container handle.
117
	 * Typically used when the container handle represents a resource that
118
	 * actually exists, although it will not fail if the resource is
119
	 * non-existent.
120
	 * 
121
	 * @param container
122
	 *            the container to be described
123
	 */
124
	public ContainerDescription(IContainer container) {
125
		super(container);
126
		this.name = container.getName();
127
		if (container.isLinked()) {
128
			this.location = container.getLocationURI();
129
		}
130
		try {
131
			if (container.isAccessible()) {
132
				defaultCharSet = container.getDefaultCharset(false);
133
				IResource[] resourceMembers = container.members();
134
				members = new ResourceDescription[resourceMembers.length];
135
				for (int i = 0; i < resourceMembers.length; i++) {
136
					members[i] = ResourceDescription
137
							.fromResource(resourceMembers[i]);
138
				}
139
			}
140
		} catch (CoreException e) {
141
			// Eat this exception because it only occurs when the resource
142
			// does not exist and we have already checked this.
143
			// We do not want to throw exceptions on the simple constructor, as
144
			// no one has actually tried to do anything yet.
145
		}
146
	}
147
148
	/**
149
	 * Create any child resources known by this container description.
150
	 * 
151
	 * @param parentHandle
152
	 *            the handle of the created parent
153
	 * @param monitor
154
	 *            the progress monitor to be used
155
	 * @param ticks
156
	 *            the number of ticks allocated for creating children
157
	 * @throws CoreException
158
	 */
159
	protected void createChildResources(IContainer parentHandle,
160
			IProgressMonitor monitor, int ticks) throws CoreException {
161
162
		// restore any children
163
		if (members != null && members.length > 0) {
164
			for (int i = 0; i < members.length; i++) {
165
				members[i].parent = parentHandle;
166
				members[i].createResource(new SubProgressMonitor(monitor, ticks
167
						/ members.length));
168
			}
169
		}
170
	}
171
172
	/*
173
	 * (non-Javadoc)
174
	 * 
175
	 * @see org.eclipse.ui.internal.ide.undo.ResourceDescription#recordStateFromHistory(org.eclipse.core.resources.IResource,
176
	 *      org.eclipse.core.runtime.IProgressMonitor)
177
	 */
178
	public void recordStateFromHistory(IResource resource,
179
			IProgressMonitor monitor) throws CoreException {
180
		monitor.beginTask(
181
				UndoMessages.FolderDescription_SavingUndoInfoProgress, 100);
182
		for (int i = 0; i < members.length; i++) {
183
			if (members[i] instanceof FileDescription) {
184
				IPath path = resource.getFullPath().append(
185
						((FileDescription) members[i]).name);
186
				IFile fileHandle = resource.getWorkspace().getRoot().getFile(
187
						path);
188
				members[i].recordStateFromHistory(fileHandle,
189
						new SubProgressMonitor(monitor, 100 / members.length));
190
			} else if (members[i] instanceof FolderDescription) {
191
				IPath path = resource.getFullPath().append(
192
						((FolderDescription) members[i]).name);
193
				IFolder folderHandle = resource.getWorkspace().getRoot()
194
						.getFolder(path);
195
				members[i].recordStateFromHistory(folderHandle,
196
						new SubProgressMonitor(monitor, 100 / members.length));
197
			}
198
		}
199
		monitor.done();
200
	}
201
202
	/**
203
	 * Return the name of the container described by this ContainerDescription.
204
	 * 
205
	 * @return the name of the container.
206
	 */
207
	public String getName() {
208
		return name;
209
	}
210
211
	/**
212
	 * Return the first folder found that has no child folders.
213
	 * 
214
	 * @return the container description for the first child in the receiver
215
	 *         that is a leaf, or this container if there are no children.
216
	 */
217
	public ContainerDescription getFirstLeafFolder() {
218
		// If there are no members, this is a leaf
219
		if (members == null || members.length == 0) {
220
			return this;
221
		}
222
		// Traverse the members and find the first potential leaf
223
		for (int i = 0; i < members.length; i++) {
224
			if (members[i] instanceof ContainerDescription) {
225
				return ((ContainerDescription) members[i]).getFirstLeafFolder();
226
			}
227
		}
228
		// No child folders were found, this is a leaf
229
		return this;
230
	}
231
232
	/**
233
	 * Add the specified resource description as a member of this resource
234
	 * description
235
	 * 
236
	 * @param member
237
	 *            the resource description considered a member of this
238
	 *            container.
239
	 */
240
	public void addMember(ResourceDescription member) {
241
		if (members == null) {
242
			members = new ResourceDescription[] { member };
243
		} else {
244
			ResourceDescription[] expandedMembers = new ResourceDescription[members.length + 1];
245
			System.arraycopy(members, 0, expandedMembers, 0, members.length);
246
			expandedMembers[members.length] = member;
247
			members = expandedMembers;
248
		}
249
	}
250
251
	/*
252
	 * (non-Javadoc)
253
	 * 
254
	 * @see org.eclipse.ui.internal.ide.undo.ResourceDescription#restoreResourceAttributes(org.eclipse.core.resources.IResource)
255
	 */
256
	protected void restoreResourceAttributes(IResource resource)
257
			throws CoreException {
258
		super.restoreResourceAttributes(resource);
259
		Assert.isLegal(resource instanceof IContainer);
260
		IContainer container = (IContainer) resource;
261
		if (defaultCharSet != null) {
262
			container.setDefaultCharset(defaultCharSet, null);
263
		}
264
	}
265
266
	/**
267
	 * Set the location to which this container is linked.
268
	 * 
269
	 * @param location
270
	 *            the location URI, or <code>null</code> if there is no link
271
	 */
272
	public void setLocation(URI location) {
273
		this.location = location;
274
	}
275
276
	/*
277
	 * (non-Javadoc)
278
	 * 
279
	 * @see org.eclipse.ui.internal.ide.undo.ResourceDescription#verifyExistence(boolean)
280
	 */
281
	public boolean verifyExistence(boolean checkMembers) {
282
		boolean existence = super.verifyExistence(checkMembers);
283
		if (existence) {
284
			if (checkMembers) {
285
				// restore any children
286
				if (members != null && members.length > 0) {
287
					for (int i = 0; i < members.length; i++) {
288
						if (!members[i].verifyExistence(checkMembers)) {
289
							return false;
290
						}
291
					}
292
				}
293
			}
294
			return true;
295
		}
296
		return false;
297
	}
298
}
(-)core refactoring/org/eclipse/jdt/internal/corext/refactoring/changes/undo/WorkspaceUndoMonitor.java (-257 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jdt.internal.corext.refactoring.changes.undo;
13
14
import org.eclipse.core.commands.ExecutionException;
15
import org.eclipse.core.commands.operations.IAdvancedUndoableOperation;
16
import org.eclipse.core.commands.operations.IAdvancedUndoableOperation2;
17
import org.eclipse.core.commands.operations.IOperationHistory;
18
import org.eclipse.core.commands.operations.IOperationHistoryListener;
19
import org.eclipse.core.commands.operations.IUndoableOperation;
20
import org.eclipse.core.commands.operations.OperationHistoryEvent;
21
import org.eclipse.core.resources.IResourceChangeEvent;
22
import org.eclipse.core.resources.IResourceChangeListener;
23
import org.eclipse.core.resources.ResourcesPlugin;
24
import org.eclipse.core.runtime.IStatus;
25
import org.eclipse.core.runtime.Status;
26
import org.eclipse.ui.PlatformUI;
27
import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
28
29
/**
30
 * WorkspaceUndoMonitor monitors the workspace for resource changes and
31
 * periodically checks the undo history to make sure it is valid.
32
 * 
33
 * This class is not intended to be instantiated or used by clients.
34
 * 
35
 * @since 3.3
36
 * 
37
 */
38
public class WorkspaceUndoMonitor {
39
40
	/**
41
	 * Singleton instance.
42
	 */
43
	private static WorkspaceUndoMonitor instance;
44
45
	/**
46
	 * Number of workspace changes that will cause validation of undo history
47
	 */
48
	private static int CHANGE_THRESHHOLD = 10;
49
50
	/**
51
	 * Get the singleton instance of this class.
52
	 * 
53
	 * @return the singleton instance of this class.
54
	 */
55
	public static WorkspaceUndoMonitor getInstance() {
56
		if (instance == null) {
57
			instance = new WorkspaceUndoMonitor();
58
		}
59
		return instance;
60
	}
61
62
	/**
63
	 * Number of workspace changes that have occurred since the last undoable
64
	 * operation was executed, undone, or redone.
65
	 */
66
	private int numChanges = 0;
67
68
	/**
69
	 * The IUndoableOperation in progress, or <code>null</code> if there is
70
	 * none in progress.
71
	 */
72
	private IUndoableOperation operationInProgress = null;
73
74
	/**
75
	 * Resource listener used to determine how often to validate the workspace
76
	 * undo history.
77
	 */
78
	private IResourceChangeListener resourceListener;
79
80
	/**
81
	 * Operation history listener used to determine whether there is an undoable
82
	 * operation in progress.
83
	 */
84
	private IOperationHistoryListener historyListener;
85
86
	/**
87
	 * Construct an instance. Should only be called by {@link #getInstance()}
88
	 */
89
	private WorkspaceUndoMonitor() {
90
		resourceListener = getResourceChangeListener();
91
		ResourcesPlugin.getWorkspace().addResourceChangeListener(
92
				resourceListener);
93
94
		historyListener = getOperationHistoryListener();
95
		getOperationHistory().addOperationHistoryListener(historyListener);
96
97
	}
98
99
	/**
100
	 * Get a change listener for listening to resource changes.
101
	 * 
102
	 * @return the resource change listeners
103
	 */
104
	private IResourceChangeListener getResourceChangeListener() {
105
		return new IResourceChangeListener() {
106
			/*
107
			 * (non-Javadoc)
108
			 * 
109
			 * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
110
			 */
111
			public void resourceChanged(IResourceChangeEvent event) {
112
				// If there is an operation in progress, this event is to be
113
				// ignored.
114
				if (operationInProgress != null) {
115
					return;
116
				}
117
				if (event.getType() == IResourceChangeEvent.POST_CHANGE
118
						|| event.getType() == IResourceChangeEvent.POST_BUILD) {
119
					// For now, we consider any change a change worth tracking.
120
					// We can be more specific later if warranted.
121
					incrementChangeCount();
122
					if (numChanges >= CHANGE_THRESHHOLD) {
123
						checkOperationHistory();
124
					}
125
				}
126
			}
127
		};
128
	}
129
130
	/**
131
	 * Get a change listener for listening to operation history changes.
132
	 * 
133
	 * @return the resource change listeners
134
	 */
135
	private IOperationHistoryListener getOperationHistoryListener() {
136
		return new IOperationHistoryListener() {
137
138
			/*
139
			 * (non-Javadoc)
140
			 * 
141
			 * @see org.eclipse.core.commands.operations.IOperationHistoryListener#historyNotification(org.eclipse.core.commands.operations.OperationHistoryEvent)
142
			 */
143
			public void historyNotification(OperationHistoryEvent event) {
144
				// We only care about events that have the workspace undo
145
				// context.
146
				if (!event.getOperation().hasContext(
147
						WorkspaceUndoUtil.getWorkspaceUndoContext())) {
148
					return;
149
				}
150
				switch (event.getEventType()) {
151
				case OperationHistoryEvent.ABOUT_TO_EXECUTE:
152
				case OperationHistoryEvent.ABOUT_TO_UNDO:
153
				case OperationHistoryEvent.ABOUT_TO_REDO:
154
					operationInProgress = event.getOperation();
155
					break;
156
				case OperationHistoryEvent.DONE:
157
				case OperationHistoryEvent.UNDONE:
158
				case OperationHistoryEvent.REDONE:
159
					resetChangeCount();
160
					operationInProgress = null;
161
					break;
162
				case OperationHistoryEvent.OPERATION_NOT_OK:
163
					operationInProgress = null;
164
					break;
165
				}
166
			}
167
168
		};
169
	}
170
171
	/**
172
	 * Shutdown the workspace undo monitor. Unhooks the listeners.
173
	 */
174
	public void shutdown() {
175
		if (resourceListener != null) {
176
			ResourcesPlugin.getWorkspace().removeResourceChangeListener(
177
					resourceListener);
178
		}
179
		if (historyListener != null) {
180
			getOperationHistory().removeOperationHistoryListener(
181
					historyListener);
182
		}
183
	}
184
185
	/**
186
	 * Get the operation history.
187
	 */
188
	private IOperationHistory getOperationHistory() {
189
		return PlatformUI.getWorkbench().getOperationSupport()
190
				.getOperationHistory();
191
	}
192
193
	/**
194
	 * Check the pending undoable operation to see if it is still valid.
195
	 */
196
	private void checkOperationHistory() {
197
		IUndoableOperation currentOp = getOperationHistory().getUndoOperation(
198
				WorkspaceUndoUtil.getWorkspaceUndoContext());
199
		// If there is no pending op, nothing to do.
200
		if (currentOp == null) {
201
			resetChangeCount();
202
			return;
203
		}
204
		// First try the simple check
205
		if (!currentOp.canUndo()) {
206
			flushWorkspaceHistory(currentOp);
207
			return;
208
		}
209
		// Now try a more advanced check. If the undoable status is definitely
210
		// an error, flush the history. Anything less than an error status
211
		// should be left alone so that the user can be prompted as to what
212
		// should be done when an undo is actually attempted.
213
		if (currentOp instanceof IAdvancedUndoableOperation
214
				&& currentOp instanceof IAdvancedUndoableOperation2) {
215
			((IAdvancedUndoableOperation2) currentOp).setQuietCompute(true);
216
			IStatus status;
217
			try {
218
				status = ((IAdvancedUndoableOperation) currentOp)
219
						.computeUndoableStatus(null);
220
			} catch (ExecutionException e) {
221
				// Things are not really OK, but we do not want to
222
				// interrupt the user with notification of this problem.
223
				// For now, we pretend that everything is OK, knowing that
224
				// computation will occur again just before the user attempts to
225
				// undo this operation.
226
				status = Status.OK_STATUS;
227
			}
228
			((IAdvancedUndoableOperation2) currentOp).setQuietCompute(false);
229
			if (status.getSeverity() == IStatus.ERROR) {
230
				flushWorkspaceHistory(currentOp);
231
			}
232
		}
233
		resetChangeCount();
234
	}
235
236
	/**
237
	 * Flush the undo and redo history for the workspace undo context.
238
	 */
239
	private void flushWorkspaceHistory(IUndoableOperation op) {
240
		getOperationHistory().dispose(
241
				WorkspaceUndoUtil.getWorkspaceUndoContext(), true, true, false);
242
	}
243
244
	/**
245
	 * Reset the workspace change count
246
	 */
247
	private void resetChangeCount() {
248
		numChanges = 0;
249
	}
250
251
	/**
252
	 * Increment the workspace change count
253
	 */
254
	private void incrementChangeCount() {
255
		numChanges++;
256
	}
257
}
(-)core refactoring/org/eclipse/jdt/internal/corext/refactoring/changes/undo/FolderDescription.java (-114 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jdt.internal.corext.refactoring.changes.undo;
13
14
import java.net.URI;
15
16
import org.eclipse.core.resources.IFolder;
17
import org.eclipse.core.resources.IResource;
18
import org.eclipse.core.resources.IWorkspaceRoot;
19
import org.eclipse.core.runtime.Assert;
20
import org.eclipse.core.runtime.CoreException;
21
import org.eclipse.core.runtime.IPath;
22
import org.eclipse.core.runtime.IProgressMonitor;
23
import org.eclipse.core.runtime.OperationCanceledException;
24
import org.eclipse.core.runtime.SubProgressMonitor;
25
26
/**
27
 * FolderDescription is a lightweight description that describes a folder to be
28
 * created.
29
 * 
30
 * This class is not intended to be instantiated or used by clients.
31
 * 
32
 * @since 3.3
33
 * 
34
 */
35
public class FolderDescription extends ContainerDescription {
36
37
	/**
38
	 * Create a FolderDescription from the specified folder handle. Typically
39
	 * used when the folder handle represents a resource that actually exists,
40
	 * although it will not fail if the resource is non-existent.
41
	 * 
42
	 * @param folder
43
	 *            the folder to be described
44
	 */
45
	public FolderDescription(IFolder folder) {
46
		super(folder);
47
	}
48
49
	/**
50
	 * Create a FolderDescription from the specified folder handle. If the
51
	 * folder to be created should be linked to a different location, specify
52
	 * the location.
53
	 * 
54
	 * @param folder
55
	 *            the folder to be described
56
	 * @param linkLocation
57
	 *            the location to which the folder is linked, or
58
	 *            <code>null</code> if it is not linked
59
	 */
60
	public FolderDescription(IFolder folder, URI linkLocation) {
61
		super(folder);
62
		this.name = folder.getName();
63
		this.location = linkLocation;
64
	}
65
66
	/*
67
	 * (non-Javadoc)
68
	 * 
69
	 * @see org.eclipse.ui.internal.ide.undo.ContainerDescription#createResourceHandle()
70
	 */
71
	public IResource createResourceHandle() {
72
		IWorkspaceRoot workspaceRoot = getWorkspace().getRoot();
73
		IPath folderPath = parent.getFullPath().append(name);
74
		return workspaceRoot.getFolder(folderPath);
75
	}
76
77
	/*
78
	 * (non-Javadoc)
79
	 * 
80
	 * @see org.eclipse.ui.internal.ide.undo.ResourceDescription#createExistentResourceFromHandle(org.eclipse.core.resources.IResource,
81
	 *      org.eclipse.core.runtime.IProgressMonitor)
82
	 */
83
	public void createExistentResourceFromHandle(IResource resource,
84
			IProgressMonitor monitor) throws CoreException {
85
86
		Assert.isLegal(resource instanceof IFolder);
87
		if (resource.exists()) {
88
			return;
89
		}
90
		IFolder folderHandle = (IFolder) resource;
91
		try {
92
			monitor.beginTask("", 200); //$NON-NLS-1$
93
			monitor.setTaskName(UndoMessages.FolderDescription_NewFolderProgress);
94
			if (monitor.isCanceled()) {
95
				throw new OperationCanceledException();
96
			}
97
			if (location != null) {
98
				folderHandle.createLink(location,
99
						IResource.ALLOW_MISSING_LOCAL, new SubProgressMonitor(
100
								monitor, 100));
101
			} else {
102
				folderHandle.create(false, true, new SubProgressMonitor(
103
						monitor, 100));
104
			}
105
			if (monitor.isCanceled()) {
106
				throw new OperationCanceledException();
107
			}
108
			createChildResources(folderHandle, monitor, 100);
109
110
		} finally {
111
			monitor.done();
112
		}
113
	}
114
}
(-)core refactoring/org/eclipse/jdt/internal/corext/refactoring/changes/DeletePackageFragmentRootChange.java (-1 / +2 lines)
Lines 35-40 Link Here
35
import org.eclipse.core.resources.IFile;
35
import org.eclipse.core.resources.IFile;
36
import org.eclipse.core.resources.IResource;
36
import org.eclipse.core.resources.IResource;
37
37
38
import org.eclipse.ui.ide.undo.ResourceDescription;
39
38
import org.eclipse.ltk.core.refactoring.Change;
40
import org.eclipse.ltk.core.refactoring.Change;
39
import org.eclipse.ltk.core.refactoring.CompositeChange;
41
import org.eclipse.ltk.core.refactoring.CompositeChange;
40
import org.eclipse.ltk.core.refactoring.NullChange;
42
import org.eclipse.ltk.core.refactoring.NullChange;
Lines 48-54 Link Here
48
50
49
import org.eclipse.jdt.internal.corext.Corext;
51
import org.eclipse.jdt.internal.corext.Corext;
50
import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
52
import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
51
import org.eclipse.jdt.internal.corext.refactoring.changes.undo.ResourceDescription;
52
import org.eclipse.jdt.internal.corext.refactoring.reorg.IPackageFragmentRootManipulationQuery;
53
import org.eclipse.jdt.internal.corext.refactoring.reorg.IPackageFragmentRootManipulationQuery;
53
import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil;
54
import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil;
54
import org.eclipse.jdt.internal.corext.util.Messages;
55
import org.eclipse.jdt.internal.corext.util.Messages;
(-)core refactoring/org/eclipse/jdt/internal/corext/refactoring/changes/DeleteFileChange.java (-1 / +2 lines)
Lines 17-27 Link Here
17
17
18
import org.eclipse.core.resources.IFile;
18
import org.eclipse.core.resources.IFile;
19
19
20
import org.eclipse.ui.ide.undo.ResourceDescription;
21
20
import org.eclipse.ltk.core.refactoring.Change;
22
import org.eclipse.ltk.core.refactoring.Change;
21
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
23
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
22
24
23
import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
25
import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
24
import org.eclipse.jdt.internal.corext.refactoring.changes.undo.ResourceDescription;
25
import org.eclipse.jdt.internal.corext.util.Messages;
26
import org.eclipse.jdt.internal.corext.util.Messages;
26
27
27
public class DeleteFileChange extends AbstractDeleteChange {
28
public class DeleteFileChange extends AbstractDeleteChange {
(-)core refactoring/org/eclipse/jdt/internal/corext/refactoring/changes/UndoablePackageDeleteChange.java (-2 / +2 lines)
Lines 19-27 Link Here
19
19
20
import org.eclipse.core.resources.IResource;
20
import org.eclipse.core.resources.IResource;
21
21
22
import org.eclipse.ltk.core.refactoring.Change;
22
import org.eclipse.ui.ide.undo.ResourceDescription;
23
23
24
import org.eclipse.jdt.internal.corext.refactoring.changes.undo.ResourceDescription;
24
import org.eclipse.ltk.core.refactoring.Change;
25
25
26
public class UndoablePackageDeleteChange extends DynamicValidationStateChange {
26
public class UndoablePackageDeleteChange extends DynamicValidationStateChange {
27
27
(-)core refactoring/org/eclipse/jdt/internal/corext/refactoring/changes/DeleteSourceManipulationChange.java (-1 / +2 lines)
Lines 18-23 Link Here
18
import org.eclipse.core.resources.IFile;
18
import org.eclipse.core.resources.IFile;
19
import org.eclipse.core.resources.IResource;
19
import org.eclipse.core.resources.IResource;
20
20
21
import org.eclipse.ui.ide.undo.ResourceDescription;
22
21
import org.eclipse.ltk.core.refactoring.Change;
23
import org.eclipse.ltk.core.refactoring.Change;
22
import org.eclipse.ltk.core.refactoring.NullChange;
24
import org.eclipse.ltk.core.refactoring.NullChange;
23
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
25
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
Lines 29-35 Link Here
29
import org.eclipse.jdt.core.JavaCore;
31
import org.eclipse.jdt.core.JavaCore;
30
32
31
import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
33
import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
32
import org.eclipse.jdt.internal.corext.refactoring.changes.undo.ResourceDescription;
33
import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil;
34
import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil;
34
import org.eclipse.jdt.internal.corext.util.Messages;
35
import org.eclipse.jdt.internal.corext.util.Messages;
35
36
(-)core refactoring/org/eclipse/jdt/internal/corext/refactoring/changes/DeleteFolderChange.java (-1 / +2 lines)
Lines 23-33 Link Here
23
import org.eclipse.core.resources.IResourceVisitor;
23
import org.eclipse.core.resources.IResourceVisitor;
24
import org.eclipse.core.resources.ResourcesPlugin;
24
import org.eclipse.core.resources.ResourcesPlugin;
25
25
26
import org.eclipse.ui.ide.undo.ResourceDescription;
27
26
import org.eclipse.ltk.core.refactoring.Change;
28
import org.eclipse.ltk.core.refactoring.Change;
27
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
29
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
28
30
29
import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
31
import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
30
import org.eclipse.jdt.internal.corext.refactoring.changes.undo.ResourceDescription;
31
import org.eclipse.jdt.internal.corext.util.Messages;
32
import org.eclipse.jdt.internal.corext.util.Messages;
32
33
33
public class DeleteFolderChange extends AbstractDeleteChange {
34
public class DeleteFolderChange extends AbstractDeleteChange {
(-)core refactoring/org/eclipse/jdt/internal/corext/refactoring/changes/UndoDeleteResourceChange.java (-1 / +2 lines)
Lines 19-29 Link Here
19
import org.eclipse.core.resources.IFolder;
19
import org.eclipse.core.resources.IFolder;
20
import org.eclipse.core.resources.IResource;
20
import org.eclipse.core.resources.IResource;
21
21
22
import org.eclipse.ui.ide.undo.ResourceDescription;
23
22
import org.eclipse.ltk.core.refactoring.Change;
24
import org.eclipse.ltk.core.refactoring.Change;
23
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
25
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
24
26
25
import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
27
import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
26
import org.eclipse.jdt.internal.corext.refactoring.changes.undo.ResourceDescription;
27
import org.eclipse.jdt.internal.corext.util.Messages;
28
import org.eclipse.jdt.internal.corext.util.Messages;
28
29
29
30
(-)META-INF/MANIFEST.MF (-1 lines)
Lines 18-24 Link Here
18
 org.eclipse.jdt.internal.corext.refactoring.base;x-internal:=true,
18
 org.eclipse.jdt.internal.corext.refactoring.base;x-internal:=true,
19
 org.eclipse.jdt.internal.corext.refactoring.binary;x-internal:=true,
19
 org.eclipse.jdt.internal.corext.refactoring.binary;x-internal:=true,
20
 org.eclipse.jdt.internal.corext.refactoring.changes;x-internal:=true,
20
 org.eclipse.jdt.internal.corext.refactoring.changes;x-internal:=true,
21
 org.eclipse.jdt.internal.corext.refactoring.changes.undo;x-internal:=true,
22
 org.eclipse.jdt.internal.corext.refactoring.code;x-internal:=true,
21
 org.eclipse.jdt.internal.corext.refactoring.code;x-internal:=true,
23
 org.eclipse.jdt.internal.corext.refactoring.code.flow;x-internal:=true,
22
 org.eclipse.jdt.internal.corext.refactoring.code.flow;x-internal:=true,
24
 org.eclipse.jdt.internal.corext.refactoring.delegates;x-internal:=true,
23
 org.eclipse.jdt.internal.corext.refactoring.delegates;x-internal:=true,

Return to bug 170061