Source Code Cross Referenced for CopyFilesAndFoldersOperation.java in  » IDE-Eclipse » ui-ide » org » eclipse » ui » actions » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » ui ide » org.eclipse.ui.actions 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*******************************************************************************
0002:         * Copyright (c) 2000, 2006 IBM Corporation and others.
0003:         * All rights reserved. This program and the accompanying materials
0004:         * are made available under the terms of the Eclipse Public License v1.0
0005:         * which accompanies this distribution, and is available at
0006:         * http://www.eclipse.org/legal/epl-v10.html
0007:         *
0008:         * Contributors:
0009:         *     IBM Corporation - initial API and implementation
0010:         *******************************************************************************/package org.eclipse.ui.actions;
0011:
0012:        import java.io.File;
0013:        import java.lang.reflect.InvocationTargetException;
0014:        import java.net.URI;
0015:        import com.ibm.icu.text.MessageFormat;
0016:        import java.util.ArrayList;
0017:        import java.util.Arrays;
0018:        import java.util.List;
0019:
0020:        import org.eclipse.core.commands.ExecutionException;
0021:        import org.eclipse.core.filesystem.EFS;
0022:        import org.eclipse.core.filesystem.IFileInfo;
0023:        import org.eclipse.core.filesystem.IFileStore;
0024:        import org.eclipse.core.resources.IContainer;
0025:        import org.eclipse.core.resources.IFile;
0026:        import org.eclipse.core.resources.IFolder;
0027:        import org.eclipse.core.resources.IProject;
0028:        import org.eclipse.core.resources.IResource;
0029:        import org.eclipse.core.resources.IWorkspace;
0030:        import org.eclipse.core.resources.IWorkspaceRoot;
0031:        import org.eclipse.core.resources.ResourcesPlugin;
0032:        import org.eclipse.core.resources.WorkspaceJob;
0033:        import org.eclipse.core.runtime.CoreException;
0034:        import org.eclipse.core.runtime.IAdaptable;
0035:        import org.eclipse.core.runtime.IPath;
0036:        import org.eclipse.core.runtime.IProgressMonitor;
0037:        import org.eclipse.core.runtime.IStatus;
0038:        import org.eclipse.core.runtime.MultiStatus;
0039:        import org.eclipse.core.runtime.OperationCanceledException;
0040:        import org.eclipse.core.runtime.Path;
0041:        import org.eclipse.core.runtime.Status;
0042:        import org.eclipse.core.runtime.SubProgressMonitor;
0043:        import org.eclipse.jface.dialogs.ErrorDialog;
0044:        import org.eclipse.jface.dialogs.IDialogConstants;
0045:        import org.eclipse.jface.dialogs.IInputValidator;
0046:        import org.eclipse.jface.dialogs.InputDialog;
0047:        import org.eclipse.jface.dialogs.MessageDialog;
0048:        import org.eclipse.jface.operation.IRunnableWithProgress;
0049:        import org.eclipse.jface.window.Window;
0050:        import org.eclipse.osgi.util.NLS;
0051:        import org.eclipse.swt.SWT;
0052:        import org.eclipse.swt.widgets.Display;
0053:        import org.eclipse.swt.widgets.Shell;
0054:        import org.eclipse.ui.PlatformUI;
0055:        import org.eclipse.ui.dialogs.IOverwriteQuery;
0056:        import org.eclipse.ui.ide.undo.AbstractWorkspaceOperation;
0057:        import org.eclipse.ui.ide.undo.CopyResourcesOperation;
0058:        import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
0059:        import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
0060:        import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
0061:        import org.eclipse.ui.internal.ide.StatusUtil;
0062:        import org.eclipse.ui.internal.ide.dialogs.IDEResourceInfoUtils;
0063:        import org.eclipse.ui.wizards.datatransfer.FileStoreStructureProvider;
0064:        import org.eclipse.ui.wizards.datatransfer.ImportOperation;
0065:
0066:        /**
0067:         * Perform the copy of file and folder resources from the clipboard when paste
0068:         * action is invoked.
0069:         * <p>
0070:         * This class may be instantiated; it is not intended to be subclassed.
0071:         * </p>
0072:         */
0073:        public class CopyFilesAndFoldersOperation {
0074:
0075:            /**
0076:             * Status containing the errors detected when running the operation or
0077:             * <code>null</code> if no errors detected.
0078:             */
0079:            private MultiStatus errorStatus;
0080:
0081:            /**
0082:             * The parent shell used to show any dialogs.
0083:             */
0084:            private Shell messageShell;
0085:
0086:            /**
0087:             * Whether or not the copy has been canceled by the user.
0088:             */
0089:            private boolean canceled = false;
0090:
0091:            /**
0092:             * Overwrite all flag.
0093:             */
0094:            private boolean alwaysOverwrite = false;
0095:
0096:            private String[] modelProviderIds;
0097:
0098:            /**
0099:             * Returns a new name for a copy of the resource at the given path in the
0100:             * given workspace. This name is determined automatically.
0101:             * 
0102:             * @param originalName
0103:             *            the full path of the resource
0104:             * @param workspace
0105:             *            the workspace
0106:             * @return the new full path for the copy
0107:             */
0108:            static IPath getAutoNewNameFor(IPath originalName,
0109:                    IWorkspace workspace) {
0110:                int counter = 1;
0111:                String resourceName = originalName.lastSegment();
0112:                IPath leadupSegment = originalName.removeLastSegments(1);
0113:
0114:                while (true) {
0115:                    String nameSegment;
0116:
0117:                    if (counter > 1) {
0118:                        nameSegment = NLS
0119:                                .bind(
0120:                                        IDEWorkbenchMessages.CopyFilesAndFoldersOperation_copyNameTwoArgs,
0121:                                        new Integer(counter), resourceName);
0122:                    } else {
0123:                        nameSegment = NLS
0124:                                .bind(
0125:                                        IDEWorkbenchMessages.CopyFilesAndFoldersOperation_copyNameOneArg,
0126:                                        resourceName);
0127:                    }
0128:
0129:                    IPath pathToTry = leadupSegment.append(nameSegment);
0130:
0131:                    if (!workspace.getRoot().exists(pathToTry)) {
0132:                        return pathToTry;
0133:                    }
0134:
0135:                    counter++;
0136:                }
0137:            }
0138:
0139:            /**
0140:             * Creates a new operation initialized with a shell.
0141:             * 
0142:             * @param shell
0143:             *            parent shell for error dialogs
0144:             */
0145:            public CopyFilesAndFoldersOperation(Shell shell) {
0146:                messageShell = shell;
0147:            }
0148:
0149:            /**
0150:             * Returns whether this operation is able to perform on-the-fly
0151:             * auto-renaming of resources with name collisions.
0152:             * 
0153:             * @return <code>true</code> if auto-rename is supported, and
0154:             *         <code>false</code> otherwise
0155:             */
0156:            protected boolean canPerformAutoRename() {
0157:                return true;
0158:            }
0159:
0160:            /**
0161:             * Returns the message for querying deep copy/move of a linked resource.
0162:             * 
0163:             * @param source
0164:             *            resource the query is made for
0165:             * @return the deep query message
0166:             */
0167:            protected String getDeepCheckQuestion(IResource source) {
0168:                return NLS
0169:                        .bind(
0170:                                IDEWorkbenchMessages.CopyFilesAndFoldersOperation_deepCopyQuestion,
0171:                                source.getFullPath().makeRelative());
0172:            }
0173:
0174:            /**
0175:             * Checks whether the infos exist.
0176:             * 
0177:             * @param stores
0178:             *            the file infos to test
0179:             * @return Multi status with one error message for each missing file.
0180:             */
0181:            IStatus checkExist(IFileStore[] stores) {
0182:                MultiStatus multiStatus = new MultiStatus(PlatformUI.PLUGIN_ID,
0183:                        IStatus.OK, getProblemsMessage(), null);
0184:
0185:                for (int i = 0; i < stores.length; i++) {
0186:                    if (stores[i].fetchInfo().exists() == false) {
0187:                        String message = NLS
0188:                                .bind(
0189:                                        IDEWorkbenchMessages.CopyFilesAndFoldersOperation_resourceDeleted,
0190:                                        stores[i].getName());
0191:                        IStatus status = new Status(IStatus.ERROR,
0192:                                PlatformUI.PLUGIN_ID, IStatus.OK, message, null);
0193:                        multiStatus.add(status);
0194:                    }
0195:                }
0196:                return multiStatus;
0197:            }
0198:
0199:            /**
0200:             * Checks whether the resources with the given names exist.
0201:             * 
0202:             * @param resources
0203:             *            IResources to checl
0204:             * @return Multi status with one error message for each missing file.
0205:             */
0206:            IStatus checkExist(IResource[] resources) {
0207:                MultiStatus multiStatus = new MultiStatus(PlatformUI.PLUGIN_ID,
0208:                        IStatus.OK, getProblemsMessage(), null);
0209:
0210:                for (int i = 0; i < resources.length; i++) {
0211:                    IResource resource = resources[i];
0212:                    if (resource != null) {
0213:                        URI location = resource.getLocationURI();
0214:                        String message = null;
0215:                        if (location != null) {
0216:                            IFileInfo info = IDEResourceInfoUtils
0217:                                    .getFileInfo(location);
0218:                            if (info == null || info.exists() == false) {
0219:                                if (resource.isLinked()) {
0220:                                    message = NLS
0221:                                            .bind(
0222:                                                    IDEWorkbenchMessages.CopyFilesAndFoldersOperation_missingLinkTarget,
0223:                                                    resource.getName());
0224:                                } else {
0225:                                    message = NLS
0226:                                            .bind(
0227:                                                    IDEWorkbenchMessages.CopyFilesAndFoldersOperation_resourceDeleted,
0228:                                                    resource.getName());
0229:                                }
0230:                            }
0231:                        }
0232:                        if (message != null) {
0233:                            IStatus status = new Status(IStatus.ERROR,
0234:                                    PlatformUI.PLUGIN_ID, IStatus.OK, message,
0235:                                    null);
0236:                            multiStatus.add(status);
0237:                        }
0238:                    }
0239:                }
0240:                return multiStatus;
0241:            }
0242:
0243:            /**
0244:             * Check if the user wishes to overwrite the supplied resource or all
0245:             * resources.
0246:             * 
0247:             * @param source
0248:             *            the source resource
0249:             * @param destination
0250:             *            the resource to be overwritten
0251:             * @return one of IDialogConstants.YES_ID, IDialogConstants.YES_TO_ALL_ID,
0252:             *         IDialogConstants.NO_ID, IDialogConstants.CANCEL_ID indicating
0253:             *         whether the current resource or all resources can be overwritten,
0254:             *         or if the operation should be canceled.
0255:             */
0256:            private int checkOverwrite(final IResource source,
0257:                    final IResource destination) {
0258:                final int[] result = new int[1];
0259:
0260:                // Dialogs need to be created and opened in the UI thread
0261:                Runnable query = new Runnable() {
0262:                    public void run() {
0263:                        String message;
0264:                        int resultId[] = { IDialogConstants.YES_ID,
0265:                                IDialogConstants.YES_TO_ALL_ID,
0266:                                IDialogConstants.NO_ID,
0267:                                IDialogConstants.CANCEL_ID };
0268:                        String labels[] = new String[] {
0269:                                IDialogConstants.YES_LABEL,
0270:                                IDialogConstants.YES_TO_ALL_LABEL,
0271:                                IDialogConstants.NO_LABEL,
0272:                                IDialogConstants.CANCEL_LABEL };
0273:
0274:                        if (destination.getType() == IResource.FOLDER) {
0275:                            if (homogenousResources(source, destination)) {
0276:                                message = NLS
0277:                                        .bind(
0278:                                                IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteMergeQuestion,
0279:                                                destination.getFullPath()
0280:                                                        .makeRelative());
0281:                            } else {
0282:                                if (destination.isLinked()) {
0283:                                    message = NLS
0284:                                            .bind(
0285:                                                    IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteNoMergeLinkQuestion,
0286:                                                    destination.getFullPath()
0287:                                                            .makeRelative());
0288:                                } else {
0289:                                    message = NLS
0290:                                            .bind(
0291:                                                    IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteNoMergeNoLinkQuestion,
0292:                                                    destination.getFullPath()
0293:                                                            .makeRelative());
0294:                                }
0295:                                resultId = new int[] { IDialogConstants.YES_ID,
0296:                                        IDialogConstants.NO_ID,
0297:                                        IDialogConstants.CANCEL_ID };
0298:                                labels = new String[] {
0299:                                        IDialogConstants.YES_LABEL,
0300:                                        IDialogConstants.NO_LABEL,
0301:                                        IDialogConstants.CANCEL_LABEL };
0302:                            }
0303:                        } else {
0304:                            String[] bindings = new String[] {
0305:                                    IDEResourceInfoUtils
0306:                                            .getLocationText(destination),
0307:                                    IDEResourceInfoUtils
0308:                                            .getDateStringValue(destination),
0309:                                    IDEResourceInfoUtils
0310:                                            .getLocationText(source),
0311:                                    IDEResourceInfoUtils
0312:                                            .getDateStringValue(source) };
0313:                            message = NLS
0314:                                    .bind(
0315:                                            IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteWithDetailsQuestion,
0316:                                            bindings);
0317:                        }
0318:                        MessageDialog dialog = new MessageDialog(
0319:                                messageShell,
0320:                                IDEWorkbenchMessages.CopyFilesAndFoldersOperation_resourceExists,
0321:                                null, message, MessageDialog.QUESTION, labels,
0322:                                0);
0323:                        dialog.open();
0324:                        if (dialog.getReturnCode() == SWT.DEFAULT) {
0325:                            // A window close returns SWT.DEFAULT, which has to be
0326:                            // mapped to a cancel
0327:                            result[0] = IDialogConstants.CANCEL_ID;
0328:                        } else {
0329:                            result[0] = resultId[dialog.getReturnCode()];
0330:                        }
0331:                    }
0332:                };
0333:                messageShell.getDisplay().syncExec(query);
0334:                return result[0];
0335:            }
0336:
0337:            /**
0338:             * Recursively collects existing files in the specified destination path.
0339:             * 
0340:             * @param destinationPath
0341:             *            destination path to check for existing files
0342:             * @param copyResources
0343:             *            resources that may exist in the destination
0344:             * @param existing
0345:             *            holds the collected existing files
0346:             */
0347:            private void collectExistingReadonlyFiles(IPath destinationPath,
0348:                    IResource[] copyResources, ArrayList existing) {
0349:                IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace()
0350:                        .getRoot();
0351:
0352:                for (int i = 0; i < copyResources.length; i++) {
0353:                    IResource source = copyResources[i];
0354:                    IPath newDestinationPath = destinationPath.append(source
0355:                            .getName());
0356:                    IResource newDestination = workspaceRoot
0357:                            .findMember(newDestinationPath);
0358:                    IFolder folder;
0359:
0360:                    if (newDestination == null) {
0361:                        continue;
0362:                    }
0363:                    folder = getFolder(newDestination);
0364:                    if (folder != null) {
0365:                        IFolder sourceFolder = getFolder(source);
0366:
0367:                        if (sourceFolder != null) {
0368:                            try {
0369:                                collectExistingReadonlyFiles(
0370:                                        newDestinationPath, sourceFolder
0371:                                                .members(), existing);
0372:                            } catch (CoreException exception) {
0373:                                recordError(exception);
0374:                            }
0375:                        }
0376:                    } else {
0377:                        IFile file = getFile(newDestination);
0378:
0379:                        if (file != null) {
0380:                            if (file.isReadOnly()) {
0381:                                existing.add(file);
0382:                            }
0383:                            if (getValidateConflictSource()) {
0384:                                IFile sourceFile = getFile(source);
0385:                                if (sourceFile != null) {
0386:                                    existing.add(sourceFile);
0387:                                }
0388:                            }
0389:                        }
0390:                    }
0391:                }
0392:            }
0393:
0394:            /**
0395:             * Copies the resources to the given destination. This method is called
0396:             * recursively to merge folders during folder copy.
0397:             * 
0398:             * @param resources
0399:             *            the resources to copy
0400:             * @param destination
0401:             *            destination to which resources will be copied
0402:             * @param subMonitor
0403:             *            a progress monitor for showing progress and for cancelation
0404:             * 
0405:             * @deprecated As of 3.3, the work is performed in the undoable operation
0406:             *             created in
0407:             *             {@link #getUndoableCopyOrMoveOperation(IResource[], IPath)}
0408:             */
0409:            protected void copy(IResource[] resources, IPath destination,
0410:                    IProgressMonitor subMonitor) throws CoreException {
0411:
0412:                subMonitor
0413:                        .beginTask(
0414:                                IDEWorkbenchMessages.CopyFilesAndFoldersOperation_CopyResourcesTask,
0415:                                resources.length);
0416:
0417:                for (int i = 0; i < resources.length; i++) {
0418:                    IResource source = resources[i];
0419:                    IPath destinationPath = destination
0420:                            .append(source.getName());
0421:                    IWorkspace workspace = source.getWorkspace();
0422:                    IWorkspaceRoot workspaceRoot = workspace.getRoot();
0423:                    IResource existing = workspaceRoot
0424:                            .findMember(destinationPath);
0425:                    if (source.getType() == IResource.FOLDER
0426:                            && existing != null) {
0427:                        // the resource is a folder and it exists in the destination,
0428:                        // copy the
0429:                        // children of the folder.
0430:                        if (homogenousResources(source, existing)) {
0431:                            IResource[] children = ((IContainer) source)
0432:                                    .members();
0433:                            copy(children, destinationPath,
0434:                                    new SubProgressMonitor(subMonitor, 1));
0435:                        } else {
0436:                            // delete the destination folder, copying a linked folder
0437:                            // over an unlinked one or vice versa. Fixes bug 28772.
0438:                            delete(existing, new SubProgressMonitor(subMonitor,
0439:                                    0));
0440:                            source.copy(destinationPath, IResource.SHALLOW,
0441:                                    new SubProgressMonitor(subMonitor, 1));
0442:                        }
0443:                    } else {
0444:                        if (existing != null) {
0445:                            if (homogenousResources(source, existing)) {
0446:                                copyExisting(source, existing,
0447:                                        new SubProgressMonitor(subMonitor, 1));
0448:                            } else {
0449:                                // Copying a linked resource over unlinked or vice
0450:                                // versa.
0451:                                // Can't use setContents here. Fixes bug 28772.
0452:                                delete(existing, new SubProgressMonitor(
0453:                                        subMonitor, 0));
0454:                                source.copy(destinationPath, IResource.SHALLOW,
0455:                                        new SubProgressMonitor(subMonitor, 1));
0456:                            }
0457:                        } else {
0458:                            source.copy(destinationPath, IResource.SHALLOW,
0459:                                    new SubProgressMonitor(subMonitor, 1));
0460:
0461:                        }
0462:
0463:                        if (subMonitor.isCanceled()) {
0464:                            throw new OperationCanceledException();
0465:                        }
0466:                    }
0467:                }
0468:            }
0469:
0470:            /**
0471:             * Sets the content of the existing file to the source file content.
0472:             * 
0473:             * @param source
0474:             *            source file to copy
0475:             * @param existing
0476:             *            existing file to set the source content in
0477:             * @param subMonitor
0478:             *            a progress monitor for showing progress and for cancelation
0479:             * @throws CoreException
0480:             *             setContents failed
0481:             */
0482:            private void copyExisting(IResource source, IResource existing,
0483:                    IProgressMonitor subMonitor) throws CoreException {
0484:                IFile existingFile = getFile(existing);
0485:
0486:                if (existingFile != null) {
0487:                    IFile sourceFile = getFile(source);
0488:
0489:                    if (sourceFile != null) {
0490:                        existingFile.setContents(sourceFile.getContents(),
0491:                                IResource.KEEP_HISTORY, new SubProgressMonitor(
0492:                                        subMonitor, 0));
0493:                    }
0494:                }
0495:            }
0496:
0497:            /**
0498:             * Copies the given resources to the destination. The current Thread is
0499:             * halted while the resources are copied using a WorkspaceModifyOperation.
0500:             * This method should be called from the UIThread.
0501:             * 
0502:             * @param resources
0503:             *            the resources to copy
0504:             * @param destination
0505:             *            destination to which resources will be copied
0506:             * @return IResource[] the resulting {@link IResource}[]
0507:             * @see WorkspaceModifyOperation
0508:             * @see Display#getThread()
0509:             * @see Thread#currentThread()
0510:             */
0511:            public IResource[] copyResources(final IResource[] resources,
0512:                    IContainer destination) {
0513:                return copyResources(resources, destination, true, null);
0514:            }
0515:
0516:            /**
0517:             * Copies the given resources to the destination in the current Thread
0518:             * without forking a new Thread or blocking using a
0519:             * WorkspaceModifyOperation. It recommended that this method only be called
0520:             * from a {@link WorkspaceJob} to avoid possible deadlock.
0521:             * 
0522:             * @param resources
0523:             *            the resources to copy
0524:             * @param destination
0525:             *            destination to which resources will be copied
0526:             * @param monitor
0527:             *            the monitor that information will be sent to.
0528:             * @return IResource[] the resulting {@link IResource}[]
0529:             * @see WorkspaceModifyOperation
0530:             * @see WorkspaceJob
0531:             * @since 3.2
0532:             */
0533:            public IResource[] copyResourcesInCurrentThread(
0534:                    final IResource[] resources, IContainer destination,
0535:                    IProgressMonitor monitor) {
0536:                return copyResources(resources, destination, false, monitor);
0537:            }
0538:
0539:            /**
0540:             * Copies the given resources to the destination.
0541:             * 
0542:             * @param resources
0543:             *            the resources to copy
0544:             * @param destination
0545:             *            destination to which resources will be copied
0546:             * @return IResource[] the resulting {@link IResource}[]
0547:             */
0548:            private IResource[] copyResources(final IResource[] resources,
0549:                    IContainer destination, boolean fork,
0550:                    IProgressMonitor monitor) {
0551:                final IPath destinationPath = destination.getFullPath();
0552:                final IResource[][] copiedResources = new IResource[1][0];
0553:
0554:                // test resources for existence separate from validate API.
0555:                // Validate is performance critical and resource exists
0556:                // check is potentially slow. Fixes bugs 16129/28602.
0557:                IStatus resourceStatus = checkExist(resources);
0558:                if (resourceStatus.getSeverity() != IStatus.OK) {
0559:                    displayError(resourceStatus);
0560:                    return copiedResources[0];
0561:                }
0562:                String errorMsg = validateDestination(destination, resources);
0563:                if (errorMsg != null) {
0564:                    displayError(errorMsg);
0565:                    return copiedResources[0];
0566:                }
0567:
0568:                IRunnableWithProgress op = new IRunnableWithProgress() {
0569:                    public void run(IProgressMonitor monitor) {
0570:                        copyResources(resources, destinationPath,
0571:                                copiedResources, monitor);
0572:                    }
0573:                };
0574:
0575:                try {
0576:                    PlatformUI.getWorkbench().getProgressService().run(fork,
0577:                            true, op);
0578:                } catch (InterruptedException e) {
0579:                    return copiedResources[0];
0580:                } catch (InvocationTargetException e) {
0581:                    display(e);
0582:                }
0583:
0584:                // If errors occurred, open an Error dialog
0585:                if (errorStatus != null) {
0586:                    displayError(errorStatus);
0587:                    errorStatus = null;
0588:                }
0589:
0590:                return copiedResources[0];
0591:            }
0592:
0593:            /**
0594:             * Return whether the operation is a move or a copy
0595:             * 
0596:             * @return whether the operation is a move or a copy
0597:             * @since 3.2
0598:             */
0599:            protected boolean isMove() {
0600:                return false;
0601:            }
0602:
0603:            private void display(InvocationTargetException e) {
0604:                // CoreExceptions are collected above, but unexpected runtime
0605:                // exceptions and errors may still occur.
0606:                IDEWorkbenchPlugin
0607:                        .getDefault()
0608:                        .getLog()
0609:                        .log(
0610:                                StatusUtil
0611:                                        .newStatus(
0612:                                                IStatus.ERROR,
0613:                                                MessageFormat
0614:                                                        .format(
0615:                                                                "Exception in {0}.performCopy(): {1}", //$NON-NLS-1$
0616:                                                                new Object[] {
0617:                                                                        getClass()
0618:                                                                                .getName(),
0619:                                                                        e
0620:                                                                                .getTargetException() }),
0621:                                                null));
0622:                displayError(NLS
0623:                        .bind(
0624:                                IDEWorkbenchMessages.CopyFilesAndFoldersOperation_internalError,
0625:                                e.getTargetException().getMessage()));
0626:            }
0627:
0628:            /**
0629:             * Copies the given URIS and folders to the destination. The current Thread
0630:             * is halted while the resources are copied using a
0631:             * WorkspaceModifyOperation. This method should be called from the UI
0632:             * Thread.
0633:             * 
0634:             * @param uris
0635:             *            the URIs to copy
0636:             * @param destination
0637:             *            destination to which files will be copied
0638:             * @see WorkspaceModifyOperation
0639:             * @see Display#getThread()
0640:             * @see Thread#currentThread()
0641:             * @since 3.2
0642:             */
0643:            public void copyFiles(URI[] uris, IContainer destination) {
0644:                IFileStore[] stores = buildFileStores(uris);
0645:                if (stores == null) {
0646:                    return;
0647:                }
0648:
0649:                copyFileStores(destination, stores, true, null);
0650:            }
0651:
0652:            /**
0653:             * Copies the given files and folders to the destination without forking a
0654:             * new Thread or blocking using a WorkspaceModifyOperation. It is
0655:             * recommended that this method only be called from a {@link WorkspaceJob}
0656:             * to avoid possible deadlock.
0657:             * 
0658:             * @param uris
0659:             *            the URIs to copy
0660:             * @param destination
0661:             *            destination to which URIS will be copied
0662:             * @param monitor
0663:             *            the monitor that information will be sent to.
0664:             * @see WorkspaceModifyOperation
0665:             * @see WorkspaceJob
0666:             * @since 3.2
0667:             */
0668:            public void copyFilesInCurrentThread(URI[] uris,
0669:                    IContainer destination, IProgressMonitor monitor) {
0670:                IFileStore[] stores = buildFileStores(uris);
0671:                if (stores == null) {
0672:                    return;
0673:                }
0674:
0675:                copyFileStores(destination, stores, false, monitor);
0676:            }
0677:
0678:            /**
0679:             * Build the collection of fileStores that map to fileNames. If any of them
0680:             * cannot be found then match then return <code>null</code>.
0681:             * 
0682:             * @param uris
0683:             * @return IFileStore[]
0684:             */
0685:            private IFileStore[] buildFileStores(URI[] uris) {
0686:                IFileStore[] stores = new IFileStore[uris.length];
0687:                for (int i = 0; i < uris.length; i++) {
0688:                    IFileStore store;
0689:                    try {
0690:                        store = EFS.getStore(uris[i]);
0691:                    } catch (CoreException e) {
0692:                        IDEWorkbenchPlugin.log(e.getMessage(), e);
0693:                        reportFileInfoNotFound(uris[i].toString());
0694:                        return null;
0695:                    }
0696:                    if (store == null) {
0697:                        reportFileInfoNotFound(uris[i].toString());
0698:                        return null;
0699:                    }
0700:                    stores[i] = store;
0701:                }
0702:                return stores;
0703:
0704:            }
0705:
0706:            /**
0707:             * Copies the given files and folders to the destination. The current Thread
0708:             * is halted while the resources are copied using a
0709:             * WorkspaceModifyOperation. This method should be called from the UI
0710:             * Thread.
0711:             * 
0712:             * @param fileNames
0713:             *            names of the files to copy
0714:             * @param destination
0715:             *            destination to which files will be copied
0716:             * @see WorkspaceModifyOperation
0717:             * @see Display#getThread()
0718:             * @see Thread#currentThread()
0719:             * @since 3.2
0720:             */
0721:            public void copyFiles(final String[] fileNames,
0722:                    IContainer destination) {
0723:                IFileStore[] stores = buildFileStores(fileNames);
0724:                if (stores == null) {
0725:                    return;
0726:                }
0727:
0728:                copyFileStores(destination, stores, true, null);
0729:            }
0730:
0731:            /**
0732:             * Copies the given files and folders to the destination without forking a
0733:             * new Thread or blocking using a WorkspaceModifyOperation. It is
0734:             * recommended that this method only be called from a {@link WorkspaceJob}
0735:             * to avoid possible deadlock.
0736:             * 
0737:             * @param fileNames
0738:             *            names of the files to copy
0739:             * @param destination
0740:             *            destination to which files will be copied
0741:             * @param monitor
0742:             *            the monitor that information will be sent to.
0743:             * @see WorkspaceModifyOperation
0744:             * @see WorkspaceJob
0745:             * @since 3.2
0746:             */
0747:            public void copyFilesInCurrentThread(final String[] fileNames,
0748:                    IContainer destination, IProgressMonitor monitor) {
0749:                IFileStore[] stores = buildFileStores(fileNames);
0750:                if (stores == null) {
0751:                    return;
0752:                }
0753:
0754:                copyFileStores(destination, stores, false, monitor);
0755:            }
0756:
0757:            /**
0758:             * Build the collection of fileStores that map to fileNames. If any of them
0759:             * cannot be found then match then return null.
0760:             * 
0761:             * @param fileNames
0762:             * @return IFileStore[]
0763:             */
0764:            private IFileStore[] buildFileStores(final String[] fileNames) {
0765:                IFileStore[] stores = new IFileStore[fileNames.length];
0766:                for (int i = 0; i < fileNames.length; i++) {
0767:                    IFileStore store = IDEResourceInfoUtils
0768:                            .getFileStore(fileNames[i]);
0769:                    if (store == null) {
0770:                        reportFileInfoNotFound(fileNames[i]);
0771:                        return null;
0772:                    }
0773:                    stores[i] = store;
0774:                }
0775:                return stores;
0776:            }
0777:
0778:            /**
0779:             * Report that a file info could not be found.
0780:             * 
0781:             * @param fileName
0782:             */
0783:            private void reportFileInfoNotFound(final String fileName) {
0784:
0785:                messageShell.getDisplay().syncExec(new Runnable() {
0786:                    public void run() {
0787:                        ErrorDialog
0788:                                .openError(
0789:                                        messageShell,
0790:                                        getProblemsTitle(),
0791:                                        NLS
0792:                                                .bind(
0793:                                                        IDEWorkbenchMessages.CopyFilesAndFoldersOperation_infoNotFound,
0794:                                                        fileName), null);
0795:                    }
0796:                });
0797:            }
0798:
0799:            /**
0800:             * Copies the given files and folders to the destination.
0801:             * 
0802:             * @param stores
0803:             *            the file stores to copy
0804:             * @param destination
0805:             *            destination to which files will be copied
0806:             */
0807:            private void copyFileStores(IContainer destination,
0808:                    final IFileStore[] stores, boolean fork,
0809:                    IProgressMonitor monitor) {
0810:                // test files for existence separate from validate API
0811:                // because an external file may not exist until the copy actually
0812:                // takes place (e.g., WinZip contents).
0813:                IStatus fileStatus = checkExist(stores);
0814:                if (fileStatus.getSeverity() != IStatus.OK) {
0815:                    displayError(fileStatus);
0816:                    return;
0817:                }
0818:                String errorMsg = validateImportDestinationInternal(
0819:                        destination, stores);
0820:                if (errorMsg != null) {
0821:                    displayError(errorMsg);
0822:                    return;
0823:                }
0824:                final IPath destinationPath = destination.getFullPath();
0825:
0826:                if (fork) {
0827:                    WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
0828:                        public void execute(IProgressMonitor monitor) {
0829:                            copyFileStores(stores, destinationPath, monitor);
0830:                        }
0831:                    };
0832:                    try {
0833:                        PlatformUI.getWorkbench().getProgressService().run(
0834:                                true, true, op);
0835:                    } catch (InterruptedException e) {
0836:                        return;
0837:                    } catch (InvocationTargetException exception) {
0838:                        display(exception);
0839:                    }
0840:                } else {
0841:                    copyFileStores(stores, destinationPath, monitor);
0842:                }
0843:
0844:                // If errors occurred, open an Error dialog
0845:                if (errorStatus != null) {
0846:                    displayError(errorStatus);
0847:                    errorStatus = null;
0848:                }
0849:            }
0850:
0851:            /**
0852:             * Display the supplied status in an error dialog.
0853:             * 
0854:             * @param status
0855:             *            The status to display
0856:             */
0857:            private void displayError(final IStatus status) {
0858:                messageShell.getDisplay().syncExec(new Runnable() {
0859:                    public void run() {
0860:                        ErrorDialog.openError(messageShell, getProblemsTitle(),
0861:                                null, status);
0862:                    }
0863:                });
0864:            }
0865:
0866:            /**
0867:             * Creates a file or folder handle for the source resource as if it were to
0868:             * be created in the destination container.
0869:             * 
0870:             * @param destination
0871:             *            destination container
0872:             * @param source
0873:             *            source resource
0874:             * @return IResource file or folder handle, depending on the source type.
0875:             */
0876:            IResource createLinkedResourceHandle(IContainer destination,
0877:                    IResource source) {
0878:                IWorkspace workspace = destination.getWorkspace();
0879:                IWorkspaceRoot workspaceRoot = workspace.getRoot();
0880:                IPath linkPath = destination.getFullPath().append(
0881:                        source.getName());
0882:                IResource linkHandle;
0883:
0884:                if (source.getType() == IResource.FOLDER) {
0885:                    linkHandle = workspaceRoot.getFolder(linkPath);
0886:                } else {
0887:                    linkHandle = workspaceRoot.getFile(linkPath);
0888:                }
0889:                return linkHandle;
0890:            }
0891:
0892:            /**
0893:             * Removes the given resource from the workspace.
0894:             * 
0895:             * @param resource
0896:             *            resource to remove from the workspace
0897:             * @param monitor
0898:             *            a progress monitor for showing progress and for cancelation
0899:             * @return true the resource was deleted successfully false the resource was
0900:             *         not deleted because a CoreException occurred
0901:             */
0902:            boolean delete(IResource resource, IProgressMonitor monitor) {
0903:                boolean force = false; // don't force deletion of out-of-sync resources
0904:
0905:                if (resource.getType() == IResource.PROJECT) {
0906:                    // if it's a project, ask whether content should be deleted too
0907:                    IProject project = (IProject) resource;
0908:                    try {
0909:                        project.delete(true, force, monitor);
0910:                    } catch (CoreException e) {
0911:                        recordError(e); // log error
0912:                        return false;
0913:                    }
0914:                } else {
0915:                    // if it's not a project, just delete it
0916:                    int flags = IResource.KEEP_HISTORY;
0917:                    if (force) {
0918:                        flags = flags | IResource.FORCE;
0919:                    }
0920:                    try {
0921:                        resource.delete(flags, monitor);
0922:                    } catch (CoreException e) {
0923:                        recordError(e); // log error
0924:                        return false;
0925:                    }
0926:                }
0927:                return true;
0928:            }
0929:
0930:            /**
0931:             * Opens an error dialog to display the given message.
0932:             * 
0933:             * @param message
0934:             *            the error message to show
0935:             */
0936:            private void displayError(final String message) {
0937:                messageShell.getDisplay().syncExec(new Runnable() {
0938:                    public void run() {
0939:                        MessageDialog.openError(messageShell,
0940:                                getProblemsTitle(), message);
0941:                    }
0942:                });
0943:            }
0944:
0945:            /**
0946:             * Returns the resource either casted to or adapted to an IFile.
0947:             * 
0948:             * @param resource
0949:             *            resource to cast/adapt
0950:             * @return the resource either casted to or adapted to an IFile.
0951:             *         <code>null</code> if the resource does not adapt to IFile
0952:             */
0953:            protected IFile getFile(IResource resource) {
0954:                if (resource instanceof  IFile) {
0955:                    return (IFile) resource;
0956:                }
0957:                return (IFile) ((IAdaptable) resource).getAdapter(IFile.class);
0958:            }
0959:
0960:            /**
0961:             * Returns java.io.File objects for the given file names.
0962:             * 
0963:             * @param fileNames
0964:             *            files to return File object for.
0965:             * @return java.io.File objects for the given file names.
0966:             * @deprecated As of 3.3, this method is no longer in use anywhere in this
0967:             *             class and is only provided for backwards compatability with
0968:             *             subclasses of the receiver.
0969:             */
0970:            protected File[] getFiles(String[] fileNames) {
0971:                File[] files = new File[fileNames.length];
0972:
0973:                for (int i = 0; i < fileNames.length; i++) {
0974:                    files[i] = new File(fileNames[i]);
0975:                }
0976:                return files;
0977:            }
0978:
0979:            /**
0980:             * Returns the resource either casted to or adapted to an IFolder.
0981:             * 
0982:             * @param resource
0983:             *            resource to cast/adapt
0984:             * @return the resource either casted to or adapted to an IFolder.
0985:             *         <code>null</code> if the resource does not adapt to IFolder
0986:             */
0987:            protected IFolder getFolder(IResource resource) {
0988:                if (resource instanceof  IFolder) {
0989:                    return (IFolder) resource;
0990:                }
0991:                return (IFolder) ((IAdaptable) resource)
0992:                        .getAdapter(IFolder.class);
0993:            }
0994:
0995:            /**
0996:             * Returns a new name for a copy of the resource at the given path in the
0997:             * given workspace.
0998:             * 
0999:             * @param originalName
1000:             *            the full path of the resource
1001:             * @param workspace
1002:             *            the workspace
1003:             * @return the new full path for the copy, or <code>null</code> if the
1004:             *         resource should not be copied
1005:             */
1006:            private IPath getNewNameFor(final IPath originalName,
1007:                    final IWorkspace workspace) {
1008:                final IResource resource = workspace.getRoot().findMember(
1009:                        originalName);
1010:                final IPath prefix = resource.getFullPath().removeLastSegments(
1011:                        1);
1012:                final String returnValue[] = { "" }; //$NON-NLS-1$
1013:
1014:                messageShell.getDisplay().syncExec(new Runnable() {
1015:                    public void run() {
1016:                        IInputValidator validator = new IInputValidator() {
1017:                            public String isValid(String string) {
1018:                                if (resource.getName().equals(string)) {
1019:                                    return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_nameMustBeDifferent;
1020:                                }
1021:                                IStatus status = workspace.validateName(string,
1022:                                        resource.getType());
1023:                                if (!status.isOK()) {
1024:                                    return status.getMessage();
1025:                                }
1026:                                if (workspace.getRoot().exists(
1027:                                        prefix.append(string))) {
1028:                                    return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_nameExists;
1029:                                }
1030:                                return null;
1031:                            }
1032:                        };
1033:
1034:                        InputDialog dialog = new InputDialog(
1035:                                messageShell,
1036:                                IDEWorkbenchMessages.CopyFilesAndFoldersOperation_inputDialogTitle,
1037:                                NLS
1038:                                        .bind(
1039:                                                IDEWorkbenchMessages.CopyFilesAndFoldersOperation_inputDialogMessage,
1040:                                                resource.getName()),
1041:                                getAutoNewNameFor(originalName, workspace)
1042:                                        .lastSegment().toString(), validator);
1043:                        dialog.setBlockOnOpen(true);
1044:                        dialog.open();
1045:                        if (dialog.getReturnCode() == Window.CANCEL) {
1046:                            returnValue[0] = null;
1047:                        } else {
1048:                            returnValue[0] = dialog.getValue();
1049:                        }
1050:                    }
1051:                });
1052:                if (returnValue[0] == null) {
1053:                    throw new OperationCanceledException();
1054:                }
1055:                return prefix.append(returnValue[0]);
1056:            }
1057:
1058:            /**
1059:             * Returns the task title for this operation's progress dialog.
1060:             * 
1061:             * @return the task title
1062:             */
1063:            protected String getOperationTitle() {
1064:                return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_operationTitle;
1065:            }
1066:
1067:            /**
1068:             * Returns the message for this operation's problems dialog.
1069:             * 
1070:             * @return the problems message
1071:             */
1072:            protected String getProblemsMessage() {
1073:                return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_problemMessage;
1074:            }
1075:
1076:            /**
1077:             * Returns the title for this operation's problems dialog.
1078:             * 
1079:             * @return the problems dialog title
1080:             */
1081:            protected String getProblemsTitle() {
1082:                return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_copyFailedTitle;
1083:            }
1084:
1085:            /**
1086:             * Returns whether the source file in a destination collision will be
1087:             * validateEdited together with the collision itself. Returns false. Should
1088:             * return true if the source file is to be deleted after the operation.
1089:             * 
1090:             * @return boolean <code>true</code> if the source file in a destination
1091:             *         collision should be validateEdited. <code>false</code> if only
1092:             *         the destination should be validated.
1093:             */
1094:            protected boolean getValidateConflictSource() {
1095:                return false;
1096:            }
1097:
1098:            /**
1099:             * Returns whether the given resources are either both linked or both
1100:             * unlinked.
1101:             * 
1102:             * @param source
1103:             *            source resource
1104:             * @param destination
1105:             *            destination resource
1106:             * @return boolean <code>true</code> if both resources are either linked
1107:             *         or unlinked. <code>false</code> otherwise.
1108:             */
1109:            protected boolean homogenousResources(IResource source,
1110:                    IResource destination) {
1111:                boolean isSourceLinked = source.isLinked();
1112:                boolean isDestinationLinked = destination.isLinked();
1113:
1114:                return (isSourceLinked && isDestinationLinked || isSourceLinked == false
1115:                        && isDestinationLinked == false);
1116:            }
1117:
1118:            /**
1119:             * Returns whether the given resource is accessible. Files and folders are
1120:             * always considered accessible and a project is accessible if it is open.
1121:             * 
1122:             * @param resource
1123:             *            the resource
1124:             * @return <code>true</code> if the resource is accessible, and
1125:             *         <code>false</code> if it is not
1126:             */
1127:            private boolean isAccessible(IResource resource) {
1128:                switch (resource.getType()) {
1129:                case IResource.FILE:
1130:                    return true;
1131:                case IResource.FOLDER:
1132:                    return true;
1133:                case IResource.PROJECT:
1134:                    return ((IProject) resource).isOpen();
1135:                default:
1136:                    return false;
1137:                }
1138:            }
1139:
1140:            /**
1141:             * Returns whether any of the given source resources are being recopied to
1142:             * their current container.
1143:             * 
1144:             * @param sourceResources
1145:             *            the source resources
1146:             * @param destination
1147:             *            the destination container
1148:             * @return <code>true</code> if at least one of the given source
1149:             *         resource's parent container is the same as the destination
1150:             */
1151:            boolean isDestinationSameAsSource(IResource[] sourceResources,
1152:                    IContainer destination) {
1153:                IPath destinationLocation = destination.getLocation();
1154:
1155:                for (int i = 0; i < sourceResources.length; i++) {
1156:                    IResource sourceResource = sourceResources[i];
1157:                    if (sourceResource.getParent().equals(destination)) {
1158:                        return true;
1159:                    } else if (destinationLocation != null) {
1160:                        // do thorough check to catch linked resources. Fixes bug 29913.
1161:                        IPath sourceLocation = sourceResource.getLocation();
1162:                        IPath destinationResource = destinationLocation
1163:                                .append(sourceResource.getName());
1164:                        if (sourceLocation != null
1165:                                && sourceLocation
1166:                                        .isPrefixOf(destinationResource)) {
1167:                            return true;
1168:                        }
1169:                    }
1170:                }
1171:                return false;
1172:            }
1173:
1174:            /**
1175:             * Copies the given resources to the destination container with the given
1176:             * name.
1177:             * <p>
1178:             * Note: the destination container may need to be created prior to copying
1179:             * the resources.
1180:             * </p>
1181:             * 
1182:             * @param resources
1183:             *            the resources to copy
1184:             * @param destination
1185:             *            the path of the destination container
1186:             * @param monitor
1187:             *            a progress monitor for showing progress and for cancelation
1188:             * @return <code>true</code> if the copy operation completed without
1189:             *         errors
1190:             */
1191:            private boolean performCopy(IResource[] resources,
1192:                    IPath destination, IProgressMonitor monitor) {
1193:                try {
1194:                    AbstractWorkspaceOperation op = getUndoableCopyOrMoveOperation(
1195:                            resources, destination);
1196:                    op.setModelProviderIds(getModelProviderIds());
1197:                    PlatformUI.getWorkbench().getOperationSupport()
1198:                            .getOperationHistory().execute(
1199:                                    op,
1200:                                    monitor,
1201:                                    WorkspaceUndoUtil
1202:                                            .getUIInfoAdapter(messageShell));
1203:                } catch (ExecutionException e) {
1204:                    if (e.getCause() instanceof  CoreException) {
1205:                        recordError((CoreException) e.getCause());
1206:                    } else {
1207:                        IDEWorkbenchPlugin.log(e.getMessage(), e);
1208:                        displayError(e.getMessage());
1209:                    }
1210:                    return false;
1211:                }
1212:                return true;
1213:            }
1214:
1215:            /**
1216:             * Individually copies the given resources to the specified destination
1217:             * container checking for name collisions. If a collision is detected, it is
1218:             * saved with a new name.
1219:             * <p>
1220:             * Note: the destination container may need to be created prior to copying
1221:             * the resources.
1222:             * </p>
1223:             * 
1224:             * @param resources
1225:             *            the resources to copy
1226:             * @param destination
1227:             *            the path of the destination container
1228:             * @return <code>true</code> if the copy operation completed without
1229:             *         errors.
1230:             */
1231:            private boolean performCopyWithAutoRename(IResource[] resources,
1232:                    IPath destination, IProgressMonitor monitor) {
1233:                IWorkspace workspace = resources[0].getWorkspace();
1234:                IPath[] destinationPaths = new IPath[resources.length];
1235:                try {
1236:                    for (int i = 0; i < resources.length; i++) {
1237:                        IResource source = resources[i];
1238:                        destinationPaths[i] = destination.append(source
1239:                                .getName());
1240:
1241:                        if (workspace.getRoot().exists(destinationPaths[i])) {
1242:                            destinationPaths[i] = getNewNameFor(
1243:                                    destinationPaths[i], workspace);
1244:                        }
1245:                    }
1246:                    CopyResourcesOperation op = new CopyResourcesOperation(
1247:                            resources,
1248:                            destinationPaths,
1249:                            IDEWorkbenchMessages.CopyFilesAndFoldersOperation_copyTitle);
1250:                    op.setModelProviderIds(getModelProviderIds());
1251:                    PlatformUI.getWorkbench().getOperationSupport()
1252:                            .getOperationHistory().execute(
1253:                                    op,
1254:                                    monitor,
1255:                                    WorkspaceUndoUtil
1256:                                            .getUIInfoAdapter(messageShell));
1257:                } catch (ExecutionException e) {
1258:                    if (e.getCause() instanceof  CoreException) {
1259:                        recordError((CoreException) e.getCause());
1260:                    } else {
1261:                        IDEWorkbenchPlugin.log(e.getMessage(), e);
1262:                        displayError(e.getMessage());
1263:                    }
1264:                    return false;
1265:                }
1266:                return true;
1267:            }
1268:
1269:            /**
1270:             * Performs an import of the given stores into the provided container.
1271:             * Returns a status indicating if the import was successful.
1272:             * 
1273:             * @param stores
1274:             *            stores that are to be imported
1275:             * @param target
1276:             *            container to which the import will be done
1277:             * @param monitor
1278:             *            a progress monitor for showing progress and for cancelation
1279:             */
1280:            private void performFileImport(IFileStore[] stores,
1281:                    IContainer target, IProgressMonitor monitor) {
1282:                IOverwriteQuery query = new IOverwriteQuery() {
1283:                    public String queryOverwrite(String pathString) {
1284:                        if (alwaysOverwrite) {
1285:                            return ALL;
1286:                        }
1287:
1288:                        final String returnCode[] = { CANCEL };
1289:                        final String msg = NLS
1290:                                .bind(
1291:                                        IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteQuestion,
1292:                                        pathString);
1293:                        final String[] options = { IDialogConstants.YES_LABEL,
1294:                                IDialogConstants.YES_TO_ALL_LABEL,
1295:                                IDialogConstants.NO_LABEL,
1296:                                IDialogConstants.CANCEL_LABEL };
1297:                        messageShell.getDisplay().syncExec(new Runnable() {
1298:                            public void run() {
1299:                                MessageDialog dialog = new MessageDialog(
1300:                                        messageShell,
1301:                                        IDEWorkbenchMessages.CopyFilesAndFoldersOperation_question,
1302:                                        null, msg, MessageDialog.QUESTION,
1303:                                        options, 0);
1304:                                dialog.open();
1305:                                int returnVal = dialog.getReturnCode();
1306:                                String[] returnCodes = { YES, ALL, NO, CANCEL };
1307:                                returnCode[0] = returnVal == -1 ? CANCEL
1308:                                        : returnCodes[returnVal];
1309:                            }
1310:                        });
1311:                        if (returnCode[0] == ALL) {
1312:                            alwaysOverwrite = true;
1313:                        } else if (returnCode[0] == CANCEL) {
1314:                            canceled = true;
1315:                        }
1316:                        return returnCode[0];
1317:                    }
1318:                };
1319:
1320:                ImportOperation op = new ImportOperation(target.getFullPath(),
1321:                        stores[0].getParent(),
1322:                        FileStoreStructureProvider.INSTANCE, query, Arrays
1323:                                .asList(stores));
1324:                op.setContext(messageShell);
1325:                op.setCreateContainerStructure(false);
1326:                try {
1327:                    op.run(monitor);
1328:                } catch (InterruptedException e) {
1329:                    return;
1330:                } catch (InvocationTargetException e) {
1331:                    if (e.getTargetException() instanceof  CoreException) {
1332:                        displayError(((CoreException) e.getTargetException())
1333:                                .getStatus());
1334:                    } else {
1335:                        display(e);
1336:                    }
1337:                    return;
1338:                }
1339:                // Special case since ImportOperation doesn't throw a CoreException on
1340:                // failure.
1341:                IStatus status = op.getStatus();
1342:                if (!status.isOK()) {
1343:                    if (errorStatus == null) {
1344:                        errorStatus = new MultiStatus(PlatformUI.PLUGIN_ID,
1345:                                IStatus.ERROR, getProblemsMessage(), null);
1346:                    }
1347:                    errorStatus.merge(status);
1348:                }
1349:            }
1350:
1351:            /**
1352:             * Records the core exception to be displayed to the user once the action is
1353:             * finished.
1354:             * 
1355:             * @param error
1356:             *            a <code>CoreException</code>
1357:             */
1358:            private void recordError(CoreException error) {
1359:                if (errorStatus == null) {
1360:                    errorStatus = new MultiStatus(PlatformUI.PLUGIN_ID,
1361:                            IStatus.ERROR, getProblemsMessage(), error);
1362:                }
1363:
1364:                errorStatus.merge(error.getStatus());
1365:            }
1366:
1367:            /**
1368:             * Checks whether the destination is valid for copying the source resources.
1369:             * <p>
1370:             * Note this method is for internal use only. It is not API.
1371:             * </p>
1372:             * 
1373:             * @param destination
1374:             *            the destination container
1375:             * @param sourceResources
1376:             *            the source resources
1377:             * @return an error message, or <code>null</code> if the path is valid
1378:             */
1379:            public String validateDestination(IContainer destination,
1380:                    IResource[] sourceResources) {
1381:                if (!isAccessible(destination)) {
1382:                    return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_destinationAccessError;
1383:                }
1384:                IContainer firstParent = null;
1385:                URI destinationLocation = destination.getLocationURI();
1386:                for (int i = 0; i < sourceResources.length; i++) {
1387:                    IResource sourceResource = sourceResources[i];
1388:                    if (firstParent == null) {
1389:                        firstParent = sourceResource.getParent();
1390:                    } else if (firstParent.equals(sourceResource.getParent()) == false) {
1391:                        // Resources must have common parent. Fixes bug 33398.
1392:                        return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_parentNotEqual;
1393:                    }
1394:
1395:                    URI sourceLocation = sourceResource.getLocationURI();
1396:                    if (sourceLocation == null) {
1397:                        if (sourceResource.isLinked()) {
1398:                            // Don't allow copying linked resources with undefined path
1399:                            // variables. See bug 28754.
1400:                            return NLS
1401:                                    .bind(
1402:                                            IDEWorkbenchMessages.CopyFilesAndFoldersOperation_missingPathVariable,
1403:                                            sourceResource.getName());
1404:                        }
1405:                        return NLS
1406:                                .bind(
1407:                                        IDEWorkbenchMessages.CopyFilesAndFoldersOperation_resourceDeleted,
1408:                                        sourceResource.getName());
1409:
1410:                    }
1411:                    if (sourceLocation.equals(destinationLocation)) {
1412:                        return NLS
1413:                                .bind(
1414:                                        IDEWorkbenchMessages.CopyFilesAndFoldersOperation_sameSourceAndDest,
1415:                                        sourceResource.getName());
1416:                    }
1417:                    // is the source a parent of the destination?
1418:                    if (new Path(sourceLocation.toString())
1419:                            .isPrefixOf(new Path(destinationLocation.toString()))) {
1420:                        return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_destinationDescendentError;
1421:                    }
1422:
1423:                    String linkedResourceMessage = validateLinkedResource(
1424:                            destination, sourceResource);
1425:                    if (linkedResourceMessage != null) {
1426:                        return linkedResourceMessage;
1427:                    }
1428:                }
1429:                return null;
1430:            }
1431:
1432:            /**
1433:             * Validates that the given source resources can be copied to the
1434:             * destination as decided by the VCM provider.
1435:             * 
1436:             * @param destination
1437:             *            copy destination
1438:             * @param sourceResources
1439:             *            source resources
1440:             * @return <code>true</code> all files passed validation or there were no
1441:             *         files to validate. <code>false</code> one or more files did not
1442:             *         pass validation.
1443:             */
1444:            private boolean validateEdit(IContainer destination,
1445:                    IResource[] sourceResources) {
1446:                ArrayList copyFiles = new ArrayList();
1447:
1448:                collectExistingReadonlyFiles(destination.getFullPath(),
1449:                        sourceResources, copyFiles);
1450:                if (copyFiles.size() > 0) {
1451:                    IFile[] files = (IFile[]) copyFiles
1452:                            .toArray(new IFile[copyFiles.size()]);
1453:                    IWorkspace workspace = ResourcesPlugin.getWorkspace();
1454:                    IStatus status = workspace
1455:                            .validateEdit(files, messageShell);
1456:
1457:                    canceled = status.isOK() == false;
1458:                    return status.isOK();
1459:                }
1460:                return true;
1461:            }
1462:
1463:            /**
1464:             * Checks whether the destination is valid for copying the source files.
1465:             * <p>
1466:             * Note this method is for internal use only. It is not API.
1467:             * </p>
1468:             * 
1469:             * @param destination
1470:             *            the destination container
1471:             * @param sourceNames
1472:             *            the source file names
1473:             * @return an error message, or <code>null</code> if the path is valid
1474:             */
1475:            public String validateImportDestination(IContainer destination,
1476:                    String[] sourceNames) {
1477:
1478:                IFileStore[] stores = new IFileStore[sourceNames.length];
1479:                for (int i = 0; i < sourceNames.length; i++) {
1480:                    IFileStore store = IDEResourceInfoUtils
1481:                            .getFileStore(sourceNames[i]);
1482:                    if (store == null) {
1483:                        return NLS
1484:                                .bind(
1485:                                        IDEWorkbenchMessages.CopyFilesAndFoldersOperation_infoNotFound,
1486:                                        sourceNames[i]);
1487:                    }
1488:                    stores[i] = store;
1489:                }
1490:                return validateImportDestinationInternal(destination, stores);
1491:
1492:            }
1493:
1494:            /**
1495:             * Checks whether the destination is valid for copying the source file
1496:             * stores.
1497:             * <p>
1498:             * Note this method is for internal use only. It is not API.
1499:             * </p>
1500:             * <p>
1501:             * TODO Bug 117804. This method has been renamed to avoid a bug in the
1502:             * Eclipse compiler with regards to visibility and type resolution when
1503:             * linking.
1504:             * </p>
1505:             * 
1506:             * @param destination
1507:             *            the destination container
1508:             * @param sourceStores
1509:             *            the source IFileStore
1510:             * @return an error message, or <code>null</code> if the path is valid
1511:             */
1512:            private String validateImportDestinationInternal(
1513:                    IContainer destination, IFileStore[] sourceStores) {
1514:                if (!isAccessible(destination))
1515:                    return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_destinationAccessError;
1516:
1517:                IFileStore destinationStore;
1518:                try {
1519:                    destinationStore = EFS.getStore(destination
1520:                            .getLocationURI());
1521:                } catch (CoreException exception) {
1522:                    IDEWorkbenchPlugin.log(exception.getLocalizedMessage(),
1523:                            exception);
1524:                    return NLS
1525:                            .bind(
1526:                                    IDEWorkbenchMessages.CopyFilesAndFoldersOperation_internalError,
1527:                                    exception.getLocalizedMessage());
1528:                }
1529:                for (int i = 0; i < sourceStores.length; i++) {
1530:                    IFileStore sourceStore = sourceStores[i];
1531:                    IFileStore sourceParentStore = sourceStore.getParent();
1532:
1533:                    if (sourceStore != null) {
1534:                        if (destinationStore.equals(sourceStore)
1535:                                || (sourceParentStore != null && destinationStore
1536:                                        .equals(sourceParentStore))) {
1537:                            return NLS
1538:                                    .bind(
1539:                                            IDEWorkbenchMessages.CopyFilesAndFoldersOperation_importSameSourceAndDest,
1540:                                            sourceStore.getName());
1541:                        }
1542:                        // work around bug 16202. replacement for
1543:                        // sourcePath.isPrefixOf(destinationPath)
1544:                        IFileStore destinationParent = destinationStore
1545:                                .getParent();
1546:                        if (sourceStore.isParentOf(destinationParent)) {
1547:                            return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_destinationDescendentError;
1548:                        }
1549:
1550:                    }
1551:                }
1552:                return null;
1553:            }
1554:
1555:            /**
1556:             * Check if the destination is valid for the given source resource.
1557:             * 
1558:             * @param destination
1559:             *            destination container of the operation
1560:             * @param source
1561:             *            source resource
1562:             * @return String error message or null if the destination is valid
1563:             */
1564:            private String validateLinkedResource(IContainer destination,
1565:                    IResource source) {
1566:                if (source.isLinked() == false) {
1567:                    return null;
1568:                }
1569:                IWorkspace workspace = destination.getWorkspace();
1570:                IResource linkHandle = createLinkedResourceHandle(destination,
1571:                        source);
1572:                IStatus locationStatus = workspace.validateLinkLocation(
1573:                        linkHandle, source.getRawLocation());
1574:
1575:                if (locationStatus.getSeverity() == IStatus.ERROR) {
1576:                    return locationStatus.getMessage();
1577:                }
1578:                IPath sourceLocation = source.getLocation();
1579:                if (source.getProject().equals(destination.getProject()) == false
1580:                        && source.getType() == IResource.FOLDER
1581:                        && sourceLocation != null) {
1582:                    // prevent merging linked folders that point to the same
1583:                    // file system folder
1584:                    try {
1585:                        IResource[] members = destination.members();
1586:                        for (int j = 0; j < members.length; j++) {
1587:                            if (sourceLocation.equals(members[j].getLocation())
1588:                                    && source.getName().equals(
1589:                                            members[j].getName())) {
1590:                                return NLS
1591:                                        .bind(
1592:                                                IDEWorkbenchMessages.CopyFilesAndFoldersOperation_sameSourceAndDest,
1593:                                                source.getName());
1594:                            }
1595:                        }
1596:                    } catch (CoreException exception) {
1597:                        displayError(NLS
1598:                                .bind(
1599:                                        IDEWorkbenchMessages.CopyFilesAndFoldersOperation_internalError,
1600:                                        exception.getMessage()));
1601:                    }
1602:                }
1603:                return null;
1604:            }
1605:
1606:            /**
1607:             * Returns whether moving all of the given source resources to the given
1608:             * destination container could be done without causing name collisions.
1609:             * 
1610:             * @param destination
1611:             *            the destination container
1612:             * @param sourceResources
1613:             *            the list of resources
1614:             * @return <code>true</code> if there would be no name collisions, and
1615:             *         <code>false</code> if there would
1616:             */
1617:            private IResource[] validateNoNameCollisions(
1618:                    IContainer destination, IResource[] sourceResources) {
1619:                List copyItems = new ArrayList();
1620:                IWorkspaceRoot workspaceRoot = destination.getWorkspace()
1621:                        .getRoot();
1622:                int overwrite = IDialogConstants.NO_ID;
1623:
1624:                // Check to see if we would be overwriting a parent folder.
1625:                // Cancel entire copy operation if we do.
1626:                for (int i = 0; i < sourceResources.length; i++) {
1627:                    final IResource sourceResource = sourceResources[i];
1628:                    final IPath destinationPath = destination.getFullPath()
1629:                            .append(sourceResource.getName());
1630:                    final IPath sourcePath = sourceResource.getFullPath();
1631:
1632:                    IResource newResource = workspaceRoot
1633:                            .findMember(destinationPath);
1634:                    if (newResource != null
1635:                            && destinationPath.isPrefixOf(sourcePath)) {
1636:                        displayError(NLS
1637:                                .bind(
1638:                                        IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteProblem,
1639:                                        destinationPath, sourcePath));
1640:
1641:                        canceled = true;
1642:                        return null;
1643:                    }
1644:                }
1645:                // Check for overwrite conflicts
1646:                for (int i = 0; i < sourceResources.length; i++) {
1647:                    final IResource source = sourceResources[i];
1648:                    final IPath destinationPath = destination.getFullPath()
1649:                            .append(source.getName());
1650:
1651:                    IResource newResource = workspaceRoot
1652:                            .findMember(destinationPath);
1653:                    if (newResource != null) {
1654:                        if (overwrite != IDialogConstants.YES_TO_ALL_ID
1655:                                || (newResource.getType() == IResource.FOLDER && homogenousResources(
1656:                                        source, destination) == false)) {
1657:                            overwrite = checkOverwrite(source, newResource);
1658:                        }
1659:                        if (overwrite == IDialogConstants.YES_ID
1660:                                || overwrite == IDialogConstants.YES_TO_ALL_ID) {
1661:                            copyItems.add(source);
1662:                        } else if (overwrite == IDialogConstants.CANCEL_ID) {
1663:                            canceled = true;
1664:                            return null;
1665:                        }
1666:                    } else {
1667:                        copyItems.add(source);
1668:                    }
1669:                }
1670:                return (IResource[]) copyItems.toArray(new IResource[copyItems
1671:                        .size()]);
1672:            }
1673:
1674:            private void copyResources(final IResource[] resources,
1675:                    final IPath destinationPath,
1676:                    final IResource[][] copiedResources,
1677:                    IProgressMonitor monitor) {
1678:                IResource[] copyResources = resources;
1679:
1680:                // Fix for bug 31116. Do not provide a task name when
1681:                // creating the task.
1682:                monitor.beginTask("", 100); //$NON-NLS-1$
1683:                monitor.setTaskName(getOperationTitle());
1684:                monitor.worked(10); // show some initial progress
1685:
1686:                // Checks only required if this is an exisiting container path.
1687:                boolean copyWithAutoRename = false;
1688:                IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
1689:                if (root.exists(destinationPath)) {
1690:                    IContainer container = (IContainer) root
1691:                            .findMember(destinationPath);
1692:                    // If we're copying to the source container then perform
1693:                    // auto-renames on all resources to avoid name collisions.
1694:                    if (isDestinationSameAsSource(copyResources, container)
1695:                            && canPerformAutoRename()) {
1696:                        copyWithAutoRename = true;
1697:                    } else {
1698:                        // If no auto-renaming will be happening, check for
1699:                        // potential name collisions at the target resource
1700:                        copyResources = validateNoNameCollisions(container,
1701:                                copyResources);
1702:                        if (copyResources == null) {
1703:                            if (canceled) {
1704:                                return;
1705:                            }
1706:                            displayError(IDEWorkbenchMessages.CopyFilesAndFoldersOperation_nameCollision);
1707:                            return;
1708:                        }
1709:                        if (validateEdit(container, copyResources) == false) {
1710:                            return;
1711:                        }
1712:                    }
1713:                }
1714:
1715:                errorStatus = null;
1716:                if (copyResources.length > 0) {
1717:                    if (copyWithAutoRename) {
1718:                        performCopyWithAutoRename(copyResources,
1719:                                destinationPath, new SubProgressMonitor(
1720:                                        monitor, 90));
1721:                    } else {
1722:                        performCopy(copyResources, destinationPath,
1723:                                new SubProgressMonitor(monitor, 90));
1724:                    }
1725:                }
1726:                monitor.done();
1727:                copiedResources[0] = copyResources;
1728:            }
1729:
1730:            private void copyFileStores(final IFileStore[] stores,
1731:                    final IPath destinationPath, IProgressMonitor monitor) {
1732:                // Checks only required if this is an exisiting container path.
1733:                IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
1734:                if (root.exists(destinationPath)) {
1735:                    IContainer container = (IContainer) root
1736:                            .findMember(destinationPath);
1737:
1738:                    performFileImport(stores, container, monitor);
1739:                }
1740:            }
1741:
1742:            /**
1743:             * Returns the model provider ids that are known to the client that
1744:             * instantiated this operation.
1745:             * 
1746:             * @return the model provider ids that are known to the client that
1747:             *         instantiated this operation.
1748:             * @since 3.2
1749:             */
1750:            public String[] getModelProviderIds() {
1751:                return modelProviderIds;
1752:            }
1753:
1754:            /**
1755:             * Sets the model provider ids that are known to the client that
1756:             * instantiated this operation. Any potential side effects reported by these
1757:             * models during validation will be ignored.
1758:             * 
1759:             * @param modelProviderIds
1760:             *            the model providers known to the client who is using this
1761:             *            operation.
1762:             * @since 3.2
1763:             */
1764:            public void setModelProviderIds(String[] modelProviderIds) {
1765:                this .modelProviderIds = modelProviderIds;
1766:            }
1767:
1768:            /**
1769:             * Returns an AbstractWorkspaceOperation suitable for performing the move or
1770:             * copy operation that will move or copy the given resources to the given
1771:             * destination path.
1772:             * 
1773:             * @param resources
1774:             *            the resources to be moved or copied
1775:             * @param destinationPath
1776:             *            the destination path to which the resources should be moved
1777:             * @return the operation that should be used to perform the move or cop
1778:             * @since 3.3
1779:             */
1780:            protected AbstractWorkspaceOperation getUndoableCopyOrMoveOperation(
1781:                    IResource[] resources, IPath destinationPath) {
1782:                return new CopyResourcesOperation(
1783:                        resources,
1784:                        destinationPath,
1785:                        IDEWorkbenchMessages.CopyFilesAndFoldersOperation_copyTitle);
1786:
1787:            }
1788:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.