KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ui.wizards.datatransfer;
12
13 import java.io.File JavaDoc;
14 import java.io.IOException JavaDoc;
15 import java.util.*;
16
17 import org.eclipse.core.resources.*;
18 import org.eclipse.core.runtime.*;
19 import org.eclipse.jface.operation.IRunnableWithProgress;
20 import org.eclipse.jface.operation.ModalContext;
21 import org.eclipse.ui.PlatformUI;
22 import org.eclipse.ui.dialogs.IOverwriteQuery;
23
24 /**
25  * Operation for exporting the contents of a resource to the local file system.
26  */

27 /*package*/
28 class FileSystemExportOperation implements IRunnableWithProgress {
29     private IPath path;
30     private IProgressMonitor monitor;
31     private FileSystemExporter exporter = new FileSystemExporter();
32     private List resourcesToExport;
33     private IOverwriteQuery overwriteCallback;
34     private IResource resource;
35     private List errorTable = new ArrayList(1);
36
37     //The constants for the overwrite 3 state
38
private static final int OVERWRITE_NOT_SET = 0;
39     private static final int OVERWRITE_NONE = 1;
40     private static final int OVERWRITE_ALL = 2;
41     private int overwriteState = OVERWRITE_NOT_SET;
42
43     private boolean createLeadupStructure = true;
44     private boolean createContainerDirectories = true;
45     /**
46      * Create an instance of this class. Use this constructor if you wish to
47      * export specific resources without a common parent resource
48      */

49     public FileSystemExportOperation(
50         List resources,
51         String JavaDoc destinationPath,
52         IOverwriteQuery overwriteImplementor) {
53         super();
54
55         // Eliminate redundancies in list of resources being exported
56
Iterator elementsEnum = resources.iterator();
57         while (elementsEnum.hasNext()) {
58             IResource currentResource = (IResource) elementsEnum.next();
59             if (isDescendent(resources, currentResource))
60                 elementsEnum.remove(); //Remove currentResource
61
}
62
63         resourcesToExport = resources;
64         path = new Path(destinationPath);
65         overwriteCallback = overwriteImplementor;
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(
72         IResource res,
73         String JavaDoc destinationPath,
74         IOverwriteQuery overwriteImplementor) {
75         super();
76         resource = res;
77         path = new Path(destinationPath);
78         overwriteCallback = overwriteImplementor;
79     }
80     /**
81      * Create an instance of this class. Use this constructor if you wish to
82      * export specific resources with a common parent resource (affects container
83      * directory creation)
84      */

85     public FileSystemExportOperation(
86         IResource res,
87         List resources,
88         String JavaDoc destinationPath,
89         IOverwriteQuery overwriteImplementor) {
90         this(res, destinationPath, overwriteImplementor);
91         resourcesToExport = resources;
92     }
93     /**
94      * Add a new entry to the error table with the passed information
95      */

96     protected void addError(String JavaDoc message, Throwable JavaDoc e) {
97         errorTable.add(
98             new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, message, e));
99     }
100     /**
101      * Answer the total number of file resources that exist at or below self in the
102      * resources hierarchy.
103      *
104      * @return int
105      * @param parentResource org.eclipse.core.resources.IResource
106      */

107     protected int countChildrenOf(IResource parentResource) throws CoreException {
108         if (parentResource.getType() == IResource.FILE)
109             return 1;
110
111         int count = 0;
112         if (parentResource.isAccessible()) {
113             IResource[] children = ((IContainer) parentResource).members();
114             for (int i = 0; i < children.length; i++)
115                 count += countChildrenOf(children[i]);
116         }
117
118         return count;
119     }
120     /**
121      * Answer a boolean indicating the number of file resources that were
122      * specified for export
123      *
124      * @return int
125      */

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

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

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

172     protected void exportChildren(IResource[] children, IPath currentPath)
173         throws InterruptedException JavaDoc {
174         for (int i = 0; i < children.length; i++) {
175             IResource child = children[i];
176             if (!child.isAccessible())
177                 continue;
178
179             if (child.getType() == IResource.FILE)
180                 exportFile((IFile) child, currentPath);
181             else {
182                 IPath destination = currentPath.append(child.getName());
183                 exporter.createFolder(destination);
184                 try {
185                     exportChildren(((IContainer) child).members(), destination);
186                 } catch (CoreException e) {
187                     // not safe to show a dialog
188
// should never happen because:
189
// i. this method is called recursively iterating over the result of #members,
190
// which only answers existing children
191
// ii. there is an #isAccessible check done before #members is invoked
192
errorTable.add(e.getStatus());
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, 0, DataTransferMessages.format("DataTransfer.cannotOverwrite", //$NON-NLS-1$
213
new Object JavaDoc[] { targetFile.getAbsolutePath()}), null));
214                 monitor.worked(1);
215                 return;
216             }
217
218             if(overwriteState == OVERWRITE_NONE)
219                 return;
220                 
221             if (overwriteState != OVERWRITE_ALL) {
222                 String JavaDoc overwriteAnswer =
223                     overwriteCallback.queryOverwrite(properPathString);
224
225                 if (overwriteAnswer.equals(IOverwriteQuery.CANCEL))
226                     throw new InterruptedException JavaDoc();
227
228                 if (overwriteAnswer.equals(IOverwriteQuery.NO)) {
229                     monitor.worked(1);
230                     return;
231                 }
232
233                 if (overwriteAnswer.equals(IOverwriteQuery.NO_ALL)) {
234                     monitor.worked(1);
235                     overwriteState = OVERWRITE_NONE;
236                     return;
237                 }
238
239                 if (overwriteAnswer.equals(IOverwriteQuery.ALL))
240                     overwriteState = OVERWRITE_ALL;
241             }
242         }
243
244         try {
245             exporter.write(file, fullPath);
246         } catch (IOException JavaDoc e) {
247             errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, DataTransferMessages.format("DataTransfer.errorExporting", //$NON-NLS-1$
248
new Object JavaDoc[] { fullPath, e.getMessage()}), e));
249         } catch (CoreException e) {
250             errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, DataTransferMessages.format("DataTransfer.errorExporting", //$NON-NLS-1$
251
new Object JavaDoc[] { fullPath, e.getMessage()}), e));
252         }
253
254         monitor.worked(1);
255         ModalContext.checkCanceled(monitor);
256     }
257     /**
258      * Export the resources contained in the previously-defined
259      * resourcesToExport collection
260      */

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

323     public IStatus getStatus() {
324         IStatus[] errors = new IStatus[errorTable.size()];
325         errorTable.toArray(errors);
326         return new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK, errors, DataTransferMessages.getString("FileSystemExportOperation.problemsExporting"), //$NON-NLS-1$
327
null);
328     }
329     /**
330      * Answer a boolean indicating whether the passed child is a descendent
331      * of one or more members of the passed resources collection
332      *
333      * @return boolean
334      * @param resources java.util.List
335      * @param child org.eclipse.core.resources.IResource
336      */

337     protected boolean isDescendent(List resources, IResource child) {
338         if (child.getType() == IResource.PROJECT)
339             return false;
340
341         IResource parent = child.getParent();
342         if (resources.contains(parent))
343             return true;
344
345         return isDescendent(resources, parent);
346     }
347     /**
348      * Export the resources that were previously specified for export
349      * (or if a single resource was specified then export it recursively)
350      */

351     public void run(IProgressMonitor progressMonitor) throws InterruptedException JavaDoc {
352         this.monitor = progressMonitor;
353
354         if (resource != null) {
355             if (createLeadupStructure)
356                 createLeadupDirectoriesFor(resource);
357
358             if (createContainerDirectories
359                 && resource.getType() != IResource.FILE) {
360                 // ensure it's a container
361
path = path.append(resource.getName());
362                 exporter.createFolder(path);
363             }
364         }
365
366         try {
367             int totalWork = IProgressMonitor.UNKNOWN;
368             try {
369                 if (resourcesToExport == null)
370                     totalWork = countChildrenOf(resource);
371                 else
372                     totalWork = countSelectedResources();
373             } catch (CoreException e) {
374                 // Should not happen
375
errorTable.add(e.getStatus());
376             }
377             monitor.beginTask(DataTransferMessages.getString("DataTransfer.exportingTitle"), totalWork); //$NON-NLS-1$
378
if (resourcesToExport == null) {
379                 exportAllResources();
380             } else {
381                 exportSpecifiedResources();
382             }
383         } finally {
384             monitor.done();
385         }
386     }
387     /**
388      * Set this boolean indicating whether a directory should be created for
389      * Folder resources that are explicitly passed for export
390      *
391      * @param value boolean
392      */

393     public void setCreateContainerDirectories(boolean value) {
394         createContainerDirectories = value;
395     }
396     /**
397      * Set this boolean indicating whether each exported resource's complete path should
398      * include containment hierarchies as dictated by its parents
399      *
400      * @param value boolean
401      */

402     public void setCreateLeadupStructure(boolean value) {
403         createLeadupStructure = value;
404     }
405     /**
406      * Set this boolean indicating whether exported resources should automatically
407      * overwrite existing files when a conflict occurs. If not
408      * query the user.
409      *
410      * @param value boolean
411      */

412     public void setOverwriteFiles(boolean value) {
413         if(value)
414             overwriteState = OVERWRITE_ALL;
415     }
416 }
417
Popular Tags