package org.openiaml.model.diagram.custom.actions;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Display;
import org.openiaml.model.actions.QuestionDialogResult;
import org.openiaml.model.custom.actions.ProgressEnabledAction;
import org.openiaml.model.diagram.helpers.GeneratedElementHandler;
import org.openiaml.model.diagram.helpers.inference.EmfInferenceHandler;
import org.openiaml.model.inference.EcoreCreateElementsHelper;
import org.openiaml.model.inference.InferenceException;
import org.openiaml.model.model.GeneratedElement;
/**
* An action which removes all generated elements contained within
* a given element. It also removes generated elements that were generated
* by the elements being deleted.
*
* @author jmwright
*/
public class DeleteContainedGeneratedElementsAction extends ProgressEnabledAction<GraphicalEditPart> {
/* (non-Javadoc)
* @see org.openiaml.model.diagram.custom.actions.ProgressEnabledAction#getErrorMessage(java.lang.Object, java.lang.String)
*/
@Override
public String getErrorMessage(GraphicalEditPart individual, String message) {
return "Could not delete contained generated elements for '" + individual + "': " + message;
}
/* (non-Javadoc)
* @see org.openiaml.model.diagram.custom.actions.ProgressEnabledAction#getProgressMessage()
*/
@Override
public String getProgressMessage() {
return "Removing contained generated elements";
}
/* (non-Javadoc)
* @see org.openiaml.model.diagram.custom.actions.ProgressEnabledAction#getSelection(java.lang.Object[])
*/
@Override
public List<GraphicalEditPart> getSelection(Object[] selection) {
final List<GraphicalEditPart> ifiles = new ArrayList<GraphicalEditPart>();
if (selection != null) {
for (Object o : selection) {
if (o instanceof GraphicalEditPart) {
ifiles.add((GraphicalEditPart) o);
}
}
}
return ifiles;
}
/**
* Extend the normal inference handler to allow us to remove elements
* that aren't contained directly later.
*
* @author jmwright
*
*/
public class CreateElementsWithinContainer {
private EObject container;
private EcoreCreateElementsHelper handler;
/**
* Calls super constructor.
*
* @param container the element to select as the containing element
*/
public CreateElementsWithinContainer(EObject container, EcoreCreateElementsHelper handler) {
this.container = container;
this.handler = handler;
}
/**
* Remove all generated elements within the given root element,
* and recursively remove other elements generated by it.
*
* @param root
* @param subProgressMonitor
* @param domain
* @param diagramEditPart
* @return true if the removal was successful; false if it was cancelled
* @throws InferenceException
* @throws ExecutionException
*/
public boolean removeContainedGeneratedElements(EObject root,
IProgressMonitor monitor, TransactionalEditingDomain domain, IGraphicalEditPart diagramEditPart) throws ExecutionException, InferenceException {
monitor.beginTask("Removing contained generated elements", 3);
// find elements to delete
monitor.subTask("Identifying contained elements");
List<GeneratedElement> result = getElementsToDelete(container);
monitor.worked(1);
GeneratedElementHandler handler = new GeneratedElementHandler(result, domain);
if (handler.needsConfirmation()) {
for (EObject element : handler.getConfirmationElements()) {
final String title = "Generated element is in use";
final String message = handler.getConfirmationMessage(element) +
"\n\nDo you wish to continue deleting the selected elements?";
final QuestionDialogResult answer = new QuestionDialogResult();
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
answer.setResult(MessageDialog.openConfirm(null, title, message));
}
});
// if we cancel, we cancel early
if (!answer.getResult())
return false;
}
}
monitor.subTask("Deleting related elements");
// delete all related elements
handler.deleteOtherElements(diagramEditPart);
monitor.worked(1);
monitor.subTask("Deleting actual elements");
for (GeneratedElement actual : result) {
handler.deleteElement(this.handler, actual, monitor, null, diagramEditPart);
}
monitor.done();
return true;
}
}
/**
* Get a list of all the objects that should be deleted within
* this container. Does not include recursive elements.
*
* @param container
* @return
*/
public List<GeneratedElement> getElementsToDelete(EObject container) {
List<GeneratedElement> result = new ArrayList<GeneratedElement>();
for (EObject child : container.eContents()) {
if (child instanceof GeneratedElement && ((GeneratedElement) child).isIsGenerated()) {
GeneratedElement gchild = (GeneratedElement) child;
// should delete this one
result.add(gchild);
}
}
return result;
}
/**
* Remove contained generated elements.
*
* @param root the element in which to remove generated elements
* @param domain
* @param diagramEditPart
* @throws InferenceException
* @throws ExecutionException
*/
public void removeContainedGeneratedElements(EObject root,
CreateElementsWithinContainer handler, IProgressMonitor monitor, TransactionalEditingDomain domain, IGraphicalEditPart diagramEditPart) throws InferenceException, ExecutionException {
monitor.beginTask("Removing contained generated elements", 50);
// but our handler will remove any incorrect elements
monitor.subTask("Removing uncontained elements");
handler.removeContainedGeneratedElements(root, new SubProgressMonitor(monitor, 50), domain, diagramEditPart);
monitor.done();
}
/**
* Wrap the action with monitor updates.
*
* @param part The edit part to work with
* @param monitor
* @return
*/
public IStatus execute(GraphicalEditPart part, IProgressMonitor monitor) {
try {
EObject container = part.resolveSemanticElement();
removeContainedGeneratedElements(container, new CreateElementsWithinContainer(
container,
new EmfInferenceHandler(
part.getEditingDomain(),
new ArrayList<Object>(), /* affected files */
new SubProgressMonitor(monitor, 100),
null /* IAdapter == null */,
container.eResource() /* eResource */
)
), monitor, part.getEditingDomain() /* editing domain */, part /* editing part */);
return Status.OK_STATUS;
} catch (InferenceException e) {
return errorStatus(e);
} catch (RuntimeException e) {
return errorStatus(e);
} catch (ExecutionException e) {
return errorStatus(e);
}
}
}