KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > ide > undo > CopyResourcesOperation


1 /*******************************************************************************
2  * Copyright (c) 2006, 2007 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.ui.ide.undo;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.eclipse.core.resources.IResource;
18 import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory;
19 import org.eclipse.core.runtime.CoreException;
20 import org.eclipse.core.runtime.IAdaptable;
21 import org.eclipse.core.runtime.IPath;
22 import org.eclipse.core.runtime.IProgressMonitor;
23 import org.eclipse.core.runtime.IStatus;
24 import org.eclipse.core.runtime.SubProgressMonitor;
25 import org.eclipse.ui.internal.ide.undo.UndoMessages;
26
27 /**
28  * A CopyResourcesOperation represents an undoable operation for copying one or
29  * more resources in the workspace. Clients may call the public API from a
30  * background thread.
31  *
32  * This operation can track any overwritten resources and restore them when the
33  * copy is undone. It is up to clients to determine whether overwrites are
34  * allowed. If a resource should not be overwritten, it should not be included
35  * in this operation. In addition to checking for overwrites, the target
36  * location for the copy is assumed to have already been validated by the
37  * client. It will not be revalidated on undo and redo.
38  *
39  * This class is intended to be instantiated and used by clients. It is not
40  * intended to be subclassed by clients.
41  *
42  * @since 3.3
43  *
44  */

45 public class CopyResourcesOperation extends
46         AbstractCopyOrMoveResourcesOperation {
47
48     IResource[] originalResources;
49
50     ResourceDescription[] snapshotResourceDescriptions;
51
52     /**
53      * Create a CopyResourcesOperation that copies a single resource to a new
54      * location. The new location includes the name of the copy.
55      *
56      * @param resource
57      * the resource to be copied
58      * @param newPath
59      * the new workspace-relative path for the copy, including its
60      * desired name.
61      * @param label
62      * the label of the operation
63      */

64     public CopyResourcesOperation(IResource resource, IPath newPath,
65             String JavaDoc label) {
66         super(new IResource[] { resource }, new IPath[] { newPath }, label);
67         setOriginalResources(new IResource[] { resource });
68     }
69
70     /**
71      * Create a CopyResourcesOperation that copies all of the specified
72      * resources to a single target location. The original resource name will be
73      * used when copied to the new location.
74      *
75      * @param resources
76      * the resources to be copied
77      * @param destinationPath
78      * the workspace-relative destination path for the copied
79      * resource.
80      * @param label
81      * the label of the operation
82      */

83     public CopyResourcesOperation(IResource[] resources, IPath destinationPath,
84             String JavaDoc label) {
85         super(resources, destinationPath, label);
86         setOriginalResources(this.resources);
87     }
88
89     /**
90      * Create a CopyResourcesOperation that copies each of the specified
91      * resources to its corresponding destination path in the destination path
92      * array. The resource name for the target is included in the corresponding
93      * destination path.
94      *
95      * @param resources
96      * the resources to be copied. Must not contain null resources.
97      * @param destinationPaths
98      * a workspace-relative destination path for each copied
99      * resource, which includes the name of the resource at the new
100      * destination. Must be the same length as the resources array,
101      * and may not contain null paths.
102      * @param label
103      * the label of the operation
104      */

105     public CopyResourcesOperation(IResource[] resources,
106             IPath[] destinationPaths, String JavaDoc label) {
107         super(resources, destinationPaths, label);
108         setOriginalResources(this.resources);
109     }
110
111     /*
112      * (non-Javadoc)
113      *
114      * This implementation copies the resources.
115      *
116      * @see org.eclipse.ui.ide.undo.AbstractWorkspaceOperation#doExecute(org.eclipse.core.runtime.IProgressMonitor,
117      * org.eclipse.core.runtime.IAdaptable)
118      */

119     protected void doExecute(IProgressMonitor monitor, IAdaptable uiInfo)
120             throws CoreException {
121         copy(monitor, uiInfo);
122     }
123
124     /**
125      * Move or copy any known resources according to the destination parameters
126      * known by this operation. Store enough information to undo and redo the
127      * operation.
128      *
129      * @param monitor
130      * the progress monitor to use for the operation
131      * @param uiInfo
132      * the IAdaptable (or <code>null</code>) provided by the
133      * caller in order to supply UI information for prompting the
134      * user if necessary. When this parameter is not
135      * <code>null</code>, it contains an adapter for the
136      * org.eclipse.swt.widgets.Shell.class
137      * @throws CoreException
138      * propagates any CoreExceptions thrown from the resources API
139      */

140     protected void copy(IProgressMonitor monitor, IAdaptable uiInfo)
141             throws CoreException {
142
143         monitor.beginTask("", 2000); //$NON-NLS-1$
144
monitor
145                 .setTaskName(UndoMessages.AbstractResourcesOperation_CopyingResourcesProgress);
146         List JavaDoc resourcesAtDestination = new ArrayList JavaDoc();
147         List JavaDoc overwrittenResources = new ArrayList JavaDoc();
148
149         for (int i = 0; i < resources.length; i++) {
150             // Copy the resources and record the overwrites that would
151
// be restored if this operation were reversed
152
ResourceDescription[] overwrites;
153             overwrites = WorkspaceUndoUtil.copy(
154                     new IResource[] { resources[i] }, getDestinationPath(
155                             resources[i], i), resourcesAtDestination,
156                     new SubProgressMonitor(monitor, 1000 / resources.length),
157                     uiInfo, true);
158             // Accumulate the overwrites into the full list
159
for (int j = 0; j < overwrites.length; j++) {
160                 overwrittenResources.add(overwrites[j]);
161             }
162         }
163
164         // Are there any previously overwritten resources to restore now?
165
if (resourceDescriptions != null) {
166             for (int i = 0; i < resourceDescriptions.length; i++) {
167                 if (resourceDescriptions[i] != null) {
168                     resourceDescriptions[i]
169                             .createResource(new SubProgressMonitor(monitor,
170                                     1000 / resourceDescriptions.length));
171                 }
172             }
173         }
174
175         // Reset resource descriptions to the just overwritten resources
176
setResourceDescriptions((ResourceDescription[]) overwrittenResources
177                 .toArray(new ResourceDescription[overwrittenResources.size()]));
178
179         // Reset the target resources to refer to the resources in their new
180
// location.
181
setTargetResources((IResource[]) resourcesAtDestination
182                 .toArray(new IResource[resourcesAtDestination.size()]));
183         monitor.done();
184     }
185
186     /*
187      * (non-Javadoc)
188      *
189      * This implementation deletes the previously made copies and restores any
190      * resources that were overwritten by the copy.
191      *
192      * @see org.eclipse.ui.ide.undo.AbstractWorkspaceOperation#doUndo(org.eclipse.core.runtime.IProgressMonitor,
193      * org.eclipse.core.runtime.IAdaptable)
194      */

195     protected void doUndo(IProgressMonitor monitor, IAdaptable uiInfo)
196             throws CoreException {
197         monitor.beginTask("", 2); //$NON-NLS-1$
198
monitor
199                 .setTaskName(UndoMessages.AbstractResourcesOperation_CopyingResourcesProgress);
200         // undoing a copy is first deleting the copied resources...
201
WorkspaceUndoUtil.delete(resources, new SubProgressMonitor(monitor, 1),
202                 uiInfo, true);
203         // then restoring any overwritten by the previous copy...
204
WorkspaceUndoUtil.recreate(resourceDescriptions,
205                 new SubProgressMonitor(monitor, 1), uiInfo);
206         setResourceDescriptions(new ResourceDescription[0]);
207         // then setting the target resources back to the original ones.
208
// Note that the destination paths never changed since they
209
// are not used during undo.
210
setTargetResources(originalResources);
211         monitor.done();
212     }
213
214     /*
215      * (non-Javadoc)
216      *
217      * @see org.eclipse.ui.ide.undo.AbstractWorkspaceOperation#updateResourceChangeDescriptionFactory(org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory,
218      * int)
219      */

220     protected boolean updateResourceChangeDescriptionFactory(
221             IResourceChangeDescriptionFactory factory, int operation) {
222         boolean update = false;
223         if (operation == UNDO) {
224             for (int i = 0; i < resources.length; i++) {
225                 update = true;
226                 IResource resource = resources[i];
227                 factory.delete(resource);
228             }
229             for (int i = 0; i < resourceDescriptions.length; i++) {
230                 update = true;
231                 IResource resource = resourceDescriptions[i]
232                         .createResourceHandle();
233                 factory.create(resource);
234             }
235         } else {
236             for (int i = 0; i < resources.length; i++) {
237                 update = true;
238                 IResource resource = resources[i];
239                 factory.copy(resource, getDestinationPath(resource, i));
240             }
241         }
242         return update;
243     }
244
245     /*
246      * (non-Javadoc)
247      *
248      * This implementation computes the ability to delete the original copy and
249      * restore any overwritten resources.
250      *
251      * @see org.eclipse.ui.ide.undo.AbstractWorkspaceOperation#computeUndoableStatus(org.eclipse.core.runtime.IProgressMonitor)
252      */

253     public IStatus computeUndoableStatus(IProgressMonitor monitor) {
254         IStatus status = super.computeUndoableStatus(monitor);
255         if (!status.isOK()) {
256             return status;
257         }
258         // If the originals no longer exist, we do not want to attempt to
259
// undo the copy which involves deleting the copies. They may be all we
260
// have left.
261
if (originalResources == null) {
262             markInvalid();
263             return getErrorStatus(UndoMessages.CopyResourcesOperation_NotAllowedDueToDataLoss);
264         }
265         for (int i = 0; i < snapshotResourceDescriptions.length; i++) {
266             if (!snapshotResourceDescriptions[i].verifyExistence(true)) {
267                 markInvalid();
268                 return getErrorStatus(UndoMessages.CopyResourcesOperation_NotAllowedDueToDataLoss);
269             }
270         }
271         // undoing a copy means deleting the copy that was made
272
if (status.isOK()) {
273             status = computeDeleteStatus();
274         }
275         // and if there were resources overwritten by the copy, can we still
276
// recreate them?
277
if (status.isOK() && resourceDescriptions != null
278                 && resourceDescriptions.length > 0) {
279             status = computeCreateStatus(true);
280         }
281
282         return status;
283     }
284
285     /*
286      * Record the original resources, including a resource description to
287      * describe it. This is so we can make sure the original resources and their
288      * subtrees are intact before allowing a copy to be undone.
289      */

290     private void setOriginalResources(IResource[] originals) {
291         originalResources = originals;
292         snapshotResourceDescriptions = new ResourceDescription[originals.length];
293         for (int i = 0; i < originals.length; i++) {
294             snapshotResourceDescriptions[i] = ResourceDescription
295                     .fromResource(originals[i]);
296         }
297     }
298 }
299
Popular Tags