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