blob: 5a055848833ff91b29cabf6f9ed93fd1fa6a3741 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2009 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.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, ""); //$NON-NLS-1$
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, ""); //$NON-NLS-1$
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;
}
}