]> git.uio.no Git - ifi-stolz-refaktor.git/blob - case-study/jdt-before/core refactoring/org/eclipse/jdt/internal/corext/refactoring/reorg/DeleteModifications.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-before / core refactoring / org / eclipse / jdt / internal / corext / refactoring / reorg / DeleteModifications.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.reorg;
12
13 import java.util.ArrayList;
14 import java.util.Arrays;
15 import java.util.Iterator;
16 import java.util.List;
17
18 import org.eclipse.core.runtime.CoreException;
19
20 import org.eclipse.core.resources.IContainer;
21 import org.eclipse.core.resources.IFile;
22 import org.eclipse.core.resources.IFolder;
23 import org.eclipse.core.resources.IResource;
24 import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory;
25
26 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
27 import org.eclipse.ltk.core.refactoring.participants.DeleteArguments;
28 import org.eclipse.ltk.core.refactoring.participants.ParticipantManager;
29 import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant;
30 import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor;
31 import org.eclipse.ltk.core.refactoring.participants.SharableParticipants;
32
33 import org.eclipse.jdt.core.ICompilationUnit;
34 import org.eclipse.jdt.core.IJavaElement;
35 import org.eclipse.jdt.core.IJavaProject;
36 import org.eclipse.jdt.core.IPackageFragment;
37 import org.eclipse.jdt.core.IPackageFragmentRoot;
38 import org.eclipse.jdt.core.IType;
39 import org.eclipse.jdt.core.JavaCore;
40 import org.eclipse.jdt.core.JavaModelException;
41
42 import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil;
43
44 /**
45  * A modification collector for Java element delete operations.
46  */
47 public class DeleteModifications extends RefactoringModifications {
48
49         private List<IJavaElement> fDelete;
50
51         /**
52          * Contains the actual packages when executing
53          * <code>handlePackageFragmentDelete</code>. This is part of the
54          * algorithm to check if a parent folder can be deleted.
55          */
56         private List<IPackageFragment> fPackagesToDelete;
57
58         public DeleteModifications() {
59                 fDelete= new ArrayList<IJavaElement>();
60                 fPackagesToDelete= new ArrayList<IPackageFragment>();
61         }
62
63         public void delete(IResource resource) {
64                 getResourceModifications().addDelete(resource);
65         }
66
67         public void delete(IResource[] resources) {
68                 for (int i= 0; i < resources.length; i++) {
69                         delete(resources[i]);
70                 }
71         }
72
73         public void delete(IJavaElement[] elements) throws CoreException {
74                 for (int i= 0; i < elements.length; i++) {
75                         delete(elements[i]);
76                 }
77         }
78
79         public void delete(IJavaElement element) throws CoreException {
80                 switch(element.getElementType()) {
81                         case IJavaElement.JAVA_MODEL:
82                                 return;
83                         case IJavaElement.JAVA_PROJECT:
84                                 fDelete.add(element);
85                                 if (element.getResource() != null)
86                                         getResourceModifications().addDelete(element.getResource());
87                                 return;
88                         case IJavaElement.PACKAGE_FRAGMENT_ROOT:
89                                 fDelete.add(element);
90                                 IResource resource= element.getResource();
91                                 // Flag an resource change even if we have an archive. If it is
92                                 // internal (we have a underlying resource then we have a resource
93                                 // change.
94                                 if (resource != null)
95                                         getResourceModifications().addDelete(resource);
96                                 IJavaProject[] referencingProjects= JavaElementUtil.getReferencingProjects((IPackageFragmentRoot) element);
97                                 for (int i= 0; i < referencingProjects.length; i++) {
98                                         IFile classpath= referencingProjects[i].getProject().getFile(".classpath"); //$NON-NLS-1$
99                                         getResourceModifications().addChanged(classpath);
100                                 }
101                                 return;
102                         case IJavaElement.PACKAGE_FRAGMENT:
103                                 fDelete.add(element);
104                                 fPackagesToDelete.add((IPackageFragment) element);
105                                 return;
106                         case IJavaElement.COMPILATION_UNIT:
107                                 fDelete.add(element);
108                                 IType[] types= ((ICompilationUnit)element).getTypes();
109                                 fDelete.addAll(Arrays.asList(types));
110                                 if (element.getResource() != null)
111                                         getResourceModifications().addDelete(element.getResource());
112                                 return;
113                         default:
114                                 fDelete.add(element);
115                 }
116
117         }
118
119         /**
120          * @return a List of IResources that are removed by package deletes
121          * @throws CoreException
122          */
123         public List<IResource> postProcess() throws CoreException {
124                 ArrayList<IResource> resourcesCollector= new ArrayList<IResource>();
125                 for (Iterator<IPackageFragment> iter= fPackagesToDelete.iterator(); iter.hasNext();) {
126                         IPackageFragment pack= iter.next();
127                         handlePackageFragmentDelete(pack, resourcesCollector);
128                 }
129                 return resourcesCollector;
130         }
131
132         @Override
133         public void buildDelta(IResourceChangeDescriptionFactory deltaFactory) {
134                 getResourceModifications().buildDelta(deltaFactory);
135         }
136
137         @Override
138         public RefactoringParticipant[] loadParticipants(RefactoringStatus status, RefactoringProcessor owner, String[] natures, SharableParticipants shared) {
139                 List<RefactoringParticipant> result= new ArrayList<RefactoringParticipant>();
140                 for (Iterator<IJavaElement> iter= fDelete.iterator(); iter.hasNext();) {
141                         result.addAll(Arrays.asList(ParticipantManager.loadDeleteParticipants(status,
142                                 owner, iter.next(),
143                                 new DeleteArguments(), natures, shared)));
144                 }
145                 result.addAll(Arrays.asList(getResourceModifications().getParticipants(status, owner, natures, shared)));
146                 return result.toArray(new RefactoringParticipant[result.size()]);
147         }
148
149         /**
150          * This method collects file and folder deletion for notifying
151          * participants. Participants will get notified of
152          *
153          * * deletion of the package (in any case)
154          * * deletion of files within the package if only the files are deleted without
155          *   the package folder ("package cleaning")
156          * * deletion of the package folder if it is not only cleared and if its parent
157          *   is not removed as well.
158          *
159          * All deleted resources are added to <code>resourcesCollector</code>
160          * @param pack the package
161          *
162          * @param resourcesCollector a collector for IResources to be deleted
163          * @throws CoreException
164          */
165         private void handlePackageFragmentDelete(IPackageFragment pack, ArrayList<IResource> resourcesCollector) throws CoreException {
166                 final IContainer container= (IContainer)pack.getResource();
167                 if (container == null)
168                         return;
169
170                 final IResource[] members= container.members();
171
172                 /*
173                  * Check whether this package is removed completely or only cleared.
174                  * The default package can never be removed completely.
175                  */
176                 if (!pack.isDefaultPackage() && canRemoveCompletely(pack)) {
177                         // This package is removed completely, which means its folder will be
178                         // deleted as well. We only notify participants of the folder deletion
179                         // if the parent folder of this folder will not be deleted as well:
180                         boolean parentIsMarked= false;
181                         final IPackageFragment parent= JavaElementUtil.getParentSubpackage(pack);
182                         if (parent == null) {
183                                 // "Parent" is the default package which will never be
184                                 // deleted physically
185                                 parentIsMarked= false;
186                         } else {
187                                 // Parent is marked if it is in the list
188                                 parentIsMarked= fPackagesToDelete.contains(parent);
189                         }
190
191                         if (parentIsMarked) {
192                                 // Parent is marked, but is it really deleted or only cleared?
193                                 if (canRemoveCompletely(parent)) {
194                                         // Parent can be removed completely, so we do not add
195                                         // this folder to the list.
196                                 } else {
197                                         // Parent cannot be removed completely, but as this folder
198                                         // can be removed, we notify the participant
199                                         resourcesCollector.add(container);
200                                         getResourceModifications().addDelete(container);
201                                 }
202                         } else {
203                                 // Parent will not be removed, but we will
204                                 resourcesCollector.add(container);
205                                 getResourceModifications().addDelete(container);
206                         }
207                 } else {
208                         // This package is only cleared because it has subpackages (=subfolders)
209                         // which are not deleted. As the package is only cleared, its folder
210                         // will not be removed and so we must notify the participant of the deleted children.
211                         for (int m= 0; m < members.length; m++) {
212                                 IResource member= members[m];
213                                 if (member instanceof IFile) {
214                                         IFile file= (IFile)member;
215                                         if ("class".equals(file.getFileExtension()) && file.isDerived()) //$NON-NLS-1$
216                                                 continue;
217                                         if (pack.isDefaultPackage() && ! JavaCore.isJavaLikeFileName(file.getName()))
218                                                 continue;
219                                         resourcesCollector.add(member);
220                                         getResourceModifications().addDelete(member);
221                                 }
222                                 if (!pack.isDefaultPackage() && member instanceof IFolder) {
223                                         // Normally, folder children of packages are packages
224                                         // as well, but in case they have been removed from the build
225                                         // path, notify the participant
226                                         IPackageFragment frag= (IPackageFragment) JavaCore.create(member);
227                                         if (frag == null) {
228                                                 resourcesCollector.add(member);
229                                                 getResourceModifications().addDelete(member);
230                                         }
231                                 }
232                         }
233                 }
234         }
235
236         /**
237          * Returns true if this initially selected package is really deletable
238          * (if it has non-selected sub packages, it may only be cleared).
239          * @param pack the package
240          * @return  true if this initially selected package is really deletable
241          * @throws JavaModelException
242          */
243         private boolean canRemoveCompletely(IPackageFragment pack) throws JavaModelException {
244                 final IPackageFragment[] subPackages= JavaElementUtil.getPackageAndSubpackages(pack);
245                 for (int i= 0; i < subPackages.length; i++) {
246                         if (!(subPackages[i].equals(pack)) && !(fPackagesToDelete.contains(subPackages[i])))
247                                 return false;
248                 }
249                 return true;
250         }
251 }