KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > refactoring > changes > RenamePackageChange


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

11 package org.eclipse.jdt.internal.corext.refactoring.changes;
12
13 import java.util.Arrays JavaDoc;
14 import java.util.Comparator JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.Map JavaDoc;
17
18 import org.eclipse.core.runtime.Assert;
19 import org.eclipse.core.runtime.CoreException;
20 import org.eclipse.core.runtime.IPath;
21 import org.eclipse.core.runtime.IProgressMonitor;
22 import org.eclipse.core.runtime.Path;
23 import org.eclipse.core.runtime.SubProgressMonitor;
24
25 import org.eclipse.core.resources.IResource;
26 import org.eclipse.core.resources.ResourcesPlugin;
27
28 import org.eclipse.ltk.core.refactoring.Change;
29 import org.eclipse.ltk.core.refactoring.NullChange;
30 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
31
32 import org.eclipse.jdt.core.ICompilationUnit;
33 import org.eclipse.jdt.core.IJavaElement;
34 import org.eclipse.jdt.core.IPackageFragment;
35 import org.eclipse.jdt.core.JavaCore;
36 import org.eclipse.jdt.core.JavaModelException;
37
38 import org.eclipse.jdt.internal.corext.refactoring.AbstractJavaElementRenameChange;
39 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
40 import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil;
41 import org.eclipse.jdt.internal.corext.util.Messages;
42
43 public final class RenamePackageChange extends AbstractJavaElementRenameChange {
44
45     private static IPath createPath(String JavaDoc packageName) {
46         return new Path(packageName.replace('.', IPath.SEPARATOR));
47     }
48
49     private Map JavaDoc fCompilationUnitStamps;
50
51     private final boolean fRenameSubpackages;
52
53     public RenamePackageChange(IPackageFragment pack, String JavaDoc newName, boolean renameSubpackages) {
54         this(pack.getPath(), pack.getElementName(), newName, IResource.NULL_STAMP, null, renameSubpackages);
55         Assert.isTrue(!pack.isReadOnly(), "package must not be read only"); //$NON-NLS-1$
56
}
57
58     private RenamePackageChange(IPath resourcePath, String JavaDoc oldName, String JavaDoc newName, long stampToRestore, Map JavaDoc compilationUnitStamps, boolean renameSubpackages) {
59         super(resourcePath, oldName, newName, stampToRestore);
60         fCompilationUnitStamps= compilationUnitStamps;
61         fRenameSubpackages= renameSubpackages;
62     }
63
64     private void addStamps(Map JavaDoc stamps, ICompilationUnit[] units) {
65         for (int i= 0; i < units.length; i++) {
66             IResource resource= units[i].getResource();
67             long stamp= IResource.NULL_STAMP;
68             if (resource != null && (stamp= resource.getModificationStamp()) != IResource.NULL_STAMP) {
69                 stamps.put(resource, new Long JavaDoc(stamp));
70             }
71         }
72     }
73
74     protected IPath createNewPath() {
75         IPackageFragment oldPackage= getPackage();
76         IPath oldPackageName= createPath(oldPackage.getElementName());
77         IPath newPackageName= createPath(getNewName());
78         return getResourcePath().removeLastSegments(oldPackageName.segmentCount()).append(newPackageName);
79     }
80
81     protected IPath createNewPath(IPackageFragment oldPackage) {
82         IPath oldPackagePath= createPath(oldPackage.getElementName());
83         IPath newPackagePath= createPath(getNewName(oldPackage));
84         return oldPackage.getPath().removeLastSegments(oldPackagePath.segmentCount()).append(newPackagePath);
85     }
86
87     protected Change createUndoChange(long stampToRestore) throws CoreException {
88         IPackageFragment pack= getPackage();
89         if (pack == null)
90             return new NullChange();
91         Map JavaDoc stamps= new HashMap JavaDoc();
92         if (!fRenameSubpackages) {
93             addStamps(stamps, pack.getCompilationUnits());
94         } else {
95             IPackageFragment[] allPackages= JavaElementUtil.getPackageAndSubpackages(pack);
96             for (int i= 0; i < allPackages.length; i++) {
97                 IPackageFragment currentPackage= allPackages[i];
98                 addStamps(stamps, currentPackage.getCompilationUnits());
99             }
100         }
101         return new RenamePackageChange(createNewPath(), getNewName(), getOldName(), stampToRestore, stamps, fRenameSubpackages);
102         // Note: This reverse change only works if the renamePackage change did
103
// not merge the source package into an existing target.
104
}
105
106     protected void doRename(IProgressMonitor pm) throws CoreException {
107         IPackageFragment pack= getPackage();
108         if (pack == null)
109             return;
110
111         if (!fRenameSubpackages) {
112             renamePackage(pack, pm, createNewPath(), getNewName());
113             
114         } else {
115             IPackageFragment[] allPackages= JavaElementUtil.getPackageAndSubpackages(pack);
116             Arrays.sort(allPackages, new Comparator JavaDoc() {
117                 public int compare(Object JavaDoc o1, Object JavaDoc o2) {
118                     String JavaDoc p1= ((IPackageFragment) o1).getElementName();
119                     String JavaDoc p2= ((IPackageFragment) o2).getElementName();
120                     return p1.compareTo(p2);
121                 }
122             });
123             int count= allPackages.length;
124             pm.beginTask("", count); //$NON-NLS-1$
125
// When renaming to subpackage (a -> a.b), do it inside-out:
126
boolean insideOut= getNewName().startsWith(getOldName());
127             try {
128                 for (int i= 0; i < count; i++) {
129                     IPackageFragment currentPackage= allPackages[insideOut ? count - i - 1 : i];
130                     renamePackage(currentPackage, new SubProgressMonitor(pm, 1), createNewPath(currentPackage), getNewName(currentPackage));
131                 }
132             } finally {
133                 pm.done();
134             }
135         }
136     }
137
138     public String JavaDoc getName() {
139         String JavaDoc msg= fRenameSubpackages ? RefactoringCoreMessages.RenamePackageChange_name_with_subpackages : RefactoringCoreMessages.RenamePackageChange_name;
140         return Messages.format(msg, new String JavaDoc[] { getOldName(), getNewName()});
141     }
142
143     private String JavaDoc getNewName(IPackageFragment subpackage) {
144         return getNewName() + subpackage.getElementName().substring(getOldName().length());
145     }
146
147     private IPackageFragment getPackage() {
148         return (IPackageFragment) getModifiedElement();
149     }
150
151     public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException {
152         pm.beginTask("", 2); //$NON-NLS-1$
153
RefactoringStatus result;
154         try {
155             result= new RefactoringStatus();
156             IJavaElement element= (IJavaElement) getModifiedElement();
157             // don't check for read-only since we don't go through
158
// validate edit.
159
result.merge(isValid(new SubProgressMonitor(pm, 1), DIRTY));
160             if (result.hasFatalError())
161                 return result;
162             if (element != null && element.exists() && element instanceof IPackageFragment) {
163                 IPackageFragment pack= (IPackageFragment) element;
164                 if (fRenameSubpackages) {
165                     IPackageFragment[] allPackages= JavaElementUtil.getPackageAndSubpackages(pack);
166                     SubProgressMonitor subPm= new SubProgressMonitor(pm, 1);
167                     subPm.beginTask("", allPackages.length); //$NON-NLS-1$
168
for (int i= 0; i < allPackages.length; i++) {
169                         // don't check for read-only since we don't go through
170
// validate edit.
171
checkIfModifiable(result, allPackages[i], DIRTY);
172                         if (result.hasFatalError())
173                             return result;
174                         isValid(result, allPackages[i], new SubProgressMonitor(subPm, 1));
175                     }
176                 } else {
177                     isValid(result, pack, new SubProgressMonitor(pm, 1));
178                 }
179             }
180         } finally {
181             pm.done();
182         }
183         return result;
184     }
185
186     private void isValid(RefactoringStatus result, IPackageFragment pack, IProgressMonitor pm) throws JavaModelException {
187         ICompilationUnit[] units= pack.getCompilationUnits();
188         pm.beginTask("", units.length); //$NON-NLS-1$
189
for (int i= 0; i < units.length; i++) {
190             pm.subTask(Messages.format(RefactoringCoreMessages.RenamePackageChange_checking_change, pack.getElementName()));
191             checkIfModifiable(result, units[i], READ_ONLY | DIRTY);
192             pm.worked(1);
193         }
194         pm.done();
195     }
196
197     private void renamePackage(IPackageFragment pack, IProgressMonitor pm, IPath newPath, String JavaDoc newName) throws JavaModelException, CoreException {
198         pack.rename(newName, false, pm);
199         if (fCompilationUnitStamps != null) {
200             IPackageFragment newPack= (IPackageFragment) JavaCore.create(ResourcesPlugin.getWorkspace().getRoot().getFolder(newPath));
201             if (newPack.exists()) {
202                 ICompilationUnit[] units= newPack.getCompilationUnits();
203                 for (int i= 0; i < units.length; i++) {
204                     IResource resource= units[i].getResource();
205                     if (resource != null) {
206                         Long JavaDoc stamp= (Long JavaDoc) fCompilationUnitStamps.get(resource);
207                         if (stamp != null) {
208                             resource.revertModificationStamp(stamp.longValue());
209                         }
210                     }
211                 }
212             }
213         }
214     }
215 }
216
Popular Tags