]> git.uio.no Git - ifi-stolz-refaktor.git/blob - case-study/jdt-before/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenameModifications.java
4ad5e9c6ed36f5c41f53fdacf0d1802d7b8e8fb3
[ifi-stolz-refaktor.git] / case-study / jdt-before / core refactoring / org / eclipse / jdt / internal / corext / refactoring / rename / RenameModifications.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2011 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;
14 import java.util.Arrays;
15 import java.util.HashSet;
16 import java.util.Iterator;
17 import java.util.List;
18 import java.util.Set;
19
20 import org.eclipse.core.runtime.Assert;
21 import org.eclipse.core.runtime.CoreException;
22 import org.eclipse.core.runtime.IPath;
23
24 import org.eclipse.core.resources.IContainer;
25 import org.eclipse.core.resources.IFile;
26 import org.eclipse.core.resources.IFolder;
27 import org.eclipse.core.resources.IProject;
28 import org.eclipse.core.resources.IResource;
29 import org.eclipse.core.resources.ResourcesPlugin;
30 import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory;
31
32 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
33 import org.eclipse.ltk.core.refactoring.participants.IParticipantDescriptorFilter;
34 import org.eclipse.ltk.core.refactoring.participants.MoveArguments;
35 import org.eclipse.ltk.core.refactoring.participants.ParticipantManager;
36 import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments;
37 import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant;
38 import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor;
39 import org.eclipse.ltk.core.refactoring.participants.RenameArguments;
40 import org.eclipse.ltk.core.refactoring.participants.SharableParticipants;
41 import org.eclipse.ltk.core.refactoring.participants.ValidateEditChecker;
42
43 import org.eclipse.jdt.core.ICompilationUnit;
44 import org.eclipse.jdt.core.IField;
45 import org.eclipse.jdt.core.IJavaElement;
46 import org.eclipse.jdt.core.IJavaProject;
47 import org.eclipse.jdt.core.ILocalVariable;
48 import org.eclipse.jdt.core.IMethod;
49 import org.eclipse.jdt.core.IPackageFragment;
50 import org.eclipse.jdt.core.IPackageFragmentRoot;
51 import org.eclipse.jdt.core.IType;
52 import org.eclipse.jdt.core.ITypeParameter;
53 import org.eclipse.jdt.core.refactoring.RenameTypeArguments;
54
55 import org.eclipse.jdt.internal.corext.refactoring.participants.ResourceModifications;
56 import org.eclipse.jdt.internal.corext.refactoring.reorg.RefactoringModifications;
57
58
59 public class RenameModifications extends RefactoringModifications {
60
61         private List<Object> fRename;
62         private List<RefactoringArguments> fRenameArguments;
63         private List<IParticipantDescriptorFilter> fParticipantDescriptorFilter;
64
65         public RenameModifications() {
66                 fRename= new ArrayList<Object>();
67                 fRenameArguments= new ArrayList<RefactoringArguments>();
68                 fParticipantDescriptorFilter= new ArrayList<IParticipantDescriptorFilter>();
69         }
70
71         public void rename(IResource resource, RenameArguments args) {
72                 add(resource, args, null);
73         }
74
75         public void rename(IJavaProject project, RenameArguments args) {
76                 add(project, args, null);
77                 IProject rProject= project.getProject();
78                 if (rProject != null) {
79                         getResourceModifications().addRename(rProject, args);
80                         IProject[] referencingProjects= rProject.getReferencingProjects();
81                         for (int i= 0; i < referencingProjects.length; i++) {
82                                 IFile classpath= getClasspathFile(referencingProjects[i]);
83                                 if (classpath != null) {
84                                         getResourceModifications().addChanged(classpath);
85                                 }
86                         }
87                 }
88         }
89
90         public void rename(IPackageFragmentRoot sourceFolder, RenameArguments arguments) {
91                 add(sourceFolder, arguments, null);
92                 if (sourceFolder.getResource() != null) {
93                         getResourceModifications().addRename(sourceFolder.getResource(), arguments);
94                 }
95         }
96
97         public void rename(IPackageFragment rootPackage, RenameArguments args, boolean renameSubPackages) throws CoreException {
98                 add(rootPackage, args, null);
99                 IPackageFragment[] allSubPackages= null;
100                 if (renameSubPackages) {
101                         allSubPackages= getSubpackages(rootPackage);
102                         for (int i= 0; i < allSubPackages.length; i++) {
103                                 IPackageFragment pack= allSubPackages[i];
104                                 RenameArguments subArgs= new RenameArguments(
105                                         getNewPackageName(rootPackage, args.getNewName(), pack.getElementName()),
106                                         args.getUpdateReferences());
107                                 add(pack, subArgs, null);
108                         }
109                 }
110                 IContainer container= (IContainer)rootPackage.getResource();
111                 if (container == null)
112                         return;
113                 IContainer target= (IContainer) ((IPackageFragmentRoot)rootPackage.getParent()).
114                         getPackageFragment(args.getNewName()).getResource();
115                 if ((!rootPackage.hasSubpackages() || renameSubPackages) && canMove(container, target)) {
116                         createIncludingParents(target.getParent());
117                         if (container.getParent().equals(target.getParent())) {
118                                 getResourceModifications().addRename(container, new RenameArguments(target.getName(), args.getUpdateReferences()));
119                         } else {
120                                 // This is a little tricky. The problem is that the refactoring participants
121                                 // don't support a generic move like the resource API does. So for the delta
122                                 // we generate one move, however for the participants we have to generate single
123                                 // moves and deletes.
124                                 try {
125                                         getResourceModifications().ignoreForDelta();
126                                         addAllResourceModifications(rootPackage, args, renameSubPackages, allSubPackages);
127                                 } finally {
128                                         getResourceModifications().trackForDelta();
129                                 }
130                                 getResourceModifications().addDelta(new ResourceModifications.MoveDescription(container, target.getFullPath()));
131                         }
132                 } else {
133                         addAllResourceModifications(rootPackage, args, renameSubPackages, allSubPackages);
134                 }
135         }
136
137         public void rename(ICompilationUnit unit, RenameArguments args) {
138                 add(unit, args, null);
139                 if (unit.getResource() != null) {
140                         getResourceModifications().addRename(unit.getResource(), new RenameArguments(args.getNewName(), args.getUpdateReferences()));
141                 }
142         }
143
144         public void rename(IType type, RenameTypeArguments args, IParticipantDescriptorFilter filter) {
145                 add(type, args, filter);
146         }
147
148         public void rename(IField field, RenameArguments args) {
149                 add(field, args, null);
150         }
151
152         public void rename(IMethod method, RenameArguments args) {
153                 add(method, args, null);
154         }
155
156         public void rename(ILocalVariable variable, RenameArguments args) {
157                 add(variable, args, null);
158         }
159
160         public void rename(ITypeParameter typeParameter, RenameArguments arguments) {
161                 add(typeParameter, arguments, null);
162         }
163
164         @Override
165         public void buildDelta(IResourceChangeDescriptionFactory builder) {
166                 for (int i= 0; i < fRename.size(); i++) {
167                         Object element= fRename.get(i);
168                         if (element instanceof IResource) {
169                                 ResourceModifications.buildMoveDelta(builder, (IResource) element, (RenameArguments) fRenameArguments.get(i));
170                         }
171                 }
172                 getResourceModifications().buildDelta(builder);
173         }
174
175         @Override
176         public void buildValidateEdits(ValidateEditChecker checker) {
177                 for (Iterator<Object> iter= fRename.iterator(); iter.hasNext();) {
178                         Object element= iter.next();
179                         if (element instanceof ICompilationUnit) {
180                                 ICompilationUnit unit= (ICompilationUnit)element;
181                                 IResource resource= unit.getResource();
182                                 if (resource != null && resource.getType() == IResource.FILE) {
183                                         checker.addFile((IFile)resource);
184                                 }
185                         }
186                 }
187         }
188
189         @Override
190         public RefactoringParticipant[] loadParticipants(RefactoringStatus status, RefactoringProcessor owner, String[] natures, SharableParticipants shared) {
191                 List<RefactoringParticipant> result= new ArrayList<RefactoringParticipant>();
192                 for (int i= 0; i < fRename.size(); i++) {
193                         result.addAll(Arrays.asList(ParticipantManager.loadRenameParticipants(status,
194                                 owner, fRename.get(i),
195                                 (RenameArguments) fRenameArguments.get(i),
196                                 fParticipantDescriptorFilter.get(i),
197                                 natures, shared)));
198                 }
199                 result.addAll(Arrays.asList(getResourceModifications().getParticipants(status, owner, natures, shared)));
200                 return result.toArray(new RefactoringParticipant[result.size()]);
201         }
202
203         private void add(Object element, RefactoringArguments args, IParticipantDescriptorFilter filter) {
204                 Assert.isNotNull(element);
205                 Assert.isNotNull(args);
206                 fRename.add(element);
207                 fRenameArguments.add(args);
208                 fParticipantDescriptorFilter.add(filter);
209         }
210
211         private void addAllResourceModifications(IPackageFragment rootPackage, RenameArguments args, boolean renameSubPackages, IPackageFragment[] allSubPackages) throws CoreException {
212                 IFolder target= addResourceModifications(rootPackage, args, rootPackage, renameSubPackages);
213                 if (renameSubPackages) {
214                         IContainer container= (IContainer) rootPackage.getResource();
215                         if (container == null)
216                                 return;
217                         boolean removeContainer= ! container.contains(target);
218                         for (int i= 0; i < allSubPackages.length; i++) {
219                                 IPackageFragment pack= allSubPackages[i];
220                                 IFolder subTarget= addResourceModifications(rootPackage, args, pack, renameSubPackages);
221                                 if (container.contains(subTarget))
222                                         removeContainer= false;
223                         }
224                         if (removeContainer) {
225                                 getResourceModifications().addDelete(container);
226                         }
227                 }
228         }
229
230         private IFolder addResourceModifications(IPackageFragment rootPackage, RenameArguments args, IPackageFragment pack, boolean renameSubPackages) throws CoreException {
231                 IContainer container= (IContainer)pack.getResource();
232                 if (container == null)
233                         return null;
234                 IFolder target= computeTargetFolder(rootPackage, args, pack);
235                 createIncludingParents(target);
236                 MoveArguments arguments= new MoveArguments(target, args.getUpdateReferences());
237                 IResource[] resourcesToMove= collectResourcesOfInterest(pack);
238                 Set<IResource> allMembers= new HashSet<IResource>(Arrays.asList(container.members()));
239                 for (int i= 0; i < resourcesToMove.length; i++) {
240                         IResource toMove= resourcesToMove[i];
241                         getResourceModifications().addMove(toMove, arguments);
242                         allMembers.remove(toMove);
243                 }
244                 for (Iterator<IResource> iter= allMembers.iterator(); iter.hasNext();) {
245                         IResource element= iter.next();
246                         if (element instanceof IFile) {
247                                 getResourceModifications().addDelete(element);
248                                 iter.remove();
249                         }
250                 }
251                 if (! renameSubPackages && allMembers.isEmpty()) {
252                         getResourceModifications().addDelete(container);
253                 }
254                 return target;
255         }
256
257         private boolean canMove(IContainer source, IContainer target) {
258                 return !target.exists() && !source.getFullPath().isPrefixOf(target.getFullPath());
259         }
260
261         private IPackageFragment[] getSubpackages(IPackageFragment pack) throws CoreException {
262                 IPackageFragmentRoot root= (IPackageFragmentRoot) pack.getParent();
263                 IJavaElement[] allPackages= root.getChildren();
264                 if (pack.isDefaultPackage())
265                         return new IPackageFragment[0];
266                 ArrayList<IPackageFragment> result= new ArrayList<IPackageFragment>();
267                 String prefix= pack.getElementName() + '.';
268                 for (int i= 0; i < allPackages.length; i++) {
269                         IPackageFragment currentPackage= (IPackageFragment) allPackages[i];
270                         if (currentPackage.getElementName().startsWith(prefix))
271                                 result.add(currentPackage);
272                 }
273                 return result.toArray(new IPackageFragment[result.size()]);
274         }
275
276         private IFolder computeTargetFolder(IPackageFragment rootPackage, RenameArguments args, IPackageFragment pack) {
277                 IPath path= pack.getParent().getPath();
278                 path= path.append(getNewPackageName(rootPackage, args.getNewName(),  pack.getElementName()).replace('.', IPath.SEPARATOR));
279                 IFolder target= ResourcesPlugin.getWorkspace().getRoot().getFolder(path);
280                 return target;
281         }
282
283         private String getNewPackageName(IPackageFragment rootPackage, String newPackageName, String oldSubPackageName) {
284                 String oldPackageName= rootPackage.getElementName();
285                 return newPackageName + oldSubPackageName.substring(oldPackageName.length());
286         }
287 }