/*
* Copyright (C) 2012 Nagoya University All rights reserved.
*/
package net.dependableos.dcase.diagram.editor.common.util;
import net.dependableos.dcase.BasicLink;
import net.dependableos.dcase.BasicNode;
import net.dependableos.dcase.Argument;
import net.dependableos.dcase.DcaseFactory;
import net.dependableos.dcase.System;
import net.dependableos.dcase.diagram.common.model.AttributeType;
import net.dependableos.dcase.diagram.common.model.NodeInfo;
import net.dependableos.dcase.diagram.common.util.Menus;
import net.dependableos.dcase.diagram.common.util.MessageTypeImpl;
import net.dependableos.dcase.diagram.common.util.Messages;
import net.dependableos.dcase.diagram.common.util.ModelUtil;
import net.dependableos.dcase.diagram.edit.parts.ArgumentEditPart;
import net.dependableos.dcase.diagram.editor.parameter.ParameterUtil;
import net.dependableos.dcase.diagram.editor.ui.PatternNumberDialog;
import net.dependableos.dcase.diagram.editor.ui.SelectSubtreeDialog;
import net.dependableos.dcase.diagram.part.PatternUtil;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.LinkedHashMap;
import java.util.HashSet;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.draw2d.FigureCanvas;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.gef.Tool;
import org.eclipse.gef.tools.AbstractTool;
import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramGraphicalViewer;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
/**
* A utility class that handles modules.
*/
public final class ModuleUtil {
/**
* the file extension of a diagram.
*/
private static final String DIAGRAM_FILE_EXTENSION_NAME = PatternUtil.getDiagramFileExtension();
/**
* the file extension of a model.
*/
private static final String MODEL_FILE_EXTENSION_NAME = PatternUtil.getModelFileExtension();
/**
* the file extension of a d* diagram.
*/
private static final String DSTAR_FILE_EXTENSION_NAME = PatternUtil.getDstarDiagramFileExtension();
/**
* the file extension of a model.
*/
private static final String DSTAR_MODEL_FILE_EXTENSION_NAME = PatternUtil.getDstarModelFileExtension();
/**
* the main module name.
*/
private static final String MAIN_MODULE_NAME = PatternUtil.getMainModuleName();
/**
* the separator string of references.
*/
private static final String REFERENCE_SEPARATOR_NAME = ";"; //$NON-NLS-1$
/**
* the separator string of modules and nodes.
*/
private static final String MODULE_SEPARATOR_NAME = "/"; //$NON-NLS-1$
/**
* the Public flag name.
*/
private static final String PUBLIC_FLAG_NAME = "P"; //$NON-NLS-1$
/**
* the separator string of responsibility.
*/
private static final String RESPONSIBILITY_SEPARATOR_NAME = PatternUtil.getResponsibilitySeparatorName(); //$NON-NLS-1$
/**
* the Contract flag name.
*/
private static final String CONTRACT_FLAG_NAME = "C"; //$NON-NLS-1$
/**
* the Responsibility Contract flag name.
*/
private static final String RESPONSIBILITY_CONTRACT_FLAG_NAME = "R"; //$NON-NLS-1$
/**
* A constructor.
*/
private ModuleUtil() {
}
/**
* Returns the reference separator.
*
* @return the reference separator.
*/
public static String getReferenceSeparator() {
return REFERENCE_SEPARATOR_NAME;
}
/**
* Returns the module separator.
*
* @return the reference separator.
*/
public static String getModuleSeparator() {
return MODULE_SEPARATOR_NAME;
}
/**
* Returns the diagram file extension.
*
* @return the diagram file extension.
*/
public static String getDiagramFileExtension() {
return DIAGRAM_FILE_EXTENSION_NAME;
}
/**
* Returns the model file extension.
*
* @return the model file extension.
*/
public static String getModelFileExtension() {
return MODEL_FILE_EXTENSION_NAME;
}
/**
* Returns the d* diagram file extension.
*
* @return the d* diagram file extension.
*/
public static String getDstarDiagramFileExtension() {
return DSTAR_FILE_EXTENSION_NAME;
}
/**
* Returns the d* model file extension.
*
* @return the d* model file extension.
*/
public static String getDstarModelFileExtension() {
return DSTAR_MODEL_FILE_EXTENSION_NAME;
}
/**
* Returns the public flag string.
*
* @return the public flag string.
*/
public static String getPublicFlagString() {
return PUBLIC_FLAG_NAME;
}
/**
* Returns the main module name.
*
* @return the main module name.
*/
public static String getMainModuleName() {
return MAIN_MODULE_NAME;
}
/**
* Returns whether the name is workspace reference.
*
* @param name
* the attachment name.
* @return whether the name is workspace reference.
*/
public static boolean isWorkspaceReference(String name) {
return PatternUtil.isWorkspaceReference(name);
}
/**
* Returns whether the node name or not.
*
* @param name
* the node name.
* @return whether the node name or not.
*/
public static boolean isPublicNodeName(String name) {
return PatternUtil.isPublicNodeName(name);
}
/**
* Returns whether the file is model file.
*
* @param file
* the file.
* @return whether the file is model file.
*/
public static boolean isModelFile(IFile file) {
return PatternUtil.isModelFile(file);
}
/**
* Returns whether the file is diagram file.
*
* @param file
* the file.
* @return whether the file is diagram file.
*/
public static boolean isDiagramFile(IFile file) {
return PatternUtil.isDiagramFile(file);
}
/**
* Returns whether the file is d* model file.
*
* @param file
* the file.
* @return whether the file is d* model file.
*/
public static boolean isDstarModelFile(IFile file) {
return PatternUtil.isDstarModelFile(file);
}
/**
* Returns whether the file is d* diagram file.
*
* @param file
* the file.
* @return whether the file is d* diagram file.
*/
public static boolean isDstarFile(IFile file) {
return PatternUtil.isDstarFile(file);
}
/**
* Returns the module name.
*
* @param file
* the diagram file or the model file.
* @return the module name.
*/
public static String getModuleName(IFile file) {
return PatternUtil.getModuleName(file);
}
/**
* Returns the module name.
*
* @param name
* the module name or node name.
* @return the module name.
*/
public static String getModuleName(String name) {
return PatternUtil.getModuleName(name);
}
/**
* Returns the node name.
*
* @param nodeName
* the node name (with module name).
* @return the node name.
*/
public static String getNodeName(String nodeName) {
return PatternUtil.getNodeName(nodeName);
}
/**
* Returns the Diagram file path.
*
* @param name
* the module name.
* @return the diagram file path.
*/
public static IPath getDiagramPath(String name) {
return PatternUtil.getDiagramPath(name);
}
/**
* Returns the Model file path.
*
* @param name
* the module name.
* @return the model file path.
*/
public static IPath getModelPath(String name) {
return PatternUtil.getModelPath(name);
}
/**
* Returns the d* Diagram file path.
*
* @return the d* diagram file path.
*/
public static IPath getDstarPath() {
return PatternUtil.getDstarPath();
}
/**
* Returns the d* Model file path.
*
* @return the d* model file path.
*/
public static IPath getDstarModelPath() {
return PatternUtil.getDstarModelPath();
}
/**
* Returns the public node reference.
*
* @param moduleName
* the module name.
* @param nodeName
* the node name.
* @return the public node reference string.
*/
public static String createNodeReference(String moduleName, String nodeName) {
return PatternUtil.createNodeReference(moduleName, nodeName);
}
/**
* Returns the public node reference.
*
* @param modelFile
* the model file.
* @param nodeName
* the node name.
* @return the public node reference string.
*/
public static String createNodeReference(IFile modelFile, String nodeName) {
return PatternUtil.createNodeReference(getModuleName(modelFile), nodeName);
}
/**
* Returns the reference number.
*
* @param reference
* RefSource value.
* @return the reference number.
*/
public static int getReferenceNumber(String reference) {
if (reference == null || reference.length() == 0) {
return 0;
} else {
return reference.split(REFERENCE_SEPARATOR_NAME).length;
}
}
/**
* Returns the attribute of node.
*
* @param node
* the node.
* @param type
* the attribute type.
* @return the attribute string.
*/
public static String getAttributeValue(BasicNode node, AttributeType type) {
NodeInfo nodeInfo = ModelUtil.createNodeInfo(node);
if (nodeInfo != null) {
return (String) nodeInfo.getAttribute(type);
} else {
return null;
}
}
/**
* Returns the attribute of editpart.
*
* @param editPart
* the editpart.
* @param type
* the attribute type.
* @return the attribute string.
*/
public static String getAttributeValue(GraphicalEditPart editPart,
AttributeType type) {
EObject eobj = DcaseEditorUtil.getElement(editPart);
if (eobj instanceof BasicNode) {
return getAttributeValue((BasicNode) eobj, type);
} else {
return null;
}
}
/**
* Returns the RefSource attribute value.
*
* @param list
* the reference list.
* @return the RefSource attribute value.
*/
private static String makeModuleReference(ArrayList<String> list) {
StringBuffer buffer = new StringBuffer();
for (String attr : list) {
if (buffer.length() > 0) {
buffer.append(REFERENCE_SEPARATOR_NAME);
}
buffer.append(attr);
}
return buffer.toString();
}
/**
* Appends reference to RefSource and returns the new references.
*
* @param allStr
* the RefSource.
* @param refStr
* the adding reference.
* @return the new references.
*/
public static String appendModuleReference(String allStr, String refStr) {
ArrayList<String> orgList = null;
if (allStr != null) {
orgList = new ArrayList<String>(Arrays.asList(allStr
.split(REFERENCE_SEPARATOR_NAME)));
} else {
orgList = new ArrayList<String>();
}
if (!orgList.contains(refStr)) {
orgList.add(refStr);
}
return makeModuleReference(orgList);
}
/**
* Appends reference to RefSource and returns the new references.
*
* @param node
* the node.
* @param refStr
* the adding reference.
* @return the new references.
*/
public static String appendModuleReference(BasicNode node, String refStr) {
return appendModuleReference(node.getRefSource(), refStr);
}
/**
* Appends reference to RefSource and returns the new references.
*
* @param editPart
* the editpart.
* @param refStr
* the adding reference.
* @return the new references.
*/
public static String appendModuleReference(GraphicalEditPart editPart,
String refStr) {
EObject eobj = DcaseEditorUtil.getElement(editPart);
if (eobj instanceof BasicNode) {
return appendModuleReference((BasicNode) eobj, refStr);
} else {
return null;
}
}
/**
* Removes reference from RefSource and returns the new references.
*
* @param allStr
* the RefSource.
* @param refStr
* the removing reference.
* @return the new references.
*/
public static String removeModuleReference(String allStr, String refStr) {
ArrayList<String> orgList = null;
if (allStr != null) {
orgList = new ArrayList<String>(Arrays.asList(allStr
.split(REFERENCE_SEPARATOR_NAME)));
} else {
orgList = new ArrayList<String>();
}
if (orgList.contains(refStr)) {
orgList.remove(refStr);
}
return makeModuleReference(orgList);
}
/**
* Removes reference from RefSource and returns the new references.
*
* @param node
* the node.
* @param refStr
* the removing reference.
* @return the new references.
*/
public static String removeModuleReference(BasicNode node, String refStr) {
return removeModuleReference(node.getRefSource(), refStr);
}
/**
* Removes reference from RefSource and returns the new references.
*
* @param editPart
* the editpart.
* @param refStr
* the removing reference.
* @return the new references.
*/
public static String removeModuleReference(GraphicalEditPart editPart,
String refStr) {
EObject eobj = DcaseEditorUtil.getElement(editPart);
if (eobj instanceof BasicNode) {
return removeModuleReference((BasicNode) eobj, refStr);
} else {
return null;
}
}
/**
* Returns the name list of modules and public nodes.
*
* @param editPart
* the argument editpart.
* @param needNode
* whether public node is needed.
* @return the map(name, reference) of modules and public nodes.
*/
public static Map<String, String> getModulesAndNodes(
GraphicalEditPart editPart, boolean needNode) throws CoreException {
IFile file = DcaseEditorUtil.getModelFile(editPart);
return getModulesAndNodes(file, needNode);
}
/**
* Returns the name list of modules and public nodes.
*
* @param editPart
* the argument editpart.
* @param needNode
* whether public node is needed.
* @param currentModuleName
* the current module name (need to check public or parent).
* @return the map(name, reference) of modules and public nodes.
*/
public static Map<String, String> getModulesAndNodes(
GraphicalEditPart editPart, boolean needNode,
String currentModuleName) throws CoreException {
IFile file = DcaseEditorUtil.getModelFile(editPart);
return getModulesAndNodes(file, needNode, currentModuleName);
}
/**
* Returns the name list of modules and public nodes.
*
* @param file
* the model file.
* @param needNode
* whether public node is needed.
* @return the map(name, reference) of modules and public nodes.
*/
public static Map<String, String> getModulesAndNodes(IFile file,
boolean needNode) throws CoreException {
return getModulesAndNodes(file, needNode, null);
}
/**
* Returns the name list of modules and public nodes.
*
* @param file
* the model file.
* @param needNode
* whether public node is needed.
* @param currentModuleName
* the current module name (need to check public or parent).
* @return the map(name, reference) of modules and public nodes.
*/
public static Map<String, String> getModulesAndNodes(IFile file,
boolean needNode, String currentModuleName) throws CoreException {
Map<String, String> moduleMap = new LinkedHashMap<String, String>();
if (file == null) {
return moduleMap;
}
IResource[] resources = getMembers(file.getProject());
for (IResource resource : resources) {
if (resource instanceof IFile) {
IFile resFile = (IFile) resource;
if (!isModelFile(resFile)) {
continue;
}
// add the module to list
String moduleName = getModuleName(resFile);
EObject eobj = ModelUtil.getModel(resFile, true);
if (eobj instanceof Argument) {
Argument argument = (Argument) eobj;
String refSourceStr = argument.getRefSource();
// check whether module is public or not.
boolean addModule = true;
if (currentModuleName != null) {
String parent = argument.getParent();
if (parent == null || !parent.equals(currentModuleName)) {
String flags = argument.getFlag();
if (flags == null || flags.length() == 0
|| flags.indexOf(PUBLIC_FLAG_NAME) < 0) {
addModule = false;
}
}
}
if (addModule) {
moduleMap.put(getModuleName(resFile),
(refSourceStr != null) ? refSourceStr : ""); //$NON-NLS-1$
}
// add public node to list
if (needNode) {
EList<BasicNode> nodes = argument.getRootBasicNode();
for (BasicNode node : nodes) {
String flags = node.getFlag();
if (flags == null || flags.length() == 0) {
continue;
}
if (flags.indexOf(PUBLIC_FLAG_NAME) >= 0) {
refSourceStr = node.getRefSource();
moduleMap.put(
createNodeReference(moduleName,
node.getName()),
(refSourceStr != null) ? refSourceStr
: ""); //$NON-NLS-1$
}
}
}
}
}
}
return moduleMap;
}
/**
* Returns the files belong to the project.
* @param project the project.
* @return the files belong to the project.
*/
public static IResource[] getMembers(IProject project) throws CoreException {
ArrayList<IResource>ret = new ArrayList<IResource>();
for (IResource res : project.members()) {
if (res instanceof IFolder) {
ret.addAll(getMembers((IFolder)res));
} else {
ret.add(res);
}
}
return ret.toArray(new IResource[ret.size()]);
}
/**
* Returns the files belong to the folder (recursively).
* @param folder the folder.
* @return the files belong to the folder.
*/
private static List<IResource> getMembers(IFolder folder) throws CoreException {
ArrayList<IResource>ret = new ArrayList<IResource>();
for (IResource res : folder.members()) {
if (res instanceof IFolder) {
ret.addAll(getMembers((IFolder)res));
} else {
ret.add(res);
}
}
return ret;
}
/**
* Opens the module diagram.
*
* @param moduleName
* the module name.
* @param isDiagram
* whether normal diagram.
* @return the opened module editor.
*/
public static IEditorPart openModuleEditor(String moduleName, boolean isDiagram) {
return PatternUtil.openModuleEditor(moduleName, isDiagram);
}
/**
* Opens the module diagram.
*
* @param moduleName
* the module name.
* @return the opened module editor.
*/
public static IEditorPart openModuleEditor(String moduleName) {
return PatternUtil.openModuleEditor(moduleName);
}
/**
* Saves the module diagram.
*
* @param moduleName
* the module name.
* @param isDiagram
* whether normal diagram.
*/
public static void saveModuleEditor(String moduleName, boolean isDiagram) {
PatternUtil.saveModuleEditor(moduleName, isDiagram);
}
/**
* Saves the module diagram.
*
* @param diagramFile the diagram file.
*/
public static void saveModuleEditor(IFile diagramFile) {
PatternUtil.saveModuleEditor(diagramFile);
}
/**
* Saves the module diagram.
*
* @param moduleName
* the module name.
*/
public static void saveModuleEditor(String moduleName) {
saveModuleEditor(moduleName, true);
}
/**
* Closes the module diagram.
*
* @param moduleName
* the module name.
* @param isDiagram
* whether normal diagram.
*/
public static void closeModuleEditor(String moduleName, boolean isDiagram) {
IEditorPart editorPart = openModuleEditor(moduleName, isDiagram);
IWorkbenchPage workbenchPage = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow().getActivePage();
workbenchPage.closeEditor(editorPart, true);
}
/**
* Closes the module diagram.
*
* @param moduleName
* the module name.
*/
public static void closeModuleEditor(String moduleName) {
closeModuleEditor(moduleName, true);
}
/**
* Checks if the attachment is URL or not.
*
* @param attachment
* the attachment.
* @return whether the attachment is URL or not.
*/
public static boolean isUrl(String attachment) {
try {
URL url = new URL(attachment);
if (!DcaseEditorUtil.checkDcaseReferenceProtocol(url.getProtocol())) {
return false;
}
} catch (MalformedURLException e) {
return false;
}
return true;
}
/**
* Returns the node number.
*
* @param moduleName
* the module name.
* @return the node number.
*/
public static int countNodes(String moduleName) {
if (moduleName == null || moduleName.length() == 0
|| isPublicNodeName(moduleName)) {
return 0;
}
IPath path = getModelPath(moduleName);
if (path != null) {
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
if (file != null) {
EObject eobj = ModelUtil.getModel(file, true);
if (eobj instanceof Argument) {
EList<BasicNode> nodes = ((Argument) eobj)
.getRootBasicNode();
return (nodes != null) ? nodes.size() : 0;
}
}
}
return 0;
}
/***
* Returns the root node of argument.
*
* @param argument
* the argument.
* @return the root node of argument.
*/
public static BasicNode getRootElement(Argument argument) {
HashSet<BasicNode> nodeSet = new HashSet<BasicNode>(
argument.getRootBasicNode());
for (BasicLink link : argument.getRootBasicLink()) {
nodeSet.remove(link.getTarget());
}
return (nodeSet.size() > 0) ? (BasicNode) nodeSet.toArray()[0] : null;
}
/**
* Returns the root node.
*
* @param file
* the module file.
* @return the root node.
*/
public static BasicNode getRootNode(IFile file) {
EObject templateModel = ModelUtil.getModel(file, true);
return getRootNode((Argument) templateModel);
}
/**
* Returns the root node.
*
* @param argument
* the argument.
* @return the root node.
*/
public static BasicNode getRootNode(Argument argument) {
List<BasicNode> nodeList = argument.getRootBasicNode();
HashSet<BasicNode> nodeSet = new HashSet<BasicNode>(nodeList);
for (BasicLink link : argument.getRootBasicLink()) {
nodeSet.remove(link.getTarget());
}
if (nodeSet.size() == 1) {
return (BasicNode) nodeSet.toArray()[0];
} else {
return null;
}
}
/**
* Returns the responsibility value.
*
* @param node
* the node.
* @return the responsibility value.
*/
public static String getResponsibilityValue(BasicNode node, int index) {
switch (index) {
case 0: // RespName
return node.getRespName();
case 1: // RespAddress
return node.getRespAddress();
case 2: // RespIcon
return node.getRespIcon();
case 3: // RespTime
return node.getRespTime();
}
return null;
}
/**
* Returns the responsibility name.
*
* @param node
* the node.
* @return the responsibility name.
*/
public static String getResponsibilityName(BasicNode node) {
return getResponsibilityValue(node, 0);
}
/**
* Returns the responsibility address.
*
* @param node
* the node.
* @return the responsibility address.
*/
public static String getResponsibilityAddress(BasicNode node) {
return getResponsibilityValue(node, 1);
}
/**
* Returns the responsibility icon path.
*
* @param node
* the node.
* @return the responsibility icon path.
*/
public static String getResponsibilityIconPath(BasicNode node) {
return getResponsibilityValue(node, 2);
}
/**
* Returns the responsibility time.
*
* @param node
* the node.
* @return the responsibility time.
*/
public static String getResponsibilityTime(BasicNode node) {
return getResponsibilityValue(node, 3);
}
/**
* Returns the responsibility value.
*
* @param argument
* the argument.
* @return the responsibility value.
*/
public static String getResponsibilityValue(Argument argument, int index) {
return getResponsibilityValue((BasicNode)argument, index);
}
/**
* Returns the responsibility name.
*
* @param node
* the argument.
* @return the responsibility name.
*/
public static String getResponsibilityName(Argument node) {
return getResponsibilityValue(node, 0);
}
/**
* Returns the responsibility address.
*
* @param node
* the argument.
* @return the responsibility address.
*/
public static String getResponsibilityAddress(Argument node) {
return getResponsibilityValue(node, 1);
}
/**
* Returns the responsibility icon path.
*
* @param node
* the argument.
* @return the responsibility icon path.
*/
public static String getResponsibilityIconPath(Argument node) {
return getResponsibilityValue(node, 2);
}
/**
* Returns the current cursor location for Diagram.
*
* @param argumentEditPart
* the argument edit part.
* @return the current point.
*/
public static Point getCurrentLocation(ArgumentEditPart argumentEditPart) {
IDiagramGraphicalViewer viewer = DcaseEditorUtil
.getCurrentDcaseEditor().getDiagramGraphicalViewer();
FigureCanvas canvas = (FigureCanvas) viewer.getControl();
// the position of scrollable diagram.
Point viewPoint = canvas.getViewport().getViewLocation();
Tool tool = argumentEditPart.getViewer().getEditDomain()
.getActiveTool();
AbstractTool aTool = (AbstractTool) tool;
Point toolLocation = null;
try {
Method method = AbstractTool.class.getDeclaredMethod("getLocation"); //$NON-NLS-1$
method.setAccessible(true);
toolLocation = ((org.eclipse.draw2d.geometry.Point) method
.invoke(aTool)).getCopy();
} catch (Exception e) {
MessageWriter.writeMessageToConsole(
Messages.AddPatternContributionItem_0,
MessageTypeImpl.CREATE_PATTERN_FAILED);
return new Point(0, 0);
}
return new Point(viewPoint.x + toolLocation.x, viewPoint.y
+ toolLocation.y);
}
/**
* Returns the contract icon string.
*
* @param node1
* the one node.
* @param node2
* the another node.
* @return the contract icon string.
*/
public static String getContractIconString(BasicNode node1, BasicNode node2) {
String ret = ""; //$NON-NLS-1$
if (node1 != null && node2 != null) {
String[] resp1 = new String[] {
getResponsibilityName(node1),
getResponsibilityAddress(node1),
getResponsibilityIconPath(node1),
};
String[] resp2 = new String[] {
getResponsibilityName(node2),
getResponsibilityAddress(node2),
getResponsibilityIconPath(node2),
};
boolean isCheck = false;
for (String s : resp1) {
if (s != null && s.length() > 0) {
isCheck = true;
break;
}
}
for (String s : resp2) {
if (s != null && s.length() > 0) {
isCheck = true;
break;
}
}
ret = RESPONSIBILITY_SEPARATOR_NAME
+ (!isCheck || Arrays.equals(resp1, resp2) ? CONTRACT_FLAG_NAME
: RESPONSIBILITY_CONTRACT_FLAG_NAME);
}
return ret;
}
/**
* Returns the extracted attachment string.
*
* @param attachment
* the attachment string.
* @return the extracted attachment string.
*/
public static String removeContractIconString(String attachment) {
if (attachment != null) {
int index = attachment.indexOf(RESPONSIBILITY_SEPARATOR_NAME);
if (index >= 0) {
return attachment.substring(0, index);
}
}
return attachment;
}
/**
* Processes the Patterns.
* @param copyArgument the copied argument.
* @return false if invalid or cancelled.
*/
public static boolean processPatterns(Argument copyArgument) {
return processPatterns(copyArgument, new HashSet<BasicNode>());
}
/**
* Processes the Patterns.
* @param copyArgument the copied argument.
* @param paramSet the processed Parameters.
* @return false if invalid or cancelled.
*/
public static boolean processPatterns(Argument copyArgument, HashSet<BasicNode> paramSet) {
// get root node
BasicNode rootNode = ModuleUtil.getRootNode(copyArgument);
if (rootNode == null) {
return false;
}
// process loop
while (true) {
// search Patterns
BasicNode cNode = searchFirstPattern(rootNode, copyArgument,
new HashSet<BasicNode>(), paramSet);
if (cNode == null) {
break;
}
if (! PatternUtil.isValid(cNode, copyArgument)) {
MessageWriter.writeMessageToConsole(
NLS.bind(Messages.AddPatternContributionItem_2, cNode.getName()),
MessageTypeImpl.CREATE_PATTERN_FAILED);
return false;
}
// process Pattern nodes.
System scNode = (System)cNode;
String subType = scNode.getSubType();
// Loop
if (PatternUtil.isLoop(subType)) {
BasicNode parent = PatternUtil.getParent(cNode, copyArgument);
String parentPath = PatternUtil.getFullPath(parent, copyArgument);
List<BasicNode> pNodeList = new ArrayList<BasicNode>();
List<BasicLink> pLinkList = new ArrayList<BasicLink>();
PatternUtil.getSubtree(scNode, copyArgument, pNodeList, pLinkList);
String leafName = scNode.getLeafNode();
BasicNode leafNode = PatternUtil.getNode(leafName, pNodeList);
if (leafNode == null) {
MessageWriter.writeMessageToConsole(
NLS.bind(Messages.AddPatternContributionItem_2, leafName),
MessageTypeImpl.CREATE_PATTERN_FAILED);
return false;
}
// get the loop number of times
String nrStr = scNode.getUserdef001();
int nr = 1;
if (nrStr != null && nrStr.length() > 0) {
nr = Integer.parseInt(nrStr);
if (nr < 1) {
nr = 1;
}
}
if (! askLoopDialog(parentPath, nr)) {
// remove the current loop pattern
copyArgument.getRootBasicNode().removeAll(pNodeList);
copyArgument.getRootBasicLink().removeAll(pLinkList);
PatternUtil.removeLinks(parent, copyArgument.getRootBasicLink());
} else {
// unroll the loop pattern
List<BasicNode> nNodeList = new ArrayList<BasicNode>();
List<BasicLink> nLinkList = new ArrayList<BasicLink>();
BasicNode newpNode = PatternUtil.copySubtree(parent, pNodeList, pLinkList,
nNodeList, nLinkList);
copyArgument.getRootBasicNode().addAll(nNodeList);
copyArgument.getRootBasicLink().addAll(nLinkList);
// add Loop node
System scNewNode = EcoreUtil.copy(scNode);
scNewNode.setUserdef001(Integer.toString(nr+1));
BasicLink scLink = DcaseFactory.eINSTANCE.createDcaseLink002();
scLink.setSource(newpNode);
scLink.setTarget(scNewNode);
copyArgument.getRootBasicNode().add(scNewNode);
copyArgument.getRootBasicLink().add(scLink);
// add link
BasicLink newLink = DcaseFactory.eINSTANCE.createDcaseLink001();
newLink.setSource(leafNode);
newLink.setTarget(newpNode);
copyArgument.getRootBasicLink().add(newLink);
}
}
// Choice
if (PatternUtil.isChoice(subType)) {
// remove from k+1 to n
List<BasicNode> childList = PatternUtil.getChildren(cNode, copyArgument);
SelectSubtreeDialog dialog = new SelectSubtreeDialog(
DcaseEditorUtil.getActiveWindowShell(), childList, scNode, copyArgument);
if (dialog.open() != Dialog.OK) {
return false;
}
List<BasicNode> removedList = dialog.getUnselectedNodes();
for (BasicNode pnode : removedList) {
ArrayList<BasicNode>pnodeList = new ArrayList<BasicNode>();
ArrayList<BasicLink>plinkList = new ArrayList<BasicLink>();
HashSet<BasicNode>checkedSet = new HashSet<BasicNode>();
PatternUtil.getSubtree(pnode, copyArgument, pnodeList, plinkList, checkedSet);
copyArgument.getRootBasicNode().removeAll(pnodeList);
copyArgument.getRootBasicLink().removeAll(plinkList);
// remove links of deleted nodes.
for (BasicNode dnode : pnodeList) {
PatternUtil.removeLinks(dnode, copyArgument.getRootBasicLink());
}
}
}
// Multiplicity
if (PatternUtil.isMultiplicity(subType)) {
int k = getPatternNumber(scNode, copyArgument);
if (k <= 0) {
return false;
}
// add k-1 times
BasicNode parent = PatternUtil.getParent(cNode, copyArgument);
ArrayList<BasicNode>pnodeList = new ArrayList<BasicNode>();
ArrayList<BasicLink>plinkList = new ArrayList<BasicLink>();
HashSet<BasicNode>checkedSet = new HashSet<BasicNode>();
BasicNode pnode = PatternUtil.getChild(cNode, copyArgument, 1);
PatternUtil.getSubtree(pnode, copyArgument, pnodeList, plinkList, checkedSet);
for (BasicLink link : copyArgument.getRootBasicLink()) {
if (link.getSource() == parent) {
link.setSiblingOrder(Integer.toString(1));
}
}
for (int i = 1; i < k; i++) {
ArrayList<BasicNode>newNodeList = new ArrayList<BasicNode>();
ArrayList<BasicLink>newLinkList = new ArrayList<BasicLink>();
BasicNode newpNode = PatternUtil.copySubtree(pnode, pnodeList, plinkList, newNodeList, newLinkList);
copyArgument.getRootBasicNode().addAll(newNodeList);
copyArgument.getRootBasicLink().addAll(newLinkList);
BasicLink newLink = DcaseFactory.eINSTANCE.createDcaseLink001();
newLink.setSource(parent);
newLink.setTarget(newpNode);
newLink.setSiblingOrder(Integer.toString(i+1));
copyArgument.getRootBasicLink().add(newLink);
}
}
// Parameter
if (PatternUtil.isParameter(subType)) {
if (!ParameterUtil.processParameter(cNode, copyArgument)) {
return false;
}
} else {
// remove the current Pattern node.
PatternUtil.removeLinks(cNode, copyArgument.getRootBasicLink());
copyArgument.getRootBasicNode().remove(cNode);
}
}
return true;
}
/**
* Returns the first Pattern node.
* @param rootNode the root node.
* @param argument the argument.
* @param nodeSet the checked node set.
* @param paramSet the checked Parameter node set.
* @return the first Pattern node.
*/
private static BasicNode searchFirstPattern(BasicNode rootNode, Argument argument,
HashSet<BasicNode> nodeSet, HashSet<BasicNode> paramSet) {
if (rootNode == null || ! nodeSet.add(rootNode)) {
return null;
}
List<BasicNode>childList = PatternUtil.getChildren(rootNode, argument, false);
if (childList == null) {
return null;
}
// check all children
while (childList.size() > 0) {
// must be Array (for siblingOrder)
ArrayList<BasicNode>nextList = new ArrayList<BasicNode>();
for (BasicNode node : childList) {
if (node instanceof System) {
String subType = ((System)node).getSubType();
if (PatternUtil.isLoop(subType) ||
PatternUtil.isChoice(subType) ||
PatternUtil.isMultiplicity(subType) ||
PatternUtil.isParameter(subType)) {
if (paramSet.add(node)) {
return node;
}
}
}
// gather grandchildren
List<BasicNode>gcList = PatternUtil.getChildren(node, argument, false);
if (gcList != null) {
for (BasicNode gcnode : gcList) {
if (nodeSet.add(gcnode)) {
nextList.add(gcnode);
}
}
}
}
// try grandchildren
childList = nextList;
}
return null;
}
/**
* Gets the number of k.
* @param scNode the System node.
* @return the number of k.
*/
private static int getPatternNumber(System scNode, Argument argument) {
int i = scNode.getI();
int j = scNode.getJ();
if (PatternUtil.isLoop(scNode.getSubType())) {
i = 1;
j = 100; // SPINNER_MAX at AttributeDialog.
}
if (i == j) {
return i;
}
PatternNumberDialog dialog = new PatternNumberDialog(
DcaseEditorUtil.getActiveWindowShell(),
NLS.bind(Menus.AddPattern_0, scNode.getSubType()),
NLS.bind(Menus.AddPattern_1, scNode.getName()), scNode, argument);
if (dialog.open() != Dialog.OK) {
return -1;
}
return dialog.getNumber();
}
/**
* Ask a question about Loop unrolling.
* @param times the times.
* @return the answer of loop unrolling.
*/
private static boolean askLoopDialog(String path, int times) {
return MessageDialog.openQuestion(
DcaseEditorUtil.getActiveWindowShell(),
NLS.bind(Menus.LoopUnroll_0, times),
NLS.bind(Menus.LoopUnroll_1, path, times));
}
}