1 17 18 19 20 package org.apache.lenya.workflow.impl; 21 22 import java.util.ArrayList ; 23 import java.util.Arrays ; 24 import java.util.HashMap ; 25 import java.util.HashSet ; 26 import java.util.Iterator ; 27 import java.util.List ; 28 import java.util.Map ; 29 import java.util.Set ; 30 31 import org.apache.lenya.workflow.Action; 32 import org.apache.lenya.workflow.BooleanVariable; 33 import org.apache.lenya.workflow.BooleanVariableInstance; 34 import org.apache.lenya.workflow.Event; 35 import org.apache.lenya.workflow.Situation; 36 import org.apache.lenya.workflow.State; 37 import org.apache.lenya.workflow.Transition; 38 import org.apache.lenya.workflow.Workflow; 39 import org.apache.lenya.workflow.WorkflowException; 40 import org.apache.lenya.workflow.WorkflowInstance; 41 import org.apache.lenya.workflow.WorkflowListener; 42 import org.apache.log4j.Category; 43 44 45 48 public abstract class WorkflowInstanceImpl implements WorkflowInstance { 49 50 private static final Category log = Category.getInstance(WorkflowInstanceImpl.class); 51 52 55 protected WorkflowInstanceImpl() { 56 } 57 58 private WorkflowImpl workflow; 59 60 64 public Workflow getWorkflow() { 65 return getWorkflowImpl(); 66 } 67 68 72 protected WorkflowImpl getWorkflowImpl() { 73 return workflow; 74 } 75 76 81 public Event[] getExecutableEvents(Situation situation) throws WorkflowException { 82 83 if (log.isDebugEnabled()) { 84 log.debug("Resolving executable events"); 85 } 86 87 Transition[] transitions = getWorkflow().getLeavingTransitions(getCurrentState()); 88 Set executableEvents = new HashSet (); 89 90 for (int i = 0; i < transitions.length; i++) { 91 if (transitions[i].canFire(situation, this)) { 92 executableEvents.add(transitions[i].getEvent()); 93 if (log.isDebugEnabled()) { 94 log.debug(" [" + transitions[i].getEvent() + "] can fire."); 95 } 96 } 97 else { 98 if (log.isDebugEnabled()) { 99 log.debug(" [" + transitions[i].getEvent() + "] can not fire."); 100 } 101 } 102 } 103 104 if (log.isDebugEnabled()) { 105 log.debug(" Resolving executable events completed."); 106 } 107 108 return (Event[]) executableEvents.toArray(new Event[executableEvents.size()]); 109 } 110 111 116 public void invoke(Situation situation, Event event) 117 throws WorkflowException { 118 if (!Arrays.asList(getExecutableEvents(situation)).contains(event)) { 119 throw new WorkflowException("The event '" + event + 120 "' cannot be invoked in the situation '" + situation + "'."); 121 } 122 123 fire(getNextTransition(event)); 124 125 for (Iterator iter = listeners.iterator(); iter.hasNext();) { 126 WorkflowListener listener = (WorkflowListener) iter.next(); 127 listener.transitionFired(this, situation, event); 128 } 129 } 130 131 137 protected TransitionImpl getNextTransition(Event event) throws WorkflowException { 138 TransitionImpl nextTransition = null; 139 Transition[] transitions = getWorkflow().getLeavingTransitions(getCurrentState()); 140 141 for (int i = 0; i < transitions.length; i++) { 142 if (transitions[i].getEvent().equals(event)) { 143 144 if (nextTransition != null) { 145 throw new WorkflowException("More than one transition found for event [" + event + "]!"); 146 } 147 148 nextTransition = (TransitionImpl) transitions[i]; 149 } 150 } 151 152 if (nextTransition == null) { 153 throw new WorkflowException("No transition found for event [" + event + "]!"); 154 } 155 156 return nextTransition; 157 } 158 159 164 protected void fire(TransitionImpl transition) throws WorkflowException { 165 Action[] actions = transition.getActions(); 166 167 for (int i = 0; i < actions.length; i++) { 168 actions[i].execute(this); 169 } 170 171 setCurrentState(transition.getDestination()); 172 } 173 174 private State currentState; 175 176 180 protected void setCurrentState(State state) { 181 this.currentState = state; 182 } 183 184 187 public State getCurrentState() { 188 return currentState; 189 } 190 191 195 protected void setWorkflow(WorkflowImpl workflow) { 196 this.workflow = workflow; 197 setCurrentState(getWorkflow().getInitialState()); 198 initVariableInstances(); 199 } 200 201 206 protected void setWorkflow(String workflowName) throws WorkflowException { 207 setWorkflow(getWorkflow(workflowName)); 208 } 209 210 216 protected abstract WorkflowImpl getWorkflow(String workflowName) 217 throws WorkflowException; 218 219 225 protected State getState(String id) throws WorkflowException { 226 return getWorkflowImpl().getState(id); 227 } 228 229 private Map variableInstances = new HashMap (); 230 231 234 protected void initVariableInstances() { 235 variableInstances.clear(); 236 237 BooleanVariable[] variables = getWorkflowImpl().getVariables(); 238 239 for (int i = 0; i < variables.length; i++) { 240 BooleanVariableInstance instance = new BooleanVariableInstanceImpl(); 241 instance.setValue(variables[i].getInitialValue()); 242 variableInstances.put(variables[i], instance); 243 } 244 } 245 246 252 protected BooleanVariableInstance getVariableInstance(BooleanVariable variable) 253 throws WorkflowException { 254 if (!variableInstances.containsKey(variable)) { 255 throw new WorkflowException("No instance for variable '" + variable.getName() + "'!"); 256 } 257 258 return (BooleanVariableInstance) variableInstances.get(variable); 259 } 260 261 264 public boolean getValue(String variableName) throws WorkflowException { 265 BooleanVariable variable = getWorkflowImpl().getVariable(variableName); 266 BooleanVariableInstance instance = getVariableInstance(variable); 267 268 return instance.getValue(); 269 } 270 271 277 protected void setValue(String variableName, boolean value) 278 throws WorkflowException { 279 BooleanVariable variable = getWorkflowImpl().getVariable(variableName); 280 BooleanVariableInstance instance = getVariableInstance(variable); 281 instance.setValue(value); 282 } 283 284 private List listeners = new ArrayList (); 285 286 289 public void addWorkflowListener(WorkflowListener listener) { 290 if (!listeners.contains(listener)) { 291 listeners.add(listener); 292 } 293 } 294 295 298 public void removeWorkflowListener(WorkflowListener listener) { 299 listeners.remove(listener); 300 } 301 302 305 public boolean isSynchronized(Event event) throws WorkflowException { 306 Transition nextTransition = getNextTransition(event); 307 return nextTransition.isSynchronized(); 308 } 309 310 } 311 | Popular Tags |