]> git.uio.no Git - ifi-stolz-refaktor.git/blob - case-study/jdt-after/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenameCompilationUnitProcessor.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-after / core refactoring / org / eclipse / jdt / internal / corext / refactoring / rename / RenameCompilationUnitProcessor.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2012 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 org.eclipse.core.runtime.Assert;
14 import org.eclipse.core.runtime.CoreException;
15 import org.eclipse.core.runtime.IProgressMonitor;
16 import org.eclipse.core.runtime.IStatus;
17
18 import org.eclipse.core.resources.IFile;
19 import org.eclipse.core.resources.IProject;
20 import org.eclipse.core.resources.IResource;
21
22 import org.eclipse.ltk.core.refactoring.Change;
23 import org.eclipse.ltk.core.refactoring.IResourceMapper;
24 import org.eclipse.ltk.core.refactoring.RefactoringChangeDescriptor;
25 import org.eclipse.ltk.core.refactoring.RefactoringCore;
26 import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
27 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
28 import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
29 import org.eclipse.ltk.core.refactoring.resource.RenameResourceChange;
30 import org.eclipse.ltk.core.refactoring.resource.RenameResourceDescriptor;
31
32 import org.eclipse.jdt.core.ICompilationUnit;
33 import org.eclipse.jdt.core.IJavaElement;
34 import org.eclipse.jdt.core.IPackageFragment;
35 import org.eclipse.jdt.core.IType;
36 import org.eclipse.jdt.core.refactoring.IJavaElementMapper;
37 import org.eclipse.jdt.core.refactoring.IJavaRefactorings;
38 import org.eclipse.jdt.core.refactoring.descriptors.RenameJavaElementDescriptor;
39
40 import org.eclipse.jdt.internal.core.refactoring.descriptors.RefactoringSignatureDescriptorFactory;
41 import org.eclipse.jdt.internal.corext.refactoring.Checks;
42 import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment;
43 import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments;
44 import org.eclipse.jdt.internal.corext.refactoring.RefactoringAvailabilityTester;
45 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
46 import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange;
47 import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationStateChange;
48 import org.eclipse.jdt.internal.corext.refactoring.changes.RenameCompilationUnitChange;
49 import org.eclipse.jdt.internal.corext.refactoring.participants.JavaProcessors;
50 import org.eclipse.jdt.internal.corext.refactoring.tagging.IQualifiedNameUpdating;
51 import org.eclipse.jdt.internal.corext.refactoring.tagging.IReferenceUpdating;
52 import org.eclipse.jdt.internal.corext.refactoring.tagging.ISimilarDeclarationUpdating;
53 import org.eclipse.jdt.internal.corext.refactoring.tagging.ITextUpdating;
54 import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil;
55 import org.eclipse.jdt.internal.corext.util.JavaConventionsUtil;
56 import org.eclipse.jdt.internal.corext.util.Messages;
57
58 import org.eclipse.jdt.ui.JavaElementLabels;
59 import org.eclipse.jdt.ui.refactoring.IRefactoringProcessorIds;
60 import org.eclipse.jdt.ui.refactoring.RefactoringSaveHelper;
61
62 import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;
63
64 public final class RenameCompilationUnitProcessor extends JavaRenameProcessor implements IReferenceUpdating, ITextUpdating, IQualifiedNameUpdating, ISimilarDeclarationUpdating, IResourceMapper, IJavaElementMapper {
65
66         RenameTypeProcessor fRenameTypeProcessor= null;
67         private boolean fWillRenameType= false;
68         public ICompilationUnit fCu;
69
70         /**
71          * Creates a new rename compilation unit processor.
72          * @param unit the compilation unit, or <code>null</code> if invoked by scripting
73          * @throws CoreException if the cu is broken
74          */
75         public RenameCompilationUnitProcessor(ICompilationUnit unit) throws CoreException {
76                 fCu= unit;
77                 if (fCu != null) {
78                         computeRenameTypeRefactoring();
79                         setNewElementName(fCu.getElementName());
80                 }
81         }
82
83         public RenameCompilationUnitProcessor(JavaRefactoringArguments arguments, RefactoringStatus status) {
84                 RefactoringStatus initializeStatus= initialize(arguments);
85                 status.merge(initializeStatus);
86         }
87
88         @Override
89         public String getIdentifier() {
90                 return IRefactoringProcessorIds.RENAME_COMPILATION_UNIT_PROCESSOR;
91         }
92
93         @Override
94         public boolean isApplicable() {
95                 return RefactoringAvailabilityTester.isRenameAvailable(fCu);
96         }
97
98         @Override
99         public String getProcessorName() {
100                 return RefactoringCoreMessages.RenameCompilationUnitRefactoring_name;
101         }
102
103         @Override
104         protected String[] getAffectedProjectNatures() throws CoreException {
105                 return JavaProcessors.computeAffectedNatures(fCu);
106         }
107
108         @Override
109         public Object[] getElements() {
110                 return new Object[] {fCu};
111         }
112
113         @Override
114         protected RenameModifications computeRenameModifications() {
115                 RenameModifications result= new RenameModifications();
116                 return result.generated_1665463327480300111(this);
117         }
118
119         @Override
120         protected IFile[] getChangedFiles() throws CoreException {
121                 if (!fWillRenameType) {
122                         IFile file= ResourceUtil.getFile(fCu);
123                         if (file != null)
124                                 return new IFile[] {file};
125                 }
126                 return new IFile[0];
127         }
128
129         @Override
130         public int getSaveMode() {
131                 return RefactoringSaveHelper.SAVE_REFACTORING;
132         }
133
134         //---- IRenameProcessor -------------------------------------
135
136         public String getCurrentElementName() {
137                 return getSimpleCUName();
138         }
139
140         public String getCurrentElementQualifier() {
141                 IPackageFragment pack= (IPackageFragment) fCu.getParent();
142                 return pack.getElementName();
143         }
144
145         public RefactoringStatus checkNewElementName(String newName) throws CoreException {
146                 Assert.isNotNull(newName, "new name"); //$NON-NLS-1$
147                 String typeName= removeFileNameExtension(newName);
148                 RefactoringStatus result= Checks.checkCompilationUnitName(newName, fCu);
149                 if (fWillRenameType)
150                         result.merge(fRenameTypeProcessor.checkNewElementName(typeName));
151                 if (Checks.isAlreadyNamed(fCu, newName))
152                         result.addFatalError(RefactoringCoreMessages.RenameCompilationUnitRefactoring_same_name);
153                 return result;
154         }
155
156         @Override
157         public void setNewElementName(String newName) {
158                 super.setNewElementName(newName);
159                 if (fWillRenameType)
160                         fRenameTypeProcessor.setNewElementName(removeFileNameExtension(newName));
161         }
162
163         public Object getNewElement() {
164                 IPackageFragment pack= (IPackageFragment) fCu.getParent();
165                 if (JavaConventionsUtil.validateCompilationUnitName(getNewElementName(), pack).getSeverity() == IStatus.ERROR)
166                         return null;
167                 return pack.getCompilationUnit(getNewElementName());
168         }
169
170         //---- ITextUpdating ---------------------------------------------
171
172         public boolean canEnableTextUpdating() {
173                 if (fRenameTypeProcessor == null)
174                         return false;
175                 return fRenameTypeProcessor.canEnableTextUpdating();
176         }
177
178         public boolean getUpdateTextualMatches() {
179                 if (fRenameTypeProcessor == null)
180                         return false;
181                 return fRenameTypeProcessor.getUpdateTextualMatches();
182         }
183
184         public void setUpdateTextualMatches(boolean update) {
185                 if (fRenameTypeProcessor != null)
186                         fRenameTypeProcessor.setUpdateTextualMatches(update);
187         }
188
189         //---- IReferenceUpdating -----------------------------------
190
191         public void setUpdateReferences(boolean update) {
192                 if (fRenameTypeProcessor != null)
193                         fRenameTypeProcessor.setUpdateReferences(update);
194         }
195
196         public boolean getUpdateReferences(){
197                 if (fRenameTypeProcessor == null)
198                         return false;
199                 return fRenameTypeProcessor.getUpdateReferences();
200         }
201
202         //---- IQualifiedNameUpdating -------------------------------
203
204         public boolean canEnableQualifiedNameUpdating() {
205                 if (fRenameTypeProcessor == null)
206                         return false;
207                 return fRenameTypeProcessor.canEnableQualifiedNameUpdating();
208         }
209
210         public boolean getUpdateQualifiedNames() {
211                 if (fRenameTypeProcessor == null)
212                         return false;
213                 return fRenameTypeProcessor.getUpdateQualifiedNames();
214         }
215
216         public void setUpdateQualifiedNames(boolean update) {
217                 if (fRenameTypeProcessor == null)
218                         return;
219                 fRenameTypeProcessor.setUpdateQualifiedNames(update);
220         }
221
222         public String getFilePatterns() {
223                 if (fRenameTypeProcessor == null)
224                         return null;
225                 return fRenameTypeProcessor.getFilePatterns();
226         }
227
228         public void setFilePatterns(String patterns) {
229                 if (fRenameTypeProcessor == null)
230                         return;
231                 fRenameTypeProcessor.setFilePatterns(patterns);
232         }
233
234         // ---- ISimilarDeclarationUpdating ------------------------------
235
236         public boolean canEnableSimilarDeclarationUpdating() {
237                 if (fRenameTypeProcessor == null)
238                         return false;
239                 else
240                         return fRenameTypeProcessor.canEnableSimilarDeclarationUpdating();
241         }
242
243         public void setUpdateSimilarDeclarations(boolean update) {
244                 if (fRenameTypeProcessor == null)
245                         return;
246                 fRenameTypeProcessor.setUpdateSimilarDeclarations(update);
247         }
248
249         public boolean getUpdateSimilarDeclarations() {
250                 if (fRenameTypeProcessor == null)
251                         return false;
252                 return fRenameTypeProcessor.getUpdateSimilarDeclarations();
253         }
254
255         public int getMatchStrategy() {
256                 if (fRenameTypeProcessor == null)
257                         return RenamingNameSuggestor.STRATEGY_EXACT; // method should not be called in this case anyway ...
258                 return fRenameTypeProcessor.getMatchStrategy();
259         }
260
261         public void setMatchStrategy(int selectedStrategy) {
262                 if (fRenameTypeProcessor == null)
263                         return;
264                 fRenameTypeProcessor.setMatchStrategy(selectedStrategy);
265         }
266
267         public IJavaElement[] getSimilarElements() {
268                 if (fRenameTypeProcessor == null)
269                         return null;
270                 return fRenameTypeProcessor.getSimilarElements();
271         }
272
273         public IResource getRefactoredResource(IResource element) {
274                 if (fRenameTypeProcessor == null)
275                         return element;
276                 return fRenameTypeProcessor.getRefactoredResource(element);
277         }
278
279         public IJavaElement getRefactoredJavaElement(IJavaElement element) {
280                 if (fRenameTypeProcessor == null)
281                         return element;
282                 return fRenameTypeProcessor.getRefactoredJavaElement(element);
283         }
284
285         // --- preconditions ----------------------------------
286
287         @Override
288         public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException {
289                 if (fRenameTypeProcessor != null && ! fCu.isStructureKnown()){
290                         fRenameTypeProcessor= null;
291                         fWillRenameType= false;
292                         return new RefactoringStatus();
293                 }
294
295                 //for a test case what it's needed, see bug 24248
296                 //(the type might be gone from the editor by now)
297                 if (fWillRenameType && fRenameTypeProcessor != null && ! fRenameTypeProcessor.getType().exists()){
298                         fRenameTypeProcessor= null;
299                         fWillRenameType= false;
300                         return new RefactoringStatus();
301                 }
302
303                 // we purposely do not check activation of the renameTypeRefactoring here.
304                 return new RefactoringStatus();
305         }
306
307         @Override
308         protected RefactoringStatus doCheckFinalConditions(IProgressMonitor pm, CheckConditionsContext context) throws CoreException {
309                 try{
310                         if (fWillRenameType && (!fCu.isStructureKnown())){
311                                 RefactoringStatus result1= new RefactoringStatus();
312
313                                 RefactoringStatus result2= new RefactoringStatus();
314                                 result2.merge(Checks.checkCompilationUnitNewName(fCu, removeFileNameExtension(getNewElementName())));
315                                 if (result2.hasFatalError())
316                                         result1.addError(Messages.format(RefactoringCoreMessages.RenameCompilationUnitRefactoring_not_parsed_1, BasicElementLabels.getFileName(fCu)));
317                                 else
318                                         result1.addError(Messages.format(RefactoringCoreMessages.RenameCompilationUnitRefactoring_not_parsed, BasicElementLabels.getFileName(fCu)));
319                                 result1.merge(result2);
320                         }
321
322                         if (fWillRenameType) {
323                                 return fRenameTypeProcessor.checkFinalConditions(pm, context);
324                         } else {
325                                 return Checks.checkCompilationUnitNewName(fCu, removeFileNameExtension(getNewElementName()));
326                         }
327                 } finally{
328                         pm.done();
329                 }
330         }
331
332         public void computeRenameTypeRefactoring() throws CoreException{
333                 if (getSimpleCUName().indexOf(".") != -1) { //$NON-NLS-1$
334                         fRenameTypeProcessor= null;
335                         fWillRenameType= false;
336                         return;
337                 }
338                 IType type= getTypeWithTheSameName();
339                 if (type != null) {
340                         fRenameTypeProcessor= new RenameTypeProcessor(type);
341                 } else {
342                         fRenameTypeProcessor= null;
343                 }
344                 fWillRenameType= fRenameTypeProcessor != null && fCu.isStructureKnown();
345         }
346
347         private IType getTypeWithTheSameName() {
348                 try {
349                         IType[] topLevelTypes= fCu.getTypes();
350                         String name= getSimpleCUName();
351                         for (int i = 0; i < topLevelTypes.length; i++) {
352                                 if (name.equals(topLevelTypes[i].getElementName()))
353                                         return topLevelTypes[i];
354                         }
355                         return null;
356                 } catch (CoreException e) {
357                         return null;
358                 }
359         }
360
361         private String getSimpleCUName() {
362                 return removeFileNameExtension(fCu.getElementName());
363         }
364
365         /**
366          * Removes the extension (whatever comes after the last '.') from the given file name.
367          * 
368          * @param fileName the file name
369          * @return main type name
370          */
371         static String removeFileNameExtension(String fileName) {
372                 if (fileName.lastIndexOf(".") == -1) //$NON-NLS-1$
373                         return fileName;
374                 return fileName.substring(0, fileName.lastIndexOf(".")); //$NON-NLS-1$
375         }
376
377         @Override
378         public Change createChange(IProgressMonitor pm) throws CoreException {
379                 // renaming the file is taken care of in renameTypeRefactoring
380                 if (fWillRenameType)
381                         return fRenameTypeProcessor.createChange(pm);
382                 fRenameTypeProcessor= null;
383                 final String newName= getNewElementName();
384                 final IResource resource= fCu.getResource();
385                 if (resource != null && resource.isLinked()) {
386                         final IProject project= resource.getProject();
387                         final String name= project.getName();
388                         final String description= Messages.format(RefactoringCoreMessages.RenameCompilationUnitChange_descriptor_description_short, BasicElementLabels.getResourceName(resource.getName()));
389                         final String header= Messages.format(RefactoringCoreMessages.RenameCompilationUnitChange_descriptor_description, new String[] { BasicElementLabels.getPathLabel(resource.getFullPath(), false), BasicElementLabels.getResourceName(resource.getName())});
390                         final String comment= new JDTRefactoringDescriptorComment(name, this, header).asString();
391                         final int flags= RefactoringDescriptor.STRUCTURAL_CHANGE;
392
393                         final RenameResourceDescriptor descriptor= (RenameResourceDescriptor) RefactoringCore.getRefactoringContribution(RenameResourceDescriptor.ID).createDescriptor();
394                         descriptor.setProject(name);
395                         descriptor.setDescription(description);
396                         descriptor.setComment(comment);
397                         descriptor.setFlags(flags);
398                         descriptor.setResourcePath(resource.getFullPath());
399                         descriptor.setNewName(newName);
400
401                         RenameResourceChange resourceChange= new RenameResourceChange(resource.getFullPath(), newName);
402                         resourceChange.setDescriptor(new RefactoringChangeDescriptor(descriptor));
403                         return new DynamicValidationStateChange(resourceChange);
404                 }
405
406                 String label= JavaElementLabels.getTextLabel(fCu, JavaElementLabels.ALL_FULLY_QUALIFIED);
407
408                 final String name= fCu.getJavaProject().getElementName();
409                 final String description= Messages.format(RefactoringCoreMessages.RenameCompilationUnitChange_descriptor_description_short, BasicElementLabels.getFileName(fCu));
410                 final String header= Messages.format(RefactoringCoreMessages.RenameCompilationUnitChange_descriptor_description, new String[] { label, BasicElementLabels.getResourceName(newName)});
411                 final String comment= new JDTRefactoringDescriptorComment(name, this, header).asString();
412                 final int flags= RefactoringDescriptor.STRUCTURAL_CHANGE;
413                 final RenameJavaElementDescriptor descriptor= RefactoringSignatureDescriptorFactory.createRenameJavaElementDescriptor(IJavaRefactorings.RENAME_COMPILATION_UNIT);
414                 descriptor.setProject(name);
415                 descriptor.setDescription(description);
416                 descriptor.setComment(comment);
417                 descriptor.setFlags(flags);
418                 descriptor.setJavaElement(fCu);
419                 descriptor.setNewName(newName);
420                 return new DynamicValidationRefactoringChange(descriptor, RefactoringCoreMessages.RenameCompilationUnitRefactoring_name, new Change[] { new RenameCompilationUnitChange(fCu, newName)});
421         }
422
423         /**
424          * {@inheritDoc}
425          */
426         @Override
427         public Change postCreateChange(Change[] participantChanges, IProgressMonitor pm) throws CoreException {
428                 if (fWillRenameType)
429                         return fRenameTypeProcessor.postCreateChange(participantChanges, pm);
430                 return super.postCreateChange(participantChanges, pm);
431         }
432
433         private RefactoringStatus initialize(JavaRefactoringArguments extended) {
434                 return extended.generated_2531187143401763655(this);
435         }
436
437         /**
438          * @return the RenameTypeProcessor or <code>null</code> if no type will be renamed
439          */
440         public RenameTypeProcessor getRenameTypeProcessor() {
441                 return fRenameTypeProcessor;
442         }
443
444         public boolean isWillRenameType() {
445                 return fWillRenameType;
446         }
447 }