KickJava   Java API By Example, From Geeks To Geeks.

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


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  * Red Hat, Inc - changed TarFileStructureProvider to TarLeveledStructureProvider
11  *******************************************************************************/

12 package org.eclipse.ui.wizards.datatransfer;
13
14 import java.io.File JavaDoc;
15 import java.io.IOException JavaDoc;
16 import java.io.InputStream JavaDoc;
17 import java.util.ArrayList JavaDoc;
18 import java.util.Arrays JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.List JavaDoc;
21
22 import org.eclipse.core.resources.IContainer;
23 import org.eclipse.core.resources.IFile;
24 import org.eclipse.core.resources.IFolder;
25 import org.eclipse.core.resources.IResource;
26 import org.eclipse.core.resources.IWorkspace;
27 import org.eclipse.core.resources.IWorkspaceRoot;
28 import org.eclipse.core.resources.ResourceAttributes;
29 import org.eclipse.core.resources.ResourcesPlugin;
30 import org.eclipse.core.runtime.CoreException;
31 import org.eclipse.core.runtime.IAdaptable;
32 import org.eclipse.core.runtime.IPath;
33 import org.eclipse.core.runtime.IProgressMonitor;
34 import org.eclipse.core.runtime.IStatus;
35 import org.eclipse.core.runtime.MultiStatus;
36 import org.eclipse.core.runtime.OperationCanceledException;
37 import org.eclipse.core.runtime.Path;
38 import org.eclipse.core.runtime.Status;
39 import org.eclipse.core.runtime.SubProgressMonitor;
40 import org.eclipse.osgi.util.NLS;
41 import org.eclipse.swt.widgets.Shell;
42 import org.eclipse.ui.PlatformUI;
43 import org.eclipse.ui.actions.WorkspaceModifyOperation;
44 import org.eclipse.ui.dialogs.ContainerGenerator;
45 import org.eclipse.ui.dialogs.IOverwriteQuery;
46 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
47 import org.eclipse.ui.internal.wizards.datatransfer.DataTransferMessages;
48 import org.eclipse.ui.internal.wizards.datatransfer.TarLeveledStructureProvider;
49
50 /**
51  * An operation which does the actual work of copying objects from the local file
52  * system into the workspace.
53  * <p>
54  * This class may be instantiated; it is not intended to be subclassed.
55  * </p>
56  */

57 public class ImportOperation extends WorkspaceModifyOperation {
58     private static final int POLICY_DEFAULT = 0;
59
60     private static final int POLICY_SKIP_CHILDREN = 1;
61
62     private static final int POLICY_FORCE_OVERWRITE = 2;
63
64     private Object JavaDoc source;
65
66     private IPath destinationPath;
67
68     private IContainer destinationContainer;
69
70     private List JavaDoc selectedFiles;
71
72     private List JavaDoc rejectedFiles;
73
74     private IImportStructureProvider provider;
75
76     private IProgressMonitor monitor;
77
78     protected IOverwriteQuery overwriteCallback;
79
80     private Shell context;
81
82     private List JavaDoc errorTable = new ArrayList JavaDoc();
83
84     private boolean createContainerStructure = true;
85
86     //The constants for the overwrite 3 state
87
private static final int OVERWRITE_NOT_SET = 0;
88
89     private static final int OVERWRITE_NONE = 1;
90
91     private static final int OVERWRITE_ALL = 2;
92
93     private int overwriteState = OVERWRITE_NOT_SET;
94
95     /**
96      * Creates a new operation that recursively imports the entire contents of the
97      * specified root file system object.
98      * <p>
99      * The <code>source</code> parameter represents the root file system object to
100      * import. All contents of this object are imported. Valid types for this parameter
101      * are determined by the supplied <code>IImportStructureProvider</code>.
102      * </p>
103      * <p>
104      * The <code>provider</code> parameter allows this operation to deal with the
105      * source object in an abstract way. This operation calls methods on the provider
106      * and the provider in turn calls specific methods on the source object.
107      * </p>
108      * <p>
109      * The default import behavior is to recreate the complete container structure
110      * for the contents of the root file system object in their destination.
111      * If <code>setCreateContainerStructure</code> is set to false then the container
112      * structure created is relative to the root file system object.
113      * </p>
114      *
115      * @param containerPath the full path of the destination container within the
116      * workspace
117      * @param source the root file system object to import
118      * @param provider the file system structure provider to use
119      * @param overwriteImplementor the overwrite strategy to use
120      */

121     public ImportOperation(IPath containerPath, Object JavaDoc source,
122             IImportStructureProvider provider,
123             IOverwriteQuery overwriteImplementor) {
124         super();
125         this.destinationPath = containerPath;
126         this.source = source;
127         this.provider = provider;
128         overwriteCallback = overwriteImplementor;
129     }
130
131     /**
132      * Creates a new operation that imports specific file system objects.
133      * In this usage context, the specified source file system object is used by the
134      * operation solely to determine the destination container structure of the file system
135      * objects being imported.
136      * <p>
137      * The <code>source</code> parameter represents the root file system object to
138      * import. Valid types for this parameter are determined by the supplied
139      * <code>IImportStructureProvider</code>. The contents of the source which
140      * are to be imported are specified in the <code>filesToImport</code>
141      * parameter.
142      * </p>
143      * <p>
144      * The <code>provider</code> parameter allows this operation to deal with the
145      * source object in an abstract way. This operation calls methods on the provider
146      * and the provider in turn calls specific methods on the source object.
147      * </p>
148      * <p>
149      * The <code>filesToImport</code> parameter specifies what contents of the root
150      * file system object are to be imported.
151      * </p>
152      * <p>
153      * The default import behavior is to recreate the complete container structure
154      * for the file system objects in their destination. If <code>setCreateContainerStructure</code>
155      * is set to <code>false</code>, then the container structure created for each of
156      * the file system objects is relative to the supplied root file system object.
157      * </p>
158      *
159      * @param containerPath the full path of the destination container within the
160      * workspace
161      * @param source the root file system object to import from
162      * @param provider the file system structure provider to use
163      * @param overwriteImplementor the overwrite strategy to use
164      * @param filesToImport the list of file system objects to be imported
165      * (element type: <code>Object</code>)
166      */

167     public ImportOperation(IPath containerPath, Object JavaDoc source,
168             IImportStructureProvider provider,
169             IOverwriteQuery overwriteImplementor, List JavaDoc filesToImport) {
170         this(containerPath, source, provider, overwriteImplementor);
171         setFilesToImport(filesToImport);
172     }
173
174     /**
175      * Creates a new operation that imports specific file system objects.
176      * <p>
177      * The <code>provider</code> parameter allows this operation to deal with the
178      * source object in an abstract way. This operation calls methods on the provider
179      * and the provider in turn calls specific methods on the source object.
180      * </p>
181      * <p>
182      * The <code>filesToImport</code> parameter specifies what file system objects
183      * are to be imported.
184      * </p>
185      * <p>
186      * The default import behavior is to recreate the complete container structure
187      * for the file system objects in their destination. If <code>setCreateContainerStructure</code>
188      * is set to <code>false</code>, then no container structure is created for each of
189      * the file system objects.
190      * </p>
191      *
192      * @param containerPath the full path of the destination container within the
193      * workspace
194      * @param provider the file system structure provider to use
195      * @param overwriteImplementor the overwrite strategy to use
196      * @param filesToImport the list of file system objects to be imported
197      * (element type: <code>Object</code>)
198      */

199     public ImportOperation(IPath containerPath,
200             IImportStructureProvider provider,
201             IOverwriteQuery overwriteImplementor, List JavaDoc filesToImport) {
202         this(containerPath, null, provider, overwriteImplementor);
203         setFilesToImport(filesToImport);
204     }
205
206     /**
207      * Prompts if existing resources should be overwritten. Recursively collects
208      * existing read-only files to overwrite and resources that should not be
209      * overwritten.
210      *
211      * @param sourceStart destination path to check for existing files
212      * @param sources file system objects that may exist in the destination
213      * @param noOverwrite files that were selected to be skipped (don't overwrite).
214      * object type IPath
215      * @param overwriteReadonly the collected existing read-only files to overwrite.
216      * object type IPath
217      * @param policy on of the POLICY constants defined in the
218      * class.
219      */

220     void collectExistingReadonlyFiles(IPath sourceStart, List JavaDoc sources,
221             ArrayList JavaDoc noOverwrite, ArrayList JavaDoc overwriteReadonly, int policy) {
222         IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
223         Iterator JavaDoc sourceIter = sources.iterator();
224         IPath sourceRootPath = null;
225
226         if (this.source != null) {
227             sourceRootPath = new Path(provider.getFullPath(this.source));
228         }
229         while (sourceIter.hasNext()) {
230             Object JavaDoc nextSource = sourceIter.next();
231             IPath sourcePath = new Path(provider.getFullPath(nextSource));
232             IPath newDestinationPath;
233             IResource newDestination;
234
235             if (sourceRootPath == null) {
236                 newDestinationPath = sourceStart.append(provider
237                         .getLabel(nextSource));
238             } else {
239                 int prefixLength = sourcePath
240                         .matchingFirstSegments(sourceRootPath);
241                 IPath relativeSourcePath = sourcePath
242                         .removeFirstSegments(prefixLength);
243                 newDestinationPath = this.destinationPath
244                         .append(relativeSourcePath);
245             }
246             newDestination = workspaceRoot.findMember(newDestinationPath);
247             if (newDestination == null) {
248                 continue;
249             }
250
251             IFolder folder = getFolder(newDestination);
252             if (folder != null) {
253                 if (policy != POLICY_FORCE_OVERWRITE) {
254                     if (this.overwriteState == OVERWRITE_NONE
255                             || !queryOverwrite(newDestinationPath)) {
256                         noOverwrite.add(folder);
257                         continue;
258                     }
259                 }
260                 if (provider.isFolder(nextSource)) {
261                     collectExistingReadonlyFiles(newDestinationPath, provider
262                             .getChildren(nextSource), noOverwrite,
263                             overwriteReadonly, POLICY_FORCE_OVERWRITE);
264                 }
265             } else {
266                 IFile file = getFile(newDestination);
267
268                 if (file != null) {
269                     if (!queryOverwriteFile(file, policy)) {
270                         noOverwrite.add(file.getFullPath());
271                     } else if (file.isReadOnly()) {
272                         overwriteReadonly.add(file);
273                     }
274                 }
275             }
276         }
277     }
278
279     /**
280      * Creates the folders that appear in the specified resource path.
281      * These folders are created relative to the destination container.
282      *
283      * @param path the relative path of the resource
284      * @return the container resource coresponding to the given path
285      * @exception CoreException if this method failed
286      */

287     IContainer createContainersFor(IPath path) throws CoreException {
288
289         IContainer currentFolder = destinationContainer;
290
291         int segmentCount = path.segmentCount();
292
293         //No containers to create
294
if (segmentCount == 0) {
295             return currentFolder;
296         }
297
298         //Needs to be handles differently at the root
299
if (currentFolder.getType() == IResource.ROOT) {
300             return createFromRoot(path);
301         }
302
303         for (int i = 0; i < segmentCount; i++) {
304             currentFolder = currentFolder.getFolder(new Path(path.segment(i)));
305             if (!currentFolder.exists()) {
306                 ((IFolder) currentFolder).create(false, true, null);
307             }
308         }
309
310         return currentFolder;
311     }
312
313     /**
314      * Creates the folders that appear in the specified resource path
315      * assuming that the destinationContainer begins at the root. Do not create projects.
316      *
317      * @param path the relative path of the resource
318      * @return the container resource coresponding to the given path
319      * @exception CoreException if this method failed
320      */

321     private IContainer createFromRoot(IPath path) throws CoreException {
322
323         int segmentCount = path.segmentCount();
324
325         //Assume the project exists
326
IContainer currentFolder = ((IWorkspaceRoot) destinationContainer)
327                 .getProject(path.segment(0));
328
329         for (int i = 1; i < segmentCount; i++) {
330             currentFolder = currentFolder.getFolder(new Path(path.segment(i)));
331             if (!currentFolder.exists()) {
332                 ((IFolder) currentFolder).create(false, true, null);
333             }
334         }
335
336         return currentFolder;
337     }
338
339     /**
340      * Deletes the given resource. If the resource fails to be deleted, adds a
341      * status object to the list to be returned by <code>getResult</code>.
342      *
343      * @param resource the resource
344      */

345     void deleteResource(IResource resource) {
346         try {
347             resource.delete(IResource.KEEP_HISTORY, null);
348         } catch (CoreException e) {
349             errorTable.add(e.getStatus());
350         }
351     }
352
353     /* (non-Javadoc)
354      * Method declared on WorkbenchModifyOperation.
355      * Imports the specified file system objects from the file system.
356      */

357     protected void execute(IProgressMonitor progressMonitor) {
358
359         monitor = progressMonitor;
360
361         try {
362             if (selectedFiles == null) {
363                 //Set the amount to 1000 as we have no idea of how long this will take
364
monitor.beginTask(DataTransferMessages.DataTransfer_importTask, 1000);
365                 ContainerGenerator generator = new ContainerGenerator(
366                         destinationPath);
367                 monitor.worked(30);
368                 validateFiles(Arrays.asList(new Object JavaDoc[] { source }));
369                 monitor.worked(50);
370                 destinationContainer = generator
371                         .generateContainer(new SubProgressMonitor(monitor, 50));
372                 importRecursivelyFrom(source, POLICY_DEFAULT);
373                 //Be sure it finishes
374
monitor.worked(90);
375             } else {
376                 // Choose twice the selected files size to take folders into account
377
int creationCount = selectedFiles.size();
378                 monitor.beginTask(DataTransferMessages.DataTransfer_importTask, creationCount + 100);
379                 ContainerGenerator generator = new ContainerGenerator(
380                         destinationPath);
381                 monitor.worked(30);
382                 validateFiles(selectedFiles);
383                 monitor.worked(50);
384                 destinationContainer = generator
385                         .generateContainer(new SubProgressMonitor(monitor, 50));
386                 importFileSystemObjects(selectedFiles);
387                 monitor.done();
388             }
389         } catch (CoreException e) {
390             errorTable.add(e.getStatus());
391         } finally {
392             monitor.done();
393         }
394     }
395
396     /**
397      * Returns the container resource that the passed file system object should be
398      * imported into.
399      *
400      * @param fileSystemObject the file system object being imported
401      * @return the container resource that the passed file system object should be
402      * imported into
403      * @exception CoreException if this method failed
404      */

405     IContainer getDestinationContainerFor(Object JavaDoc fileSystemObject)
406             throws CoreException {
407         IPath pathname = new Path(provider.getFullPath(fileSystemObject));
408
409         if (createContainerStructure) {
410             return createContainersFor(pathname.removeLastSegments(1));
411         }
412         if (source == fileSystemObject) {
413             return null;
414         }
415         IPath sourcePath = new Path(provider.getFullPath(source));
416         IPath destContainerPath = pathname.removeLastSegments(1);
417         IPath relativePath = destContainerPath.removeFirstSegments(
418                 sourcePath.segmentCount()).setDevice(null);
419         return createContainersFor(relativePath);
420         
421     }
422
423     /**
424      * Returns the resource either casted to or adapted to an IFile.
425      *
426      * @param resource resource to cast/adapt
427      * @return the resource either casted to or adapted to an IFile.
428      * <code>null</code> if the resource does not adapt to IFile
429      */

430     IFile getFile(IResource resource) {
431         if (resource instanceof IFile) {
432             return (IFile) resource;
433         }
434         Object JavaDoc adapted = ((IAdaptable) resource).getAdapter(IFile.class);
435         if(adapted == null) {
436             return null;
437         }
438         return (IFile) adapted;
439       
440     }
441
442     /**
443      * Returns the resource either casted to or adapted to an IFolder.
444      *
445      * @param resource resource to cast/adapt
446      * @return the resource either casted to or adapted to an IFolder.
447      * <code>null</code> if the resource does not adapt to IFolder
448      */

449     IFolder getFolder(IResource resource) {
450         if (resource instanceof IFolder) {
451             return (IFolder) resource;
452         }
453         Object JavaDoc adapted = ((IAdaptable) resource).getAdapter(IFolder.class);
454         if(adapted == null) {
455             return null;
456         }
457         return (IFolder) adapted;
458     }
459
460     /**
461      * Returns the rejected files based on the given multi status.
462      *
463      * @param multiStatus multi status to use to determine file rejection
464      * @param files source files
465      * @return list of rejected files as absolute paths. Object type IPath.
466      */

467     ArrayList JavaDoc getRejectedFiles(IStatus multiStatus, IFile[] files) {
468         ArrayList JavaDoc filteredFiles = new ArrayList JavaDoc();
469
470         IStatus[] status = multiStatus.getChildren();
471         for (int i = 0; i < status.length; i++) {
472             if (status[i].isOK() == false) {
473                 errorTable.add(status[i]);
474                 filteredFiles.add(files[i].getFullPath());
475             }
476         }
477         return filteredFiles;
478     }
479
480     /**
481      * Returns the status of the import operation.
482      * If there were any errors, the result is a status object containing
483      * individual status objects for each error.
484      * If there were no errors, the result is a status object with error code <code>OK</code>.
485      *
486      * @return the status
487      */

488     public IStatus getStatus() {
489         IStatus[] errors = new IStatus[errorTable.size()];
490         errorTable.toArray(errors);
491         return new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK, errors,
492                 DataTransferMessages.ImportOperation_importProblems,
493                 null);
494     }
495
496     /**
497      * Imports the specified file system object into the workspace.
498      * If the import fails, adds a status object to the list to be returned by
499      * <code>getResult</code>.
500      *
501      * @param fileObject the file system object to be imported
502      * @param policy determines how the file object is imported
503      */

504     void importFile(Object JavaDoc fileObject, int policy) {
505         IContainer containerResource;
506         try {
507             containerResource = getDestinationContainerFor(fileObject);
508         } catch (CoreException e) {
509             IStatus coreStatus = e.getStatus();
510             String JavaDoc newMessage = NLS.bind(DataTransferMessages.ImportOperation_coreImportError, fileObject, coreStatus.getMessage());
511             IStatus status = new Status(coreStatus.getSeverity(), coreStatus
512                     .getPlugin(), coreStatus.getCode(), newMessage, null);
513             errorTable.add(status);
514             return;
515         }
516
517         String JavaDoc fileObjectPath = provider.getFullPath(fileObject);
518         monitor.subTask(fileObjectPath);
519         IFile targetResource = containerResource.getFile(new Path(provider
520                 .getLabel(fileObject)));
521         monitor.worked(1);
522
523         if (rejectedFiles.contains(targetResource.getFullPath())) {
524             return;
525         }
526
527         // ensure that the source and target are not the same
528
IPath targetPath = targetResource.getLocation();
529         // Use Files for comparison to avoid platform specific case issues
530
if (targetPath != null
531                 && (targetPath.toFile().equals(new File JavaDoc(fileObjectPath)))) {
532             errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0,
533                     NLS.bind(DataTransferMessages.ImportOperation_targetSameAsSourceError, fileObjectPath), null));
534             return;
535         }
536
537         InputStream JavaDoc contentStream = provider.getContents(fileObject);
538         if (contentStream == null) {
539             errorTable
540                     .add(new Status(
541                             IStatus.ERROR,
542                             PlatformUI.PLUGIN_ID,
543                             0,
544                             NLS.bind(DataTransferMessages.ImportOperation_openStreamError, fileObjectPath),
545                             null));
546             return;
547         }
548
549         try {
550             if (targetResource.exists()) {
551                 targetResource.setContents(contentStream,
552                         IResource.KEEP_HISTORY, null);
553             } else {
554                 targetResource.create(contentStream, false, null);
555             }
556             setResourceAttributes(targetResource,fileObject);
557             
558             if (provider instanceof TarLeveledStructureProvider) {
559                 try {
560                     targetResource.setResourceAttributes(((TarLeveledStructureProvider) provider).getResourceAttributes(fileObject));
561                 } catch (CoreException e) {
562                     errorTable.add(e.getStatus());
563                 }
564             }
565         } catch (CoreException e) {
566             errorTable.add(e.getStatus());
567         } finally {
568             try {
569                 contentStream.close();
570             } catch (IOException JavaDoc e) {
571                 errorTable
572                         .add(new Status(
573                                 IStatus.ERROR,
574                                 PlatformUI.PLUGIN_ID,
575                                 0,
576                                 NLS.bind(DataTransferMessages.ImportOperation_closeStreamError, fileObjectPath),
577                                 e));
578             }
579         }
580     }
581
582     /**
583      * Reuse the file attributes set in the import.
584      * @param targetResource
585      * @param fileObject
586      */

587     private void setResourceAttributes(IFile targetResource, Object JavaDoc fileObject) {
588         
589         if(fileObject instanceof File JavaDoc) {
590             try {
591                 targetResource.setResourceAttributes(ResourceAttributes.fromFile((File JavaDoc) fileObject));
592             } catch (CoreException e) {
593                 //Inform the log that the attributes reading failed
594
IDEWorkbenchPlugin.log(e.getStatus().getMessage(), e);
595             }
596         }
597         
598     }
599
600     /**
601      * Imports the specified file system objects into the workspace.
602      * If the import fails, adds a status object to the list to be returned by
603      * <code>getStatus</code>.
604      *
605      * @param filesToImport the list of file system objects to import
606      * (element type: <code>Object</code>)
607      * @exception OperationCanceledException if canceled
608      */

609     void importFileSystemObjects(List JavaDoc filesToImport) {
610         Iterator JavaDoc filesEnum = filesToImport.iterator();
611         while (filesEnum.hasNext()) {
612             Object JavaDoc fileSystemObject = filesEnum.next();
613             if (source == null) {
614                 // We just import what we are given into the destination
615
IPath sourcePath = new Path(provider
616                         .getFullPath(fileSystemObject)).removeLastSegments(1);
617                 if (provider.isFolder(fileSystemObject) && sourcePath.isEmpty()) {
618                     // If we don't have a parent then we have selected the
619
// file systems root. Roots can't copied (at least not
620
// under windows).
621
errorTable.add(new Status(IStatus.INFO,
622                             PlatformUI.PLUGIN_ID, 0, DataTransferMessages.ImportOperation_cannotCopy,
623                             null));
624                     continue;
625                 }
626                 source = sourcePath.toFile();
627             }
628             importRecursivelyFrom(fileSystemObject, POLICY_DEFAULT);
629         }
630     }
631
632     /**
633      * Imports the specified file system container object into the workspace.
634      * If the import fails, adds a status object to the list to be returned by
635      * <code>getResult</code>.
636      *
637      * @param folderObject the file system container object to be imported
638      * @param policy determines how the folder object and children are imported
639      * @return the policy to use to import the folder's children
640      */

641     int importFolder(Object JavaDoc folderObject, int policy) {
642         IContainer containerResource;
643         try {
644             containerResource = getDestinationContainerFor(folderObject);
645         } catch (CoreException e) {
646             errorTable.add(e.getStatus());
647             return policy;
648         }
649
650         if (containerResource == null) {
651             return policy;
652         }
653
654         monitor.subTask(provider.getFullPath(folderObject));
655         IWorkspace workspace = destinationContainer.getWorkspace();
656         IPath containerPath = containerResource.getFullPath();
657         IPath resourcePath = containerPath.append(provider
658                 .getLabel(folderObject));
659
660         // Do not attempt the import if the resource path is unchanged. This may happen
661
// when importing from a zip file.
662
if (resourcePath.equals(containerPath)) {
663             return policy;
664         }
665
666         if (workspace.getRoot().exists(resourcePath)) {
667             if (rejectedFiles.contains(resourcePath)) {
668                 return POLICY_SKIP_CHILDREN;
669             }
670
671             return POLICY_FORCE_OVERWRITE;
672         }
673
674         try {
675             workspace.getRoot().getFolder(resourcePath).create(false, true,
676                     null);
677         } catch (CoreException e) {
678             errorTable.add(e.getStatus());
679         }
680
681         return policy;
682     }
683
684     /**
685      * Imports the specified file system object recursively into the workspace.
686      * If the import fails, adds a status object to the list to be returned by
687      * <code>getStatus</code>.
688      *
689      * @param fileSystemObject the file system object to be imported
690      * @param policy determines how the file system object and children are imported
691      * @exception OperationCanceledException if canceled
692      */

693     void importRecursivelyFrom(Object JavaDoc fileSystemObject, int policy) {
694         if (monitor.isCanceled()) {
695             throw new OperationCanceledException();
696         }
697
698         if (!provider.isFolder(fileSystemObject)) {
699             importFile(fileSystemObject, policy);
700             return;
701         }
702
703         int childPolicy = importFolder(fileSystemObject, policy);
704         if (childPolicy != POLICY_SKIP_CHILDREN) {
705             Iterator JavaDoc children = provider.getChildren(fileSystemObject)
706                     .iterator();
707             while (children.hasNext()) {
708                 importRecursivelyFrom(children.next(), childPolicy);
709             }
710         }
711     }
712
713     /**
714      * Queries the user whether the resource with the specified path should be
715      * overwritten by a file system object that is being imported.
716      *
717      * @param resourcePath the workspace path of the resource that needs to be overwritten
718      * @return <code>true</code> to overwrite, <code>false</code> to not overwrite
719      * @exception OperationCanceledException if canceled
720      */

721     boolean queryOverwrite(IPath resourcePath)
722             throws OperationCanceledException {
723         String JavaDoc overwriteAnswer = overwriteCallback.queryOverwrite(resourcePath
724                 .makeRelative().toString());
725
726         if (overwriteAnswer.equals(IOverwriteQuery.CANCEL)) {
727             throw new OperationCanceledException(DataTransferMessages.DataTransfer_emptyString);
728         }
729
730         if (overwriteAnswer.equals(IOverwriteQuery.NO)) {
731             return false;
732         }
733
734         if (overwriteAnswer.equals(IOverwriteQuery.NO_ALL)) {
735             this.overwriteState = OVERWRITE_NONE;
736             return false;
737         }
738
739         if (overwriteAnswer.equals(IOverwriteQuery.ALL)) {
740             this.overwriteState = OVERWRITE_ALL;
741         }
742
743         return true;
744     }
745
746     /**
747      * Returns whether the given file should be overwritten.
748      *
749      * @param targetFile the file to ask to overwrite
750      * @param policy determines if the user is queried for overwrite
751      * @return <code>true</code> if the file should be overwritten, and
752      * <code>false</code> if not.
753      */

754     boolean queryOverwriteFile(IFile targetFile, int policy) {
755         //If force overwrite is on don't bother
756
if (policy != POLICY_FORCE_OVERWRITE) {
757             if (this.overwriteState == OVERWRITE_NOT_SET
758                     && !queryOverwrite(targetFile.getFullPath())) {
759                 return false;
760             }
761             if (this.overwriteState == OVERWRITE_NONE) {
762                 return false;
763             }
764         }
765         return true;
766     }
767
768     /**
769      * Sets the context for use by the VCM provider to prompt the user
770      * for check-out of files.
771      *
772      * @param shell context for use by the VCM provider to prompt user
773      * for check-out. The user will not be prompted if set to <code>null</code>.
774      * @see IWorkspace#validateEdit(org.eclipse.core.resources.IFile[], java.lang.Object)
775      * @since 2.1
776      */

777     public void setContext(Shell shell) {
778         context = shell;
779     }
780
781     /**
782      * Sets whether the containment structures that are implied from the full paths
783      * of file system objects being imported should be duplicated in the workbench.
784      *
785      * @param value <code>true</code> if containers should be created, and
786      * <code>false</code> otherwise
787      */

788     public void setCreateContainerStructure(boolean value) {
789         createContainerStructure = value;
790     }
791
792     /**
793      * Sets the file system objects to import.
794      *
795      * @param filesToImport the list of file system objects to be imported
796      * (element type: <code>Object</code>)
797      */

798     public void setFilesToImport(List JavaDoc filesToImport) {
799         this.selectedFiles = filesToImport;
800     }
801
802     /**
803      * Sets whether imported file system objects should automatically overwrite
804      * existing workbench resources when a conflict occurs.
805      *
806      * @param value <code>true</code> to automatically overwrite, and
807      * <code>false</code> otherwise
808      */

809     public void setOverwriteResources(boolean value) {
810         if (value) {
811             this.overwriteState = OVERWRITE_ALL;
812         }
813     }
814
815     /**
816      * Validates that the given source resources can be copied to the
817      * destination as decided by the VCM provider.
818      *
819      * @param existingFiles existing files to validate
820      * @return list of rejected files as absolute paths. Object type IPath.
821      */

822     ArrayList JavaDoc validateEdit(List JavaDoc existingFiles) {
823        
824         if (existingFiles.size() > 0) {
825             IFile[] files = (IFile[]) existingFiles
826                     .toArray(new IFile[existingFiles.size()]);
827             IWorkspace workspace = ResourcesPlugin.getWorkspace();
828             IStatus status = workspace.validateEdit(files, context);
829
830             //If there was a mix return the bad ones
831
if (status.isMultiStatus()) {
832                 return getRejectedFiles(status, files);
833             }
834             
835            if(!status.isOK()){
836                 //If just a single status reject them all
837
errorTable.add(status);
838                 ArrayList JavaDoc filteredFiles = new ArrayList JavaDoc();
839
840                 for (int i = 0; i < files.length; i++) {
841                     filteredFiles.add(files[i].getFullPath());
842                 }
843                 return filteredFiles;
844            }
845             
846         }
847         return new ArrayList JavaDoc();
848     }
849
850     /**
851      * Validates the given file system objects.
852      * The user is prompted to overwrite existing files.
853      * Existing read-only files are validated with the VCM provider.
854      *
855      * @param sourceFiles files to validate
856      */

857     void validateFiles(List JavaDoc sourceFiles) {
858         ArrayList JavaDoc noOverwrite = new ArrayList JavaDoc();
859         ArrayList JavaDoc overwriteReadonly = new ArrayList JavaDoc();
860
861         collectExistingReadonlyFiles(destinationPath, sourceFiles, noOverwrite,
862                 overwriteReadonly, POLICY_DEFAULT);
863         rejectedFiles = validateEdit(overwriteReadonly);
864         rejectedFiles.addAll(noOverwrite);
865     }
866 }
867
Popular Tags