KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > refactoring > reorg > PasteAction


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

11 package org.eclipse.jdt.internal.ui.refactoring.reorg;
12
13 import java.lang.reflect.InvocationTargetException JavaDoc;
14 import java.util.ArrayList JavaDoc;
15 import java.util.Arrays JavaDoc;
16 import java.util.HashSet JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.List JavaDoc;
19 import java.util.ListIterator JavaDoc;
20 import java.util.Map JavaDoc;
21 import java.util.Set JavaDoc;
22
23 import org.eclipse.text.edits.TextEdit;
24
25 import org.eclipse.core.runtime.Assert;
26 import org.eclipse.core.runtime.CoreException;
27 import org.eclipse.core.runtime.IAdaptable;
28 import org.eclipse.core.runtime.IPath;
29 import org.eclipse.core.runtime.IProgressMonitor;
30 import org.eclipse.core.runtime.OperationCanceledException;
31 import org.eclipse.core.runtime.SubProgressMonitor;
32
33 import org.eclipse.core.filebuffers.ITextFileBuffer;
34
35 import org.eclipse.core.resources.IContainer;
36 import org.eclipse.core.resources.IFile;
37 import org.eclipse.core.resources.IFolder;
38 import org.eclipse.core.resources.IProject;
39 import org.eclipse.core.resources.IResource;
40 import org.eclipse.core.resources.IWorkspaceRunnable;
41
42 import org.eclipse.swt.dnd.Clipboard;
43 import org.eclipse.swt.dnd.FileTransfer;
44 import org.eclipse.swt.dnd.TextTransfer;
45 import org.eclipse.swt.dnd.Transfer;
46 import org.eclipse.swt.dnd.TransferData;
47 import org.eclipse.swt.widgets.Shell;
48
49 import org.eclipse.jface.dialogs.MessageDialog;
50 import org.eclipse.jface.dialogs.ProgressMonitorDialog;
51 import org.eclipse.jface.operation.IRunnableContext;
52 import org.eclipse.jface.operation.IRunnableWithProgress;
53 import org.eclipse.jface.preference.IPreferenceStore;
54 import org.eclipse.jface.viewers.IStructuredSelection;
55
56 import org.eclipse.jface.text.BadLocationException;
57
58 import org.eclipse.ui.IEditorPart;
59 import org.eclipse.ui.ISharedImages;
60 import org.eclipse.ui.IWorkbenchSite;
61 import org.eclipse.ui.IWorkingSet;
62 import org.eclipse.ui.PartInitException;
63 import org.eclipse.ui.PlatformUI;
64 import org.eclipse.ui.actions.CopyFilesAndFoldersOperation;
65 import org.eclipse.ui.actions.CopyProjectOperation;
66 import org.eclipse.ui.part.ResourceTransfer;
67
68 import org.eclipse.ltk.core.refactoring.Change;
69 import org.eclipse.ltk.core.refactoring.Refactoring;
70 import org.eclipse.ltk.core.refactoring.RefactoringCore;
71 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
72 import org.eclipse.ltk.core.refactoring.TextFileChange;
73
74 import org.eclipse.jdt.core.IClasspathEntry;
75 import org.eclipse.jdt.core.ICompilationUnit;
76 import org.eclipse.jdt.core.IJavaElement;
77 import org.eclipse.jdt.core.IJavaProject;
78 import org.eclipse.jdt.core.IPackageDeclaration;
79 import org.eclipse.jdt.core.IPackageFragment;
80 import org.eclipse.jdt.core.IPackageFragmentRoot;
81 import org.eclipse.jdt.core.ISourceRange;
82 import org.eclipse.jdt.core.IType;
83 import org.eclipse.jdt.core.JavaCore;
84 import org.eclipse.jdt.core.JavaModelException;
85 import org.eclipse.jdt.core.ToolFactory;
86 import org.eclipse.jdt.core.compiler.IScanner;
87 import org.eclipse.jdt.core.compiler.ITerminalSymbols;
88 import org.eclipse.jdt.core.compiler.InvalidInputException;
89 import org.eclipse.jdt.core.dom.AST;
90 import org.eclipse.jdt.core.dom.ASTNode;
91 import org.eclipse.jdt.core.dom.ASTParser;
92 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
93 import org.eclipse.jdt.core.dom.BodyDeclaration;
94 import org.eclipse.jdt.core.dom.CompilationUnit;
95 import org.eclipse.jdt.core.dom.Modifier;
96 import org.eclipse.jdt.core.dom.PackageDeclaration;
97 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
98
99 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
100 import org.eclipse.jdt.internal.corext.refactoring.Checks;
101 import org.eclipse.jdt.internal.corext.refactoring.TypedSource;
102 import org.eclipse.jdt.internal.corext.refactoring.changes.CompilationUnitChange;
103 import org.eclipse.jdt.internal.corext.refactoring.changes.TextChangeCompatibility;
104 import org.eclipse.jdt.internal.corext.refactoring.reorg.IConfirmQuery;
105 import org.eclipse.jdt.internal.corext.refactoring.reorg.IReorgQueries;
106 import org.eclipse.jdt.internal.corext.refactoring.reorg.JavaElementTransfer;
107 import org.eclipse.jdt.internal.corext.refactoring.reorg.ParentChecker;
108 import org.eclipse.jdt.internal.corext.refactoring.reorg.ReorgUtils;
109 import org.eclipse.jdt.internal.corext.refactoring.structure.ASTNodeSearchUtil;
110 import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringFileBuffers;
111 import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil;
112 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
113 import org.eclipse.jdt.internal.corext.util.JdtFlags;
114 import org.eclipse.jdt.internal.corext.util.Messages;
115
116 import org.eclipse.jdt.launching.IVMInstall;
117 import org.eclipse.jdt.launching.IVMInstall2;
118 import org.eclipse.jdt.launching.IVMInstallType;
119 import org.eclipse.jdt.launching.JavaRuntime;
120 import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
121 import org.eclipse.jdt.launching.environments.IExecutionEnvironmentsManager;
122
123 import org.eclipse.jdt.ui.JavaUI;
124 import org.eclipse.jdt.ui.PreferenceConstants;
125 import org.eclipse.jdt.ui.actions.SelectionDispatchAction;
126
127 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
128 import org.eclipse.jdt.internal.ui.JavaPlugin;
129 import org.eclipse.jdt.internal.ui.refactoring.RefactoringExecutionHelper;
130 import org.eclipse.jdt.internal.ui.refactoring.RefactoringMessages;
131 import org.eclipse.jdt.internal.ui.refactoring.RefactoringSaveHelper;
132 import org.eclipse.jdt.internal.ui.util.BusyIndicatorRunnableContext;
133 import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
134 import org.eclipse.jdt.internal.ui.util.SelectionUtil;
135 import org.eclipse.jdt.internal.ui.wizards.buildpaths.BuildPathsBlock;
136 import org.eclipse.jdt.internal.ui.workingsets.OthersWorkingSetUpdater;
137
138 public class PasteAction extends SelectionDispatchAction{
139
140     private final Clipboard fClipboard;
141
142     public PasteAction(IWorkbenchSite site, Clipboard clipboard) {
143         super(site);
144         Assert.isNotNull(clipboard);
145         fClipboard= clipboard;
146         
147         setText(ReorgMessages.PasteAction_4);
148         setDescription(ReorgMessages.PasteAction_5);
149
150         ISharedImages workbenchImages= JavaPlugin.getDefault().getWorkbench().getSharedImages();
151         setDisabledImageDescriptor(workbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE_DISABLED));
152         setImageDescriptor(workbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE));
153         setHoverImageDescriptor(workbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE));
154
155         PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.PASTE_ACTION);
156     }
157     
158     /* (non-Javadoc)
159      * @see org.eclipse.jdt.ui.actions.SelectionDispatchAction#selectionChanged(org.eclipse.jface.viewers.IStructuredSelection)
160      */

161     public void selectionChanged(IStructuredSelection selection) {
162         // Moved condition checking to run (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=78450)
163
}
164
165     private Paster[] createEnabledPasters(TransferData[] availableDataTypes) throws JavaModelException {
166         Paster paster;
167         Shell shell = getShell();
168         List JavaDoc result= new ArrayList JavaDoc(2);
169         paster= new ProjectPaster(shell, fClipboard);
170         if (paster.canEnable(availableDataTypes))
171             result.add(paster);
172         
173         paster= new JavaElementAndResourcePaster(shell, fClipboard);
174         if (paster.canEnable(availableDataTypes))
175             result.add(paster);
176
177         paster= new TypedSourcePaster(shell, fClipboard);
178         if (paster.canEnable(availableDataTypes))
179             result.add(paster);
180
181         paster= new FilePaster(shell, fClipboard);
182         if (paster.canEnable(availableDataTypes))
183             result.add(paster);
184         
185         paster= new WorkingSetPaster(shell, fClipboard);
186         if (paster.canEnable(availableDataTypes))
187             result.add(paster);
188         
189         paster= new TextPaster(shell, fClipboard);
190         if (paster.canEnable(availableDataTypes))
191             result.add(paster);
192         return (Paster[]) result.toArray(new Paster[result.size()]);
193     }
194
195     private static Object JavaDoc getContents(final Clipboard clipboard, final Transfer transfer, Shell shell) {
196         //see bug 33028 for explanation why we need this
197
final Object JavaDoc[] result= new Object JavaDoc[1];
198         shell.getDisplay().syncExec(new Runnable JavaDoc() {
199             public void run() {
200                 result[0]= clipboard.getContents(transfer);
201             }
202         });
203         return result[0];
204     }
205     
206     private static boolean isAvailable(Transfer transfer, TransferData[] availableDataTypes) {
207         for (int i= 0; i < availableDataTypes.length; i++) {
208             if (transfer.isSupportedType(availableDataTypes[i])) return true;
209         }
210         return false;
211     }
212
213     public void run(IStructuredSelection selection) {
214         try {
215             TransferData[] availableTypes= fClipboard.getAvailableTypes();
216             List JavaDoc elements= selection.toList();
217             IResource[] resources= ReorgUtils.getResources(elements);
218             IJavaElement[] javaElements= ReorgUtils.getJavaElements(elements);
219             IWorkingSet[] workingSets= ReorgUtils.getWorkingSets(elements);
220             Paster[] pasters= createEnabledPasters(availableTypes);
221             for (int i= 0; i < pasters.length; i++) {
222                 if (pasters[i].canPasteOn(javaElements, resources, workingSets)) {
223                     pasters[i].paste(javaElements, resources, workingSets, availableTypes);
224                     return;// one is enough
225
}
226             }
227             String JavaDoc msg= resources.length + javaElements.length + workingSets.length == 0
228                     ? ReorgMessages.PasteAction_cannot_no_selection
229                     : ReorgMessages.PasteAction_cannot_selection;
230             MessageDialog.openError(JavaPlugin.getActiveWorkbenchShell(), ReorgMessages.PasteAction_name, msg);
231         } catch (JavaModelException e) {
232             ExceptionHandler.handle(e, RefactoringMessages.OpenRefactoringWizardAction_refactoring, RefactoringMessages.OpenRefactoringWizardAction_exception);
233         } catch (InvocationTargetException JavaDoc e) {
234             ExceptionHandler.handle(e, RefactoringMessages.OpenRefactoringWizardAction_refactoring, RefactoringMessages.OpenRefactoringWizardAction_exception);
235         } catch (InterruptedException JavaDoc e) {
236             // OK
237
}
238     }
239
240     private abstract static class Paster{
241         private final Shell fShell;
242         private final Clipboard fClipboard2;
243         protected Paster(Shell shell, Clipboard clipboard){
244             fShell= shell;
245             fClipboard2= clipboard;
246         }
247         protected final Shell getShell() {
248             return fShell;
249         }
250         protected final Clipboard getClipboard() {
251             return fClipboard2;
252         }
253
254         protected final IResource[] getClipboardResources(TransferData[] availableDataTypes) {
255             Transfer transfer= ResourceTransfer.getInstance();
256             if (isAvailable(transfer, availableDataTypes)) {
257                 return (IResource[])getContents(fClipboard2, transfer, getShell());
258             }
259             return null;
260         }
261
262         protected final IJavaElement[] getClipboardJavaElements(TransferData[] availableDataTypes) {
263             Transfer transfer= JavaElementTransfer.getInstance();
264             if (isAvailable(transfer, availableDataTypes)) {
265                 return (IJavaElement[])getContents(fClipboard2, transfer, getShell());
266             }
267             return null;
268         }
269     
270         protected final TypedSource[] getClipboardTypedSources(TransferData[] availableDataTypes) {
271             Transfer transfer= TypedSourceTransfer.getInstance();
272             if (isAvailable(transfer, availableDataTypes)) {
273                 return (TypedSource[])getContents(fClipboard2, transfer, getShell());
274             }
275             return null;
276         }
277     
278         protected final String JavaDoc getClipboardText(TransferData[] availableDataTypes) {
279             Transfer transfer= TextTransfer.getInstance();
280             if (isAvailable(transfer, availableDataTypes)) {
281                 return (String JavaDoc) getContents(fClipboard2, transfer, getShell());
282             }
283             return null;
284         }
285
286         /**
287          * Used to be called on selection change, but is only called on execution now
288          * (before {@link #canPasteOn(IJavaElement[], IResource[], IWorkingSet[])}).
289          * @param availableTypes transfer types
290          * @return whether the paste action can be enabled
291          * @throws JavaModelException
292          */

293         public abstract boolean canEnable(TransferData[] availableTypes) throws JavaModelException;
294         
295         /**
296          * Only called if {@link #canEnable(TransferData[])} returns <code>true</code>.
297          * @param selectedJavaElements
298          * @param selectedResources
299          * @param selectedWorkingSets
300          * @return whether the paste action can be enabled
301          * @throws JavaModelException
302          */

303         public abstract boolean canPasteOn(IJavaElement[] selectedJavaElements, IResource[] selectedResources, IWorkingSet[] selectedWorkingSets) throws JavaModelException;
304         
305         /**
306          * only called if {@link #canPasteOn(IJavaElement[], IResource[], IWorkingSet[])} returns <code>true</code>
307          * @param selectedJavaElements
308          * @param selectedResources
309          * @param selectedWorkingSets
310          * @param availableTypes
311          * @throws JavaModelException
312          * @throws InterruptedException
313          * @throws InvocationTargetException
314          */

315         public abstract void paste(IJavaElement[] selectedJavaElements, IResource[] selectedResources, IWorkingSet[] selectedWorkingSets, TransferData[] availableTypes) throws JavaModelException, InterruptedException JavaDoc, InvocationTargetException JavaDoc;
316     }
317     
318     private static class TextPaster extends Paster {
319
320         private static class ParsedCu {
321             private final String JavaDoc fText;
322             private final String JavaDoc fTypeName;
323             private final String JavaDoc fPackageName;
324
325             public static ParsedCu[] parse(IJavaProject javaProject, String JavaDoc text) {
326                 IScanner scanner= ToolFactory.createScanner(false, false, false, false);
327                 scanner.setSource(text.toCharArray());
328                 
329                 ArrayList JavaDoc cus= new ArrayList JavaDoc();
330                 int start= 0;
331                 boolean tokensScanned= false;
332                 int tok;
333                 while (true) {
334                     try {
335                         tok= scanner.getNextToken();
336                     } catch (InvalidInputException e) {
337                         // Handle gracefully to give the ASTParser a chance to recover,
338
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=168691
339
tok= ITerminalSymbols.TokenNameEOF;
340                     }
341                     if (tok == ITerminalSymbols.TokenNamepackage && tokensScanned) {
342                         int packageStart= scanner.getCurrentTokenStartPosition();
343                         ParsedCu cu= parseCu(javaProject, text.substring(start, packageStart));
344                         if (cu != null) {
345                             cus.add(cu);
346                             start= packageStart;
347                         }
348                     } else if (tok == ITerminalSymbols.TokenNameEOF) {
349                         ParsedCu cu= parseCu(javaProject, text.substring(start, text.length()));
350                         if (cu != null) {
351                             cus.add(cu);
352                         }
353                         break;
354                     }
355                     tokensScanned= true;
356                 }
357
358                 return (ParsedCu[]) cus.toArray(new ParsedCu[cus.size()]);
359             }
360             
361             private static ParsedCu parseCu(IJavaProject javaProject, String JavaDoc text) {
362                 String JavaDoc packageName= IPackageFragment.DEFAULT_PACKAGE_NAME;
363                 ASTParser parser= ASTParser.newParser(AST.JLS3);
364                 parser.setProject(javaProject);
365                 parser.setSource(text.toCharArray());
366                 parser.setStatementsRecovery(true);
367                 CompilationUnit unit= (CompilationUnit) parser.createAST(null);
368                 
369                 if (unit == null)
370                     return null;
371                 
372                 int typesCount= unit.types().size();
373                 String JavaDoc typeName= null;
374                 if (typesCount > 0) {
375                     // get first most visible type:
376
int maxVisibility= Modifier.PRIVATE;
377                     for (ListIterator JavaDoc iter= unit.types().listIterator(typesCount); iter.hasPrevious();) {
378                         AbstractTypeDeclaration type= (AbstractTypeDeclaration) iter.previous();
379                         int visibility= JdtFlags.getVisibilityCode(type);
380                         if (! JdtFlags.isHigherVisibility(maxVisibility, visibility)) {
381                             maxVisibility= visibility;
382                             typeName= type.getName().getIdentifier();
383                         }
384                     }
385                 }
386                 if (typeName == null)
387                     return null;
388                 
389                 PackageDeclaration pack= unit.getPackage();
390                 if (pack != null) {
391                     packageName= pack.getName().getFullyQualifiedName();
392                 }
393                 
394                 return new ParsedCu(text, typeName, packageName);
395             }
396             
397             private ParsedCu(String JavaDoc text, String JavaDoc typeName, String JavaDoc packageName) {
398                 fText= text;
399                 fTypeName= typeName;
400                 fPackageName= packageName;
401             }
402
403             public String JavaDoc getTypeName() {
404                 return fTypeName;
405             }
406
407             public String JavaDoc getPackageName() {
408                 return fPackageName;
409             }
410
411             public String JavaDoc getText() {
412                 return fText;
413             }
414         }
415         
416         private IPackageFragmentRoot fDestination;
417         /**
418          * destination pack iff pasted 1 CU to package fragment or compilation unit, <code>null</code> otherwise
419          */

420         private IPackageFragment fDestinationPack;
421         private ParsedCu[] fParsedCus;
422         private TransferData[] fAvailableTypes;
423         
424         protected TextPaster(Shell shell, Clipboard clipboard) {
425             super(shell, clipboard);
426         }
427         
428         public boolean canEnable(TransferData[] availableTypes) {
429             fAvailableTypes= availableTypes;
430             return PasteAction.isAvailable(TextTransfer.getInstance(), availableTypes);
431         }
432
433         public boolean canPasteOn(IJavaElement[] javaElements, IResource[] resources, IWorkingSet[] selectedWorkingSets) throws JavaModelException {
434             if (selectedWorkingSets.length != 0)
435                 return false;
436             if (resources.length != 0)
437                 return false; //alternative: create text file?
438
if (javaElements.length > 1)
439                 return false;
440             
441             String JavaDoc text= getClipboardText(fAvailableTypes);
442             IJavaProject javaProject= null;
443             IJavaElement destination= null;
444             if (javaElements.length == 1) {
445                 destination= javaElements[0];
446                 javaProject= destination.getJavaProject();
447             }
448             fParsedCus= ParsedCu.parse(javaProject, text);
449             
450             if (fParsedCus.length == 0)
451                 return false;
452             
453             if (destination == null)
454                 return true;
455             
456             /*
457              * 1 CU: paste into package, adapt package declaration
458              * 2+ CUs: always paste into source folder
459              */

460             
461             IPackageFragmentRoot packageFragmentRoot;
462             IPackageFragment destinationPack;
463             switch (destination.getElementType()) {
464                 case IJavaElement.JAVA_PROJECT :
465                     IPackageFragmentRoot[] packageFragmentRoots= ((IJavaProject) destination).getPackageFragmentRoots();
466                     for (int i= 0; i < packageFragmentRoots.length; i++) {
467                         packageFragmentRoot= packageFragmentRoots[i];
468                         if (isWritable(packageFragmentRoot)) {
469                             fDestination= packageFragmentRoot;
470                             return true;
471                         }
472                     }
473                     return false;
474                     
475                 case IJavaElement.PACKAGE_FRAGMENT_ROOT :
476                     packageFragmentRoot= (IPackageFragmentRoot) destination;
477                     if (isWritable(packageFragmentRoot)) {
478                         fDestination= packageFragmentRoot;
479                         return true;
480                     }
481                     return false;
482                     
483                 case IJavaElement.PACKAGE_FRAGMENT :
484                     destinationPack= (IPackageFragment) destination;
485                     packageFragmentRoot= (IPackageFragmentRoot) destinationPack.getParent();
486                     if (isWritable(packageFragmentRoot)) {
487                         fDestination= packageFragmentRoot;
488                         if (fParsedCus.length == 1) {
489                             fDestinationPack= destinationPack;
490                         }
491                         return true;
492                     }
493                     return false;
494                     
495                 case IJavaElement.COMPILATION_UNIT :
496                     destinationPack= (IPackageFragment) destination.getParent();
497                     packageFragmentRoot= (IPackageFragmentRoot) destinationPack.getParent();
498                     if (isWritable(packageFragmentRoot)) {
499                         fDestination= packageFragmentRoot;
500                         if (fParsedCus.length == 1) {
501                             fDestinationPack= destinationPack;
502                         }
503                         return true;
504                     }
505                     return false;
506                     
507                 default:
508                     return false;
509             }
510         }
511         
512         private boolean isWritable(IPackageFragmentRoot packageFragmentRoot) {
513             try {
514                 return packageFragmentRoot.exists() && ! packageFragmentRoot.isArchive() && ! packageFragmentRoot.isReadOnly()
515                         && packageFragmentRoot.getKind() == IPackageFragmentRoot.K_SOURCE;
516             } catch (JavaModelException e) {
517                 return false;
518             }
519         }
520
521         public void paste(IJavaElement[] javaElements, IResource[] resources, IWorkingSet[] selectedWorkingSets, TransferData[] availableTypes) throws JavaModelException, InterruptedException JavaDoc, InvocationTargetException JavaDoc{
522             final IEditorPart[] editorPart= new IEditorPart[1];
523             
524             IRunnableWithProgress op= new IRunnableWithProgress() {
525                 private IPath fVMPath;
526                 private String JavaDoc fCompilerCompliance;
527
528                 public void run(IProgressMonitor monitor) throws InvocationTargetException JavaDoc {
529                     
530                     final ArrayList JavaDoc cus= new ArrayList JavaDoc();
531                     try {
532                         JavaCore.run(new IWorkspaceRunnable() {
533                             public void run(IProgressMonitor pm) throws CoreException {
534                                 pm.beginTask("", 1 + fParsedCus.length); //$NON-NLS-1$
535

536                                 if (fDestination == null) {
537                                     fDestination= createNewProject(new SubProgressMonitor(pm, 1));
538                                 } else {
539                                     pm.worked(1);
540                                 }
541                                 IConfirmQuery confirmQuery= new ReorgQueries(getShell()).createYesYesToAllNoNoToAllQuery(ReorgMessages.PasteAction_TextPaster_confirmOverwriting, true, IReorgQueries.CONFIRM_OVERWRITING);
542                                 for (int i= 0; i < fParsedCus.length; i++) {
543                                     if (pm.isCanceled())
544                                         break;
545                                     ICompilationUnit cu= pasteCU(fParsedCus[i], new SubProgressMonitor(pm, 1), confirmQuery);
546                                     if (cu != null)
547                                         cus.add(cu);
548                                 }
549                                 
550                             }
551                         }, monitor);
552                     } catch (OperationCanceledException e) {
553                         // cancelling is fine
554
} catch (CoreException e) {
555                         throw new InvocationTargetException JavaDoc(e);
556                     } finally {
557                         monitor.done();
558                     }
559                     IResource[] cuResources= ResourceUtil.getFiles((ICompilationUnit[]) cus.toArray(new ICompilationUnit[cus.size()]));
560                     SelectionUtil.selectAndReveal(cuResources, PlatformUI.getWorkbench().getActiveWorkbenchWindow());
561                 }
562
563                 private ICompilationUnit pasteCU(ParsedCu parsedCu, SubProgressMonitor pm, IConfirmQuery confirmQuery) throws CoreException, OperationCanceledException {
564                     pm.beginTask("", 4); //$NON-NLS-1$
565
try {
566                         IPackageFragment destinationPack;
567                         if (fDestinationPack != null) {
568                             destinationPack= fDestinationPack;
569                             pm.worked(1);
570                         } else {
571                             String JavaDoc packageName= parsedCu.getPackageName();
572                             destinationPack= fDestination.getPackageFragment(packageName);
573                             if (! destinationPack.exists()) {
574                                 JavaModelUtil.getPackageFragmentRoot(destinationPack).createPackageFragment(packageName, true, new SubProgressMonitor(pm, 1));
575                             } else {
576                                 pm.worked(1);
577                             }
578                         }
579                         
580                         final String JavaDoc cuName= parsedCu.getTypeName() + JavaModelUtil.DEFAULT_CU_SUFFIX;
581                         ICompilationUnit cu= destinationPack.getCompilationUnit(cuName);
582                         boolean alreadyExists= cu.exists();
583                         if (alreadyExists) {
584                             String JavaDoc msg= Messages.format(ReorgMessages.PasteAction_TextPaster_exists, new Object JavaDoc[] {cuName});
585                             boolean overwrite= confirmQuery.confirm(msg);
586                             if (! overwrite)
587                                 return null;
588                             
589                             editorPart[0]= openCu(cu); //Open editor before overwriting to allow undo to restore original package declaration
590
}
591                         
592                         destinationPack.createCompilationUnit(cuName, parsedCu.getText(), true, new SubProgressMonitor(pm, 1));
593                         
594                         if (! alreadyExists) {
595                             editorPart[0]= openCu(cu);
596                         }
597                         if (fDestinationPack != null && ! fDestinationPack.getElementName().equals(parsedCu.getPackageName())) {
598                             if (fDestinationPack.getElementName().length() == 0) {
599                                 removePackageDeclaration(cu);
600                             } else {
601                                 cu.createPackageDeclaration(fDestinationPack.getElementName(), new SubProgressMonitor(pm, 1));
602                             }
603                             if (! alreadyExists && editorPart[0] != null)
604                                 editorPart[0].doSave(new SubProgressMonitor(pm, 1)); //avoid showing error marker due to missing/wrong package declaration
605
else
606                                 pm.worked(1);
607                         } else {
608                             pm.worked(1);
609                         }
610                         return cu;
611                     } finally {
612                         pm.done();
613                     }
614                 }
615
616                 private IPackageFragmentRoot createNewProject(SubProgressMonitor pm) throws CoreException {
617                     pm.beginTask("", 10); //$NON-NLS-1$
618
IProject project;
619                     int i= 1;
620                     do {
621                         String JavaDoc name= Messages.format(ReorgMessages.PasteAction_projectName, i == 1 ? (Object JavaDoc) "" : new Integer JavaDoc(i)); //$NON-NLS-1$
622
project= JavaPlugin.getWorkspace().getRoot().getProject(name);
623                         i++;
624                     } while (project.exists());
625                     
626                     BuildPathsBlock.createProject(project, null, new SubProgressMonitor(pm, 3));
627                     BuildPathsBlock.addJavaNature(project, new SubProgressMonitor(pm, 1));
628                     IJavaProject javaProject= JavaCore.create(project);
629                     
630                     IResource srcFolder;
631                     IPreferenceStore store= PreferenceConstants.getPreferenceStore();
632                     String JavaDoc sourceFolderName= store.getString(PreferenceConstants.SRCBIN_SRCNAME);
633                     if (store.getBoolean(PreferenceConstants.SRCBIN_FOLDERS_IN_NEWPROJ) && sourceFolderName.length() > 0) {
634                         IFolder folder= project.getFolder(sourceFolderName);
635                         if (! folder.exists()) {
636                             folder.create(false, true, new SubProgressMonitor(pm, 1));
637                         }
638                         srcFolder= folder;
639                     } else {
640                         srcFolder= project;
641                     }
642                     
643                     computeLatestVM();
644                     if (fCompilerCompliance != null) {
645                         Map JavaDoc options= javaProject.getOptions(false);
646                         JavaModelUtil.setCompilanceOptions(options, fCompilerCompliance);
647                         JavaModelUtil.setDefaultClassfileOptions(options, fCompilerCompliance);
648                         javaProject.setOptions(options);
649                     }
650                     IClasspathEntry srcEntry= JavaCore.newSourceEntry(srcFolder.getFullPath());
651                     IClasspathEntry jreEntry= JavaCore.newContainerEntry(fVMPath);
652                     IPath outputLocation= BuildPathsBlock.getDefaultOutputLocation(javaProject);
653                     IClasspathEntry[] cpes= new IClasspathEntry[] { srcEntry, jreEntry };
654                     javaProject.setRawClasspath(cpes, outputLocation, new SubProgressMonitor(pm, 1));
655                     return javaProject.getPackageFragmentRoot(srcFolder);
656                 }
657
658                 private void computeLatestVM() {
659                     IVMInstall bestVM= JavaRuntime.getDefaultVMInstall();
660                     String JavaDoc bestVersion= getVMVersion(bestVM);
661                     
662                     IExecutionEnvironmentsManager eeManager= JavaRuntime.getExecutionEnvironmentsManager();
663                     IExecutionEnvironment bestEE= null;
664                     
665                     IExecutionEnvironment[] ees= eeManager.getExecutionEnvironments();
666                     for (int j= 0; j < ees.length; j++) {
667                         IExecutionEnvironment ee= ees[j];
668                         IVMInstall vm= ee.getDefaultVM();
669                         String JavaDoc ver= getVMVersion(vm);
670                         if (ver != null && (bestVersion == null || JavaModelUtil.isVersionLessThan(bestVersion, ver))) {
671                             bestVersion= ver;
672                             bestEE= ee;
673                         }
674                     }
675                     
676                     IVMInstallType[] vmTypes= JavaRuntime.getVMInstallTypes();
677                     for (int i= 0; i < vmTypes.length; i++) {
678                         IVMInstall[] vms= vmTypes[i].getVMInstalls();
679                         for (int j= 0; j < vms.length; j++) {
680                             IVMInstall vm= vms[j];
681                             String JavaDoc ver= getVMVersion(vm);
682                             if (ver != null && (bestVersion == null || JavaModelUtil.isVersionLessThan(bestVersion, ver))) {
683                                 bestVersion= ver;
684                                 bestVM= vm;
685                                 bestEE= null;
686                             }
687                         }
688                     }
689                     
690                     if (bestEE != null) {
691                         fVMPath= JavaRuntime.newJREContainerPath(bestEE);
692                         fCompilerCompliance= bestVersion;
693                     } else if (bestVM != null) {
694                         fVMPath= JavaRuntime.newJREContainerPath(bestVM);
695                         fCompilerCompliance= bestVersion;
696                     } else {
697                         fVMPath= JavaRuntime.newDefaultJREContainerPath();
698                     }
699                 }
700
701                 private String JavaDoc getVMVersion(IVMInstall vm) {
702                     if (vm instanceof IVMInstall2) {
703                         IVMInstall2 vm2= (IVMInstall2) vm;
704                         return JavaModelUtil.getCompilerCompliance(vm2, null);
705                     } else {
706                         return null;
707                     }
708                 }
709
710                 private void removePackageDeclaration(final ICompilationUnit cu) throws JavaModelException, CoreException {
711                     IPackageDeclaration[] packageDeclarations= cu.getPackageDeclarations();
712                     if (packageDeclarations.length != 0) {
713                         ITextFileBuffer buffer= null;
714                         try {
715                             buffer= RefactoringFileBuffers.acquire(cu);
716                             ISourceRange sourceRange= packageDeclarations[0].getSourceRange();
717                             buffer.getDocument().replace(sourceRange.getOffset(), sourceRange.getLength(), ""); //$NON-NLS-1$
718
} catch (BadLocationException e) {
719                             JavaPlugin.log(e);
720                         } finally {
721                             if (buffer != null)
722                                 RefactoringFileBuffers.release(cu);
723                         }
724                     }
725                 }
726             };
727             
728             IRunnableContext context= JavaPlugin.getActiveWorkbenchWindow();
729             if (context == null) {
730                 context= new BusyIndicatorRunnableContext();
731             }
732             //TODO: wrap op in workspace runnable and pass to JavaCore.run(..); take project creation out of UI thread.
733
PlatformUI.getWorkbench().getProgressService().runInUI(context, op, JavaPlugin.getWorkspace().getRoot());
734             
735             if (editorPart[0] != null)
736                 editorPart[0].getEditorSite().getPage().activate(editorPart[0]); //activate editor again, since runInUI restores previous active part
737
}
738
739         private IEditorPart openCu(ICompilationUnit cu) {
740             try {
741                 return JavaUI.openInEditor(cu, true, true);
742             } catch (PartInitException e) {
743                 JavaPlugin.log(e);
744                 return null;
745             } catch (JavaModelException e) {
746                 JavaPlugin.log(e);
747                 return null;
748             }
749         }
750     }
751     
752     private static class WorkingSetPaster extends Paster {
753         protected WorkingSetPaster(Shell shell, Clipboard clipboard) {
754             super(shell, clipboard);
755         }
756         public void paste(IJavaElement[] selectedJavaElements, IResource[] selectedResources, IWorkingSet[] selectedWorkingSets, TransferData[] availableTypes) throws JavaModelException, InterruptedException JavaDoc, InvocationTargetException JavaDoc {
757             IWorkingSet workingSet= selectedWorkingSets[0];
758             Set JavaDoc elements= new HashSet JavaDoc(Arrays.asList(workingSet.getElements()));
759             IJavaElement[] javaElements= getClipboardJavaElements(availableTypes);
760             if (javaElements != null) {
761                 for (int i= 0; i < javaElements.length; i++) {
762                     if (!ReorgUtils.containsElementOrParent(elements, javaElements[i]))
763                         elements.add(javaElements[i]);
764                 }
765             }
766             IResource[] resources= getClipboardResources(availableTypes);
767             if (resources != null) {
768                 List JavaDoc realJavaElements= new ArrayList JavaDoc();
769                 List JavaDoc realResource= new ArrayList JavaDoc();
770                 ReorgUtils.splitIntoJavaElementsAndResources(resources, realJavaElements, realResource);
771                 for (Iterator JavaDoc iter= realJavaElements.iterator(); iter.hasNext();) {
772                     IJavaElement element= (IJavaElement)iter.next();
773                     if (!ReorgUtils.containsElementOrParent(elements, element))
774                         elements.add(element);
775                 }
776                 for (Iterator JavaDoc iter= realResource.iterator(); iter.hasNext();) {
777                     IResource element= (IResource)iter.next();
778                     if (!ReorgUtils.containsElementOrParent(elements, element))
779                         elements.add(element);
780                 }
781             }
782             workingSet.setElements((IAdaptable[])elements.toArray(new IAdaptable[elements.size()]));
783         }
784         public boolean canEnable(TransferData[] availableTypes) throws JavaModelException {
785             return isAvailable(ResourceTransfer.getInstance(), availableTypes) ||
786                 isAvailable(JavaElementTransfer.getInstance(), availableTypes);
787         }
788         public boolean canPasteOn(IJavaElement[] selectedJavaElements, IResource[] selectedResources, IWorkingSet[] selectedWorkingSets) throws JavaModelException {
789             if (selectedResources.length != 0 || selectedJavaElements.length != 0 || selectedWorkingSets.length != 1)
790                 return false;
791             IWorkingSet ws= selectedWorkingSets[0];
792             return !OthersWorkingSetUpdater.ID.equals(ws.getId());
793         }
794     }
795     
796     private static class ProjectPaster extends Paster{
797         
798         protected ProjectPaster(Shell shell, Clipboard clipboard) {
799             super(shell, clipboard);
800         }
801
802         public boolean canEnable(TransferData[] availableDataTypes) {
803             boolean resourceTransfer= isAvailable(ResourceTransfer.getInstance(), availableDataTypes);
804             boolean javaElementTransfer= isAvailable(JavaElementTransfer.getInstance(), availableDataTypes);
805             if (! javaElementTransfer)
806                 return canPasteSimpleProjects(availableDataTypes);
807             if (! resourceTransfer)
808                 return canPasteJavaProjects(availableDataTypes);
809             return canPasteJavaProjects(availableDataTypes) && canPasteSimpleProjects(availableDataTypes);
810         }
811         
812         public void paste(IJavaElement[] javaElements, IResource[] resources, IWorkingSet[] selectedWorkingSets, TransferData[] availableTypes) {
813             pasteProjects(availableTypes);
814         }
815
816         private void pasteProjects(TransferData[] availableTypes) {
817             pasteProjects(getProjectsToPaste(availableTypes));
818         }
819         
820         private void pasteProjects(IProject[] projects){
821             Shell shell= getShell();
822             for (int i = 0; i < projects.length; i++) {
823                 new CopyProjectOperation(shell).copyProject(projects[i]);
824             }
825         }
826         private IProject[] getProjectsToPaste(TransferData[] availableTypes) {
827             IResource[] resources= getClipboardResources(availableTypes);
828             IJavaElement[] javaElements= getClipboardJavaElements(availableTypes);
829             Set JavaDoc result= new HashSet JavaDoc();
830             if (resources != null)
831                 result.addAll(Arrays.asList(resources));
832             if (javaElements != null)
833                 result.addAll(Arrays.asList(ReorgUtils.getNotNulls(ReorgUtils.getResources(javaElements))));
834             Assert.isTrue(result.size() > 0);
835             return (IProject[]) result.toArray(new IProject[result.size()]);
836         }
837
838         public boolean canPasteOn(IJavaElement[] javaElements, IResource[] resources, IWorkingSet[] selectedWorkingSets) {
839             return selectedWorkingSets.length == 0; // Can't paste on working sets here
840
}
841         
842         private boolean canPasteJavaProjects(TransferData[] availableDataTypes) {
843             IJavaElement[] javaElements= getClipboardJavaElements(availableDataTypes);
844             return javaElements != null &&
845                     javaElements.length != 0 &&
846                     ! ReorgUtils.hasElementsNotOfType(javaElements, IJavaElement.JAVA_PROJECT);
847         }
848
849         private boolean canPasteSimpleProjects(TransferData[] availableDataTypes) {
850             IResource[] resources= getClipboardResources(availableDataTypes);
851             if (resources == null || resources.length == 0) return false;
852             for (int i= 0; i < resources.length; i++) {
853                 if (resources[i].getType() != IResource.PROJECT || ! ((IProject)resources[i]).isOpen())
854                     return false;
855             }
856             return true;
857         }
858     }
859     
860     private static class FilePaster extends Paster{
861         protected FilePaster(Shell shell, Clipboard clipboard) {
862             super(shell, clipboard);
863         }
864
865         public void paste(IJavaElement[] javaElements, IResource[] resources, IWorkingSet[] selectedWorkingSets, TransferData[] availableTypes) throws JavaModelException {
866             String JavaDoc[] fileData= getClipboardFiles(availableTypes);
867             if (fileData == null)
868                 return;
869             
870             IContainer container= getAsContainer(getTarget(javaElements, resources));
871             if (container == null)
872                 return;
873                 
874             new CopyFilesAndFoldersOperation(getShell()).copyFiles(fileData, container);
875         }
876         
877         private Object JavaDoc getTarget(IJavaElement[] javaElements, IResource[] resources) {
878             if (javaElements.length + resources.length == 1){
879                 if (javaElements.length == 1)
880                     return javaElements[0];
881                 else
882                     return resources[0];
883             } else
884                 return getCommonParent(javaElements, resources);
885         }
886
887         public boolean canPasteOn(IJavaElement[] javaElements, IResource[] resources, IWorkingSet[] selectedWorkingSets) throws JavaModelException {
888             Object JavaDoc target= getTarget(javaElements, resources);
889             return target != null && canPasteFilesOn(getAsContainer(target)) && selectedWorkingSets.length == 0;
890         }
891
892         public boolean canEnable(TransferData[] availableDataTypes) throws JavaModelException {
893             return isAvailable(FileTransfer.getInstance(), availableDataTypes);
894         }
895                 
896         private boolean canPasteFilesOn(Object JavaDoc target) {
897             boolean isPackageFragment= target instanceof IPackageFragment;
898             boolean isJavaProject= target instanceof IJavaProject;
899             boolean isPackageFragmentRoot= target instanceof IPackageFragmentRoot;
900             boolean isContainer= target instanceof IContainer;
901         
902             if (!(isPackageFragment || isJavaProject || isPackageFragmentRoot || isContainer))
903                 return false;
904
905             if (isContainer) {
906                 return true;
907             } else {
908                 IJavaElement element= (IJavaElement)target;
909                 return !element.isReadOnly();
910             }
911         }
912         
913         private IContainer getAsContainer(Object JavaDoc target) throws JavaModelException{
914             if (target == null)
915                 return null;
916             if (target instanceof IContainer)
917                 return (IContainer)target;
918             if (target instanceof IFile)
919                 return ((IFile)target).getParent();
920             return getAsContainer(((IJavaElement)target).getCorrespondingResource());
921         }
922         
923         private String JavaDoc[] getClipboardFiles(TransferData[] availableDataTypes) {
924             Transfer transfer= FileTransfer.getInstance();
925             if (isAvailable(transfer, availableDataTypes)) {
926                 return (String JavaDoc[])getContents(getClipboard(), transfer, getShell());
927             }
928             return null;
929         }
930         private Object JavaDoc getCommonParent(IJavaElement[] javaElements, IResource[] resources) {
931             return new ParentChecker(resources, javaElements).getCommonParent();
932         }
933     }
934     private static class JavaElementAndResourcePaster extends Paster {
935
936         protected JavaElementAndResourcePaster(Shell shell, Clipboard clipboard) {
937             super(shell, clipboard);
938         }
939
940         private TransferData[] fAvailableTypes;
941
942         public void paste(IJavaElement[] javaElements, IResource[] resources, IWorkingSet[] selectedWorkingSets, TransferData[] availableTypes) throws JavaModelException, InterruptedException JavaDoc, InvocationTargetException JavaDoc{
943             IResource[] clipboardResources= getClipboardResources(availableTypes);
944             if (clipboardResources == null)
945                 clipboardResources= new IResource[0];
946             IJavaElement[] clipboardJavaElements= getClipboardJavaElements(availableTypes);
947             if (clipboardJavaElements == null)
948                 clipboardJavaElements= new IJavaElement[0];
949
950             Object JavaDoc destination= getTarget(javaElements, resources);
951             if (destination instanceof IJavaElement)
952                 ReorgCopyStarter.create(clipboardJavaElements, clipboardResources, (IJavaElement)destination).run(getShell());
953             else if (destination instanceof IResource)
954                 ReorgCopyStarter.create(clipboardJavaElements, clipboardResources, (IResource)destination).run(getShell());
955         }
956
957         private Object JavaDoc getTarget(IJavaElement[] javaElements, IResource[] resources) {
958             if (javaElements.length + resources.length == 1){
959                 if (javaElements.length == 1)
960                     return javaElements[0];
961                 else
962                     return resources[0];
963             } else
964                 return getCommonParent(javaElements, resources);
965         }
966         
967         private Object JavaDoc getCommonParent(IJavaElement[] javaElements, IResource[] resources) {
968             return new ParentChecker(resources, javaElements).getCommonParent();
969         }
970
971         public boolean canPasteOn(IJavaElement[] javaElements, IResource[] resources, IWorkingSet[] selectedWorkingSets) throws JavaModelException {
972             if (selectedWorkingSets.length != 0)
973                 return false;
974             IResource[] clipboardResources= getClipboardResources(fAvailableTypes);
975             if (clipboardResources == null)
976                 clipboardResources= new IResource[0];
977             IJavaElement[] clipboardJavaElements= getClipboardJavaElements(fAvailableTypes);
978             if (clipboardJavaElements == null)
979                 clipboardJavaElements= new IJavaElement[0];
980             Object JavaDoc destination= getTarget(javaElements, resources);
981             if (destination instanceof IJavaElement)
982                 return ReorgCopyStarter.create(clipboardJavaElements, clipboardResources, (IJavaElement)destination) != null;
983             if (destination instanceof IResource)
984                 return ReorgCopyStarter.create(clipboardJavaElements, clipboardResources, (IResource)destination) != null;
985             return false;
986         }
987         
988         public boolean canEnable(TransferData[] availableTypes) {
989             fAvailableTypes= availableTypes;
990             return isAvailable(JavaElementTransfer.getInstance(), availableTypes) || isAvailable(ResourceTransfer.getInstance(), availableTypes);
991         }
992     }
993     
994     private static class TypedSourcePaster extends Paster{
995
996         protected TypedSourcePaster(Shell shell, Clipboard clipboard) {
997             super(shell, clipboard);
998         }
999         private TransferData[] fAvailableTypes;
1000
1001        public boolean canEnable(TransferData[] availableTypes) throws JavaModelException {
1002            fAvailableTypes= availableTypes;
1003            return isAvailable(TypedSourceTransfer.getInstance(), availableTypes);
1004        }
1005
1006        public boolean canPasteOn(IJavaElement[] selectedJavaElements, IResource[] selectedResources, IWorkingSet[] selectedWorkingSets) throws JavaModelException {
1007            if (selectedResources.length != 0 || selectedWorkingSets.length != 0)
1008                return false;
1009            TypedSource[] typedSources= getClipboardTypedSources(fAvailableTypes);
1010            Object JavaDoc destination= getTarget(selectedJavaElements, selectedResources);
1011            if (destination instanceof IJavaElement)
1012                return ReorgTypedSourcePasteStarter.create(typedSources, (IJavaElement)destination) != null;
1013            return false;
1014        }
1015        
1016        public void paste(IJavaElement[] selectedJavaElements, IResource[] selectedResources, IWorkingSet[] selectedWorkingSets, TransferData[] availableTypes) throws JavaModelException, InterruptedException JavaDoc, InvocationTargetException JavaDoc {
1017            TypedSource[] typedSources= getClipboardTypedSources(availableTypes);
1018            IJavaElement destination= getTarget(selectedJavaElements, selectedResources);
1019            ReorgTypedSourcePasteStarter.create(typedSources, destination).run(getShell());
1020        }
1021        
1022        private static IJavaElement getTarget(IJavaElement[] selectedJavaElements, IResource[] selectedResources) {
1023            Assert.isTrue(selectedResources.length == 0);
1024            if (selectedJavaElements.length == 1)
1025                return getAsTypeOrCu(selectedJavaElements[0]);
1026            Object JavaDoc parent= new ParentChecker(selectedResources, selectedJavaElements).getCommonParent();
1027            if (parent instanceof IJavaElement)
1028                return getAsTypeOrCu((IJavaElement)parent);
1029            return null;
1030        }
1031        private static IJavaElement getAsTypeOrCu(IJavaElement element) {
1032            //try to get type first
1033
if (element.getElementType() == IJavaElement.COMPILATION_UNIT || element.getElementType() == IJavaElement.TYPE)
1034                return element;
1035            IJavaElement ancestorType= element.getAncestor(IJavaElement.TYPE);
1036            if (ancestorType != null)
1037                return ancestorType;
1038            return ReorgUtils.getCompilationUnit(element);
1039        }
1040        private static class ReorgTypedSourcePasteStarter {
1041    
1042            private final PasteTypedSourcesRefactoring fPasteRefactoring;
1043
1044            private ReorgTypedSourcePasteStarter(PasteTypedSourcesRefactoring pasteRefactoring) {
1045                Assert.isNotNull(pasteRefactoring);
1046                fPasteRefactoring= pasteRefactoring;
1047            }
1048    
1049            public static ReorgTypedSourcePasteStarter create(TypedSource[] typedSources, IJavaElement destination) {
1050                Assert.isNotNull(typedSources);
1051                Assert.isNotNull(destination);
1052                PasteTypedSourcesRefactoring pasteRefactoring= PasteTypedSourcesRefactoring.create(typedSources);
1053                if (pasteRefactoring == null)
1054                    return null;
1055                if (! pasteRefactoring.setDestination(destination).isOK())
1056                    return null;
1057                return new ReorgTypedSourcePasteStarter(pasteRefactoring);
1058            }
1059
1060            public void run(Shell parent) throws InterruptedException JavaDoc, InvocationTargetException JavaDoc {
1061                IRunnableContext context= new ProgressMonitorDialog(parent);
1062                new RefactoringExecutionHelper(fPasteRefactoring, RefactoringCore.getConditionCheckingFailedSeverity(), RefactoringSaveHelper.SAVE_NOTHING, parent, context).perform(false, false);
1063            }
1064        }
1065        private static class PasteTypedSourcesRefactoring extends Refactoring {
1066            
1067            private final TypedSource[] fSources;
1068            private IJavaElement fDestination;
1069            
1070            static PasteTypedSourcesRefactoring create(TypedSource[] sources){
1071                if (! isAvailable(sources))
1072                    return null;
1073                return new PasteTypedSourcesRefactoring(sources);
1074            }
1075            public RefactoringStatus setDestination(IJavaElement destination) {
1076                fDestination= destination;
1077                if (ReorgUtils.getCompilationUnit(destination) == null)
1078                    return RefactoringStatus.createFatalErrorStatus(ReorgMessages.PasteAction_wrong_destination);
1079                if (! destination.exists())
1080                    return RefactoringStatus.createFatalErrorStatus(ReorgMessages.PasteAction_element_doesnot_exist);
1081                if (! canPasteAll(destination))
1082                    return RefactoringStatus.createFatalErrorStatus(ReorgMessages.PasteAction_invalid_destination);
1083                return new RefactoringStatus();
1084            }
1085            private boolean canPasteAll(IJavaElement destination) {
1086                for (int i= 0; i < fSources.length; i++) {
1087                    if (! canPaste(fSources[i].getType(), destination))
1088                        return false;
1089                }
1090                return true;
1091            }
1092            private static boolean canPaste(int elementType, IJavaElement destination) {
1093                IType ancestorType= getAncestorType(destination);
1094                if (ancestorType != null)
1095                    return canPasteToType(elementType);
1096                return canPasteToCu(elementType);
1097            }
1098            private static boolean canPasteToType(int elementType) {
1099                return elementType == IJavaElement.TYPE ||
1100                        elementType == IJavaElement.FIELD ||
1101                        elementType == IJavaElement.INITIALIZER ||
1102                        elementType == IJavaElement.METHOD;
1103            }
1104            private static boolean canPasteToCu(int elementType) {
1105                return elementType == IJavaElement.PACKAGE_DECLARATION ||
1106                        elementType == IJavaElement.TYPE ||
1107                        elementType == IJavaElement.IMPORT_DECLARATION;
1108            }
1109            PasteTypedSourcesRefactoring(TypedSource[] sources){
1110                Assert.isNotNull(sources);
1111                Assert.isTrue(sources.length != 0);
1112                fSources= sources;
1113            }
1114
1115            private static boolean isAvailable(TypedSource[] sources) {
1116                return sources != null && sources.length > 0;
1117            }
1118
1119            public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException {
1120                return new RefactoringStatus();
1121            }
1122
1123            public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException {
1124                RefactoringStatus result= Checks.validateModifiesFiles(
1125                    ResourceUtil.getFiles(new ICompilationUnit[]{getDestinationCu()}), getValidationContext());
1126                return result;
1127            }
1128
1129            public Change createChange(IProgressMonitor pm) throws CoreException {
1130                ASTParser p= ASTParser.newParser(AST.JLS3);
1131                p.setSource(getDestinationCu());
1132                CompilationUnit cuNode= (CompilationUnit) p.createAST(pm);
1133                ASTRewrite rewrite= ASTRewrite.create(cuNode.getAST());
1134                TypedSource source= null;
1135                for (int i= fSources.length - 1; i >= 0; i--) {
1136                    source= fSources[i];
1137                    final ASTNode destination= getDestinationNodeForSourceElement(fDestination, source.getType(), cuNode);
1138                    if (destination != null) {
1139                        if (destination instanceof CompilationUnit)
1140                            insertToCu(rewrite, createNewNodeToInsertToCu(source, rewrite), (CompilationUnit) destination);
1141                        else if (destination instanceof AbstractTypeDeclaration)
1142                            insertToType(rewrite, createNewNodeToInsertToType(source, rewrite), (AbstractTypeDeclaration) destination);
1143                    }
1144                }
1145                final CompilationUnitChange result= new CompilationUnitChange(ReorgMessages.PasteAction_change_name, getDestinationCu());
1146                try {
1147                    ITextFileBuffer buffer= RefactoringFileBuffers.acquire(getDestinationCu());
1148                    TextEdit rootEdit= rewrite.rewriteAST(buffer.getDocument(), fDestination.getJavaProject().getOptions(true));
1149                    if (getDestinationCu().isWorkingCopy())
1150                        result.setSaveMode(TextFileChange.LEAVE_DIRTY);
1151                    TextChangeCompatibility.addTextEdit(result, ReorgMessages.PasteAction_edit_name, rootEdit);
1152                } finally {
1153                    RefactoringFileBuffers.release(getDestinationCu());
1154                }
1155                return result;
1156            }
1157
1158            private static void insertToType(ASTRewrite rewrite, ASTNode node, AbstractTypeDeclaration typeDeclaration) {
1159                switch (node.getNodeType()) {
1160                    case ASTNode.ANNOTATION_TYPE_DECLARATION:
1161                    case ASTNode.ENUM_DECLARATION:
1162                    case ASTNode.TYPE_DECLARATION:
1163                    case ASTNode.METHOD_DECLARATION:
1164                    case ASTNode.FIELD_DECLARATION:
1165                    case ASTNode.INITIALIZER:
1166                        rewrite.getListRewrite(typeDeclaration, typeDeclaration.getBodyDeclarationsProperty()).insertAt(node, ASTNodes.getInsertionIndex((BodyDeclaration) node, typeDeclaration.bodyDeclarations()), null);
1167                        break;
1168                    default:
1169                        Assert.isTrue(false, String.valueOf(node.getNodeType()));
1170                }
1171            }
1172
1173            private static void insertToCu(ASTRewrite rewrite, ASTNode node, CompilationUnit cuNode) {
1174                switch (node.getNodeType()) {
1175                    case ASTNode.TYPE_DECLARATION:
1176                    case ASTNode.ENUM_DECLARATION:
1177                    case ASTNode.ANNOTATION_TYPE_DECLARATION:
1178                        rewrite.getListRewrite(cuNode, CompilationUnit.TYPES_PROPERTY).insertAt(node, ASTNodes.getInsertionIndex((AbstractTypeDeclaration) node, cuNode.types()), null);
1179                        break;
1180                    case ASTNode.IMPORT_DECLARATION:
1181                        rewrite.getListRewrite(cuNode, CompilationUnit.IMPORTS_PROPERTY).insertLast(node, null);
1182                        break;
1183                    case ASTNode.PACKAGE_DECLARATION:
1184                        // only insert if none exists
1185
if (cuNode.getPackage() == null)
1186                            rewrite.set(cuNode, CompilationUnit.PACKAGE_PROPERTY, node, null);
1187                        break;
1188                    default:
1189                        Assert.isTrue(false, String.valueOf(node.getNodeType()));
1190                }
1191            }
1192
1193            /**
1194             * @return an AbstractTypeDeclaration, a CompilationUnit, or null
1195             */

1196            private ASTNode getDestinationNodeForSourceElement(IJavaElement destination, int kind, CompilationUnit unit) throws JavaModelException {
1197                final IType ancestor= getAncestorType(destination);
1198                if (ancestor != null)
1199                    return ASTNodeSearchUtil.getAbstractTypeDeclarationNode(ancestor, unit);
1200                if (kind == IJavaElement.TYPE || kind == IJavaElement.PACKAGE_DECLARATION || kind == IJavaElement.IMPORT_DECLARATION || kind == IJavaElement.IMPORT_CONTAINER)
1201                    return unit;
1202                return null;
1203            }
1204            
1205            private static IType getAncestorType(IJavaElement destinationElement) {
1206                return destinationElement.getElementType() == IJavaElement.TYPE ? (IType)destinationElement: (IType)destinationElement.getAncestor(IJavaElement.TYPE);
1207            }
1208            private ASTNode createNewNodeToInsertToCu(TypedSource source, ASTRewrite rewrite) {
1209                switch(source.getType()){
1210                    case IJavaElement.TYPE:
1211                        return rewrite.createStringPlaceholder(source.getSource(), ASTNode.TYPE_DECLARATION);
1212                    case IJavaElement.PACKAGE_DECLARATION:
1213                        return rewrite.createStringPlaceholder(source.getSource(), ASTNode.PACKAGE_DECLARATION);
1214                    case IJavaElement.IMPORT_DECLARATION:
1215                        return rewrite.createStringPlaceholder(source.getSource(), ASTNode.IMPORT_DECLARATION);
1216                    default: Assert.isTrue(false, String.valueOf(source.getType()));
1217                        return null;
1218                }
1219            }
1220            
1221            private ASTNode createNewNodeToInsertToType(TypedSource source, ASTRewrite rewrite) {
1222                switch(source.getType()){
1223                    case IJavaElement.TYPE:
1224                        return rewrite.createStringPlaceholder(source.getSource(), ASTNode.TYPE_DECLARATION);
1225                    case IJavaElement.METHOD:
1226                        return rewrite.createStringPlaceholder(source.getSource(), ASTNode.METHOD_DECLARATION);
1227                    case IJavaElement.FIELD:
1228                        return rewrite.createStringPlaceholder(source.getSource(), ASTNode.FIELD_DECLARATION);
1229                    case IJavaElement.INITIALIZER:
1230                        return rewrite.createStringPlaceholder(source.getSource(), ASTNode.INITIALIZER);
1231                    default: Assert.isTrue(false);
1232                        return null;
1233                }
1234            }
1235            
1236            private ICompilationUnit getDestinationCu() {
1237                return ReorgUtils.getCompilationUnit(fDestination);
1238            }
1239
1240            public String JavaDoc getName() {
1241                return ReorgMessages.PasteAction_name;
1242            }
1243        }
1244    }
1245}
1246
Popular Tags