KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > refactoring > rename > RenamePackageProcessor


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.corext.refactoring.rename;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Arrays JavaDoc;
15 import java.util.Collection JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.HashSet JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.List JavaDoc;
20 import java.util.Set JavaDoc;
21 import java.util.Map.Entry;
22
23 import org.eclipse.text.edits.MalformedTreeException;
24 import org.eclipse.text.edits.ReplaceEdit;
25 import org.eclipse.text.edits.TextEdit;
26
27 import org.eclipse.core.runtime.Assert;
28 import org.eclipse.core.runtime.CoreException;
29 import org.eclipse.core.runtime.IPath;
30 import org.eclipse.core.runtime.IProgressMonitor;
31 import org.eclipse.core.runtime.SubProgressMonitor;
32
33 import org.eclipse.core.resources.IContainer;
34 import org.eclipse.core.resources.IFile;
35 import org.eclipse.core.resources.IFolder;
36 import org.eclipse.core.resources.IResource;
37
38 import org.eclipse.ltk.core.refactoring.Change;
39 import org.eclipse.ltk.core.refactoring.CompositeChange;
40 import org.eclipse.ltk.core.refactoring.IResourceMapper;
41 import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
42 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
43 import org.eclipse.ltk.core.refactoring.RefactoringStatusContext;
44 import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
45 import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments;
46 import org.eclipse.ltk.core.refactoring.participants.RenameArguments;
47
48 import org.eclipse.jdt.core.Flags;
49 import org.eclipse.jdt.core.IClassFile;
50 import org.eclipse.jdt.core.ICompilationUnit;
51 import org.eclipse.jdt.core.IImportDeclaration;
52 import org.eclipse.jdt.core.IJavaElement;
53 import org.eclipse.jdt.core.IJavaProject;
54 import org.eclipse.jdt.core.IMethod;
55 import org.eclipse.jdt.core.IPackageFragment;
56 import org.eclipse.jdt.core.IPackageFragmentRoot;
57 import org.eclipse.jdt.core.IType;
58 import org.eclipse.jdt.core.JavaModelException;
59 import org.eclipse.jdt.core.Signature;
60 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
61 import org.eclipse.jdt.core.refactoring.IJavaElementMapper;
62 import org.eclipse.jdt.core.refactoring.IJavaRefactorings;
63 import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor;
64 import org.eclipse.jdt.core.refactoring.descriptors.RenameJavaElementDescriptor;
65 import org.eclipse.jdt.core.search.IJavaSearchConstants;
66 import org.eclipse.jdt.core.search.IJavaSearchScope;
67 import org.eclipse.jdt.core.search.SearchEngine;
68 import org.eclipse.jdt.core.search.SearchMatch;
69 import org.eclipse.jdt.core.search.SearchPattern;
70 import org.eclipse.jdt.core.search.SearchRequestor;
71
72 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
73 import org.eclipse.jdt.internal.corext.refactoring.Checks;
74 import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptor;
75 import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment;
76 import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments;
77 import org.eclipse.jdt.internal.corext.refactoring.RefactoringAvailabilityTester;
78 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
79 import org.eclipse.jdt.internal.corext.refactoring.RefactoringScopeFactory;
80 import org.eclipse.jdt.internal.corext.refactoring.RefactoringSearchEngine;
81 import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup;
82 import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;
83 import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange;
84 import org.eclipse.jdt.internal.corext.refactoring.changes.RenamePackageChange;
85 import org.eclipse.jdt.internal.corext.refactoring.changes.TextChangeCompatibility;
86 import org.eclipse.jdt.internal.corext.refactoring.code.ScriptableRefactoring;
87 import org.eclipse.jdt.internal.corext.refactoring.participants.JavaProcessors;
88 import org.eclipse.jdt.internal.corext.refactoring.rename.RenamePackageProcessor.ImportsManager.ImportChange;
89 import org.eclipse.jdt.internal.corext.refactoring.tagging.IQualifiedNameUpdating;
90 import org.eclipse.jdt.internal.corext.refactoring.tagging.IReferenceUpdating;
91 import org.eclipse.jdt.internal.corext.refactoring.tagging.ITextUpdating;
92 import org.eclipse.jdt.internal.corext.refactoring.util.Changes;
93 import org.eclipse.jdt.internal.corext.refactoring.util.CommentAnalyzer;
94 import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil;
95 import org.eclipse.jdt.internal.corext.refactoring.util.QualifiedNameFinder;
96 import org.eclipse.jdt.internal.corext.refactoring.util.QualifiedNameSearchResult;
97 import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil;
98 import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager;
99 import org.eclipse.jdt.internal.corext.util.Messages;
100 import org.eclipse.jdt.internal.corext.util.Resources;
101 import org.eclipse.jdt.internal.corext.util.SearchUtils;
102
103 import org.eclipse.jdt.internal.ui.JavaPlugin;
104 import org.eclipse.jdt.internal.ui.refactoring.RefactoringSaveHelper;
105
106 public class RenamePackageProcessor extends JavaRenameProcessor implements
107         IReferenceUpdating, ITextUpdating, IQualifiedNameUpdating, IResourceMapper, IJavaElementMapper {
108     
109     private static final String JavaDoc ATTRIBUTE_QUALIFIED= "qualified"; //$NON-NLS-1$
110
private static final String JavaDoc ATTRIBUTE_TEXTUAL_MATCHES= "textual"; //$NON-NLS-1$
111
private static final String JavaDoc ATTRIBUTE_PATTERNS= "patterns"; //$NON-NLS-1$
112
private static final String JavaDoc ATTRIBUTE_HIERARCHICAL= "hierarchical"; //$NON-NLS-1$
113

114     private IPackageFragment fPackage;
115     
116     private TextChangeManager fChangeManager;
117     private ImportsManager fImportsManager;
118     private QualifiedNameSearchResult fQualifiedNameSearchResult;
119     
120     private boolean fUpdateReferences;
121     private boolean fUpdateTextualMatches;
122     private boolean fUpdateQualifiedNames;
123     private String JavaDoc fFilePatterns;
124     private boolean fRenameSubpackages;
125
126     public static final String JavaDoc IDENTIFIER= "org.eclipse.jdt.ui.renamePackageProcessor"; //$NON-NLS-1$
127
private RenamePackageChange fRenamePackageChange;
128
129     /**
130      * Creates a new rename package processor.
131      * @param fragment the package fragment, or <code>null</code> if invoked by scripting
132      */

133     public RenamePackageProcessor(IPackageFragment fragment) {
134         fPackage= fragment;
135         if (fPackage != null)
136             setNewElementName(fPackage.getElementName());
137         fUpdateReferences= true;
138         fUpdateTextualMatches= false;
139         fRenameSubpackages= false;
140     }
141
142     public String JavaDoc getIdentifier() {
143         return IDENTIFIER;
144     }
145     
146     public boolean isApplicable() throws CoreException {
147         return RefactoringAvailabilityTester.isRenameAvailable(fPackage);
148     }
149     
150     public String JavaDoc getProcessorName(){
151         return RefactoringCoreMessages.RenamePackageRefactoring_name;
152     }
153     
154     protected String JavaDoc[] getAffectedProjectNatures() throws CoreException {
155         return JavaProcessors.computeAffectedNatures(fPackage);
156     }
157     
158     public Object JavaDoc[] getElements() {
159         return new Object JavaDoc[] {fPackage};
160     }
161     
162     protected RenameModifications computeRenameModifications() throws CoreException {
163         RenameModifications result= new RenameModifications();
164         result.rename(fPackage, new RenameArguments(getNewElementName(), getUpdateReferences()), fRenameSubpackages);
165         return result;
166     }
167     
168     protected IFile[] getChangedFiles() throws CoreException {
169         Set JavaDoc combined= new HashSet JavaDoc();
170         combined.addAll(Arrays.asList(ResourceUtil.getFiles(fChangeManager.getAllCompilationUnits())));
171         if (fRenameSubpackages) {
172             IPackageFragment[] allPackages= JavaElementUtil.getPackageAndSubpackages(fPackage);
173             for (int i= 0; i < allPackages.length; i++) {
174                 combined.addAll(Arrays.asList(ResourceUtil.getFiles(allPackages[i].getCompilationUnits())));
175             }
176         } else {
177             combined.addAll(Arrays.asList(ResourceUtil.getFiles(fPackage.getCompilationUnits())));
178         }
179         if (fQualifiedNameSearchResult != null)
180             combined.addAll(Arrays.asList(fQualifiedNameSearchResult.getAllFiles()));
181         return (IFile[]) combined.toArray(new IFile[combined.size()]);
182     }
183     
184     public int getSaveMode() {
185         return RefactoringSaveHelper.SAVE_ALL;
186     }
187     
188     //---- ITextUpdating -------------------------------------------------
189

190     public boolean canEnableTextUpdating() {
191         return true;
192     }
193     
194     public boolean getUpdateTextualMatches() {
195         return fUpdateTextualMatches;
196     }
197
198     public void setUpdateTextualMatches(boolean update) {
199         fUpdateTextualMatches= update;
200     }
201
202     //---- IReferenceUpdating --------------------------------------
203

204     public boolean canEnableUpdateReferences() {
205         return true;
206     }
207
208     public void setUpdateReferences(boolean update) {
209         fUpdateReferences= update;
210     }
211     
212     public boolean getUpdateReferences(){
213         return fUpdateReferences;
214     }
215     
216     //---- IQualifiedNameUpdating ----------------------------------
217

218     public boolean canEnableQualifiedNameUpdating() {
219         return !fPackage.isDefaultPackage();
220     }
221     
222     public boolean getUpdateQualifiedNames() {
223         return fUpdateQualifiedNames;
224     }
225     
226     public void setUpdateQualifiedNames(boolean update) {
227         fUpdateQualifiedNames= update;
228     }
229     
230     public String JavaDoc getFilePatterns() {
231         return fFilePatterns;
232     }
233     
234     public void setFilePatterns(String JavaDoc patterns) {
235         Assert.isNotNull(patterns);
236         fFilePatterns= patterns;
237     }
238     
239     //---- IResourceMapper ----------------------------------
240

241     public IResource getRefactoredResource(IResource element) {
242         IFolder packageFolder= (IFolder) fPackage.getResource();
243         if (packageFolder == null)
244             return element;
245         
246         IContainer newPackageFolder= (IContainer) getNewPackage().getResource();
247         
248         if (packageFolder.equals(element))
249             return newPackageFolder;
250         
251         IPath packagePath= packageFolder.getProjectRelativePath();
252         IPath elementPath= element.getProjectRelativePath();
253         
254         if (packagePath.isPrefixOf(elementPath)) {
255             if (fRenameSubpackages || (element instanceof IFile && packageFolder.equals(element.getParent()))) {
256                 IPath pathInPackage= elementPath.removeFirstSegments(packagePath.segmentCount());
257                 if (element instanceof IFile)
258                     return newPackageFolder.getFile(pathInPackage);
259                 else
260                     return newPackageFolder.getFolder(pathInPackage);
261             }
262         }
263         return element;
264     }
265     
266     //---- IJavaElementMapper ----------------------------------
267

268     public IJavaElement getRefactoredJavaElement(IJavaElement element) {
269         return new GenericRefactoringHandleTransplanter() {
270             protected IPackageFragment transplantHandle(IPackageFragmentRoot parent, IPackageFragment element) {
271                 if (! fRenameSubpackages) {
272                     if (fPackage.equals(element))
273                         return getNewPackage();
274                 } else {
275                     String JavaDoc packName= element.getElementName();
276                     String JavaDoc packageName= fPackage.getElementName();
277                     if (fPackage.getParent().equals(parent)
278                             && packName.startsWith(packageName + '.')) {
279                         String JavaDoc newPackName= getNewElementName() + packName.substring(packageName.length() - 1);
280                         return getPackageFragmentRoot().getPackageFragment(newPackName);
281                     }
282                 }
283                 return super.transplantHandle(parent, element);
284             }
285             
286             protected IMethod transplantHandle(IType parent, IMethod element) {
287                 String JavaDoc[] parameterTypes= resolveParameterTypes(element);
288                 return parent.getMethod(element.getElementName(), parameterTypes);
289             }
290             
291             private String JavaDoc[] resolveParameterTypes(IMethod method) {
292                 final String JavaDoc[] oldParameterTypes= method.getParameterTypes();
293                 final String JavaDoc[] newparams= new String JavaDoc[oldParameterTypes.length];
294
295                 final String JavaDoc[] possibleOldSigs= new String JavaDoc[2];
296                 //using type signature, since there is no package signature
297
possibleOldSigs[0]= Signature.createTypeSignature(fPackage.getElementName(), false);
298                 possibleOldSigs[1]= Signature.createTypeSignature(fPackage.getElementName(), true);
299
300                 final String JavaDoc[] possibleNewSigs= new String JavaDoc[2];
301                 possibleNewSigs[0]= Signature.createTypeSignature(getNewElementName(), false);
302                 possibleNewSigs[1]= Signature.createTypeSignature(getNewElementName(), true);
303
304                 // Textually replace all occurrences
305
// This handles stuff like Map<SomeClass, some.package.SomeClass>
306
for (int i= 0; i < oldParameterTypes.length; i++) {
307                     newparams[i]= oldParameterTypes[i];
308                     for (int j= 0; j < possibleOldSigs.length; j++) {
309                         newparams[i]= replaceAll(newparams[i], possibleOldSigs[j], possibleNewSigs[j]);
310                     }
311                 }
312                 return newparams;
313             }
314             
315             private String JavaDoc replaceAll(final String JavaDoc source, final String JavaDoc replaceFrom, final String JavaDoc replaceTo) {
316                 final StringBuffer JavaDoc buf= new StringBuffer JavaDoc(source.length());
317                 int currentIndex= 0;
318                 int matchIndex;
319                 while ((matchIndex= source.indexOf(replaceFrom, currentIndex)) != -1) {
320                     buf.append(source.substring(currentIndex, matchIndex));
321                     buf.append(replaceTo);
322                     currentIndex= matchIndex + replaceFrom.length();
323                 }
324                 buf.append(source.substring(currentIndex));
325                 return buf.toString();
326             }
327         }.transplantHandle(element);
328     }
329
330     //----
331

332     public boolean canEnableRenameSubpackages() throws JavaModelException {
333         return fPackage.hasSubpackages();
334     }
335     
336     public boolean getRenameSubpackages() {
337         return fRenameSubpackages;
338     }
339
340     public void setRenameSubpackages(boolean rename) {
341         fRenameSubpackages= rename;
342     }
343     
344     //---- IRenameProcessor ----------------------------------------------
345

346     public final String JavaDoc getCurrentElementName(){
347         return fPackage.getElementName();
348     }
349     
350     public String JavaDoc getCurrentElementQualifier() {
351         return ""; //$NON-NLS-1$
352
}
353     
354     public RefactoringStatus checkNewElementName(String JavaDoc newName) throws CoreException {
355         Assert.isNotNull(newName, "new name"); //$NON-NLS-1$
356
RefactoringStatus result= Checks.checkPackageName(newName);
357         if (result.hasFatalError())
358             return result;
359         if (Checks.isAlreadyNamed(fPackage, newName)) {
360             result.addFatalError(RefactoringCoreMessages.RenamePackageRefactoring_another_name);
361             return result;
362         }
363         result.merge(checkPackageInCurrentRoot(newName));
364         return result;
365     }
366     
367     public Object JavaDoc getNewElement(){
368         return getNewPackage();
369     }
370
371     private IPackageFragment getNewPackage() {
372         IPackageFragmentRoot root= getPackageFragmentRoot();
373         return root.getPackageFragment(getNewElementName());
374     }
375     
376     public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException {
377         return new RefactoringStatus();
378     }
379     
380     protected RefactoringStatus doCheckFinalConditions(IProgressMonitor pm, CheckConditionsContext context) throws CoreException {
381         try{
382             pm.beginTask("", 23 + (fUpdateQualifiedNames ? 10 : 0) + (fUpdateTextualMatches ? 10 : 0)); //$NON-NLS-1$
383
pm.setTaskName(RefactoringCoreMessages.RenamePackageRefactoring_checking);
384             RefactoringStatus result= new RefactoringStatus();
385             result.merge(checkNewElementName(getNewElementName()));
386             pm.worked(1);
387             result.merge(checkForMainAndNativeMethods());
388             pm.worked(2);
389             
390             if (fPackage.isReadOnly()){
391                 String JavaDoc message= Messages.format(RefactoringCoreMessages.RenamePackageRefactoring_Packagered_only, fPackage.getElementName());
392                 result.addFatalError(message);
393             } else if (Resources.isReadOnly(fPackage.getResource())) {
394                 String JavaDoc message= Messages.format(RefactoringCoreMessages.RenamePackageRefactoring_resource_read_only, fPackage.getElementName());
395                 result.addError(message);
396             }
397                 
398             result.merge(checkPackageName(getNewElementName()));
399             if (result.hasFatalError())
400                 return result;
401             
402             fChangeManager= new TextChangeManager();
403             fImportsManager= new ImportsManager();
404             
405             SubProgressMonitor subPm= new SubProgressMonitor(pm, 16);
406             if (fRenameSubpackages) {
407                 IPackageFragment[] allSubpackages= JavaElementUtil.getPackageAndSubpackages(fPackage);
408                 subPm.beginTask("", allSubpackages.length); //$NON-NLS-1$
409
for (int i= 0; i < allSubpackages.length; i++) {
410                     new PackageRenamer(allSubpackages[i], this, fChangeManager, fImportsManager).doRename(new SubProgressMonitor(subPm, 1), result);
411                 }
412                 subPm.done();
413             } else {
414                 new PackageRenamer(fPackage, this, fChangeManager, fImportsManager).doRename(subPm, result);
415             }
416             
417             fImportsManager.rewriteImports(fChangeManager, new SubProgressMonitor(pm, 3));
418             
419             if (fUpdateTextualMatches) {
420                 pm.subTask(RefactoringCoreMessages.RenamePackageRefactoring_searching_text);
421                 TextMatchUpdater.perform(new SubProgressMonitor(pm, 10), RefactoringScopeFactory.create(fPackage), this, fChangeManager, new SearchResultGroup[0]);
422             }
423
424             if (fUpdateQualifiedNames)
425                 computeQualifiedNameMatches(new SubProgressMonitor(pm, 10));
426             
427             return result;
428         } finally{
429             pm.done();
430         }
431     }
432     
433     public IPackageFragment getPackage() {
434         return fPackage;
435     }
436     
437     private RefactoringStatus checkForMainAndNativeMethods() throws CoreException{
438         RefactoringStatus result= new RefactoringStatus();
439         if (fRenameSubpackages) {
440             IPackageFragment[] allSubpackages= JavaElementUtil.getPackageAndSubpackages(fPackage);
441             for (int i= 0; i < allSubpackages.length; i++) {
442                 ICompilationUnit[] cus= allSubpackages[i].getCompilationUnits();
443                 for (int c= 0; c < cus.length; c++)
444                     result.merge(Checks.checkForMainAndNativeMethods(cus[c]));
445             }
446         } else {
447             ICompilationUnit[] cus= fPackage.getCompilationUnits();
448             for (int i= 0; i < cus.length; i++)
449                 result.merge(Checks.checkForMainAndNativeMethods(cus[i]));
450         }
451         return result;
452     }
453     
454     /*
455      * returns true if the new name is ok if the specified root.
456      * if a package fragment with this name exists and has java resources,
457      * then the name is not ok.
458      */

459     public static boolean isPackageNameOkInRoot(String JavaDoc newName, IPackageFragmentRoot root) throws CoreException {
460         IPackageFragment pack= root.getPackageFragment(newName);
461         if (! pack.exists())
462             return true;
463         else if (pack.containsJavaResources())
464             return false;
465         else if (pack.getNonJavaResources().length != 0)
466             return false;
467         else
468             return true;
469     }
470     
471     private RefactoringStatus checkPackageInCurrentRoot(String JavaDoc newName) throws CoreException {
472         if (fRenameSubpackages) {
473             String JavaDoc currentName= getCurrentElementName();
474             if (isAncestorPackage(currentName, newName)) {
475                 // renaming to subpackage (a -> a.b) is always OK, since all subpackages are also renamed
476
return null;
477             }
478             if (! isAncestorPackage(newName, currentName)) {
479                 // renaming to an unrelated package
480
if (! isPackageNameOkInRoot(newName, getPackageFragmentRoot())) {
481                     return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.RenamePackageRefactoring_package_exists);
482                 }
483             }
484             // renaming to superpackage (a.b -> a) or another package is OK iff
485
// 'a.b' does not contain any subpackage that would collide with another subpackage of 'a'
486
// (e.g. a.b.c collides if a.c already exists, but a.b.b does not collide with a.b)
487
IPackageFragment[] packsToRename= JavaElementUtil.getPackageAndSubpackages(fPackage);
488             for (int i = 0; i < packsToRename.length; i++) {
489                 IPackageFragment pack = packsToRename[i];
490                 String JavaDoc newPack= newName + pack.getElementName().substring(currentName.length());
491                 if (! isAncestorPackage(currentName, newPack) && ! isPackageNameOkInRoot(newPack, getPackageFragmentRoot())) {
492                     String JavaDoc msg= Messages.format(RefactoringCoreMessages.RenamePackageProcessor_subpackage_collides, newPack);
493                     return RefactoringStatus.createFatalErrorStatus(msg);
494                 }
495             }
496             return null;
497             
498         } else if (! isPackageNameOkInRoot(newName, getPackageFragmentRoot())) {
499             return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.RenamePackageRefactoring_package_exists);
500         } else {
501             return null;
502         }
503     }
504
505     private boolean isAncestorPackage(String JavaDoc ancestor, String JavaDoc descendant) {
506         int a= ancestor.length();
507         int d= descendant.length();
508         if (a == d || (a < d && descendant.charAt(a) == '.'))
509             return descendant.startsWith(ancestor);
510         else
511             return false;
512     }
513
514     private IPackageFragmentRoot getPackageFragmentRoot() {
515         return ((IPackageFragmentRoot)fPackage.getParent());
516     }
517     
518     private RefactoringStatus checkPackageName(String JavaDoc newName) throws CoreException {
519         RefactoringStatus status= new RefactoringStatus();
520         IPackageFragmentRoot[] roots= fPackage.getJavaProject().getPackageFragmentRoots();
521         Set JavaDoc topLevelTypeNames= getTopLevelTypeNames();
522         for (int i= 0; i < roots.length; i++) {
523             if (! isPackageNameOkInRoot(newName, roots[i])){
524                 String JavaDoc message= Messages.format(RefactoringCoreMessages.RenamePackageRefactoring_aleady_exists, new Object JavaDoc[]{getNewElementName(), roots[i].getElementName()});
525                 status.merge(RefactoringStatus.createWarningStatus(message));
526                 status.merge(checkTypeNameConflicts(roots[i], newName, topLevelTypeNames));
527             }
528         }
529         return status;
530     }
531     
532     private Set JavaDoc getTopLevelTypeNames() throws CoreException {
533         ICompilationUnit[] cus= fPackage.getCompilationUnits();
534         Set JavaDoc result= new HashSet JavaDoc(2 * cus.length);
535         for (int i= 0; i < cus.length; i++) {
536             result.addAll(getTopLevelTypeNames(cus[i]));
537         }
538         return result;
539     }
540     
541     private static Collection JavaDoc getTopLevelTypeNames(ICompilationUnit iCompilationUnit) throws CoreException {
542         IType[] types= iCompilationUnit.getTypes();
543         List JavaDoc result= new ArrayList JavaDoc(types.length);
544         for (int i= 0; i < types.length; i++) {
545             result.add(types[i].getElementName());
546         }
547         return result;
548     }
549     
550     private RefactoringStatus checkTypeNameConflicts(IPackageFragmentRoot root, String JavaDoc newName, Set JavaDoc topLevelTypeNames) throws CoreException {
551         IPackageFragment otherPack= root.getPackageFragment(newName);
552         if (fPackage.equals(otherPack))
553             return null;
554         ICompilationUnit[] cus= otherPack.getCompilationUnits();
555         RefactoringStatus result= new RefactoringStatus();
556         for (int i= 0; i < cus.length; i++) {
557             result.merge(checkTypeNameConflicts(cus[i], topLevelTypeNames));
558         }
559         return result;
560     }
561     
562     private RefactoringStatus checkTypeNameConflicts(ICompilationUnit iCompilationUnit, Set JavaDoc topLevelTypeNames) throws CoreException {
563         RefactoringStatus result= new RefactoringStatus();
564         IType[] types= iCompilationUnit.getTypes();
565         String JavaDoc packageName= iCompilationUnit.getParent().getElementName();
566         for (int i= 0; i < types.length; i++) {
567             String JavaDoc name= types[i].getElementName();
568             if (topLevelTypeNames.contains(name)){
569                 String JavaDoc[] keys= {packageName, name};
570                 String JavaDoc msg= Messages.format(RefactoringCoreMessages.RenamePackageRefactoring_contains_type, keys);
571                 RefactoringStatusContext context= JavaStatusContext.create(types[i]);
572                 result.addError(msg, context);
573             }
574         }
575         return result;
576     }
577
578     public Change createChange(IProgressMonitor monitor) throws CoreException {
579         try {
580             monitor.beginTask(RefactoringCoreMessages.RenamePackageRefactoring_creating_change, 1);
581             final RenameJavaElementDescriptor descriptor= createRefactoringDescriptor();
582             final DynamicValidationRefactoringChange result= new DynamicValidationRefactoringChange(descriptor, RefactoringCoreMessages.RenamePackageRefactoring_change_name);
583             result.addAll(fChangeManager.getAllChanges());
584             fRenamePackageChange= new RenamePackageChange( fPackage, getNewElementName(), fRenameSubpackages);
585             result.add(fRenamePackageChange);
586             monitor.worked(1);
587             return result;
588         } finally {
589             fChangeManager= null;
590             fImportsManager= null;
591             monitor.done();
592         }
593     }
594
595     private RenameJavaElementDescriptor createRefactoringDescriptor() {
596         String JavaDoc project= null;
597         IJavaProject javaProject= fPackage.getJavaProject();
598         if (javaProject != null)
599             project= javaProject.getElementName();
600         final int flags= JavaRefactoringDescriptor.JAR_MIGRATION | JavaRefactoringDescriptor.JAR_REFACTORING | RefactoringDescriptor.STRUCTURAL_CHANGE | RefactoringDescriptor.MULTI_CHANGE;
601         final String JavaDoc description= Messages.format(RefactoringCoreMessages.RenamePackageProcessor_descriptor_description_short, fPackage.getElementName());
602         final String JavaDoc header= Messages.format(RefactoringCoreMessages.RenamePackageProcessor_descriptor_description, new String JavaDoc[] { fPackage.getElementName(), getNewElementName()});
603         final JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(project, this, header);
604         if (fRenameSubpackages)
605             comment.addSetting(RefactoringCoreMessages.RenamePackageProcessor_rename_subpackages);
606         final RenameJavaElementDescriptor descriptor= new RenameJavaElementDescriptor(IJavaRefactorings.RENAME_PACKAGE);
607         descriptor.setProject(project);
608         descriptor.setDescription(description);
609         descriptor.setComment(comment.asString());
610         descriptor.setFlags(flags);
611         descriptor.setJavaElement(fPackage);
612         descriptor.setNewName(getNewElementName());
613         descriptor.setUpdateReferences(fUpdateReferences);
614         descriptor.setUpdateTextualOccurrences(fUpdateTextualMatches);
615         descriptor.setUpdateQualifiedNames(fUpdateQualifiedNames);
616         if (fUpdateQualifiedNames && fFilePatterns != null && !"".equals(fFilePatterns)) //$NON-NLS-1$
617
descriptor.setFileNamePatterns(fFilePatterns);
618         descriptor.setUpdateHierarchy(fRenameSubpackages);
619         return descriptor;
620     }
621
622     public Change postCreateChange(Change[] participantChanges, IProgressMonitor pm) throws CoreException {
623         if (fQualifiedNameSearchResult != null) {
624             CompositeChange parent= (CompositeChange) fRenamePackageChange.getParent();
625             try {
626                 /*
627                  * Sneak text changes in before the package rename to ensure
628                  * modified files are still at original location (see
629                  * https://bugs.eclipse.org/bugs/show_bug.cgi?id=154238)
630                  */

631                 parent.remove(fRenamePackageChange);
632                 parent.add(fQualifiedNameSearchResult.getSingleChange(Changes.getModifiedFiles(participantChanges)));
633             } finally {
634                 fQualifiedNameSearchResult= null;
635                 parent.add(fRenamePackageChange);
636                 fRenamePackageChange= null;
637             }
638         }
639         return null;
640     }
641     
642     private void computeQualifiedNameMatches(IProgressMonitor pm) throws CoreException {
643         if (fQualifiedNameSearchResult == null)
644             fQualifiedNameSearchResult= new QualifiedNameSearchResult();
645         QualifiedNameFinder.process(fQualifiedNameSearchResult, fPackage.getElementName(), getNewElementName(),
646             fFilePatterns, fPackage.getJavaProject().getProject(), pm);
647     }
648
649     public String JavaDoc getNewPackageName(String JavaDoc oldSubPackageName) {
650         String JavaDoc oldPackageName= getPackage().getElementName();
651         return getNewElementName() + oldSubPackageName.substring(oldPackageName.length());
652     }
653     
654     private static class PackageRenamer {
655         private final IPackageFragment fPackage;
656         private final RenamePackageProcessor fProcessor;
657         private final TextChangeManager fTextChangeManager;
658         private final ImportsManager fImportsManager;
659         
660         /** references to fPackage (can include star imports which also import namesake package fragments) */
661         private SearchResultGroup[] fOccurrences;
662         
663         /** References in CUs from fOccurrences and fPackage to types in namesake packages.
664          * <p>These need an import with the old package name.
665          * <p>- from fOccurrences (without namesakes): may have shared star import
666          * (star-import not updated here, but for fOccurrences)
667          * <p>- from fPackage: may have unimported references to types of namesake packages
668          * <p>- both: may have unused imports of namesake packages.
669          * <p>Mutable List of SearchResultGroup. */

670         private List JavaDoc fReferencesToTypesInNamesakes;
671     
672         /** References in CUs from namesake packages to types in fPackage.
673          * <p>These need an import with the new package name.
674          * <p>Mutable List of SearchResultGroup. */

675         private List JavaDoc fReferencesToTypesInPackage;
676         
677         public PackageRenamer(IPackageFragment pack, RenamePackageProcessor processor, TextChangeManager textChangeManager, ImportsManager importsManager) {
678             fPackage= pack;
679             fProcessor= processor;
680             fTextChangeManager= textChangeManager;
681             fImportsManager= importsManager;
682         }
683     
684         void doRename(IProgressMonitor pm, RefactoringStatus result) throws CoreException {
685             pm.beginTask("", 16); //$NON-NLS-1$
686
if (fProcessor.getUpdateReferences()){
687                 pm.setTaskName(RefactoringCoreMessages.RenamePackageRefactoring_searching);
688                 fOccurrences= getReferences(new SubProgressMonitor(pm, 4), result);
689                 fReferencesToTypesInNamesakes= getReferencesToTypesInNamesakes(new SubProgressMonitor(pm, 4), result);
690                 fReferencesToTypesInPackage= getReferencesToTypesInPackage(new SubProgressMonitor(pm, 4), result);
691                 pm.setTaskName(RefactoringCoreMessages.RenamePackageRefactoring_checking);
692                 result.merge(analyzeAffectedCompilationUnits());
693                 pm.worked(1);
694             } else {
695                 fOccurrences= new SearchResultGroup[0];
696                 pm.worked(13);
697             }
698         
699             if (result.hasFatalError())
700                 return;
701             
702             if (fProcessor.getUpdateReferences())
703                 addReferenceUpdates(new SubProgressMonitor(pm, 3));
704             else
705                 pm.worked(3);
706             
707             pm.done();
708         }
709     
710         private SearchResultGroup[] getReferences(IProgressMonitor pm, RefactoringStatus status) throws CoreException {
711             IJavaSearchScope scope= RefactoringScopeFactory.create(fPackage);
712             SearchPattern pattern= SearchPattern.createPattern(fPackage, IJavaSearchConstants.REFERENCES);
713             return RefactoringSearchEngine.search(pattern, scope, pm, status);
714         }
715         
716         private void addReferenceUpdates(IProgressMonitor pm) throws CoreException {
717             pm.beginTask("", fOccurrences.length + fReferencesToTypesInPackage.size() + fReferencesToTypesInNamesakes.size()); //$NON-NLS-1$
718
for (int i= 0; i < fOccurrences.length; i++){
719                 ICompilationUnit cu= fOccurrences[i].getCompilationUnit();
720                 if (cu == null)
721                     continue;
722                 SearchMatch[] results= fOccurrences[i].getSearchResults();
723                 for (int j= 0; j < results.length; j++){
724                     SearchMatch result= results[j];
725                     IJavaElement enclosingElement= SearchUtils.getEnclosingJavaElement(result);
726                     if (enclosingElement instanceof IImportDeclaration) {
727                         IImportDeclaration importDeclaration= (IImportDeclaration) enclosingElement;
728                         String JavaDoc updatedImport= getUpdatedImport(importDeclaration);
729                         updateImport(cu, importDeclaration, updatedImport);
730                     } else { // is reference
731
TextChangeCompatibility.addTextEdit(fTextChangeManager.get(cu), RefactoringCoreMessages.RenamePackageRefactoring_update_reference, createTextChange(result));
732                     }
733                 }
734                 if (fReferencesToTypesInNamesakes.size() != 0) {
735                     SearchResultGroup typeRefsRequiringOldNameImport= extractGroupFor(cu, fReferencesToTypesInNamesakes);
736                     if (typeRefsRequiringOldNameImport != null)
737                         addTypeImports(typeRefsRequiringOldNameImport);
738                 }
739                 if (fReferencesToTypesInPackage.size() != 0) {
740                     SearchResultGroup typeRefsRequiringNewNameImport= extractGroupFor(cu, fReferencesToTypesInPackage);
741                     if (typeRefsRequiringNewNameImport != null)
742                         updateTypeImports(typeRefsRequiringNewNameImport);
743                 }
744                 pm.worked(1);
745             }
746     
747             if (fReferencesToTypesInNamesakes.size() != 0) {
748                 for (Iterator JavaDoc iter= fReferencesToTypesInNamesakes.iterator(); iter.hasNext();) {
749                     SearchResultGroup referencesToTypesInNamesakes= (SearchResultGroup) iter.next();
750                     addTypeImports(referencesToTypesInNamesakes);
751                     pm.worked(1);
752                 }
753             }
754             if (fReferencesToTypesInPackage.size() != 0) {
755                 for (Iterator JavaDoc iter= fReferencesToTypesInPackage.iterator(); iter.hasNext();) {
756                     SearchResultGroup namesakeReferencesToPackage= (SearchResultGroup) iter.next();
757                     updateTypeImports(namesakeReferencesToPackage);
758                     pm.worked(1);
759                 }
760             }
761             pm.done();
762         }
763     
764         /** Removes the found SearchResultGroup from the list iff found.
765          * @param searchResultGroups List of SearchResultGroup
766          * @return the SearchResultGroup for cu, or null iff not found */

767         private static SearchResultGroup extractGroupFor(ICompilationUnit cu, List JavaDoc searchResultGroups) {
768             for (Iterator JavaDoc iter= searchResultGroups.iterator(); iter.hasNext();) {
769                 SearchResultGroup group= (SearchResultGroup) iter.next();
770                 if (cu.equals(group.getCompilationUnit())) {
771                     iter.remove();
772                     return group;
773                 }
774             }
775             return null;
776         }
777         
778         private TextEdit createTextChange(SearchMatch searchResult) {
779             return new ReplaceEdit(searchResult.getOffset(), searchResult.getLength(), getNewPackageName());
780         }
781         
782         private RefactoringStatus analyzeAffectedCompilationUnits() throws CoreException {
783             //TODO: also for both fReferencesTo...; only check each CU once!
784
RefactoringStatus result= new RefactoringStatus();
785             fOccurrences= Checks.excludeCompilationUnits(fOccurrences, result);
786             if (result.hasFatalError())
787                 return result;
788             
789             result.merge(Checks.checkCompileErrorsInAffectedFiles(fOccurrences));
790             return result;
791         }
792     
793         /**
794          * @return search scope with
795          * <p>- fPackage and
796          * <p>- all CUs from fOccurrences which are not in a namesake package
797          */

798         private IJavaSearchScope getPackageAndOccurrencesWithoutNamesakesScope() {
799             List JavaDoc scopeList= new ArrayList JavaDoc();
800             scopeList.add(fPackage);
801             for (int i= 0; i < fOccurrences.length; i++) {
802                 ICompilationUnit cu= fOccurrences[i].getCompilationUnit();
803                 if (cu == null)
804                     continue;
805                 IPackageFragment pack= (IPackageFragment) cu.getParent();
806                 if (! pack.getElementName().equals(fPackage.getElementName()))
807                     scopeList.add(cu);
808             }
809             return SearchEngine.createJavaSearchScope((IJavaElement[]) scopeList.toArray(new IJavaElement[scopeList.size()]));
810         }
811     
812         private List JavaDoc getReferencesToTypesInNamesakes(IProgressMonitor pm, RefactoringStatus status) throws CoreException {
813             pm.beginTask("", 2); //$NON-NLS-1$
814
// e.g. renaming B-p.p; project C requires B, X and has ref to B-p.p and X-p.p;
815
// goal: find refs to X-p.p in CUs from fOccurrences
816

817             // (1) find namesake packages (scope: all packages referenced by CUs in fOccurrences and fPackage)
818
IJavaElement[] elements= new IJavaElement[fOccurrences.length + 1];
819             for (int i= 0; i < fOccurrences.length; i++) {
820                 elements[i]= fOccurrences[i].getCompilationUnit();
821             }
822             elements[fOccurrences.length]= fPackage;
823             IJavaSearchScope namesakePackagesScope= RefactoringScopeFactory.createReferencedScope(elements);
824             IPackageFragment[] namesakePackages= getNamesakePackages(namesakePackagesScope, new SubProgressMonitor(pm, 1));
825             if (namesakePackages.length == 0) {
826                 pm.done();
827                 return new ArrayList JavaDoc(0);
828             }
829             
830             // (2) find refs in fOccurrences and fPackage to namesake packages
831
// (from fOccurrences (without namesakes): may have shared star import)
832
// (from fPackage: may have unimported references to types of namesake packages)
833
IType[] typesToSearch= getTypesInPackages(namesakePackages);
834             if (typesToSearch.length == 0) {
835                 pm.done();
836                 return new ArrayList JavaDoc(0);
837             }
838             SearchPattern pattern= RefactoringSearchEngine.createOrPattern(typesToSearch, IJavaSearchConstants.REFERENCES);
839             IJavaSearchScope scope= getPackageAndOccurrencesWithoutNamesakesScope();
840             SearchResultGroup[] results= RefactoringSearchEngine.search(pattern, scope, new SubProgressMonitor(pm, 1), status);
841             pm.done();
842             return new ArrayList JavaDoc(Arrays.asList(results));
843         }
844     
845         private List JavaDoc getReferencesToTypesInPackage(IProgressMonitor pm, RefactoringStatus status) throws CoreException {
846             pm.beginTask("", 2); //$NON-NLS-1$
847
IJavaSearchScope referencedFromNamesakesScope= RefactoringScopeFactory.create(fPackage);
848             IPackageFragment[] namesakePackages= getNamesakePackages(referencedFromNamesakesScope, new SubProgressMonitor(pm, 1));
849             if (namesakePackages.length == 0) {
850                 pm.done();
851                 return new ArrayList JavaDoc(0);
852             }
853         
854             IJavaSearchScope scope= SearchEngine.createJavaSearchScope(namesakePackages);
855             IType[] typesToSearch= getTypesInPackage(fPackage);
856             if (typesToSearch.length == 0) {
857                 pm.done();
858                 return new ArrayList JavaDoc(0);
859             }
860             SearchPattern pattern= RefactoringSearchEngine.createOrPattern(typesToSearch, IJavaSearchConstants.REFERENCES);
861             SearchResultGroup[] results= RefactoringSearchEngine.search(pattern, scope, new SubProgressMonitor(pm, 1), status);
862             pm.done();
863             return new ArrayList JavaDoc(Arrays.asList(results));
864         }
865     
866         private IType[] getTypesInPackage(IPackageFragment packageFragment) throws JavaModelException {
867             List JavaDoc types= new ArrayList JavaDoc();
868             addContainedTypes(packageFragment, types);
869             return (IType[]) types.toArray(new IType[types.size()]);
870         }
871     
872         /**
873          * @return all package fragments in <code>scope</code> with same name as <code>fPackage</code>, excluding fPackage
874          */

875         private IPackageFragment[] getNamesakePackages(IJavaSearchScope scope, IProgressMonitor pm) throws CoreException {
876             SearchPattern pattern= SearchPattern.createPattern(fPackage.getElementName(), IJavaSearchConstants.PACKAGE, IJavaSearchConstants.DECLARATIONS, SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE);
877             
878             final HashSet JavaDoc packageFragments= new HashSet JavaDoc();
879             SearchRequestor requestor= new SearchRequestor() {
880                 public void acceptSearchMatch(SearchMatch match) throws CoreException {
881                     IJavaElement enclosingElement= SearchUtils.getEnclosingJavaElement(match);
882                     if (enclosingElement instanceof IPackageFragment) {
883                         IPackageFragment pack= (IPackageFragment) enclosingElement;
884                         if (! fPackage.equals(pack))
885                             packageFragments.add(pack);
886                     }
887                 }
888             };
889             new SearchEngine().search(pattern, SearchUtils.getDefaultSearchParticipants(), scope, requestor, pm);
890             
891             return (IPackageFragment[]) packageFragments.toArray(new IPackageFragment[packageFragments.size()]);
892         }
893         
894         private IType[] getTypesInPackages(IPackageFragment[] packageFragments) throws JavaModelException {
895             List JavaDoc types= new ArrayList JavaDoc();
896             for (int i= 0; i < packageFragments.length; i++) {
897                 IPackageFragment pack= packageFragments[i];
898                 addContainedTypes(pack, types);
899             }
900             return (IType[]) types.toArray(new IType[types.size()]);
901         }
902     
903         private void addContainedTypes(IPackageFragment pack, List JavaDoc typesCollector) throws JavaModelException {
904             IJavaElement[] children= pack.getChildren();
905             for (int c= 0; c < children.length; c++) {
906                 IJavaElement child= children[c];
907                 if (child instanceof ICompilationUnit) {
908                     typesCollector.addAll(Arrays.asList(((ICompilationUnit) child).getTypes()));
909                 } else if (child instanceof IClassFile) {
910                     typesCollector.add(((IClassFile) child).getType());
911                 }
912             }
913         }
914         
915         private void updateImport(ICompilationUnit cu, IImportDeclaration importDeclaration, String JavaDoc updatedImport) throws JavaModelException {
916             ImportChange importChange= fImportsManager.getImportChange(cu);
917             if (Flags.isStatic(importDeclaration.getFlags())) {
918                 importChange.removeStaticImport(importDeclaration.getElementName());
919                 importChange.addStaticImport(Signature.getQualifier(updatedImport), Signature.getSimpleName(updatedImport));
920             } else {
921                 importChange.removeImport(importDeclaration.getElementName());
922                 importChange.addImport(updatedImport);
923             }
924         }
925         
926         /**
927          * Add new imports to types in <code>typeReferences</code> with package <code>fPackage</code>.
928          */

929         private void addTypeImports(SearchResultGroup typeReferences) throws CoreException {
930             SearchMatch[] searchResults= typeReferences.getSearchResults();
931             for (int i= 0; i < searchResults.length; i++) {
932                 SearchMatch result= searchResults[i];
933                 IJavaElement enclosingElement= SearchUtils.getEnclosingJavaElement(result);
934                 if (! (enclosingElement instanceof IImportDeclaration)) {
935                     String JavaDoc reference= getNormalizedTypeReference(result);
936                     if (! reference.startsWith(fPackage.getElementName())) {
937                         // is unqualified
938
reference= cutOffInnerTypes(reference);
939                         ImportChange importChange= fImportsManager.getImportChange(typeReferences.getCompilationUnit());
940                         importChange.addImport(fPackage.getElementName() + '.' + reference);
941                     }
942                 }
943             }
944         }
945     
946         /**
947          * Add new imports to types in <code>typeReferences</code> with package <code>fNewElementName</code>
948          * and remove old import with <code>fPackage</code>.
949          */

950         private void updateTypeImports(SearchResultGroup typeReferences) throws CoreException {
951             SearchMatch[] searchResults= typeReferences.getSearchResults();
952             for (int i= 0; i < searchResults.length; i++) {
953                 SearchMatch result= searchResults[i];
954                 IJavaElement enclosingElement= SearchUtils.getEnclosingJavaElement(result);
955                 if (enclosingElement instanceof IImportDeclaration) {
956                     IImportDeclaration importDeclaration= (IImportDeclaration) enclosingElement;
957                     updateImport(typeReferences.getCompilationUnit(), importDeclaration, getUpdatedImport(importDeclaration));
958                 } else {
959                     String JavaDoc reference= getNormalizedTypeReference(result);
960                     if (! reference.startsWith(fPackage.getElementName())) {
961                         reference= cutOffInnerTypes(reference);
962                         ImportChange importChange= fImportsManager.getImportChange(typeReferences.getCompilationUnit());
963                         importChange.removeImport(fPackage.getElementName() + '.' + reference);
964                         importChange.addImport(getNewPackageName() + '.' + reference);
965                     } // else: already found & updated with package reference search
966
}
967             }
968         }
969         
970         private static String JavaDoc getNormalizedTypeReference(SearchMatch searchResult) throws JavaModelException {
971             ICompilationUnit cu= SearchUtils.getCompilationUnit(searchResult);
972             String JavaDoc reference= cu.getBuffer().getText(searchResult.getOffset(), searchResult.getLength());
973             //reference may be package-qualified -> normalize (remove comments, etc.):
974
return CommentAnalyzer.normalizeReference(reference);
975         }
976         
977         private static String JavaDoc cutOffInnerTypes(String JavaDoc reference) {
978             int dotPos= reference.indexOf('.'); // cut off inner types
979
if (dotPos != -1)
980                 reference= reference.substring(0, dotPos);
981             return reference;
982         }
983         
984         private String JavaDoc getUpdatedImport(IImportDeclaration importDeclaration) {
985             String JavaDoc fullyQualifiedImportType= importDeclaration.getElementName();
986             int offsetOfDotBeforeTypeName= fPackage.getElementName().length();
987             String JavaDoc result= getNewPackageName() + fullyQualifiedImportType.substring(offsetOfDotBeforeTypeName);
988             return result;
989         }
990     
991         private String JavaDoc getNewPackageName() {
992             return fProcessor.getNewPackageName(fPackage.getElementName());
993         }
994     }
995     
996     /**
997      * Collector for import additions/removals.
998      * Saves all changes for a one-pass rewrite.
999      */

1000    static class ImportsManager {
1001        public static class ImportChange {
1002            private ArrayList JavaDoc/*<String>*/ fStaticToRemove= new ArrayList JavaDoc();
1003            private ArrayList JavaDoc/*<String[2]>*/ fStaticToAdd= new ArrayList JavaDoc();
1004            private ArrayList JavaDoc/*<String>*/ fToRemove= new ArrayList JavaDoc();
1005            private ArrayList JavaDoc/*<String>*/ fToAdd= new ArrayList JavaDoc();
1006            
1007            public void removeStaticImport(String JavaDoc elementName) {
1008                fStaticToRemove.add(elementName);
1009            }
1010    
1011            public void addStaticImport(String JavaDoc declaringType, String JavaDoc memberName) {
1012                fStaticToAdd.add(new String JavaDoc[] {declaringType, memberName});
1013            }
1014            
1015            public void removeImport(String JavaDoc elementName) {
1016                fToRemove.add(elementName);
1017            }
1018            
1019            public void addImport(String JavaDoc elementName) {
1020                fToAdd.add(elementName);
1021            }
1022        }
1023        
1024        private HashMap JavaDoc/*<ICompilationUnit, ImportChange>*/ fImportChanges= new HashMap JavaDoc();
1025        
1026        public ImportChange getImportChange(ICompilationUnit cu) {
1027            ImportChange importChange= (ImportChange) fImportChanges.get(cu);
1028            if (importChange == null) {
1029                importChange= new ImportChange();
1030                fImportChanges.put(cu, importChange);
1031            }
1032            return importChange;
1033        }
1034    
1035        public void rewriteImports(TextChangeManager changeManager, IProgressMonitor pm) throws CoreException {
1036            for (Iterator JavaDoc iter= fImportChanges.entrySet().iterator(); iter.hasNext();) {
1037                Entry entry= (Entry) iter.next();
1038                ICompilationUnit cu= (ICompilationUnit) entry.getKey();
1039                ImportChange importChange= (ImportChange) entry.getValue();
1040                
1041                ImportRewrite importRewrite= StubUtility.createImportRewrite(cu, true);
1042                importRewrite.setFilterImplicitImports(false);
1043                for (Iterator JavaDoc iterator= importChange.fStaticToRemove.iterator(); iterator.hasNext();) {
1044                    importRewrite.removeStaticImport((String JavaDoc) iterator.next());
1045                }
1046                for (Iterator JavaDoc iterator= importChange.fToRemove.iterator(); iterator.hasNext();) {
1047                    importRewrite.removeImport((String JavaDoc) iterator.next());
1048                }
1049                for (Iterator JavaDoc iterator= importChange.fStaticToAdd.iterator(); iterator.hasNext();) {
1050                    String JavaDoc[] toAdd= (String JavaDoc[]) iterator.next();
1051                    importRewrite.addStaticImport(toAdd[0], toAdd[1], true);
1052                }
1053                for (Iterator JavaDoc iterator= importChange.fToAdd.iterator(); iterator.hasNext();) {
1054                    importRewrite.addImport((String JavaDoc) iterator.next());
1055                }
1056                
1057                if (importRewrite.hasRecordedChanges()) {
1058                    TextEdit importEdit= importRewrite.rewriteImports(pm);
1059                    String JavaDoc name= RefactoringCoreMessages.RenamePackageRefactoring_update_imports;
1060                    try {
1061                        TextChangeCompatibility.addTextEdit(changeManager.get(cu), name, importEdit);
1062                    } catch (MalformedTreeException e) {
1063                        JavaPlugin.logErrorMessage("MalformedTreeException while processing cu " + cu); //$NON-NLS-1$
1064
throw e;
1065                    }
1066                }
1067            }
1068        }
1069    }
1070
1071    public RefactoringStatus initialize(RefactoringArguments arguments) {
1072        if (arguments instanceof JavaRefactoringArguments) {
1073            final JavaRefactoringArguments extended= (JavaRefactoringArguments) arguments;
1074            final String JavaDoc handle= extended.getAttribute(JDTRefactoringDescriptor.ATTRIBUTE_INPUT);
1075            if (handle != null) {
1076                final IJavaElement element= JDTRefactoringDescriptor.handleToElement(extended.getProject(), handle, false);
1077                if (element == null || !element.exists() || element.getElementType() != IJavaElement.PACKAGE_FRAGMENT)
1078                    return ScriptableRefactoring.createInputFatalStatus(element, getRefactoring().getName(), IJavaRefactorings.RENAME_PACKAGE);
1079                else
1080                    fPackage= (IPackageFragment) element;
1081            } else
1082                return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JDTRefactoringDescriptor.ATTRIBUTE_INPUT));
1083            final String JavaDoc name= extended.getAttribute(JDTRefactoringDescriptor.ATTRIBUTE_NAME);
1084            if (name != null && !"".equals(name)) //$NON-NLS-1$
1085
setNewElementName(name);
1086            else
1087                return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JDTRefactoringDescriptor.ATTRIBUTE_NAME));
1088            final String JavaDoc patterns= extended.getAttribute(ATTRIBUTE_PATTERNS);
1089            if (patterns != null && !"".equals(patterns)) //$NON-NLS-1$
1090
fFilePatterns= patterns;
1091            else
1092                fFilePatterns= ""; //$NON-NLS-1$
1093
final String JavaDoc references= extended.getAttribute(JDTRefactoringDescriptor.ATTRIBUTE_REFERENCES);
1094            if (references != null) {
1095                fUpdateReferences= Boolean.valueOf(references).booleanValue();
1096            } else
1097                return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JDTRefactoringDescriptor.ATTRIBUTE_REFERENCES));
1098            final String JavaDoc matches= extended.getAttribute(ATTRIBUTE_TEXTUAL_MATCHES);
1099            if (matches != null) {
1100                fUpdateTextualMatches= Boolean.valueOf(matches).booleanValue();
1101            } else
1102                return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_TEXTUAL_MATCHES));
1103            final String JavaDoc qualified= extended.getAttribute(ATTRIBUTE_QUALIFIED);
1104            if (qualified != null) {
1105                fUpdateQualifiedNames= Boolean.valueOf(qualified).booleanValue();
1106            } else
1107                return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_QUALIFIED));
1108            final String JavaDoc hierarchical= extended.getAttribute(ATTRIBUTE_HIERARCHICAL);
1109            if (hierarchical != null) {
1110                fRenameSubpackages= Boolean.valueOf(hierarchical).booleanValue();
1111            } else
1112                return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_HIERARCHICAL));
1113        } else
1114            return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.InitializableRefactoring_inacceptable_arguments);
1115        return new RefactoringStatus();
1116    }
1117}
1118
Popular Tags