| /******************************************************************************* |
| * Copyright (c) 2003, 2011 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.ant.internal.ui.refactoring; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.ant.core.AntCorePlugin; |
| import org.eclipse.ant.internal.core.IAntCoreConstants; |
| import org.eclipse.ant.internal.ui.AntUtil; |
| import org.eclipse.ant.launching.IAntLaunchConstants; |
| import org.eclipse.core.externaltools.internal.IExternalToolConstants; |
| import org.eclipse.core.resources.IContainer; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IWorkspace; |
| import org.eclipse.core.resources.IWorkspaceRoot; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.OperationCanceledException; |
| import org.eclipse.core.runtime.content.IContentDescription; |
| import org.eclipse.core.runtime.content.IContentType; |
| import org.eclipse.core.variables.IStringVariableManager; |
| import org.eclipse.core.variables.VariablesPlugin; |
| import org.eclipse.debug.core.DebugPlugin; |
| import org.eclipse.debug.core.ILaunchConfiguration; |
| import org.eclipse.debug.core.ILaunchConfigurationType; |
| import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; |
| import org.eclipse.debug.core.ILaunchManager; |
| import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; |
| import org.eclipse.ltk.core.refactoring.Change; |
| import org.eclipse.ltk.core.refactoring.CompositeChange; |
| import org.eclipse.ltk.core.refactoring.RefactoringStatus; |
| |
| import com.ibm.icu.text.MessageFormat; |
| |
| public class LaunchConfigurationBuildfileChange extends Change { |
| |
| private ILaunchConfiguration fLaunchConfiguration; |
| private String fNewBuildfileLocation; |
| private String fNewProjectName; |
| private String fNewLaunchConfigurationName; |
| private String fOldBuildfileLocation; |
| private String fOldProjectName; |
| private ILaunchConfigurationWorkingCopy fNewLaunchConfiguration; |
| private String fNewConfigContainerName; |
| |
| /** |
| * Create a change for each launch configuration which needs to be updated for this IJavaProject rename. |
| * @since 3.5 |
| */ |
| public static Change createChangesForProjectRename(IProject project, String newProjectName) throws CoreException { |
| String projectName= project.getDescription().getName(); |
| ILaunchConfiguration[] configs = getAntLaunchConfigurations(); |
| List changes= createChangesForProjectRename(configs, projectName, newProjectName); |
| return createChangeFromList(changes, RefactoringMessages.LaunchConfigurationBuildfileChange_7); |
| } |
| |
| /** |
| * Create a change for each launch configuration which needs to be updated for this buildfile rename. |
| */ |
| public static Change createChangesForBuildfileRename(IFile file, String newBuildfileName) throws CoreException { |
| IContentDescription description= null; |
| try { |
| description= file.getContentDescription(); |
| } catch (CoreException e) { |
| //missing file |
| return null; |
| } |
| if (description == null) { |
| return null; |
| } |
| IContentType contentType= description.getContentType(); |
| if (contentType == null || !AntCorePlugin.ANT_BUILDFILE_CONTENT_TYPE.equals(contentType.getId())) { |
| return null; //not an Ant buildfile |
| } |
| ILaunchConfiguration[] configs = getAntLaunchConfigurations(); |
| List changes= createChangesForBuildfileRename(file, configs, file.getProject().getName(), newBuildfileName); |
| return createChangeFromList(changes, RefactoringMessages.LaunchConfigurationBuildfileChange_7); |
| } |
| |
| private static ILaunchConfiguration[] getAntLaunchConfigurations() throws CoreException { |
| ILaunchManager manager= DebugPlugin.getDefault().getLaunchManager(); |
| // Ant launch configurations |
| ILaunchConfigurationType configurationType= manager.getLaunchConfigurationType(IAntLaunchConstants.ID_ANT_LAUNCH_CONFIGURATION_TYPE); |
| ILaunchConfiguration[] configs= manager.getLaunchConfigurations(configurationType); |
| return configs; |
| } |
| |
| /** |
| * Take a list of Changes, and return a unique Change, a CompositeChange, or null. |
| */ |
| private static Change createChangeFromList(List changes, String changeLabel) { |
| int nbChanges= changes.size(); |
| if (nbChanges == 0) { |
| return null; |
| } else if (nbChanges == 1) { |
| return (Change) changes.get(0); |
| } else { |
| return new CompositeChange(changeLabel, (Change[])changes.toArray(new Change[changes.size()])); |
| } |
| } |
| |
| /** |
| * Create a change for each launch configuration from the given list which needs |
| * to be updated for this IProject rename. |
| */ |
| private static List createChangesForProjectRename(ILaunchConfiguration[] configs, String projectName, String newProjectName) throws CoreException { |
| List changes= new ArrayList(); |
| for (int i= 0; i < configs.length; i++) { |
| ILaunchConfiguration launchConfiguration = configs[i]; |
| String launchConfigurationProjectName= launchConfiguration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String)null); |
| if (projectName.equals(launchConfigurationProjectName)) { |
| LaunchConfigurationBuildfileChange change = new LaunchConfigurationBuildfileChange(launchConfiguration, null, null, newProjectName, false); |
| String newContainerName = computeNewContainerName(launchConfiguration); |
| if (newContainerName != null) { |
| change.setNewContainerName(newContainerName); |
| } |
| |
| changes.add(change); |
| } |
| } |
| return changes; |
| } |
| |
| /** |
| * Create a change for each launch configuration from the given list which needs |
| * to be updated for this buildfile rename. |
| */ |
| private static List createChangesForBuildfileRename(IFile buildfile, ILaunchConfiguration[] configs, String projectName, String newBuildfileName) throws CoreException { |
| List changes= new ArrayList(); |
| for (int i= 0; i < configs.length; i++) { |
| ILaunchConfiguration launchConfiguration = configs[i]; |
| String launchConfigurationProjectName= launchConfiguration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String)null); |
| if (projectName.equals(launchConfigurationProjectName)) { |
| LaunchConfigurationBuildfileChange change = new LaunchConfigurationBuildfileChange(launchConfiguration, buildfile.getName(), newBuildfileName, null, false); |
| changes.add(change); |
| } |
| } |
| return changes; |
| } |
| |
| protected void setNewContainerName(String newContainerName) { |
| fNewConfigContainerName = newContainerName; |
| } |
| |
| /** |
| * Creates a new container name for the given configuration |
| * @param launchConfiguration |
| * @return the new container name |
| * @since 3.5 |
| */ |
| private static String computeNewContainerName(ILaunchConfiguration launchConfiguration) { |
| IFile file = launchConfiguration.getFile(); |
| if (file != null) { |
| return file.getParent().getProjectRelativePath().toString(); |
| } |
| return null; |
| } |
| |
| protected LaunchConfigurationBuildfileChange(ILaunchConfiguration launchConfiguration, String oldBuildFileName, String newBuildfileName, String newProjectName, boolean undo) throws CoreException { |
| fLaunchConfiguration= launchConfiguration; |
| fNewLaunchConfiguration= launchConfiguration.getWorkingCopy(); |
| fNewBuildfileLocation= newBuildfileName; |
| fNewProjectName= newProjectName; |
| fOldBuildfileLocation= oldBuildFileName; |
| fOldProjectName= fLaunchConfiguration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String) null); |
| if (fNewBuildfileLocation != null) { |
| // generate the new configuration name |
| String launchConfigurationName= fLaunchConfiguration.getName(); |
| fNewLaunchConfigurationName= launchConfigurationName.replaceAll(oldBuildFileName, newBuildfileName); |
| if (launchConfigurationName.equals(fNewLaunchConfigurationName) || (!undo && DebugPlugin.getDefault().getLaunchManager().isExistingLaunchConfigurationName(fNewLaunchConfigurationName))) { |
| fNewLaunchConfigurationName= null; |
| } |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ltk.core.refactoring.Change#getName() |
| */ |
| public String getName() { |
| if (fNewLaunchConfigurationName != null) { |
| return MessageFormat.format(RefactoringMessages.LaunchConfigurationBuildfileChange_0, new String[] {fLaunchConfiguration.getName(), fNewLaunchConfigurationName}); |
| } |
| if (fNewProjectName == null) { |
| return MessageFormat.format(RefactoringMessages.LaunchConfigurationBuildfileChange_1, new String[] {fLaunchConfiguration.getName()}); |
| } |
| return MessageFormat.format(RefactoringMessages.LaunchConfigurationBuildfileChange_2, new String[] {fLaunchConfiguration.getName()}); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ltk.core.refactoring.Change#initializeValidationData(org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| public void initializeValidationData(IProgressMonitor pm) { |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ltk.core.refactoring.Change#isValid(org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException, OperationCanceledException { |
| if (fLaunchConfiguration.exists()) { |
| String buildFileLocation= fLaunchConfiguration.getAttribute(IExternalToolConstants.ATTR_LOCATION, IAntCoreConstants.EMPTY_STRING); |
| if (fOldBuildfileLocation == null || (buildFileLocation.endsWith(fOldBuildfileLocation + '}') || buildFileLocation.endsWith(fOldBuildfileLocation))) { |
| String projectName= fLaunchConfiguration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String)null); |
| if (fOldProjectName.equals(projectName)) { |
| return new RefactoringStatus(); |
| } |
| return RefactoringStatus.createWarningStatus(MessageFormat.format(RefactoringMessages.LaunchConfigurationBuildfileChange_4, new String[] {fLaunchConfiguration.getName(), fOldProjectName})); |
| } |
| return RefactoringStatus.createWarningStatus(MessageFormat.format(RefactoringMessages.LaunchConfigurationBuildfileChange_5, new String[] {fLaunchConfiguration.getName(), fOldBuildfileLocation})); |
| } |
| return RefactoringStatus.createFatalErrorStatus(MessageFormat.format(RefactoringMessages.LaunchConfigurationBuildfileChange_6, new String[] {fLaunchConfiguration.getName()})); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ltk.core.refactoring.Change#perform(org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| public Change perform(IProgressMonitor pm) throws CoreException { |
| if (fNewConfigContainerName != null) { |
| IWorkspace workspace = ResourcesPlugin.getWorkspace(); |
| IWorkspaceRoot root = workspace.getRoot(); |
| IProject project = root.getProject(fNewProjectName); |
| IContainer container = (IContainer) project.findMember(fNewConfigContainerName); |
| fNewLaunchConfiguration.setContainer(container); |
| } |
| |
| String oldBuildfileLocation= fNewLaunchConfiguration.getAttribute(IExternalToolConstants.ATTR_LOCATION, IAntCoreConstants.EMPTY_STRING); |
| String oldProjectName; |
| if (fNewBuildfileLocation != null) { |
| String newBuildFileLocation= oldBuildfileLocation.replaceFirst(fOldBuildfileLocation, fNewBuildfileLocation); |
| fNewLaunchConfiguration.setAttribute(IExternalToolConstants.ATTR_LOCATION, newBuildFileLocation); |
| fNewLaunchConfiguration.setMappedResources(new IResource[] {getAssociatedFile(newBuildFileLocation)}); |
| } |
| if (fNewProjectName != null) { |
| oldProjectName= fOldProjectName; |
| fNewLaunchConfiguration.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, fNewProjectName); |
| String newBuildFileLocation= oldBuildfileLocation.replaceFirst(oldProjectName, fNewProjectName); |
| fNewLaunchConfiguration.setAttribute(IExternalToolConstants.ATTR_LOCATION, newBuildFileLocation); |
| fNewLaunchConfiguration.setMappedResources(new IResource[] {getAssociatedFile(newBuildFileLocation)}); |
| String launchConfigurationName= fLaunchConfiguration.getName(); |
| fNewLaunchConfigurationName= launchConfigurationName.replaceFirst(oldProjectName, fNewProjectName); |
| if (launchConfigurationName.equals(fNewLaunchConfigurationName) || DebugPlugin.getDefault().getLaunchManager().isExistingLaunchConfigurationName(fNewLaunchConfigurationName)) { |
| fNewLaunchConfigurationName= null; |
| } |
| } else { |
| oldProjectName= null; |
| } |
| if (fNewLaunchConfigurationName != null) { |
| fNewLaunchConfiguration.rename(fNewLaunchConfigurationName); |
| } |
| |
| fNewLaunchConfiguration.doSave(); |
| |
| // create the undo change |
| return new LaunchConfigurationBuildfileChange(fNewLaunchConfiguration, fNewBuildfileLocation, fOldBuildfileLocation, oldProjectName, true); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ltk.core.refactoring.Change#getModifiedElement() |
| */ |
| public Object getModifiedElement() { |
| return fLaunchConfiguration; |
| } |
| |
| private IFile getAssociatedFile(String location) { |
| IFile file= null; |
| IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager(); |
| try { |
| String expandedLocation= manager.performStringSubstitution(location); |
| if (expandedLocation != null) { |
| file= AntUtil.getFileForLocation(expandedLocation, null); |
| } |
| } catch (CoreException e) { |
| } |
| return file; |
| } |
| } |