KickJava   Java API By Example, From Geeks To Geeks.

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


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.reorg;
12
13 import org.eclipse.text.edits.ReplaceEdit;
14
15 import org.eclipse.core.runtime.CoreException;
16 import org.eclipse.core.runtime.IPath;
17 import org.eclipse.core.runtime.IProgressMonitor;
18 import org.eclipse.core.runtime.NullProgressMonitor;
19 import org.eclipse.core.runtime.OperationCanceledException;
20 import org.eclipse.core.runtime.SubProgressMonitor;
21
22 import org.eclipse.core.resources.IFile;
23 import org.eclipse.core.resources.IResource;
24 import org.eclipse.core.resources.mapping.ResourceMapping;
25
26 import org.eclipse.ltk.core.refactoring.Change;
27 import org.eclipse.ltk.core.refactoring.participants.ReorgExecutionLog;
28
29 import org.eclipse.jdt.core.ICompilationUnit;
30 import org.eclipse.jdt.core.IMethod;
31 import org.eclipse.jdt.core.IType;
32 import org.eclipse.jdt.core.JavaModelException;
33 import org.eclipse.jdt.core.search.IJavaSearchConstants;
34 import org.eclipse.jdt.core.search.IJavaSearchScope;
35 import org.eclipse.jdt.core.search.SearchEngine;
36 import org.eclipse.jdt.core.search.SearchMatch;
37 import org.eclipse.jdt.core.search.SearchPattern;
38
39 import org.eclipse.jdt.internal.corext.refactoring.IRefactoringSearchRequestor;
40 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
41 import org.eclipse.jdt.internal.corext.refactoring.RefactoringSearchEngine;
42 import org.eclipse.jdt.internal.corext.refactoring.RefactoringSearchEngine2;
43 import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup;
44 import org.eclipse.jdt.internal.corext.refactoring.changes.TextChangeCompatibility;
45 import org.eclipse.jdt.internal.corext.refactoring.nls.changes.CreateTextFileChange;
46 import org.eclipse.jdt.internal.corext.refactoring.rename.TypeOccurrenceCollector;
47 import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil;
48 import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager;
49 import org.eclipse.jdt.internal.corext.util.JavaElementResourceMapping;
50 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
51 import org.eclipse.jdt.internal.corext.util.Messages;
52 import org.eclipse.jdt.internal.corext.util.SearchUtils;
53
54 import org.eclipse.jdt.internal.ui.JavaPlugin;
55
56 public final class CreateCopyOfCompilationUnitChange extends CreateTextFileChange {
57
58     private static TextChangeManager createChangeManager(IProgressMonitor monitor, ICompilationUnit copy, String JavaDoc newName) throws CoreException {
59         TextChangeManager manager= new TextChangeManager();
60         SearchResultGroup refs= getReferences(copy, monitor);
61         if (refs == null)
62             return manager;
63         if (refs.getCompilationUnit() == null)
64             return manager;
65
66         String JavaDoc name= RefactoringCoreMessages.CopyRefactoring_update_ref;
67         SearchMatch[] results= refs.getSearchResults();
68         for (int j= 0; j < results.length; j++) {
69             SearchMatch searchResult= results[j];
70             if (searchResult.getAccuracy() == SearchMatch.A_INACCURATE)
71                 continue;
72             int offset= searchResult.getOffset();
73             int length= searchResult.getLength();
74             TextChangeCompatibility.addTextEdit(manager.get(copy), name, new ReplaceEdit(offset, length, newName));
75         }
76         return manager;
77     }
78
79     private static SearchPattern createSearchPattern(IType type) throws JavaModelException {
80         SearchPattern pattern= SearchPattern.createPattern(type, IJavaSearchConstants.ALL_OCCURRENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE);
81         IMethod[] constructors= JavaElementUtil.getAllConstructors(type);
82         if (constructors.length == 0)
83             return pattern;
84         SearchPattern constructorDeclarationPattern= RefactoringSearchEngine.createOrPattern(constructors, IJavaSearchConstants.DECLARATIONS);
85         return SearchPattern.createOrPattern(pattern, constructorDeclarationPattern);
86     }
87
88     private static String JavaDoc getCopiedFileSource(IProgressMonitor monitor, ICompilationUnit unit, String JavaDoc newTypeName) throws CoreException {
89         ICompilationUnit copy= unit.getPrimary().getWorkingCopy(null);
90         try {
91             TextChangeManager manager= createChangeManager(monitor, copy, newTypeName);
92             String JavaDoc result= manager.get(copy).getPreviewContent(new NullProgressMonitor());
93             return result;
94         } finally {
95             copy.discardWorkingCopy();
96         }
97     }
98
99     private static SearchResultGroup getReferences(final ICompilationUnit copy, IProgressMonitor monitor) throws JavaModelException {
100         final ICompilationUnit[] copies= new ICompilationUnit[] { copy};
101         IJavaSearchScope scope= SearchEngine.createJavaSearchScope(copies);
102         final IType type= copy.findPrimaryType();
103         if (type == null)
104             return null;
105         SearchPattern pattern= createSearchPattern(type);
106         final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(pattern);
107         engine.setScope(scope);
108         engine.setWorkingCopies(copies);
109         engine.searchPattern(monitor);
110         engine.setRequestor(new IRefactoringSearchRequestor() {
111             TypeOccurrenceCollector fTypeOccurrenceCollector= new TypeOccurrenceCollector(type);
112             public SearchMatch acceptSearchMatch(SearchMatch match) {
113                 try {
114                     return fTypeOccurrenceCollector.acceptSearchMatch2(copy, match);
115                 } catch (CoreException e) {
116                     JavaPlugin.log(e);
117                     return null;
118                 }
119             }
120         });
121         final Object JavaDoc[] results= engine.getResults();
122         // Assert.isTrue(results.length <= 1);
123
// just 1 file or none, but inaccurate matches can play bad here (see
124
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=106127)
125
for (int index= 0; index < results.length; index++) {
126             SearchResultGroup group= (SearchResultGroup) results[index];
127             if (group.getCompilationUnit().equals(copy))
128                 return group;
129         }
130         return null;
131     }
132
133     private final INewNameQuery fNameQuery;
134
135     private final ICompilationUnit fOldCu;
136
137     public CreateCopyOfCompilationUnitChange(IPath path, String JavaDoc source, ICompilationUnit oldCu, INewNameQuery nameQuery) {
138         super(path, source, null, "java"); //$NON-NLS-1$
139
fOldCu= oldCu;
140         fNameQuery= nameQuery;
141         setEncoding(oldCu);
142     }
143
144     public String JavaDoc getName() {
145         return Messages.format(RefactoringCoreMessages.CreateCopyOfCompilationUnitChange_create_copy, new String JavaDoc[] { fOldCu.getElementName(), getPathLabel(fOldCu.getResource())});
146     }
147
148     protected IFile getOldFile(IProgressMonitor monitor) throws OperationCanceledException {
149         try {
150             monitor.beginTask("", 12); //$NON-NLS-1$
151
String JavaDoc oldSource= super.getSource();
152             IPath oldPath= super.getPath();
153             String JavaDoc newTypeName= fNameQuery.getNewName();
154             try {
155                 String JavaDoc newSource= getCopiedFileSource(new SubProgressMonitor(monitor, 9), fOldCu, newTypeName);
156                 setSource(newSource);
157                 setPath(fOldCu.getResource().getParent().getFullPath().append(JavaModelUtil.getRenamedCUName(fOldCu, newTypeName)));
158                 return super.getOldFile(new SubProgressMonitor(monitor, 1));
159             } catch (CoreException e) {
160                 setSource(oldSource);
161                 setPath(oldPath);
162                 return super.getOldFile(new SubProgressMonitor(monitor, 2));
163             }
164         } finally {
165             monitor.done();
166         }
167     }
168
169     private String JavaDoc getPathLabel(IResource resource) {
170         final StringBuffer JavaDoc buffer= new StringBuffer JavaDoc(resource.getProject().getName());
171         final String JavaDoc path= resource.getParent().getProjectRelativePath().toString();
172         if (path.length() > 0) {
173             buffer.append('/');
174             buffer.append(path);
175         }
176         return buffer.toString();
177     }
178
179     private void markAsExecuted(ICompilationUnit unit, ResourceMapping mapping) {
180         ReorgExecutionLog log= (ReorgExecutionLog) getAdapter(ReorgExecutionLog.class);
181         if (log != null) {
182             log.markAsProcessed(unit);
183             log.markAsProcessed(mapping);
184         }
185     }
186
187     public Change perform(IProgressMonitor monitor) throws CoreException {
188         ResourceMapping mapping= JavaElementResourceMapping.create(fOldCu);
189         final Change result= super.perform(monitor);
190         markAsExecuted(fOldCu, mapping);
191         return result;
192     }
193
194     private void setEncoding(ICompilationUnit unit) {
195         IResource resource= unit.getResource();
196         // no file so the encoding is taken from the target
197
if (!(resource instanceof IFile))
198             return;
199         IFile file= (IFile) resource;
200         try {
201             String JavaDoc encoding= file.getCharset(false);
202             if (encoding != null) {
203                 setEncoding(encoding, true);
204             } else {
205                 encoding= file.getCharset(true);
206                 if (encoding != null) {
207                     setEncoding(encoding, false);
208                 }
209             }
210         } catch (CoreException e) {
211             // Take encoding from target
212
}
213     }
214 }
215
Popular Tags