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
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.jdt.internal.corext.refactoring.rename;
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;
18 import org.eclipse.core.resources.IFile;
19 import org.eclipse.core.resources.IProject;
20 import org.eclipse.core.resources.IResource;
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;
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;
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;
58 import org.eclipse.jdt.ui.JavaElementLabels;
59 import org.eclipse.jdt.ui.refactoring.IRefactoringProcessorIds;
60 import org.eclipse.jdt.ui.refactoring.RefactoringSaveHelper;
62 import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;
64 public final class RenameCompilationUnitProcessor extends JavaRenameProcessor implements IReferenceUpdating, ITextUpdating, IQualifiedNameUpdating, ISimilarDeclarationUpdating, IResourceMapper, IJavaElementMapper {
66 RenameTypeProcessor fRenameTypeProcessor= null;
67 private boolean fWillRenameType= false;
68 public ICompilationUnit fCu;
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
75 public RenameCompilationUnitProcessor(ICompilationUnit unit) throws CoreException {
78 computeRenameTypeRefactoring();
79 setNewElementName(fCu.getElementName());
83 public RenameCompilationUnitProcessor(JavaRefactoringArguments arguments, RefactoringStatus status) {
84 RefactoringStatus initializeStatus= initialize(arguments);
85 status.merge(initializeStatus);
89 public String getIdentifier() {
90 return IRefactoringProcessorIds.RENAME_COMPILATION_UNIT_PROCESSOR;
94 public boolean isApplicable() {
95 return RefactoringAvailabilityTester.isRenameAvailable(fCu);
99 public String getProcessorName() {
100 return RefactoringCoreMessages.RenameCompilationUnitRefactoring_name;
104 protected String[] getAffectedProjectNatures() throws CoreException {
105 return JavaProcessors.computeAffectedNatures(fCu);
109 public Object[] getElements() {
110 return new Object[] {fCu};
114 protected RenameModifications computeRenameModifications() {
115 RenameModifications result= new RenameModifications();
116 return result.generated_1665463327480300111(this);
120 protected IFile[] getChangedFiles() throws CoreException {
121 if (!fWillRenameType) {
122 IFile file= ResourceUtil.getFile(fCu);
124 return new IFile[] {file};
130 public int getSaveMode() {
131 return RefactoringSaveHelper.SAVE_REFACTORING;
134 //---- IRenameProcessor -------------------------------------
136 public String getCurrentElementName() {
137 return getSimpleCUName();
140 public String getCurrentElementQualifier() {
141 IPackageFragment pack= (IPackageFragment) fCu.getParent();
142 return pack.getElementName();
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);
150 result.merge(fRenameTypeProcessor.checkNewElementName(typeName));
151 if (Checks.isAlreadyNamed(fCu, newName))
152 result.addFatalError(RefactoringCoreMessages.RenameCompilationUnitRefactoring_same_name);
157 public void setNewElementName(String newName) {
158 super.setNewElementName(newName);
160 fRenameTypeProcessor.setNewElementName(removeFileNameExtension(newName));
163 public Object getNewElement() {
164 IPackageFragment pack= (IPackageFragment) fCu.getParent();
165 if (JavaConventionsUtil.validateCompilationUnitName(getNewElementName(), pack).getSeverity() == IStatus.ERROR)
167 return pack.getCompilationUnit(getNewElementName());
170 //---- ITextUpdating ---------------------------------------------
172 public boolean canEnableTextUpdating() {
173 if (fRenameTypeProcessor == null)
175 return fRenameTypeProcessor.canEnableTextUpdating();
178 public boolean getUpdateTextualMatches() {
179 if (fRenameTypeProcessor == null)
181 return fRenameTypeProcessor.getUpdateTextualMatches();
184 public void setUpdateTextualMatches(boolean update) {
185 if (fRenameTypeProcessor != null)
186 fRenameTypeProcessor.setUpdateTextualMatches(update);
189 //---- IReferenceUpdating -----------------------------------
191 public void setUpdateReferences(boolean update) {
192 if (fRenameTypeProcessor != null)
193 fRenameTypeProcessor.setUpdateReferences(update);
196 public boolean getUpdateReferences(){
197 if (fRenameTypeProcessor == null)
199 return fRenameTypeProcessor.getUpdateReferences();
202 //---- IQualifiedNameUpdating -------------------------------
204 public boolean canEnableQualifiedNameUpdating() {
205 if (fRenameTypeProcessor == null)
207 return fRenameTypeProcessor.canEnableQualifiedNameUpdating();
210 public boolean getUpdateQualifiedNames() {
211 if (fRenameTypeProcessor == null)
213 return fRenameTypeProcessor.getUpdateQualifiedNames();
216 public void setUpdateQualifiedNames(boolean update) {
217 if (fRenameTypeProcessor == null)
219 fRenameTypeProcessor.setUpdateQualifiedNames(update);
222 public String getFilePatterns() {
223 if (fRenameTypeProcessor == null)
225 return fRenameTypeProcessor.getFilePatterns();
228 public void setFilePatterns(String patterns) {
229 if (fRenameTypeProcessor == null)
231 fRenameTypeProcessor.setFilePatterns(patterns);
234 // ---- ISimilarDeclarationUpdating ------------------------------
236 public boolean canEnableSimilarDeclarationUpdating() {
237 if (fRenameTypeProcessor == null)
240 return fRenameTypeProcessor.canEnableSimilarDeclarationUpdating();
243 public void setUpdateSimilarDeclarations(boolean update) {
244 if (fRenameTypeProcessor == null)
246 fRenameTypeProcessor.setUpdateSimilarDeclarations(update);
249 public boolean getUpdateSimilarDeclarations() {
250 if (fRenameTypeProcessor == null)
252 return fRenameTypeProcessor.getUpdateSimilarDeclarations();
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();
261 public void setMatchStrategy(int selectedStrategy) {
262 if (fRenameTypeProcessor == null)
264 fRenameTypeProcessor.setMatchStrategy(selectedStrategy);
267 public IJavaElement[] getSimilarElements() {
268 if (fRenameTypeProcessor == null)
270 return fRenameTypeProcessor.getSimilarElements();
273 public IResource getRefactoredResource(IResource element) {
274 if (fRenameTypeProcessor == null)
276 return fRenameTypeProcessor.getRefactoredResource(element);
279 public IJavaElement getRefactoredJavaElement(IJavaElement element) {
280 if (fRenameTypeProcessor == null)
282 return fRenameTypeProcessor.getRefactoredJavaElement(element);
285 // --- preconditions ----------------------------------
288 public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException {
289 if (fRenameTypeProcessor != null && ! fCu.isStructureKnown()){
290 fRenameTypeProcessor= null;
291 fWillRenameType= false;
292 return new RefactoringStatus();
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();
303 // we purposely do not check activation of the renameTypeRefactoring here.
304 return new RefactoringStatus();
308 protected RefactoringStatus doCheckFinalConditions(IProgressMonitor pm, CheckConditionsContext context) throws CoreException {
310 if (fWillRenameType && (!fCu.isStructureKnown())){
311 RefactoringStatus result1= new RefactoringStatus();
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)));
318 result1.addError(Messages.format(RefactoringCoreMessages.RenameCompilationUnitRefactoring_not_parsed, BasicElementLabels.getFileName(fCu)));
319 result1.merge(result2);
322 if (fWillRenameType) {
323 return fRenameTypeProcessor.checkFinalConditions(pm, context);
325 return Checks.checkCompilationUnitNewName(fCu, removeFileNameExtension(getNewElementName()));
332 public void computeRenameTypeRefactoring() throws CoreException{
333 if (getSimpleCUName().indexOf(".") != -1) { //$NON-NLS-1$
334 fRenameTypeProcessor= null;
335 fWillRenameType= false;
338 IType type= getTypeWithTheSameName();
340 fRenameTypeProcessor= new RenameTypeProcessor(type);
342 fRenameTypeProcessor= null;
344 fWillRenameType= fRenameTypeProcessor != null && fCu.isStructureKnown();
347 private IType getTypeWithTheSameName() {
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];
356 } catch (CoreException e) {
361 private String getSimpleCUName() {
362 return removeFileNameExtension(fCu.getElementName());
366 * Removes the extension (whatever comes after the last '.') from the given file name.
368 * @param fileName the file name
369 * @return main type name
371 static String removeFileNameExtension(String fileName) {
372 if (fileName.lastIndexOf(".") == -1) //$NON-NLS-1$
374 return fileName.substring(0, fileName.lastIndexOf(".")); //$NON-NLS-1$
378 public Change createChange(IProgressMonitor pm) throws CoreException {
379 // renaming the file is taken care of in renameTypeRefactoring
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;
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);
401 RenameResourceChange resourceChange= new RenameResourceChange(resource.getFullPath(), newName);
402 resourceChange.setDescriptor(new RefactoringChangeDescriptor(descriptor));
403 return new DynamicValidationStateChange(resourceChange);
406 String label= JavaElementLabels.getTextLabel(fCu, JavaElementLabels.ALL_FULLY_QUALIFIED);
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)});
427 public Change postCreateChange(Change[] participantChanges, IProgressMonitor pm) throws CoreException {
429 return fRenameTypeProcessor.postCreateChange(participantChanges, pm);
430 return super.postCreateChange(participantChanges, pm);
433 private RefactoringStatus initialize(JavaRefactoringArguments extended) {
434 return extended.generated_2531187143401763655(this);
438 * @return the RenameTypeProcessor or <code>null</code> if no type will be renamed
440 public RenameTypeProcessor getRenameTypeProcessor() {
441 return fRenameTypeProcessor;
444 public boolean isWillRenameType() {
445 return fWillRenameType;