KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > wizards > datatransfer > FileSystemExportOperation


1 /*******************************************************************************
2  * Copyright (c) 2000, 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.ui.internal.wizards.datatransfer;
12
13 import java.io.File JavaDoc;
14 import java.io.IOException JavaDoc;
15 import java.util.ArrayList JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18
19 import org.eclipse.core.resources.IContainer;
20 import org.eclipse.core.resources.IFile;
21 import org.eclipse.core.resources.IResource;
22 import org.eclipse.core.runtime.CoreException;
23 import org.eclipse.core.runtime.IPath;
24 import org.eclipse.core.runtime.IProgressMonitor;
25 import org.eclipse.core.runtime.IStatus;
26 import org.eclipse.core.runtime.MultiStatus;
27 import org.eclipse.core.runtime.Path;
28 import org.eclipse.core.runtime.Status;
29 import org.eclipse.jface.operation.IRunnableWithProgress;
30 import org.eclipse.jface.operation.ModalContext;
31 import org.eclipse.osgi.util.NLS;
32 import org.eclipse.ui.PlatformUI;
33 import org.eclipse.ui.dialogs.IOverwriteQuery;
34
35
36 /**
37  * Operation for exporting the contents of a resource to the local file system.
38  */

39 public class FileSystemExportOperation implements IRunnableWithProgress {
40     private IPath path;
41
42     private IProgressMonitor monitor;
43
44     private FileSystemExporter exporter = new FileSystemExporter();
45
46     private List JavaDoc resourcesToExport;
47
48     private IOverwriteQuery overwriteCallback;
49
50     private IResource resource;
51
52     private List JavaDoc errorTable = new ArrayList JavaDoc(1);
53
54     //The constants for the overwrite 3 state
55
private static final int OVERWRITE_NOT_SET = 0;
56
57     private static final int OVERWRITE_NONE = 1;
58
59     private static final int OVERWRITE_ALL = 2;
60
61     private int overwriteState = OVERWRITE_NOT_SET;
62
63     private boolean createLeadupStructure = true;
64
65     private boolean createContainerDirectories = true;
66
67     /**
68      * Create an instance of this class. Use this constructor if you wish to
69      * recursively export a single resource
70      */

71     public FileSystemExportOperation(IResource res, String JavaDoc destinationPath,
72             IOverwriteQuery overwriteImplementor) {
73         super();
74         resource = res;
75         path = new Path(destinationPath);
76         overwriteCallback = overwriteImplementor;
77     }
78
79     /**
80      * Create an instance of this class. Use this constructor if you wish to
81      * export specific resources with a common parent resource (affects container
82      * directory creation)
83      */

84     public FileSystemExportOperation(IResource res, List JavaDoc resources,
85             String JavaDoc destinationPath, IOverwriteQuery overwriteImplementor) {
86         this(res, destinationPath, overwriteImplementor);
87         resourcesToExport = resources;
88     }
89
90     /**
91      * Answer the total number of file resources that exist at or below self in the
92      * resources hierarchy.
93      *
94      * @return int
95      * @param parentResource org.eclipse.core.resources.IResource
96      */

97     protected int countChildrenOf(IResource parentResource)
98             throws CoreException {
99         if (parentResource.getType() == IResource.FILE) {
100             return 1;
101         }
102
103         int count = 0;
104         if (parentResource.isAccessible()) {
105             IResource[] children = ((IContainer) parentResource).members();
106             for (int i = 0; i < children.length; i++) {
107                 count += countChildrenOf(children[i]);
108             }
109         }
110
111         return count;
112     }
113
114     /**
115      * Answer a boolean indicating the number of file resources that were
116      * specified for export
117      *
118      * @return int
119      */

120     protected int countSelectedResources() throws CoreException {
121         int result = 0;
122         Iterator JavaDoc resources = resourcesToExport.iterator();
123
124         while (resources.hasNext()) {
125             result += countChildrenOf((IResource) resources.next());
126         }
127
128         return result;
129     }
130
131     /**
132      * Create the directories required for exporting the passed resource,
133      * based upon its container hierarchy
134      *
135      * @param childResource org.eclipse.core.resources.IResource
136      */

137     protected void createLeadupDirectoriesFor(IResource childResource) {
138         IPath resourcePath = childResource.getFullPath().removeLastSegments(1);
139
140         for (int i = 0; i < resourcePath.segmentCount(); i++) {
141             path = path.append(resourcePath.segment(i));
142             exporter.createFolder(path);
143         }
144     }
145
146     /**
147      * Recursively export the previously-specified resource
148      */

149     protected void exportAllResources() throws InterruptedException JavaDoc {
150         if (resource.getType() == IResource.FILE) {
151             exportFile((IFile) resource, path);
152         } else {
153             try {
154                 exportChildren(((IContainer) resource).members(), path);
155             } catch (CoreException e) {
156                 // not safe to show a dialog
157
// should never happen because the file system export wizard ensures that the
158
// single resource chosen for export is both existent and accessible
159
errorTable.add(e.getStatus());
160             }
161         }
162     }
163
164     /**
165      * Export all of the resources contained in the passed collection
166      *
167      * @param children java.util.Enumeration
168      * @param currentPath IPath
169      */

170     protected void exportChildren(IResource[] children, IPath currentPath)
171             throws InterruptedException JavaDoc {
172         for (int i = 0; i < children.length; i++) {
173             IResource child = children[i];
174             if (!child.isAccessible()) {
175                 continue;
176             }
177
178             if (child.getType() == IResource.FILE) {
179                 exportFile((IFile) child, currentPath);
180             } else {
181                 IPath destination = currentPath.append(child.getName());
182                 exporter.createFolder(destination);
183                 try {
184                     exportChildren(((IContainer) child).members(), destination);
185                 } catch (CoreException e) {
186                     // not safe to show a dialog
187
// should never happen because:
188
// i. this method is called recursively iterating over the result of #members,
189
// which only answers existing children
190
// ii. there is an #isAccessible check done before #members is invoked
191
errorTable.add(e.getStatus());
192                 }
193             }
194         }
195     }
196
197     /**
198      * Export the passed file to the specified location
199      *
200      * @param file org.eclipse.core.resources.IFile
201      * @param location org.eclipse.core.runtime.IPath
202      */

203     protected void exportFile(IFile file, IPath location)
204             throws InterruptedException JavaDoc {
205         IPath fullPath = location.append(file.getName());
206         monitor.subTask(file.getFullPath().toString());
207         String JavaDoc properPathString = fullPath.toOSString();
208         File JavaDoc targetFile = new File JavaDoc(properPathString);
209
210         if (targetFile.exists()) {
211             if (!targetFile.canWrite()) {
212                 errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID,
213                         0, NLS.bind(DataTransferMessages.DataTransfer_cannotOverwrite, targetFile.getAbsolutePath()),
214                         null));
215                 monitor.worked(1);
216                 return;
217             }
218
219             if (overwriteState == OVERWRITE_NONE) {
220                 return;
221             }
222
223             if (overwriteState != OVERWRITE_ALL) {
224                 String JavaDoc overwriteAnswer = overwriteCallback
225                         .queryOverwrite(properPathString);
226
227                 if (overwriteAnswer.equals(IOverwriteQuery.CANCEL)) {
228                     throw new InterruptedException JavaDoc();
229                 }
230
231                 if (overwriteAnswer.equals(IOverwriteQuery.NO)) {
232                     monitor.worked(1);
233                     return;
234                 }
235
236                 if (overwriteAnswer.equals(IOverwriteQuery.NO_ALL)) {
237                     monitor.worked(1);
238                     overwriteState = OVERWRITE_NONE;
239                     return;
240                 }
241
242                 if (overwriteAnswer.equals(IOverwriteQuery.ALL)) {
243                     overwriteState = OVERWRITE_ALL;
244                 }
245             }
246         }
247
248         try {
249             exporter.write(file, fullPath);
250         } catch (IOException JavaDoc e) {
251             errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0,
252                     NLS.bind(DataTransferMessages.DataTransfer_errorExporting, fullPath, e.getMessage()), e));
253         } catch (CoreException e) {
254             errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0,
255                     NLS.bind(DataTransferMessages.DataTransfer_errorExporting, fullPath, e.getMessage()), e));
256         }
257
258         monitor.worked(1);
259         ModalContext.checkCanceled(monitor);
260     }
261
262     /**
263      * Export the resources contained in the previously-defined
264      * resourcesToExport collection
265      */

266     protected void exportSpecifiedResources() throws InterruptedException JavaDoc {
267         Iterator JavaDoc resources = resourcesToExport.iterator();
268         IPath initPath = (IPath) path.clone();
269
270         while (resources.hasNext()) {
271             IResource currentResource = (IResource) resources.next();
272             if (!currentResource.isAccessible()) {
273                 continue;
274             }
275
276             path = initPath;
277
278             if (resource == null) {
279                 // No root resource specified and creation of containment directories
280
// is required. Create containers from depth 2 onwards (ie.- project's
281
// child inclusive) for each resource being exported.
282
if (createLeadupStructure) {
283                     createLeadupDirectoriesFor(currentResource);
284                 }
285
286             } else {
287                 // Root resource specified. Must create containment directories
288
// from this point onwards for each resource being exported
289
IPath containersToCreate = currentResource.getFullPath()
290                         .removeFirstSegments(
291                                 resource.getFullPath().segmentCount())
292                         .removeLastSegments(1);
293
294                 for (int i = 0; i < containersToCreate.segmentCount(); i++) {
295                     path = path.append(containersToCreate.segment(i));
296                     exporter.createFolder(path);
297                 }
298             }
299
300             if (currentResource.getType() == IResource.FILE) {
301                 exportFile((IFile) currentResource, path);
302             } else {
303                 if (createContainerDirectories) {
304                     path = path.append(currentResource.getName());
305                     exporter.createFolder(path);
306                 }
307
308                 try {
309                     exportChildren(((IContainer) currentResource).members(),
310                             path);
311                 } catch (CoreException e) {
312                     // should never happen because #isAccessible is called before #members is invoked,
313
// which implicitly does an existence check
314
errorTable.add(e.getStatus());
315                 }
316             }
317         }
318     }
319
320     /**
321      * Returns the status of the export operation.
322      * If there were any errors, the result is a status object containing
323      * individual status objects for each error.
324      * If there were no errors, the result is a status object with error code <code>OK</code>.
325      *
326      * @return the status
327      */

328     public IStatus getStatus() {
329         IStatus[] errors = new IStatus[errorTable.size()];
330         errorTable.toArray(errors);
331         return new MultiStatus(
332                 PlatformUI.PLUGIN_ID,
333                 IStatus.OK,
334                 errors,
335                 DataTransferMessages.FileSystemExportOperation_problemsExporting,
336                 null);
337     }
338
339     /**
340      * Answer a boolean indicating whether the passed child is a descendent
341      * of one or more members of the passed resources collection
342      *
343      * @return boolean
344      * @param resources java.util.List
345      * @param child org.eclipse.core.resources.IResource
346      */

347     protected boolean isDescendent(List JavaDoc resources, IResource child) {
348         if (child.getType() == IResource.PROJECT) {
349             return false;
350         }
351
352         IResource parent = child.getParent();
353         if (resources.contains(parent)) {
354             return true;
355         }
356
357         return isDescendent(resources, parent);
358     }
359
360     /**
361      * Export the resources that were previously specified for export
362      * (or if a single resource was specified then export it recursively)
363      */

364     public void run(IProgressMonitor progressMonitor)
365             throws InterruptedException JavaDoc {
366         this.monitor = progressMonitor;
367
368         if (resource != null) {
369             if (createLeadupStructure) {
370                 createLeadupDirectoriesFor(resource);
371             }
372
373             if (createContainerDirectories
374                     && resource.getType() != IResource.FILE) {
375                 // ensure it's a container
376
path = path.append(resource.getName());
377                 exporter.createFolder(path);
378             }
379         }
380
381         try {
382             int totalWork = IProgressMonitor.UNKNOWN;
383             try {
384                 if (resourcesToExport == null) {
385                     totalWork = countChildrenOf(resource);
386                 } else {
387                     totalWork = countSelectedResources();
388                 }
389             } catch (CoreException e) {
390                 // Should not happen
391
errorTable.add(e.getStatus());
392             }
393             monitor.beginTask(DataTransferMessages.DataTransfer_exportingTitle, totalWork);
394             if (resourcesToExport == null) {
395                 exportAllResources();
396             } else {
397                 exportSpecifiedResources();
398             }
399         } finally {
400             monitor.done();
401         }
402     }
403
404     /**
405      * Set this boolean indicating whether a directory should be created for
406      * Folder resources that are explicitly passed for export
407      *
408      * @param value boolean
409      */

410     public void setCreateContainerDirectories(boolean value) {
411         createContainerDirectories = value;
412     }
413
414     /**
415      * Set this boolean indicating whether each exported resource's complete path should
416      * include containment hierarchies as dictated by its parents
417      *
418      * @param value boolean
419      */

420     public void setCreateLeadupStructure(boolean value) {
421         createLeadupStructure = value;
422     }
423
424     /**
425      * Set this boolean indicating whether exported resources should automatically
426      * overwrite existing files when a conflict occurs. If not
427      * query the user.
428      *
429      * @param value boolean
430      */

431     public void setOverwriteFiles(boolean value) {
432         if (value) {
433             overwriteState = OVERWRITE_ALL;
434         }
435     }
436 }
437
Popular Tags