KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > refactoring > reorg > DeleteChangeCreator


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.reorg;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.List JavaDoc;
16 import java.util.Map JavaDoc;
17
18 import org.eclipse.text.edits.TextEdit;
19
20 import org.eclipse.core.runtime.Assert;
21 import org.eclipse.core.runtime.CoreException;
22
23 import org.eclipse.core.filebuffers.ITextFileBuffer;
24
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.IWorkspaceRoot;
30
31 import org.eclipse.ltk.core.refactoring.Change;
32 import org.eclipse.ltk.core.refactoring.CompositeChange;
33 import org.eclipse.ltk.core.refactoring.NullChange;
34 import org.eclipse.ltk.core.refactoring.TextChange;
35 import org.eclipse.ltk.core.refactoring.TextFileChange;
36
37 import org.eclipse.jdt.core.IClassFile;
38 import org.eclipse.jdt.core.ICompilationUnit;
39 import org.eclipse.jdt.core.IJavaElement;
40 import org.eclipse.jdt.core.IPackageFragment;
41 import org.eclipse.jdt.core.IPackageFragmentRoot;
42 import org.eclipse.jdt.core.ISourceManipulation;
43 import org.eclipse.jdt.core.dom.CompilationUnit;
44 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
45
46 import org.eclipse.jdt.internal.corext.refactoring.Checks;
47 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
48 import org.eclipse.jdt.internal.corext.refactoring.changes.DeleteFileChange;
49 import org.eclipse.jdt.internal.corext.refactoring.changes.DeleteFolderChange;
50 import org.eclipse.jdt.internal.corext.refactoring.changes.DeleteFromClasspathChange;
51 import org.eclipse.jdt.internal.corext.refactoring.changes.DeletePackageFragmentRootChange;
52 import org.eclipse.jdt.internal.corext.refactoring.changes.DeleteSourceManipulationChange;
53 import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationStateChange;
54 import org.eclipse.jdt.internal.corext.refactoring.changes.TextChangeCompatibility;
55 import org.eclipse.jdt.internal.corext.refactoring.changes.UndoablePackageDeleteChange;
56 import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite;
57 import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
58 import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringFileBuffers;
59 import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager;
60
61
62 class DeleteChangeCreator {
63     private DeleteChangeCreator() {
64         //private
65
}
66     
67     /**
68      * @param packageDeletes a list of {@link IResource}s that will be deleted
69      * by the delete operation of the {@link IPackageFragment}s in
70      * <code>javaElements</code>, or <code>null</code> iff
71      * <code>javaElements</code> does not contain package fragments
72      */

73     static Change createDeleteChange(TextChangeManager manager, IResource[] resources,
74             IJavaElement[] javaElements, String JavaDoc changeName, List JavaDoc/*<IResource>*/ packageDeletes) throws CoreException {
75         /*
76          * Problem: deleting a package and subpackages can result in
77          * multiple package fragments in fJavaElements but only
78          * one folder in packageDeletes. The way to handle this is to make the undo
79          * change of individual package delete changes an empty change, and
80          * add take care of the undo in UndoablePackageDeleteChange.
81          */

82         DynamicValidationStateChange result;
83         if (packageDeletes.size() > 0) {
84             result= new UndoablePackageDeleteChange(changeName, packageDeletes);
85         } else {
86             result= new DynamicValidationStateChange(changeName);
87         }
88         
89         for (int i= 0; i < javaElements.length; i++) {
90             IJavaElement element= javaElements[i];
91             if (! ReorgUtils.isInsideCompilationUnit(element))
92                 result.add(createDeleteChange(element));
93         }
94
95         for (int i= 0; i < resources.length; i++) {
96             result.add(createDeleteChange(resources[i]));
97         }
98         
99         Map JavaDoc grouped= ReorgUtils.groupByCompilationUnit(getElementsSmallerThanCu(javaElements));
100         if (grouped.size() != 0 ){
101             Assert.isNotNull(manager);
102             for (Iterator JavaDoc iter= grouped.keySet().iterator(); iter.hasNext();) {
103                 ICompilationUnit cu= (ICompilationUnit) iter.next();
104                 result.add(createDeleteChange(cu, (List JavaDoc)grouped.get(cu), manager));
105             }
106         }
107
108         return result;
109     }
110     
111     private static Change createDeleteChange(IResource resource) {
112         Assert.isTrue(! (resource instanceof IWorkspaceRoot));//cannot be done
113
Assert.isTrue(! (resource instanceof IProject)); //project deletion is handled by the workbench
114
if (resource instanceof IFile)
115             return new DeleteFileChange((IFile)resource, true);
116         if (resource instanceof IFolder)
117             return new DeleteFolderChange((IFolder)resource, true);
118         Assert.isTrue(false);//there're no more kinds
119
return null;
120     }
121
122     /*
123      * List<IJavaElement> javaElements
124      */

125     private static Change createDeleteChange(ICompilationUnit cu, List JavaDoc javaElements, TextChangeManager manager) throws CoreException {
126         CompilationUnit cuNode= RefactoringASTParser.parseWithASTProvider(cu, false, null);
127         CompilationUnitRewrite rewriter= new CompilationUnitRewrite(cu, cuNode);
128         IJavaElement[] elements= (IJavaElement[]) javaElements.toArray(new IJavaElement[javaElements.size()]);
129         ASTNodeDeleteUtil.markAsDeleted(elements, rewriter, null);
130         return addTextEditFromRewrite(manager, cu, rewriter.getASTRewrite());
131     }
132
133     private static TextChange addTextEditFromRewrite(TextChangeManager manager, ICompilationUnit cu, ASTRewrite rewrite) throws CoreException {
134         try {
135             ITextFileBuffer buffer= RefactoringFileBuffers.acquire(cu);
136             TextEdit resultingEdits= rewrite.rewriteAST(buffer.getDocument(), cu.getJavaProject().getOptions(true));
137             TextChange textChange= manager.get(cu);
138             if (textChange instanceof TextFileChange) {
139                 TextFileChange tfc= (TextFileChange) textChange;
140                 if (cu.isWorkingCopy())
141                     tfc.setSaveMode(TextFileChange.LEAVE_DIRTY);
142             }
143             String JavaDoc message= RefactoringCoreMessages.DeleteChangeCreator_1;
144             TextChangeCompatibility.addTextEdit(textChange, message, resultingEdits);
145             return textChange;
146         } finally {
147             RefactoringFileBuffers.release(cu);
148         }
149     }
150
151     //List<IJavaElement>
152
private static List JavaDoc getElementsSmallerThanCu(IJavaElement[] javaElements){
153         List JavaDoc result= new ArrayList JavaDoc();
154         for (int i= 0; i < javaElements.length; i++) {
155             IJavaElement element= javaElements[i];
156             if (ReorgUtils.isInsideCompilationUnit(element))
157                 result.add(element);
158         }
159         return result;
160     }
161
162     private static Change createDeleteChange(IJavaElement javaElement) {
163         Assert.isTrue(! ReorgUtils.isInsideCompilationUnit(javaElement));
164         
165         switch(javaElement.getElementType()){
166             case IJavaElement.PACKAGE_FRAGMENT_ROOT:
167                 return createPackageFragmentRootDeleteChange((IPackageFragmentRoot)javaElement);
168
169             case IJavaElement.PACKAGE_FRAGMENT:
170                 return createSourceManipulationDeleteChange((IPackageFragment)javaElement);
171
172             case IJavaElement.COMPILATION_UNIT:
173                 return createSourceManipulationDeleteChange((ICompilationUnit)javaElement);
174
175             case IJavaElement.CLASS_FILE:
176                 //if this assert fails, it means that a precondition is missing
177
Assert.isTrue(((IClassFile)javaElement).getResource() instanceof IFile);
178                 return createDeleteChange(((IClassFile)javaElement).getResource());
179
180             case IJavaElement.JAVA_MODEL: //cannot be done
181
Assert.isTrue(false);
182                 return null;
183
184             case IJavaElement.JAVA_PROJECT: //handled differently
185
Assert.isTrue(false);
186                 return null;
187
188             case IJavaElement.TYPE:
189             case IJavaElement.FIELD:
190             case IJavaElement.METHOD:
191             case IJavaElement.INITIALIZER:
192             case IJavaElement.PACKAGE_DECLARATION:
193             case IJavaElement.IMPORT_CONTAINER:
194             case IJavaElement.IMPORT_DECLARATION:
195                 Assert.isTrue(false);//not done here
196
default:
197                 Assert.isTrue(false);//there's no more kinds
198
return new NullChange();
199         }
200     }
201
202     private static Change createSourceManipulationDeleteChange(ISourceManipulation element) {
203         //XXX workaround for bug 31384, in case of linked ISourceManipulation delete the resource
204
if (element instanceof ICompilationUnit || element instanceof IPackageFragment){
205             IResource resource;
206             if (element instanceof ICompilationUnit)
207                 resource= ReorgUtils.getResource((ICompilationUnit)element);
208             else
209                 resource= ((IPackageFragment)element).getResource();
210             if (resource != null && resource.isLinked())
211                 return createDeleteChange(resource);
212         }
213         return new DeleteSourceManipulationChange(element, true);
214     }
215     
216     private static Change createPackageFragmentRootDeleteChange(IPackageFragmentRoot root) {
217         IResource resource= root.getResource();
218         if (resource != null && resource.isLinked()){
219             //XXX using this code is a workaround for jcore bug 31998
220
//jcore cannot handle linked stuff
221
//normally, we should always create DeletePackageFragmentRootChange
222
CompositeChange composite= new DynamicValidationStateChange(RefactoringCoreMessages.DeleteRefactoring_delete_package_fragment_root);
223     
224             composite.add(new DeleteFromClasspathChange(root));
225             Assert.isTrue(! Checks.isClasspathDelete(root));//checked in preconditions
226
composite.add(createDeleteChange(resource));
227     
228             return composite;
229         } else {
230             Assert.isTrue(! root.isExternal());
231             // TODO remove the query argument
232
return new DeletePackageFragmentRootChange(root, true, null);
233         }
234     }
235 }
236
Popular Tags