blob: 87ff78b838718ee9a2c437a221b2d6f18761a483 [file] [log] [blame]
/***************************************************************************************************
* Copyright (c) 2003, 2004 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.jst.j2ee.internal.rename;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.common.command.AbstractCommand;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jst.j2ee.application.Module;
import org.eclipse.jst.j2ee.internal.J2EEEditModel;
import org.eclipse.jst.j2ee.internal.earcreation.AddModuleToEARProjectCommand;
import org.eclipse.jst.j2ee.internal.earcreation.EAREditModel;
import org.eclipse.jst.j2ee.internal.earcreation.EARNatureRuntime;
import org.eclipse.jst.j2ee.internal.earcreation.RemoveModuleFromEARProjectCommand;
import org.eclipse.jst.j2ee.internal.earcreation.UpdateModuleReferencesInEARProjectCommand;
import org.eclipse.jst.j2ee.internal.project.J2EECreationResourceHandler;
import org.eclipse.wst.common.frameworks.internal.operations.WTPOperation;
import org.eclipse.wst.common.internal.emfworkbench.EMFWorkbenchContext;
import org.eclipse.wst.common.internal.emfworkbench.WorkbenchResourceHelper;
import org.eclipse.wst.common.internal.emfworkbench.integration.ComposedEditModel;
import org.eclipse.wst.common.internal.emfworkbench.integration.EditModel;
import org.eclipse.wst.common.internal.emfworkbench.integration.LooseComposedEditModel;
public class RenameModuleOperation extends WTPOperation {
protected RenameOptions options;
protected IProject renamedProject = null;
protected LooseComposedEditModel renameEditModel = null;
/*
* key is an EAREditModel and the value is a list of rename commands. We cache the commands and
* execute later because the modules still need to exist when we go to change module dependency
* references.
*/
protected Map deferredCommands;
protected IProgressMonitor monitor;
protected RenameModuleDependencyOperation renameModuleDependencyOperation;
protected List dirtyEarModels;
protected static String EDIT_MODEL_KEY = "RENAME_MODULES"; //$NON-NLS-1$
public RenameModuleOperation(RenameOptions options) {
this.options = options;
}
/**
* @see HeadlessJ2EEOperation#execute(IProgressMonitor)
*/
protected void execute(IProgressMonitor aMonitor) throws CoreException, InvocationTargetException, InterruptedException {
this.monitor = aMonitor;
try {
buildRenameCommandsIfNecessary();
if (options.shouldRenameModuleDependencies()) {
renameModuleDependencies();
}
checkIfEarsAreDirty();
executeDeferredCommands();
saveModelsIfNecessary();
} finally {
releaseModels();
}
}
protected void checkIfEarsAreDirty() {
dirtyEarModels = new ArrayList();
if (deferredCommands == null)
return;
Iterator models = deferredCommands.keySet().iterator();
while (models.hasNext()) {
EAREditModel model = (EAREditModel) models.next();
if (model.isDirty() && !dirtyEarModels.contains(model)) {
dirtyEarModels.add(model);
}
}
}
protected void buildRenameCommands() {
deferredCommands = new HashMap();
List earProjects = EARNatureRuntime.getAllEARProjectsInWorkbench();
for (int i = 0; i < earProjects.size(); i++) {
IProject p = (IProject) earProjects.get(i);
EARNatureRuntime runtime = EARNatureRuntime.getRuntime(p);
if (runtime != null)
buildRenameCommands(runtime);
}
}
protected void buildRenameCommands(EARNatureRuntime runtime) {
List commands = new ArrayList();
List projects = options.getModuleAndUtilityProjects();
EAREditModel model = null;
try {
model = runtime.getEarEditModelForWrite(this);
if (options.shouldRenameModules()) {
for (int i = 0; i < projects.size(); i++) {
IProject project = (IProject) projects.get(i);
Module m = runtime.getModule(project);
if (m != null) {
String uri;
//Do not rename the module uri unless it was
//the same as the original project name.
boolean changedUri = false;
if (!m.getUri().startsWith(project.getName()))
uri = m.getUri();
else {
changedUri = true;
// the following was taken from
// WebProjectInfo.getDefaultUri()
uri = options.getNewName().replace(' ', '_');
uri += "." + URI.createURI(m.getUri()).fileExtension(); //$NON-NLS-1$
}
//AbstractCommand.class.getClass();
CompoundCommand compoundCommand = new CompoundCommand();
compoundCommand.append(new RemoveModuleFromEARProjectCommand(m, runtime.getProject()));
renamedProject = project.getWorkspace().getRoot().getProject(options.getNewName());
compoundCommand.append(new AddModuleToEARProjectCommand(renamedProject, runtime.getProject(), uri, options.getNewContextRoot(), null));
if (changedUri)
compoundCommand.append(new UpdateModuleReferencesInEARProjectCommand(runtime.getProject(), m, uri));
commands.add(compoundCommand);
}
}
}
} finally {
if (!commands.isEmpty()) {
deferredCommands.put(model, commands);
} else {
model.releaseAccess(this);
}
}
}
/**
* Do this for unhandled exceptions
*/
/**
* Do this for unhandled exceptions
*/
protected void releaseModels() {
if (renameEditModel != null) {
renameEditModel = null;
}
if (deferredCommands != null) {
Iterator iterator = deferredCommands.keySet().iterator();
EditModel model = null;
while (iterator.hasNext()) {
model = (EditModel) iterator.next();
model.releaseAccess(this);
}
deferredCommands.clear();
}
}
public void release() {
releaseModels();
}
/**
* After a normal execution flow, save the models if necessary
*/
protected void saveModelsIfNecessary() {
if (deferredCommands == null)
return;
Iterator models = deferredCommands.keySet().iterator();
while (models.hasNext()) {
EAREditModel model = (EAREditModel) models.next();
if (model.isDirty()) {
if (dirtyEarModels.contains(model)) {
model.saveIfNecessary(this);
} else {
model.save(this);
}
}
}
}
protected void renameModuleDependencies() throws InvocationTargetException, InterruptedException {
getRenameModuleDependencyOperation().run(monitor);
}
protected void executeDeferredCommands() {
Iterator it = deferredCommands.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
List commands = (List) entry.getValue();
executeCommands(commands);
}
}
protected void executeCommands(List commands) {
for (int i = 0; i < commands.size(); i++) {
AbstractCommand cmd = (AbstractCommand) commands.get(i);
cmd.execute();
}
}
/**
* Use this only for validate edits
*/
public ComposedEditModel getRenameEditModel() {
if (renameEditModel == null)
initializeRenameEditModel();
return renameEditModel;
}
protected void initializeRenameEditModel() {
if (options.getAllProjectsToRename().size() == 0) {
throw new RuntimeException(J2EECreationResourceHandler.getString("RenameModuleOperation_UI_0")); //$NON-NLS-1$
}
IProject project = null;
project = (IProject) options.getAllProjectsToRename().get(0);
buildRenameCommandsIfNecessary();
renameEditModel = new LooseComposedEditModel(EDIT_MODEL_KEY, (EMFWorkbenchContext) WorkbenchResourceHelper.getEMFContext(project)) {
/**
* @see org.eclipse.jst.j2ee.internal.internal.workbench.EditModel#getNonResourceFiles()
*/
public List getNonResourceFiles() {
List result = super.getNonResourceFiles();
result.addAll(getAffectedNonResourceFiles());
return result;
}
};
Iterator it = deferredCommands.keySet().iterator();
while (it.hasNext()) {
renameEditModel.addChild((J2EEEditModel) it.next());
}
}
protected void buildRenameCommandsIfNecessary() {
if (deferredCommands != null && !deferredCommands.isEmpty())
return;
buildRenameCommands();
}
/**
* Return a list of all the non-resource files that will get modified as a result of running
* this operation; used for validate edit.
*/
protected List getAffectedNonResourceFiles() {
if (options.shouldRenameModuleDependencies())
return getRenameModuleDependencyOperation().getAffectedFiles();
return Collections.EMPTY_LIST;
}
protected RenameModuleDependencyOperation getRenameModuleDependencyOperation() {
if (renameModuleDependencyOperation == null) {
List earEditModels = new ArrayList();
earEditModels.addAll(deferredCommands.keySet());
renameModuleDependencyOperation = new RenameModuleDependencyOperation(earEditModels, new HashSet(options.getModuleAndUtilityProjects()), renamedProject);
}
return renameModuleDependencyOperation;
}
public IStatus getStatus() {
return renameModuleDependencyOperation.getStatus();
}
}