/*
* Copyright (C) 2012,2013 Nagoya University All rights reserved.
*/
package net.dependableos.dcase.diagram.editor.command;
import net.dependableos.dcase.Argument;
import net.dependableos.dcase.BasicLink;
import net.dependableos.dcase.DcaseFactory;
import net.dependableos.dcase.DcaseLink003;
import net.dependableos.dcase.Userdef005;
import net.dependableos.dcase.diagram.common.exception.DcaseRuntimeException;
import net.dependableos.dcase.diagram.common.util.Messages;
import net.dependableos.dcase.diagram.common.util.MessageTypeImpl;
import net.dependableos.dcase.diagram.common.util.ModelUtil;
import net.dependableos.dcase.diagram.part.DcaseDiagramEditorUtil;
import net.dependableos.dcase.diagram.part.PatternUtil;
import net.dependableos.dcase.diagram.edit.parts.ArgumentEditPart;
import net.dependableos.dcase.diagram.edit.parts.custom.DcaseNodeEditPart;
import net.dependableos.dcase.diagram.editor.common.util.DcaseEditorUtil;
import net.dependableos.dcase.diagram.editor.common.util.MessageWriter;
import net.dependableos.dcase.diagram.editor.common.util.ModuleUtil;
import net.dependableos.dcase.impl.ArgumentImpl;
import java.util.Collections;
import java.util.HashSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.operations.OperationHistoryFactory;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gef.RequestConstants;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gef.requests.GroupRequest;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
import org.eclipse.gmf.runtime.emf.core.GMFEditingDomainFactory;
import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
/**
* A handler to add module (prototype)
*/
public class CreateDstarHandler extends AbstractEditPartHandler {
/**
* the Labels for executing commands.
*/
private final String ADD_DIAGRAM_CMD_LABEL = "command for creating diagram"; //$NON-NLS-1$
private final String CREATE_DSTAR_CMD_LABEL = "command for adding dstar"; //$NON-NLS-1$
private final String SELECT_OLD_CMD_LABEL = "command for selecting argument"; //$NON-NLS-1$
private final String DELETE_OLD_CMD_LABEL = "command for deleting argument"; //$NON-NLS-1$
private final String ADD_DSTAR_CMD_LABEL = "command for adding argument"; //$NON-NLS-1$
private final String SELECT_DSTAR_CMD_LABEL = "command for selecting argument"; //$NON-NLS-1$
private final String ARRANGE_DSTAR_CMD_LABEL = "command for arranging argument"; //$NON-NLS-1$
private final String PERSIST_DSTAR_CMD_LABEL = "command for persisting argument"; //$NON-NLS-1$
private final String DELETE_SELECTED_CMD_LABEL = "command for deleting selected editParts"; //$NON-NLS-1$
/**
* Creates Module file and adds Module node to current diagram.
*
* @param event
* ExecutionEvent
* @return the result of the execution.
* @throws ExecutionException
* if an exception occurred during execution.
*/
public Object execute(ExecutionEvent event) throws ExecutionException {
ArgumentEditPart argumentEditPart = DcaseEditorUtil
.getCurrentArgumentEditPart();
IFile currentFile = DcaseEditorUtil.getModelFile(argumentEditPart);
Diagram currentDiagram = DcaseEditorUtil.getCurrentDiagram();
TransactionalEditingDomain currentDomain = GMFEditingDomainFactory.INSTANCE
.getEditingDomain(currentDiagram.eResource().getResourceSet());
// *** Get d* file names ***
final IFile newDiagramFile = ResourcesPlugin.getWorkspace().getRoot()
.getFile(PatternUtil.getDstarPath(currentFile));
final IFile newModelFile = ResourcesPlugin.getWorkspace().getRoot()
.getFile(PatternUtil.getDstarModelPath(currentFile));
// *** Create new Module diagram ***
// create diagram and model file
AbstractTransactionalCommand createCmd = new AbstractTransactionalCommand(
currentDomain, ADD_DIAGRAM_CMD_LABEL, Collections.EMPTY_LIST) {
protected CommandResult doExecuteWithResult(
IProgressMonitor monitor, IAdaptable info)
throws ExecutionException {
if (newDiagramFile.exists()) {
PatternUtil.openModuleEditor(newDiagramFile);
} else {
URI diagramURI = URI.createPlatformResourceURI(
newDiagramFile.getFullPath().toOSString(), false);
URI modelURI = URI.createPlatformResourceURI(
newModelFile.getFullPath().toOSString(), false);
Resource diagram = DcaseDiagramEditorUtil.createDiagram(
diagramURI, modelURI, monitor);
try {
DcaseDiagramEditorUtil.openDiagram(diagram);
} catch (Exception e) {
MessageWriter.writeMessageToConsole(
Messages.CreateModuleHandler_2,
MessageTypeImpl.MODULE_FILE_CREATE_FAILED);
throw new DcaseRuntimeException(
Messages.CreateModuleHandler_2, null, null, 0,
MessageTypeImpl.MODULE_FILE_CREATE_FAILED);
}
}
return CommandResult.newOKCommandResult();
}
};
if (!newModelFile
.equals(DcaseEditorUtil.getModelFile(argumentEditPart))) {
OperationHistoryFactory.getOperationHistory().execute(createCmd,
new NullProgressMonitor(), null);
}
// *** get new Argument
final ArgumentEditPart newArgumentEditPart = DcaseEditorUtil
.getCurrentArgumentEditPart();
EObject naobj = DcaseEditorUtil.getElement(newArgumentEditPart);
if (!(naobj instanceof Argument)) {
return null;
}
Argument newArgument = (Argument) naobj;
ArgumentImpl addedArgument = (ArgumentImpl) DcaseFactory.eINSTANCE
.createArgument();
Diagram newDiagram = DcaseEditorUtil.getCurrentDiagram();
TransactionalEditingDomain newDomain = GMFEditingDomainFactory.INSTANCE
.getEditingDomain(newDiagram.eResource().getResourceSet());
// *** Save previous responsibilities and links by hand ***
HashMap<String, String> oldLinkMap = new HashMap<String, String>();
HashSet<String> handLinkSet = new HashSet<String>();
for (BasicLink link : newArgument.getRootBasicLink()) {
if (link.getSource() == null || link.getTarget() == null) {
continue;
}
String linkName = createLinkName(link.getSource().getName(), link
.getTarget().getName());
String attachmentStr = ModuleUtil.removeContractIconString(link
.getAttachment());
// save the responsibility
if (attachmentStr != null && attachmentStr.length() > 0) {
oldLinkMap.put(linkName, attachmentStr);
}
// save the link (if link is added automatically, userdef012 is not empty...
if (link.getUserdef012() == null
|| link.getUserdef012().length() == 0) {
handLinkSet.add(linkName);
}
}
// *** add nodes and links
Map<String, String> moduleList = null;
HashMap<String, Userdef005> nodeMap = new HashMap<String, Userdef005>();
HashSet<String> linkSet = new HashSet<String>();
try {
moduleList = ModuleUtil.getModulesAndNodes(argumentEditPart, true);
} catch (CoreException e) {
e.printStackTrace();
return null;
}
// create nodes
for (String name : moduleList.keySet()) {
if (!ModuleUtil.isPublicNodeName(name)
&& !oldLinkMap.containsValue(name)) {
Userdef005 newNode = DcaseFactory.eINSTANCE.createUserdef005();
IFile moduleModelFile = ResourcesPlugin.getWorkspace()
.getRoot().getFile(ModuleUtil.getModelPath(name));
EObject aobj = ModelUtil.getModel(moduleModelFile, true);
if (aobj instanceof Argument) {
newNode.setRespName(((Argument) aobj).getRespName());
newNode.setRespAddress(((Argument) aobj).getRespAddress());
newNode.setRespIcon(((Argument) aobj).getRespIcon());
newNode.setRespTime(((Argument) aobj).getRespTime());
newNode.setDesc(ModuleUtil
.getResponsibilityName((Argument) aobj));
}
nodeMap.put(name, newNode);
newNode.setName(name);
newNode.setAttachment(name);
addedArgument.getRootBasicNode().add(newNode);
}
}
// create links by hand
String separator = ModuleUtil.getReferenceSeparator();
for (String linkName : handLinkSet) {
String srcArray[] = linkName.split(separator);
DcaseLink003 newLink = createLink(linkName,
nodeMap.get(srcArray[0]), nodeMap.get(srcArray[1]),
oldLinkMap);
addedArgument.getRootBasicLink().add(newLink);
}
// create links automatically
for (String name : moduleList.keySet()) {
String tgtName = ModuleUtil.getModuleName(name);
String refName = moduleList.get(name);
if (refName == null || refName.length() == 0) {
continue;
}
String srcArray[] = refName.split(separator);
for (String srcKey : srcArray) {
String srcName = ModuleUtil.getModuleName(srcKey);
String newLinkName = createLinkName(srcName, tgtName);
if (linkSet.contains(newLinkName)) {
continue;
}
linkSet.add(newLinkName);
if (!nodeMap.containsKey(srcName)) {
continue;
}
if (!nodeMap.containsKey(tgtName)) {
continue;
}
if (handLinkSet.contains(newLinkName)) {
continue;
}
DcaseLink003 newLink = createLink(newLinkName,
nodeMap.get(srcName), nodeMap.get(tgtName), oldLinkMap);
newLink.setUserdef012("auto"); //$NON-NLS-1$
addedArgument.getRootBasicLink().add(newLink);
}
}
Set<String> idSet = new HashSet<String>();
CompoundCommand addCmd = new CompoundCommand(CREATE_DSTAR_CMD_LABEL);
// select old nodes
ICommand selectOldCommand = new SelectExcludesCommand(
SELECT_OLD_CMD_LABEL, newArgumentEditPart, idSet);
addCmd.add(new ICommandProxy(selectOldCommand));
// delete old nodes
AbstractTransactionalCommand deleteOldCommand = new AbstractTransactionalCommand(
newDomain, DELETE_OLD_CMD_LABEL, Collections.EMPTY_LIST) {
protected CommandResult doExecuteWithResult(
IProgressMonitor monitor, IAdaptable info)
throws ExecutionException {
List<DcaseNodeEditPart> selectedList = DcaseEditorUtil
.getSelectedPart();
if (selectedList.size() == 0) {
return CommandResult.newOKCommandResult();
}
CompoundCommand deleteCmd = new CompoundCommand(
DELETE_SELECTED_CMD_LABEL);
for (DcaseNodeEditPart editPart : selectedList) {
GroupRequest deleteReq = new GroupRequest(
RequestConstants.REQ_DELETE);
deleteReq.setEditParts(editPart);
deleteCmd.add(editPart.getCommand(deleteReq));
}
newArgumentEditPart.getDiagramEditDomain()
.getDiagramCommandStack().execute(deleteCmd);
return CommandResult.newOKCommandResult();
}
};
addCmd.add(new ICommandProxy(deleteOldCommand));
ICommand additionCommand = new ModelAdditionCommand(newDomain,
ADD_DSTAR_CMD_LABEL, null, addedArgument, newArgument, false);
addCmd.add(new ICommandProxy(additionCommand));
ICommand selectCommand = new SelectExcludesCommand(
SELECT_DSTAR_CMD_LABEL, newArgumentEditPart, idSet);
addCmd.add(new ICommandProxy(selectCommand));
ICommand arrangeCommand = new ArrangeExcludesCommand(newDomain,
ARRANGE_DSTAR_CMD_LABEL, null, newArgumentEditPart, idSet);
addCmd.add(new ICommandProxy(arrangeCommand));
ICommand persistanceCommand = new NotationPersistanceCommand(newDomain,
PERSIST_DSTAR_CMD_LABEL, null, newArgumentEditPart);
addCmd.add(new ICommandProxy(persistanceCommand));
// execute
newArgumentEditPart.getDiagramEditDomain().getDiagramCommandStack()
.execute(addCmd);
// *** save diagram
ModuleUtil.saveModuleEditor(DcaseEditorUtil.getDiagramFile(newDiagram));
//ModuleUtil.saveModuleEditor(ModuleUtil.getMainModuleName(), false);
return null;
}
private DcaseLink003 createLink(String newLinkName, Userdef005 srcNode,
Userdef005 tgtNode, HashMap<String, String> oldLinkMap) {
DcaseLink003 newLink = DcaseFactory.eINSTANCE.createDcaseLink003();
newLink.setName(newLinkName);
newLink.setSource(srcNode);
newLink.setTarget(tgtNode);
String addedStr = ModuleUtil.getContractIconString(srcNode, tgtNode);
// restore responsibility
if (oldLinkMap.containsKey(newLinkName)) {
newLink.setAttachment(oldLinkMap.get(newLinkName) + addedStr);
} else {
newLink.setAttachment(addedStr);
}
return newLink;
}
private String createLinkName(String src, String tgt) {
if (src == null || tgt == null || src.length() == 0
|| tgt.length() == 0) {
return ""; //$NON-NLS-1$
}
return src + ModuleUtil.getReferenceSeparator() + tgt;
}
}