/** * Copyright 2010 JBoss Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.drools.osworkflow.instance.node; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.drools.definition.process.Connection; import org.drools.osworkflow.core.OSWorkflowConnection; import org.drools.osworkflow.core.node.StepNode; import org.drools.osworkflow.instance.OSWorkflowProcessInstance; import org.drools.process.instance.ProcessInstance; import org.drools.runtime.process.NodeInstance; import org.drools.workflow.instance.NodeInstanceContainer; import org.drools.workflow.instance.impl.NodeInstanceImpl; import com.opensymphony.module.propertyset.map.MapPropertySet; import com.opensymphony.workflow.basic.BasicWorkflowContext; import com.opensymphony.workflow.loader.ActionDescriptor; import com.opensymphony.workflow.loader.ConditionalResultDescriptor; import com.opensymphony.workflow.loader.ConditionsDescriptor; import com.opensymphony.workflow.loader.FunctionDescriptor; import com.opensymphony.workflow.loader.RestrictionDescriptor; import com.opensymphony.workflow.loader.ResultDescriptor; import com.opensymphony.workflow.spi.Step; import com.opensymphony.workflow.util.DefaultVariableResolver; public class StepNodeInstance extends NodeInstanceImpl implements Step { private static final long serialVersionUID = 510l; private String status; private String owner; public StepNode getStepNode() { return (StepNode) getNode(); } public OSWorkflowProcessInstance getOSWorkflowProcessInstance() { return (OSWorkflowProcessInstance) getProcessInstance(); } public int getStepId() { return (int) getNodeId(); } public void internalTrigger(NodeInstance from, String type) { Map<String, Object> transientVars = new HashMap<String, Object>(); transientVars.put("context", new BasicWorkflowContext("caller")); List<FunctionDescriptor> preFunctions = getStepNode().getPreFunctions(); if (preFunctions != null) { for (FunctionDescriptor preFunction: preFunctions) { getOSWorkflowProcessInstance().executeFunction(preFunction, transientVars); } } setStatus(type); Collection<ActionDescriptor> actions = getStepNode().getActions(); for (ActionDescriptor action: actions) { if (action.getAutoExecute() && isAvailableAction(action)) { doAction(action.getId(), null); break; } } } public void doAction(int actionId, Map inputs) { Map<String, Object> transientVars = new HashMap<String, Object>(); transientVars.put("context", new BasicWorkflowContext("caller")); ActionDescriptor action = getStepNode().getAction(actionId); if (action == null) { throw new IllegalArgumentException( "Unknown action id " + actionId); } List<FunctionDescriptor> preFunctions = action.getPreFunctions(); if (preFunctions != null) { for (FunctionDescriptor preFunction: preFunctions) { getOSWorkflowProcessInstance().executeFunction(preFunction, transientVars); } } boolean executed = false; List<ConditionalResultDescriptor> conditionalResults = action.getConditionalResults(); if (conditionalResults != null) { for (ConditionalResultDescriptor conditionalResult: conditionalResults) { if (getOSWorkflowProcessInstance().passesConditions(null, conditionalResult.getConditions(), (int) getNodeId())) { executeResult(conditionalResult, actionId, transientVars); } } } if (!executed) { executeResult(action.getUnconditionalResult(), actionId, transientVars); } List<FunctionDescriptor> postFunctions = action.getPostFunctions(); if (postFunctions != null) { for (FunctionDescriptor postFunction: postFunctions) { getOSWorkflowProcessInstance().executeFunction(postFunction, transientVars); } } if (action.isFinish()) { ((ProcessInstance) getProcessInstance()) .setState(ProcessInstance.STATE_COMPLETED); } } protected void executeResult(ResultDescriptor result, int actionId, Map<String, Object> transientVars) { List<FunctionDescriptor> preFunctions = result.getPreFunctions(); if (preFunctions != null) { for (FunctionDescriptor preFunction: preFunctions) { getOSWorkflowProcessInstance().executeFunction(preFunction, transientVars); } } String owner = null; if (result.getOwner() != null) { MapPropertySet ps = new MapPropertySet(); ps.setMap(new HashMap()); Object o = new DefaultVariableResolver().translateVariables(result.getOwner(), transientVars, ps); owner = (o != null) ? o.toString() : null; } if (result.getStep() == -1 || result.getStep() == getNodeId()) { setOwner(owner); setStatus(result.getStatus()); } else { setStatus(result.getOldStatus()); List<FunctionDescriptor> postFunctions = getStepNode().getPostFunctions(); if (postFunctions != null) { for (FunctionDescriptor postFunction: postFunctions) { getOSWorkflowProcessInstance().executeFunction(postFunction, transientVars); } } ((NodeInstanceContainer) getNodeInstanceContainer()).removeNodeInstance(this); for (Connection connection: getNode().getOutgoingConnections(actionId + "")) { NodeInstance nodeInstance = ((NodeInstanceContainer) getNodeInstanceContainer()) .getNodeInstance(connection.getTo()); if (nodeInstance instanceof StepNodeInstance) { ((StepNodeInstance) nodeInstance).setOwner(owner); } ((org.drools.workflow.instance.NodeInstance) nodeInstance) .trigger(this, connection.getToType()); } } List<FunctionDescriptor> postFunctions = result.getPostFunctions(); if (postFunctions != null) { for (FunctionDescriptor postFunction: postFunctions) { getOSWorkflowProcessInstance().executeFunction(postFunction, transientVars); } } } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public boolean isAvailableAction(int actionId) { return isAvailableAction(getStepNode().getAction(actionId)); } private boolean isAvailableAction(ActionDescriptor action) { if (action == null) { return false; } RestrictionDescriptor restriction = action.getRestriction(); if (restriction != null) { ConditionsDescriptor conditions = restriction.getConditionsDescriptor(); if (conditions != null) { return getOSWorkflowProcessInstance().passesConditions( conditions.getType(), conditions.getConditions(), (int) getNodeId()); } } return true; } public List<Integer> getAvailableActions() { List<Integer> ids = new ArrayList<Integer>(); for (ActionDescriptor action: getStepNode().getActions()) { if (isAvailableAction(action)) { ids.add(action.getId()); } } return ids; } protected void triggerConnection(Connection connection) { Map<String, Object> transientVars = new HashMap<String, Object>(); if (connection instanceof OSWorkflowConnection) { List<FunctionDescriptor> functions = ((OSWorkflowConnection) connection).getPreFunctions(); if (functions != null) { for (FunctionDescriptor function: functions) { getOSWorkflowProcessInstance().executeFunction(function, transientVars); } } super.triggerConnection(connection); functions = ((OSWorkflowConnection) connection).getPostFunctions(); if (functions != null) { for (FunctionDescriptor function: functions) { getOSWorkflowProcessInstance().executeFunction(function, transientVars); } } } else { super.triggerConnection(connection); } } public int getActionId() { // TODO return 0; } public String getCaller() { // TODO return null; } public Date getDueDate() { // TODO return null; } public long getEntryId() { // TODO return 0; } public Date getFinishDate() { // TODO return null; } public void setOwner(String owner) { this.owner = owner; } public String getOwner() { return owner; } public long[] getPreviousStepIds() { // TODO return null; } public Date getStartDate() { // TODO return null; } }