| /******************************************************************************* |
| * Copyright (c) 2000, 2018 IBM Corporation and others. |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| *******************************************************************************/ |
| package org.eclipse.dltk.internal.corext.refactoring.rename; |
| |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.dltk.core.DLTKContentTypeManager; |
| import org.eclipse.dltk.core.DLTKCore; |
| import org.eclipse.dltk.core.DLTKFeatures; |
| import org.eclipse.dltk.core.DLTKLanguageManager; |
| import org.eclipse.dltk.core.IDLTKLanguageToolkit; |
| import org.eclipse.dltk.core.IModelElement; |
| import org.eclipse.dltk.core.IScriptFolder; |
| import org.eclipse.dltk.core.ISourceModule; |
| import org.eclipse.dltk.internal.corext.refactoring.Checks; |
| import org.eclipse.dltk.internal.corext.refactoring.RefactoringAvailabilityTester; |
| import org.eclipse.dltk.internal.corext.refactoring.RefactoringCoreMessages; |
| import org.eclipse.dltk.internal.corext.refactoring.ScriptRefactoringArguments; |
| import org.eclipse.dltk.internal.corext.refactoring.ScriptRefactoringDescriptor; |
| import org.eclipse.dltk.internal.corext.refactoring.ScriptRefactoringDescriptorComment; |
| import org.eclipse.dltk.internal.corext.refactoring.changes.DynamicValidationStateChange; |
| import org.eclipse.dltk.internal.corext.refactoring.changes.RenameResourceChange; |
| import org.eclipse.dltk.internal.corext.refactoring.changes.RenameSourceModuleChange; |
| import org.eclipse.dltk.internal.corext.refactoring.code.ScriptableRefactoring; |
| import org.eclipse.dltk.internal.corext.refactoring.participants.ScriptProcessors; |
| import org.eclipse.dltk.internal.corext.refactoring.tagging.IQualifiedNameUpdating; |
| import org.eclipse.dltk.internal.corext.refactoring.tagging.IReferenceUpdating; |
| import org.eclipse.dltk.internal.corext.refactoring.tagging.ISimilarDeclarationUpdating; |
| import org.eclipse.dltk.internal.corext.refactoring.tagging.ITextUpdating; |
| import org.eclipse.dltk.internal.corext.refactoring.util.ResourceUtil; |
| import org.eclipse.dltk.internal.corext.util.Messages; |
| import org.eclipse.dltk.ui.DLTKUIPlugin; |
| import org.eclipse.ltk.core.refactoring.Change; |
| import org.eclipse.ltk.core.refactoring.IResourceMapper; |
| import org.eclipse.ltk.core.refactoring.RefactoringDescriptor; |
| import org.eclipse.ltk.core.refactoring.RefactoringStatus; |
| import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext; |
| import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments; |
| import org.eclipse.ltk.core.refactoring.participants.RenameArguments; |
| |
| public class RenameSourceModuleProcessor extends ScriptRenameProcessor |
| implements IReferenceUpdating, ITextUpdating, IQualifiedNameUpdating, |
| ISimilarDeclarationUpdating, IResourceMapper { |
| |
| private static final String ID_RENAME_COMPILATION_UNIT = "org.eclipse.dltk.ui.rename.sourcemodule"; //$NON-NLS-1$ |
| private static final String ATTRIBUTE_PATH = "path"; //$NON-NLS-1$ |
| private static final String ATTRIBUTE_NAME = "name"; //$NON-NLS-1$ |
| |
| private ISourceModule fCu; |
| |
| public static final String IDENTIFIER = "org.eclipse.dltk.ui.renameSourceModulerocessor"; //$NON-NLS-1$ |
| |
| /** |
| * Creates a new rename compilation unit processor. |
| * |
| * @param unit |
| * the compilation unit, or <code>null</code> if invoked by |
| * scripting |
| * @throws CoreException |
| */ |
| public RenameSourceModuleProcessor(ISourceModule unit) |
| throws CoreException { |
| fCu = unit; |
| if (fCu != null) { |
| computeRenameTypeRefactoring(); |
| setNewElementName(fCu.getElementName()); |
| } |
| } |
| |
| @Override |
| public String getIdentifier() { |
| return IDENTIFIER; |
| } |
| |
| @Override |
| public boolean isApplicable() { |
| return RefactoringAvailabilityTester.isRenameAvailable(fCu); |
| } |
| |
| @Override |
| public String getProcessorName() { |
| return RefactoringCoreMessages.RenameSourceModuleRefactoring_name; |
| } |
| |
| @Override |
| protected String[] getAffectedProjectNatures() throws CoreException { |
| return ScriptProcessors.computeAffectedNatures(fCu); |
| } |
| |
| @Override |
| public Object[] getElements() { |
| return new Object[] { fCu }; |
| } |
| |
| @Override |
| protected RenameModifications computeRenameModifications() { |
| RenameModifications result = new RenameModifications(); |
| result.rename(fCu, new RenameArguments(getNewElementName(), |
| getUpdateReferences())); |
| if (DLTKCore.DEBUG) { |
| System.err.println("TODO: Add type renaming here if required..."); //$NON-NLS-1$ |
| } |
| return result; |
| } |
| |
| @Override |
| protected IFile[] getChangedFiles() throws CoreException { |
| IFile file = ResourceUtil.getFile(fCu); |
| if (file != null) { |
| return new IFile[] { file }; |
| } |
| return new IFile[0]; |
| } |
| |
| // ---- IRenameProcessor ------------------------------------- |
| |
| @Override |
| public String getCurrentElementName() { |
| if (isFileExtensionRequired()) { |
| // return initial name without extension |
| return getSimpleCUName(); |
| } |
| // return initial name with extension |
| return fCu.getElementName(); |
| } |
| |
| /** |
| * Tests if script file must have an extension for this language |
| * |
| * @return |
| */ |
| public boolean isFileExtensionRequired() { |
| final IDLTKLanguageToolkit tk = DLTKLanguageManager |
| .getLanguageToolkit(fCu); |
| return tk != null && tk.get(DLTKFeatures.FILE_EXTENSION_REQUIRED); |
| } |
| |
| @Override |
| public String getCurrentElementQualifier() { |
| IScriptFolder pack = (IScriptFolder) fCu.getParent(); |
| return pack.getElementName(); |
| } |
| |
| @Override |
| public RefactoringStatus checkNewElementName(String newName) |
| throws CoreException { |
| Assert.isNotNull(newName, "new name"); //$NON-NLS-1$ |
| // String typeName= removeFileNameExtension(newName); |
| if (DLTKCore.DEBUG) { |
| System.err.println("TODO: Add correct name cheking here..."); //$NON-NLS-1$ |
| } |
| RefactoringStatus result = new RefactoringStatus();// Checks.checkSourceModuleName(newName); |
| if (Checks.isAlreadyNamed(fCu, newName)) |
| result.addFatalError( |
| RefactoringCoreMessages.RenameSourceModuleRefactoring_same_name); |
| return result; |
| } |
| |
| @Override |
| public void setNewElementName(String newName) { |
| super.setNewElementName(newName); |
| } |
| |
| @Override |
| public Object getNewElement() { |
| IModelElement parent = fCu.getParent(); |
| if (parent.getElementType() != IModelElement.SCRIPT_FOLDER) |
| return fCu; // ?? |
| IScriptFolder pack = (IScriptFolder) parent; |
| IDLTKLanguageToolkit tk = null; |
| tk = DLTKLanguageManager.getLanguageToolkit(pack); |
| if (tk != null && !DLTKContentTypeManager |
| .isValidFileNameForContentType(tk, getNewElementName())) { |
| return fCu; // ?? |
| } |
| return pack.getSourceModule(getNewElementName()); |
| } |
| |
| // ---- ITextUpdating --------------------------------------------- |
| |
| @Override |
| public boolean canEnableTextUpdating() { |
| return false; |
| } |
| |
| @Override |
| public boolean getUpdateTextualMatches() { |
| return false; |
| } |
| |
| @Override |
| public void setUpdateTextualMatches(boolean update) { |
| } |
| |
| // ---- IReferenceUpdating ----------------------------------- |
| |
| @Override |
| public boolean canEnableUpdateReferences() { |
| return false; |
| } |
| |
| @Override |
| public void setUpdateReferences(boolean update) { |
| } |
| |
| @Override |
| public boolean getUpdateReferences() { |
| return false; |
| } |
| |
| // ---- IQualifiedNameUpdating ------------------------------- |
| |
| @Override |
| public boolean canEnableQualifiedNameUpdating() { |
| return false; |
| } |
| |
| @Override |
| public boolean getUpdateQualifiedNames() { |
| return false; |
| } |
| |
| @Override |
| public void setUpdateQualifiedNames(boolean update) { |
| } |
| |
| @Override |
| public String getFilePatterns() { |
| return null; |
| } |
| |
| @Override |
| public void setFilePatterns(String patterns) { |
| } |
| |
| // ---- ISimilarDeclarationUpdating ------------------------------ |
| |
| @Override |
| public boolean canEnableSimilarDeclarationUpdating() { |
| return false; |
| } |
| |
| @Override |
| public void setUpdateSimilarDeclarations(boolean update) { |
| return; |
| } |
| |
| @Override |
| public boolean getUpdateSimilarDeclarations() { |
| return false; |
| } |
| |
| @Override |
| public int getMatchStrategy() { |
| return RenamingNameSuggestor.STRATEGY_EXACT; // method should not be |
| // called in this case |
| // anyway ... |
| } |
| |
| @Override |
| public void setMatchStrategy(int selectedStrategy) { |
| return; |
| } |
| |
| public IModelElement[] getSimilarElements() { |
| return null; |
| } |
| |
| @Override |
| public IResource getRefactoredResource(IResource element) { |
| return element; |
| } |
| |
| public IModelElement getRefactoredScriptElement(IModelElement element) { |
| return element; |
| } |
| |
| // --- preconditions ---------------------------------- |
| |
| @Override |
| public RefactoringStatus checkInitialConditions(IProgressMonitor pm) |
| throws CoreException { |
| |
| // we purposely do not check activation of the renameTypeRefactoring |
| // here. |
| return new RefactoringStatus(); |
| } |
| |
| @Override |
| protected RefactoringStatus doCheckFinalConditions(IProgressMonitor pm, |
| CheckConditionsContext context) throws CoreException { |
| try { |
| return Checks.checkSourceModuleNewName(fCu, getNewElementName()); |
| } finally { |
| pm.done(); |
| } |
| } |
| |
| private void computeRenameTypeRefactoring() throws CoreException { |
| if (getSimpleCUName().indexOf(".") != -1) { //$NON-NLS-1$ |
| return; |
| } |
| } |
| |
| private String getSimpleCUName() { |
| return removeFileNameExtension(fCu.getElementName()); |
| } |
| |
| /** |
| * Removes the extension (whatever comes after the last '.') from the given |
| * file name. |
| */ |
| public static String removeFileNameExtension(String fileName) { |
| if (fileName.lastIndexOf(".") == -1) //$NON-NLS-1$ |
| return fileName; |
| return fileName.substring(0, fileName.lastIndexOf(".")); //$NON-NLS-1$ |
| } |
| |
| @Override |
| public Change createChange(IProgressMonitor pm) throws CoreException { |
| // renaming the file is taken care of in renameTypeRefactoring |
| final String newName = getNewElementName(); |
| final IResource resource = ResourceUtil.getResource(fCu); |
| if (resource != null && resource.isLinked()) { |
| final Map arguments = new HashMap(); |
| final IProject project = resource.getProject(); |
| final String name = project.getName(); |
| final String description = Messages.format( |
| RefactoringCoreMessages.RenameSourceModuleChange_descriptor_description_short, |
| resource.getName()); |
| final String header = Messages.format( |
| RefactoringCoreMessages.RenameSourceModuleChange_descriptor_description, |
| resource.getFullPath().toString(), newName); |
| final String comment = new ScriptRefactoringDescriptorComment(this, |
| header).asString(); |
| final ScriptRefactoringDescriptor descriptor = new ScriptRefactoringDescriptor( |
| RenameResourceProcessor.ID_RENAME_RESOURCE, name, |
| description, comment, arguments, |
| (RefactoringDescriptor.STRUCTURAL_CHANGE |
| | RefactoringDescriptor.MULTI_CHANGE |
| | RefactoringDescriptor.BREAKING_CHANGE)); |
| arguments.put(ScriptRefactoringDescriptor.ATTRIBUTE_INPUT, |
| ScriptRefactoringDescriptor.resourceToHandle(name, |
| resource)); |
| arguments.put(ScriptRefactoringDescriptor.ATTRIBUTE_NAME, newName); |
| return new DynamicValidationStateChange(new RenameResourceChange( |
| descriptor, resource, newName, comment)); |
| } |
| String label = null; |
| if (fCu != null) { |
| final IScriptFolder fragment = (IScriptFolder) fCu.getParent(); |
| if (!fragment.isRootFolder()) |
| label = fragment.getElementName() + "." + fCu.getElementName(); //$NON-NLS-1$ |
| else |
| label = fCu.getElementName(); |
| } else |
| label = fCu.getElementName(); |
| final Map arguments = new HashMap(); |
| final String name = fCu.getScriptProject().getElementName(); |
| final String description = Messages.format( |
| RefactoringCoreMessages.RenameSourceModuleChange_descriptor_description_short, |
| fCu.getElementName()); |
| final String header = Messages.format( |
| RefactoringCoreMessages.RenameSourceModuleChange_descriptor_description, |
| label, newName); |
| final String comment = new ScriptRefactoringDescriptorComment(this, |
| header).asString(); |
| final ScriptRefactoringDescriptor descriptor = new ScriptRefactoringDescriptor( |
| RenameSourceModuleProcessor.ID_RENAME_COMPILATION_UNIT, name, |
| description, comment, arguments, |
| ScriptRefactoringDescriptor.ARCHIVE_IMPORTABLE |
| | ScriptRefactoringDescriptor.ARCHIVE_REFACTORABLE |
| | RefactoringDescriptor.STRUCTURAL_CHANGE |
| | RefactoringDescriptor.MULTI_CHANGE); |
| arguments.put(ScriptRefactoringDescriptor.ATTRIBUTE_INPUT, |
| descriptor.elementToHandle(fCu)); |
| arguments.put(ScriptRefactoringDescriptor.ATTRIBUTE_NAME, newName); |
| return new DynamicValidationStateChange(new RenameSourceModuleChange( |
| descriptor, fCu, newName, comment)); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public Change postCreateChange(Change[] participantChanges, |
| IProgressMonitor pm) throws CoreException { |
| return super.postCreateChange(participantChanges, pm); |
| } |
| |
| @Override |
| public RefactoringStatus initialize(RefactoringArguments arguments) { |
| if (arguments instanceof ScriptRefactoringArguments) { |
| final ScriptRefactoringArguments generic = (ScriptRefactoringArguments) arguments; |
| final String path = generic.getAttribute(ATTRIBUTE_PATH); |
| if (path != null) { |
| final IResource resource = ResourcesPlugin.getWorkspace() |
| .getRoot().findMember(new Path(path)); |
| if (resource == null || !resource.exists()) { |
| return ScriptableRefactoring.createInputFatalStatus( |
| resource, getRefactoring().getName(), |
| ID_RENAME_COMPILATION_UNIT); |
| } |
| fCu = (ISourceModule) DLTKCore.create(resource); |
| try { |
| computeRenameTypeRefactoring(); |
| } catch (CoreException exception) { |
| DLTKUIPlugin.log(exception); |
| } |
| } else |
| return RefactoringStatus.createFatalErrorStatus(Messages.format( |
| RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, |
| ATTRIBUTE_PATH)); |
| final String name = generic.getAttribute(ATTRIBUTE_NAME); |
| if (name != null && !"".equals(name)) //$NON-NLS-1$ |
| setNewElementName(name); |
| else |
| return RefactoringStatus.createFatalErrorStatus(Messages.format( |
| RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, |
| ATTRIBUTE_NAME)); |
| } else |
| return RefactoringStatus.createFatalErrorStatus( |
| RefactoringCoreMessages.InitializableRefactoring_inacceptable_arguments); |
| return new RefactoringStatus(); |
| } |
| } |