KickJava   Java API By Example, From Geeks To Geeks.

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


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 MoveResourcesOperation represents an undoable operation for moving 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  * move 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 move 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 MoveResourcesOperation extends
46         AbstractCopyOrMoveResourcesOperation {
47
48     IResource[] originalResources;
49
50     IPath originalDestination;
51
52     IPath[] originalDestinationPaths;
53
54     /**
55      * Create a MoveResourcesOperation that moves all of the specified resources
56      * to the same target location, using their existing names.
57      *
58      * @param resources
59      * the resources to be moved
60      * @param destinationPath
61      * the destination path for the resources, not including the name
62      * of the moved resource.
63      * @param label
64      * the label of the operation
65      */

66     public MoveResourcesOperation(IResource[] resources, IPath destinationPath,
67             String JavaDoc label) {
68         super(resources, destinationPath, label);
69         originalResources = this.resources;
70         originalDestination = this.destination;
71         originalDestinationPaths = this.destinationPaths;
72     }
73
74     /**
75      * Create a MoveResourcesOperation that moves a single resource to a new
76      * location. The new location includes the name of the resource, so this may
77      * be used for a move/rename operation or a simple move.
78      *
79      * @param resource
80      * the resource to be moved
81      * @param newPath
82      * the new path for the resource, including its desired name.
83      * @param label
84      * the label of the operation
85      */

86     public MoveResourcesOperation(IResource resource, IPath newPath,
87             String JavaDoc label) {
88         super(new IResource[] { resource }, new IPath[] { newPath }, label);
89         originalResources = this.resources;
90         originalDestination = this.destination;
91         originalDestinationPaths = this.destinationPaths;
92     }
93
94     /*
95      * (non-Javadoc)
96      *
97      * Map execute to moving the resources
98      *
99      * @see org.eclipse.ui.ide.undo.AbstractWorkspaceOperation#doExecute(org.eclipse.core.runtime.IProgressMonitor,
100      * org.eclipse.core.runtime.IAdaptable)
101      */

102     protected void doExecute(IProgressMonitor monitor, IAdaptable uiInfo)
103             throws CoreException {
104         move(monitor, uiInfo);
105     }
106
107     /**
108      * Move any known resources according to the destination parameters known by
109      * this operation. Store enough information to undo and redo the operation.
110      *
111      * @param monitor
112      * the progress monitor to use for the operation
113      * @param uiInfo
114      * the IAdaptable (or <code>null</code>) provided by the
115      * caller in order to supply UI information for prompting the
116      * user if necessary. When this parameter is not
117      * <code>null</code>, it contains an adapter for the
118      * org.eclipse.swt.widgets.Shell.class
119      * @throws CoreException
120      * propagates any CoreExceptions thrown from the resources API
121      */

122     protected void move(IProgressMonitor monitor, IAdaptable uiInfo)
123             throws CoreException {
124
125         monitor.beginTask("", 2000); //$NON-NLS-1$
126
monitor
127                 .setTaskName(UndoMessages.AbstractResourcesOperation_MovingResources);
128         List JavaDoc resourcesAtDestination = new ArrayList JavaDoc();
129         List JavaDoc undoDestinationPaths = new ArrayList JavaDoc();
130         List JavaDoc overwrittenResources = new ArrayList JavaDoc();
131
132         for (int i = 0; i < resources.length; i++) {
133             // Move the resources and record the overwrites that would
134
// be restored if this operation were reversed
135
ResourceDescription[] overwrites;
136             overwrites = WorkspaceUndoUtil.move(
137                     new IResource[] { resources[i] }, getDestinationPath(
138                             resources[i], i), resourcesAtDestination,
139                     undoDestinationPaths, new SubProgressMonitor(monitor,
140                             1000 / resources.length), uiInfo, true);
141
142             // Accumulate the overwrites into the full list
143
for (int j = 0; j < overwrites.length; j++) {
144                 overwrittenResources.add(overwrites[j]);
145             }
146         }
147
148         // Are there any previously overwritten resources to restore now?
149
if (resourceDescriptions != null) {
150             for (int i = 0; i < resourceDescriptions.length; i++) {
151                 if (resourceDescriptions[i] != null) {
152                     resourceDescriptions[i]
153                             .createResource(new SubProgressMonitor(monitor,
154                                     1000 / resourceDescriptions.length));
155                 }
156             }
157         }
158
159         // Reset resource descriptions to the just overwritten resources
160
setResourceDescriptions((ResourceDescription[]) overwrittenResources
161                 .toArray(new ResourceDescription[overwrittenResources.size()]));
162
163         // Reset the target resources to refer to the resources in their new
164
// location.
165
setTargetResources((IResource[]) resourcesAtDestination
166                 .toArray(new IResource[resourcesAtDestination.size()]));
167         // Reset the destination paths that correspond to these resources
168
destinationPaths = (IPath[]) undoDestinationPaths
169                 .toArray(new IPath[undoDestinationPaths.size()]);
170         destination = null;
171
172         monitor.done();
173     }
174
175     /*
176      * (non-Javadoc)
177      *
178      * Map undo to moving the resources.
179      *
180      * @see org.eclipse.ui.ide.undo.AbstractWorkspaceOperation#doUndo(org.eclipse.core.runtime.IProgressMonitor,
181      * org.eclipse.core.runtime.IAdaptable)
182      */

183     protected void doUndo(IProgressMonitor monitor, IAdaptable uiInfo)
184             throws CoreException {
185         // We've recorded the original moves atomically, so perform the move
186
move(monitor, uiInfo);
187         // Now reset everything back to the way it was originally.
188
// If we don't do this, the move will be "precisely reversed."
189
// For example, if we merged a folder by moving certain files,
190
// we want redo to redo the folder merge, rather than remembering
191
// only the files that were originally merged. This makes us more
192
// adaptable to changes in the target.
193
setTargetResources(originalResources);
194         this.resourceDescriptions = new ResourceDescription[0];
195         this.destination = originalDestination;
196         this.destinationPaths = originalDestinationPaths;
197     }
198
199     /*
200      * (non-Javadoc)
201      *
202      * @see org.eclipse.ui.ide.undo.AbstractWorkspaceOperation#updateResourceChangeDescriptionFactory(org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory,
203      * int)
204      */

205     protected boolean updateResourceChangeDescriptionFactory(
206             IResourceChangeDescriptionFactory factory, int operation) {
207         for (int i = 0; i < resources.length; i++) {
208             IResource resource = resources[i];
209             factory.move(resource, getDestinationPath(resource, i));
210         }
211         return true;
212     }
213
214     /*
215      * (non-Javadoc)
216      *
217      * Map undo to move status.
218      *
219      * @see org.eclipse.ui.ide.undo.AbstractWorkspaceOperation#computeUndoableStatus(org.eclipse.core.runtime.IProgressMonitor)
220      */

221     public IStatus computeUndoableStatus(IProgressMonitor monitor) {
222         IStatus status = super.computeUndoableStatus(monitor);
223         if (status.isOK()) {
224             status = computeMoveOrCopyStatus();
225         }
226         return status;
227     }
228 }
229
Popular Tags