package org.js.model.workflow.util; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.eclipse.core.runtime.Assert; import org.eclipse.emf.common.command.Command; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.edit.command.DeleteCommand; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.jwt.meta.model.core.Model; import org.eclipse.jwt.meta.model.core.PackageableElement; import org.eclipse.jwt.meta.model.events.Event; import org.eclipse.jwt.meta.model.events.EventsFactory; import org.eclipse.jwt.meta.model.organisations.OrganisationsFactory; import org.eclipse.jwt.meta.model.organisations.Role; import org.eclipse.jwt.meta.model.processes.Action; import org.eclipse.jwt.meta.model.processes.Activity; import org.eclipse.jwt.meta.model.processes.ActivityEdge; import org.eclipse.jwt.meta.model.processes.ActivityNode; import org.eclipse.jwt.meta.model.processes.FinalNode; import org.eclipse.jwt.meta.model.processes.ForkNode; import org.eclipse.jwt.meta.model.processes.InitialNode; import org.eclipse.jwt.meta.model.processes.JoinNode; import org.eclipse.jwt.meta.model.processes.ProcessesFactory; import org.js.model.workflow.State; import org.js.model.workflow.StateEnum; /** * This class provides methods relating to jwt meta model. * * @author Xi * */ public class WorkflowModelUtil { public static final String SPECIALIZATION_ACTION = "Specialization"; public static final String IDLE_ACTION = "Idle"; public static final String INITIAL_NODE = "InitialNode"; public static final String ACTIVITY_FINAL_NODE = "ActivityFinalNode"; public static ProcessesFactory processFactory = ProcessesFactory.eINSTANCE; public static EventsFactory eventsFactory = EventsFactory.eINSTANCE; public static OrganisationsFactory organisatoinFactory = OrganisationsFactory.eINSTANCE; public static Action addAction(Activity activity, String name) { Action action = processFactory.createAction(); action.setName(name); activity.getNodes().add(action); return action; } public static Event addEvent(Activity activity, String name) { Event event = eventsFactory.createEvent(); if (name == null || name.equals("")) { name = "Event" + String.valueOf(getEventList(activity).size()); } event.setName(name); activity.getNodes().add(event); return event; } /** * remove activity node (event, action, initial/final node) * * @param activity * @param name * @return */ public static ActivityNode removeActivityNode(Activity activity, String name) { ActivityNode actNode = (ActivityNode) getActivityNode(activity, name); if (actNode != null) { activity.getNodes().remove(actNode); } return actNode; } public static ActivityNode removeActivityNode(Activity activity, ActivityNode actNode) { if (activity.getNodes().contains(actNode)) { activity.getNodes().remove(actNode); } return actNode; } public static Role addRole(Model workflowModel, String name) { Role role = organisatoinFactory.createRole(); if (name == null || name.equals("")) { name = "Role" + String.valueOf(getRoleList(workflowModel).size()); } role.setName(name); workflowModel.getElements().add(role); return role; } public static Role removeRole(Model workflowModel, String name) { Role role = getRole(workflowModel, name); removeRole(workflowModel, role); return role; } public static Role removeRole(Model workflowModel, Role role) { if (role != null) { EditingDomain domain = AdapterFactoryEditingDomain.getEditingDomainFor(role); if (domain != null) { Command refcommand = DeleteCommand.create(domain, role); if (refcommand.canExecute()) { refcommand.execute(); } } // workflowModel.getElements().remove(role); } return role; } public static InitialNode addInitialNode(Activity activity, String name) { // InitialNode initNode = (InitialNode) getActivityNode(activity, // name); // if (initNode == null) { InitialNode initNode = processFactory.createInitialNode(); initNode.setName(name); activity.getNodes().add(initNode); // } return initNode; } public static FinalNode addFinalNode(Activity activity, String name) { // FinalNode finalNode = (FinalNode) getActivityNode(activity, // FINAL_NODE_NAME); // if (finalNode == null) { FinalNode finalNode = processFactory.createFinalNode(); finalNode.setName(name); activity.getNodes().add(finalNode); // } return finalNode; } public static ForkNode addForkNode(Activity activity) { ForkNode forkNode = processFactory.createForkNode(); activity.getNodes().add(forkNode); return forkNode; } public static JoinNode addJoinNode(Activity activity) { JoinNode joinNode = processFactory.createJoinNode(); activity.getNodes().add(joinNode); return joinNode; } public static ActivityEdge addEdge(Activity activity, ActivityNode source, ActivityNode target) { ActivityEdge actEdge = processFactory.createActivityEdge(); actEdge.setSource(source); actEdge.setTarget(target); activity.getEdges().add(actEdge); return actEdge; } public static ActivityEdge getEdge(Activity activity, ActivityNode source, ActivityNode target) { ActivityEdge result = null; for (ActivityEdge actiEdge : activity.getEdges()) { if (actiEdge.getSource().equals(source) && actiEdge.getTarget().equals(target)) { return actiEdge; } } return result; } public static ActivityEdge removeEdge(Activity activity, ActivityNode source, ActivityNode target) { ActivityEdge edgeToRemove = null; for (ActivityEdge actiEdge : activity.getEdges()) { if (actiEdge.getSource().equals(source) && actiEdge.getTarget().equals(target)) { edgeToRemove = actiEdge; break; } } removeEdge(activity, edgeToRemove); return edgeToRemove; } public static void removeEdge(Activity activity, ActivityEdge edge) { ActivityNode source = edge.getSource(); ActivityNode target = edge.getTarget(); activity.getEdges().remove(edge); source.getOut().remove(edge); target.getIn().remove(edge); } public static ArrayList<Action> getActionList(Activity activity) { EList<ActivityNode> actNodes = activity.getNodes(); ArrayList<Action> result = new ArrayList<Action>(); Iterator<ActivityNode> it = actNodes.iterator(); while (it.hasNext()) { ActivityNode actNode = it.next(); if (actNode instanceof Action) { result.add((Action) actNode); } } return result; } public static ArrayList<Role> getRoleList(Model workflowModel) { EList<PackageableElement> pEleList = workflowModel.getElements(); ArrayList<Role> result = new ArrayList<Role>(); Iterator<PackageableElement> it = pEleList.iterator(); while (it.hasNext()) { PackageableElement pEle = it.next(); if (pEle instanceof Role) { result.add((Role) pEle); } } return result; } public static ArrayList<Event> getEventList(Activity activity) { EList<ActivityNode> actNodes = activity.getNodes(); ArrayList<Event> result = new ArrayList<Event>(); Iterator<ActivityNode> it = actNodes.iterator(); while (it.hasNext()) { ActivityNode actNode = it.next(); if (actNode instanceof Event) { result.add((Event) actNode); } } return result; } /** * return role if workflow model contains the role with given name. * * @param activity * @param name * @return */ public static Role getRole(Model workflowModel, String name) { for (PackageableElement role : workflowModel.getElements()) { if (role.getName().equals(name)) { return (Role) role; } } return null; } /** * return node if activity contains the node with given name. * * @param activity * @param name * @return */ public static ActivityNode getActivityNode(Activity activity, String name) { for (ActivityNode actNode : activity.getNodes()) { String tempName = ""; if (actNode instanceof Action) { tempName = getActionName((Action) actNode); } else { tempName = actNode.getName(); } if (tempName.equals(name)) return actNode; } return null; } /** * action name is sum of role name and action state value, so this method helps us to get the real name of the * action. * * @param action * @return action name */ public static String getActionName(Action action) { String tempName = action.getName(); int length = tempName.length(); int nameLength = length; if (tempName.contains(StateEnum.INACTIVE.toString())) { nameLength = length - StateEnum.INACTIVE.toString().length() - 4; } else if (tempName.contains(StateEnum.ENABLED.toString())) { nameLength = length - StateEnum.ENABLED.toString().length() - 4; } else if (tempName.contains(StateEnum.RUNNING.toString())) { nameLength = length - StateEnum.RUNNING.toString().length() - 4; } else if (tempName.contains(StateEnum.COMPLETED.toString())) { nameLength = length - StateEnum.COMPLETED.toString().length() - 4; } return tempName.substring(0, nameLength); } public static void setActionName(Action action) { State state = (State) WorkflowConfUtil.getAspectInstance(action, WorkflowConfUtil.STATE_ASPECT); String stateName = state.getState().toString(); String actionName = getActionName(action); actionName += " (" + stateName + ") "; action.setName(actionName); } public static boolean comparatorForRole(Role role1, Role role2) { Assert.isNotNull(role1); Assert.isNotNull(role2); return role1.getName().equals(role2.getName()); } public static boolean comparatorForActNode(ActivityNode actNode1, ActivityNode actNode2) { return actNode1.getName().equals(actNode2.getName()); } /** * check if the activity node name is contained * * @param activity * @param name * @return */ public static boolean containsActNodeName(Activity activity, String name) { for (ActivityNode actNode : activity.getNodes()) { if (actNode.getName().equals(name)) { return true; } } return false; } /** * get the precede action. * * @param actNode * @return precede action */ public static Action getPrecedeAction(ActivityNode actNode) { Action preAction = null; if (actNode.getIn() != null && actNode.getIn().size() > 0) { ActivityEdge actEdge = actNode.getIn().get(0); ActivityNode preActNode = actEdge.getSource(); if (preActNode instanceof Action) { preAction = (Action) preActNode; } else { preAction = getPrecedeAction(preActNode); } } return preAction; } public static ArrayList<Action> getNextSpecializationActions(Action action) { ArrayList<Action> nextActions = new ArrayList<Action>(); if (action.getOut().get(0).getTarget() instanceof ForkNode) { ActivityNode forkNode = action.getOut().get(0).getTarget(); for (ActivityEdge actEdge : forkNode.getOut()) { ActivityNode actNode = actEdge.getTarget(); if (actNode instanceof Action && (WorkflowModelUtil.getActionName((Action) actNode).equals(WorkflowModelUtil.SPECIALIZATION_ACTION))) { nextActions.add((Action) actNode); } } } else if (action.getOut().get(0).getTarget() instanceof Action) { nextActions.add((Action) action.getOut().get(0).getTarget()); } return nextActions; } /** * get the precede activity node. * * @param actNode * @return precede activity node */ public static ActivityNode getPriorActNode(ActivityNode actNode) { ActivityEdge actEdge = actNode.getIn().get(0); ActivityNode preActNode = actEdge.getSource(); return preActNode; } /** * get the next activity nodes. * * @param actNode * @return */ public static ArrayList<ActivityNode> getNextActNodes(ActivityNode actNode) { EList<ActivityEdge> actEdges = actNode.getOut(); ArrayList<ActivityNode> preActNodes = new ArrayList<ActivityNode>(); for (ActivityEdge actEdge : actEdges) { preActNodes.add(actEdge.getTarget()); } return preActNodes; } /** * get the precede activity nodes. * * @param actNode * @return precede activity nodes */ public static List<ActivityNode> getPrecedeActNodes(ActivityNode actNode) { EList<ActivityEdge> actEdges = actNode.getIn(); ArrayList<ActivityNode> preActNodes = new ArrayList<ActivityNode>(); for (ActivityEdge edge : actEdges) { preActNodes.add(edge.getSource()); } return preActNodes; } /** * set the state of given action. * * @param action */ public static void setActionState(Action action) { Action preAction = getPrecedeAction(action); State stateAspect = (State) WorkflowConfUtil.getAspectInstance(action, WorkflowConfUtil.STATE_ASPECT); if (stateAspect == null) { stateAspect = (State) WorkflowConfUtil.addAspectInstance(action, WorkflowConfUtil.STATE_ASPECT); } if (preAction != null) { State preState = (State) WorkflowConfUtil.getAspectInstance(preAction, WorkflowConfUtil.STATE_ASPECT); if (preState.getState() == StateEnum.COMPLETED) { stateAspect.setState(StateEnum.ENABLED); } else { stateAspect.setState(StateEnum.INACTIVE); } } else { stateAspect.setState(StateEnum.ENABLED); } setActionName(action); } /** * set the state for the given action. * * @param action * @param state */ public static void setActionState(Action action, StateEnum state) { State stateAspect = (State) WorkflowConfUtil.getAspectInstance(action, WorkflowConfUtil.STATE_ASPECT); stateAspect.setState(state); setActionName(action); } /** * all all actions in the stage of the given action. * * @param activity * @param action */ public static ArrayList<Action> getStagedActions(Activity activity, Action action) { ArrayList<Action> stagedActions = new ArrayList<Action>(); org.js.model.rbac.Role role = WorkflowUtil.getRBACRole(action); if (role != null) { for (org.js.model.rbac.Role parent : role.getParentRoles()) { for (org.js.model.rbac.Role child : parent.getChildRoles()) { if (child != null) { stagedActions.addAll(getActions(activity, child)); } } } } return stagedActions; } /** * all actions performed by the given role. these actions should be in the same stage. * * @param activity * @param role * @return */ public static ArrayList<Action> getActions(Activity activity, org.js.model.rbac.Role role) { ArrayList<Action> actions = new ArrayList<Action>(); for (Action action : getActionList(activity)) { org.js.model.rbac.Role tempRole = WorkflowUtil.getRBACRole(action); if (tempRole != null && tempRole.getId().equals(role.getId())) { actions.add(action); } } return actions; } public static Action getIdleAction(Activity activity) { for (ActivityNode actNode : activity.getNodes()) { if (actNode instanceof Action && WorkflowModelUtil.getActionName((Action) actNode).equals(WorkflowModelUtil.IDLE_ACTION)) { return (Action) actNode; } } return null; } public static FinalNode getFinalNode(Activity activity) { for (ActivityNode actNode : activity.getNodes()) { if (actNode instanceof FinalNode) { return (FinalNode) actNode; } } return null; } public static InitialNode getInitialNode(Activity activity) { InitialNode node = null; for (ActivityNode actNode : activity.getNodes()) { if (actNode instanceof InitialNode) { node = (InitialNode) actNode; } } return node; } /** * find the path between the given left node and a given right node. * * @param leftActivityNode * @param rightActivityNode * @param path * @return */ public static Set<EObject> findPath(ActivityNode leftActivityNode, ActivityNode rightActivityNode, Set<EObject> path) { Set<EObject> result = new HashSet<EObject>(); EList<ActivityEdge> in = rightActivityNode.getIn(); for (ActivityEdge activityEdge : in) { if (result.isEmpty()) { Set<EObject> elements = new HashSet<EObject>(); ActivityNode source = activityEdge.getSource(); if (source != null) { elements.addAll(path); elements.add(activityEdge); if (leftActivityNode.equals(source)) { // stop and return original path set result = elements; break; } else elements.add(source); result = findPath(leftActivityNode, source, elements); } } } return result; } }