blob: cbcd53f643ca3c8e24221a87407f95b1f2b5e650 [file] [log] [blame]
//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.authoring.ui.actions;
import java.lang.reflect.InvocationTargetException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.command.AbstractCommand;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.UnexecutableCommand;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.IEditingDomainProvider;
import org.eclipse.emf.edit.ui.action.CommandActionHandler;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.authoring.ui.editors.EditorChooser;
import org.eclipse.epf.common.ui.util.MsgBox;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.diagram.core.services.DiagramManager;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.LibraryServiceUtil;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.edit.validation.IValidator;
import org.eclipse.epf.library.edit.validation.IValidatorFactory;
import org.eclipse.epf.library.ui.actions.LibraryLockingOperationRunner;
import org.eclipse.epf.services.ILibraryPersister;
import org.eclipse.epf.services.ILibraryPersister.FailSafeMethodLibraryPersister;
import org.eclipse.epf.uma.ContentElement;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.NamedElement;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.util.ContentDescriptionFactory;
import org.eclipse.epf.uma.util.MessageException;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchPart;
/**
* Renames method element.
*
* @author Phong Nguyen Le
* @since 1.2
*/
public class RenameAction extends
CommandActionHandler implements IWorkbenchPartAction, IModifyingAction {
private static final String LABEL = AuthoringUIResources.renameAction_text;
private IStructuredSelection selection;
private IWorkbenchPart activePart;
/**
* Creates an instance
* @param text
*/
public RenameAction(String text) {
super(null, text);
}
/**
* Creates an instance
*
*/
public RenameAction() {
this(LABEL);
}
/**
* Returns <code>true</code> if the selected method elements can be
* renamed.
*/
private boolean canRename(IStructuredSelection selection) {
if (!(domain instanceof AdapterFactoryEditingDomain) || selection.size() > 1)
return false;
Object element = TngUtil.unwrap(selection.getFirstElement());
if (element instanceof NamedElement
&& !TngUtil.isPredefined((MethodElement) element)) {
return true;
}
return false;
}
/**
* @see org.eclipse.emf.edit.ui.action.CommandActionHandler#updateSelection(org.eclipse.jface.viewers.IStructuredSelection)
*/
public boolean updateSelection(IStructuredSelection selection) {
boolean ret = false;
if(canRename(selection)) {
this.selection = selection;
ret = super.updateSelection(selection);
}
setEnabled(ret);
return ret;
}
@Override
public Command createCommand(Collection<?> selection) {
if(selection.isEmpty()) {
return UnexecutableCommand.INSTANCE;
}
Object o = TngUtil.unwrap(selection.iterator().next());
if(o instanceof NamedElement) {
return new RenameCommand((NamedElement) o, null);
}
return UnexecutableCommand.INSTANCE;
}
/**
* @see org.eclipse.epf.authoring.ui.actions.IWorkbenchPartAction#setActiveWorkbenchPart(org.eclipse.ui.IWorkbenchPart)
*/
public void setActiveWorkbenchPart(IWorkbenchPart workbenchPart) {
if(workbenchPart instanceof IEditingDomainProvider) {
domain = ((IEditingDomainProvider)workbenchPart).getEditingDomain();
}
activePart = workbenchPart;
}
private void superRun() {
final NamedElement e = (NamedElement) TngUtil.unwrap(selection.getFirstElement());
// Resource resource = e.eResource();
// if(resource != null) {
// org.eclipse.core.resources.IFile file = WorkspaceSynchronizer.getFile(e.eResource());
// if(file != null) {
// RepositoryProvider provider = RepositoryProvider.getProvider(file.getProject());
// if(provider != null) {
// IFileHistoryProvider historyProvider = provider.getFileHistoryProvider();
// FileModificationValidator modValidator = provider.getFileModificationValidator2();
// String id = provider.getID();
// Subscriber subscriber = provider.getSubscriber();
// System.out.println(id);
// }
// }
// }
Shell shell = activePart.getSite().getShell();
// check if container's resource can be modified
//
if (e.eContainer() != null
&& e.eContainer().eResource() != e.eResource()) {
IStatus status = UserInteractionHelper.checkModify(e.eContainer(), shell);
if (!status.isOK()) {
AuthoringUIPlugin
.getDefault()
.getMsgDialog()
.displayError(
AuthoringUIResources.renameDialog_title,
AuthoringUIResources.renameDialog_renameError,
status);
return;
}
}
final IValidator validator = IValidatorFactory.INSTANCE
.createNameValidator(e, ((AdapterFactoryEditingDomain)domain).getAdapterFactory());
IInputValidator inputValidator = new IInputValidator() {
public String isValid(String newText) {
if (validator != null) {
return UserInteractionHelper
.getSimpleErrorMessage(validator
.isValid(newText));
}
return null;
}
};
boolean getInput = true;
InputDialog inputDlg = new InputDialog(Display.getCurrent()
.getActiveShell(), AuthoringUIResources.rename_text,
AuthoringUIResources.newname_text, e.getName(),
inputValidator);
while (getInput) {
getInput = false;
if (inputDlg.open() == Window.OK) {
String newName = inputDlg.getValue().trim();
if(e instanceof ContentElement) {
newName = StrUtil.makeValidFileName(newName);
}
if (!newName.equals(e.getName())) {
if (e instanceof MethodConfiguration) {
String[] configNames = LibraryServiceUtil
.getMethodConfigurationNames(LibraryService
.getInstance()
.getCurrentMethodLibrary());
for (int i = 0; i < configNames.length; i++) {
if (newName.equals(configNames[i])) {
AuthoringUIPlugin
.getDefault()
.getMsgDialog()
.displayError(
AuthoringUIResources.renameDialog_title,
AuthoringUIResources
.bind(
AuthoringUIResources.duplicateElementNameError_msg,
newName));
getInput = true;
break;
}
}
}
if (getInput == true) {
inputDlg = new InputDialog(Display.getCurrent()
.getActiveShell(),
AuthoringUIResources.rename_text,
AuthoringUIResources.newname_text, e
.getName(), inputValidator);
continue;
}
if (e instanceof MethodPlugin) {
String msg = AuthoringUIResources.bind(AuthoringUIResources.methodPluginDescriptionPage_confirmRename, (new Object[] { e.getName(), newName }));
String title = AuthoringUIResources.methodPluginDescriptionPage_confirmRename_title;
if (!MessageDialog.openConfirm(shell, title, msg)) {
return;
}
EditorChooser.getInstance().closeMethodEditorsForPluginElements((MethodPlugin)e);
}
RenameCommand renameCmd = (RenameCommand) command;
renameCmd.setNewName(newName);
renameCmd.setShell(shell);
super.run();
}
}
}
}
/**
* @see org.eclipse.emf.edit.ui.action.CommandActionHandler#run()
*/
public void run() {
BusyIndicator.showWhile(activePart.getSite()
.getShell().getDisplay(), new Runnable() {
public void run() {
LibraryLockingOperationRunner runner = new LibraryLockingOperationRunner();
runner.run(new IRunnableWithProgress() {
public void run(IProgressMonitor monitor)
throws InvocationTargetException,
InterruptedException {
superRun();
}
});
}
});
}
public static void doRename(final NamedElement e, final String newName) {
new RenameCommand(e, newName).execute();
}
private static class RenameCommand extends AbstractCommand {
private NamedElement e;
private String newName;
private String oldName;
private Shell shell;
Collection<Resource> renamedResources;
public RenameCommand(NamedElement e, String newName) {
this.e = e;
this.newName = newName;
}
public void setNewName(String newName) {
this.newName = newName;
}
public void setShell(Shell shell) {
this.shell = shell;
}
private void rollback() {
// restore old name
//
setName(oldName);
// restore old location
//
if(!renamedResources.isEmpty()) {
adjustLocation(renamedResources, new ArrayList<Resource>());
}
}
private void handlePersistenceException(Exception e1) {
AuthoringUIPlugin.getDefault().getLogger().logError(e1);
String details = e1.getMessage() != null ? MessageFormat
.format(": {0}", new Object[] { e1.getMessage() }) : ""; //$NON-NLS-1$ //$NON-NLS-2$
String msg = MessageFormat.format(
AuthoringUIResources.ElementsView_err_saving,
new Object[] {
e.eResource().getURI().toFileString(),
details });
throw new MessageException(msg);
}
private ILibraryPersister.FailSafeMethodLibraryPersister getPersister() {
return LibraryServiceUtil.getPersisterFor(e.eResource())
.getFailSafePersister();
}
/**
* Adjusts location of all affected resources.
*
* @return resources whose location has been adjusted
*/
private IStatus adjustLocation(Collection<Resource> renamedResources) {
Collection<Resource> resourcesToRename = new ArrayList<Resource>();
if (e instanceof ContentElement
&& ContentDescriptionFactory
.hasPresentation((MethodElement) e)) {
resourcesToRename.add(((ContentElement) e).getPresentation()
.eResource());
}
resourcesToRename.add(e.eResource());
return adjustLocation(resourcesToRename, renamedResources);
}
/**
* Adjusts location of the specified resources.
*
* @return resources whose location has been adjusted
*/
private IStatus adjustLocation(Collection<Resource> resourcesToRename, Collection<Resource> renamedResources) {
FailSafeMethodLibraryPersister persister = getPersister();
try {
for (Resource resource : resourcesToRename) {
URI oldURI = resource.getURI();
persister.adjustLocation(resource);
if(!resource.getURI().equals(oldURI)) {
renamedResources.add(resource);
}
}
return Status.OK_STATUS;
} catch (Exception e) {
AuthoringUIPlugin.getDefault().getLogger().logError(e);
try {
persister.rollback();
}
catch(Exception ex) {
AuthoringUIPlugin.getDefault().getLogger().logError(e);
}
return new Status(IStatus.ERROR, AuthoringUIPlugin.getDefault().getId(),
e.getMessage(), e);
}
}
private void setName(String newName) {
e.setName(newName);
// Special handling for ProcessComponent to keep its
// name and the name of its process in sync.
if (e instanceof ProcessComponent) {
Process proc = ((ProcessComponent) e).getProcess();
proc.setName(newName);
}
}
public void execute() {
oldName = e.getName();
setName(newName);
renamedResources = new ArrayList<Resource>();
// rename file(s)
//
Runnable runnable = new Runnable() {
public void run() {
IStatus status = adjustLocation(renamedResources);
if(!status.isOK()) {
rollback();
Exception ex = (Exception) status.getException();
throw ex instanceof RuntimeException ? (RuntimeException) ex : new WrappedException(ex);
}
}
};
boolean result = UserInteractionHelper.runWithProgress(runnable,
AuthoringUIResources.ElementsView_renaming_text);
if(!result) {
return;
}
IStatus status = UserInteractionHelper.checkModify(e,
shell == null ? MsgBox.getDefaultShell() : shell);
if (!status.isOK()) {
AuthoringUIPlugin.getDefault().getMsgDialog().displayError(
AuthoringUIResources.renameDialog_title,
AuthoringUIResources.renameDialog_renameError,
status);
UserInteractionHelper.runWithProgress(new Runnable() {
public void run() {
rollback();
}
}, ""); //$NON-NLS-1$
return;
}
// Save the modified file(s).
//
runnable = new Runnable() {
public void run() {
// Save the modified file(s).
//
ILibraryPersister.FailSafeMethodLibraryPersister persister = getPersister();
try {
try {
persister.save(e.eResource());
persister.commit();
} catch (Exception e1) {
try {
persister.rollback();
}
catch(Exception e) {
AuthoringUIPlugin.getDefault().getLogger().logError(e);
}
handlePersistenceException(e1);
}
}
catch(RuntimeException e) {
rollback();
throw e;
}
// change diagram resource as well
if (e instanceof ProcessComponent) {
Process proc = ((ProcessComponent) e).getProcess();
DiagramManager mgr = DiagramManager.getInstance(proc, this);
if(mgr != null) {
try {
mgr.updateResourceURI();
}
catch(Exception e) {
AuthoringUIPlugin.getDefault().getLogger().logError(e);
}
finally {
try {
mgr.removeConsumer(this);
}
catch(Exception e) {
AuthoringUIPlugin.getDefault().getLogger().logError(e);
}
}
}
}
}
};
UserInteractionHelper.runWithProgress(runnable,
AuthoringUIResources.ElementsView_renaming_text);
}
public void redo() {
execute();
}
@Override
protected boolean prepare() {
return true;
}
@Override
public void dispose() {
e = null;
super.dispose();
}
}
}