KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jbpm > bpel > def > Scope


1 package org.jbpm.bpel.def;
2
3 import java.util.ArrayList JavaDoc;
4 import java.util.Collection JavaDoc;
5 import java.util.HashMap JavaDoc;
6 import java.util.HashSet JavaDoc;
7 import java.util.Iterator JavaDoc;
8 import java.util.List JavaDoc;
9 import java.util.Map JavaDoc;
10
11 import javax.wsdl.Message;
12 import javax.xml.namespace.QName JavaDoc;
13
14 import org.jbpm.bpel.data.def.ElementTypeInfo;
15 import org.jbpm.bpel.data.def.MessageTypeInfo;
16 import org.jbpm.bpel.data.def.VariableDefinition;
17 import org.jbpm.bpel.data.def.VariableTypeInfo;
18 import org.jbpm.bpel.exe.Fault;
19 import org.jbpm.bpel.exe.ScopeInstance;
20 import org.jbpm.bpel.service.def.CorrelationSetDefinition;
21 import org.jbpm.bpel.service.def.PartnerLinkDefinition;
22 import org.jbpm.bpel.wsdl.util.WsdlUtil;
23 import org.jbpm.bpel.xml.BpelConstants;
24 import org.jbpm.graph.def.DelegationException;
25 import org.jbpm.graph.def.Node;
26 import org.jbpm.graph.exe.ExecutionContext;
27 import org.jbpm.graph.exe.Token;
28
29 /**
30  * Represents a BPEL scope activity.
31  * @see "WS-BPEL 2.0 §13"
32  * @author Juan Cantú
33  * @version $Revision: 1.17 $ $Date: 2005/06/23 02:22:46 $
34  */

35 public class Scope extends CompositeActivity {
36   protected Activity root;
37   private transient List JavaDoc nodes = null;
38   
39   private static final long serialVersionUID = 1L;
40   /** Compensation handler type. */
41   public static final HandlerType COMPENSATION = new HandlerType("compensation");
42
43   /** Non-discriminating fault handler type. */
44   public static final HandlerType CATCH_ALL = new HandlerType("catchAll");
45
46   /** Forced termination handler type. */
47   public static final HandlerType TERMINATION = new HandlerType("termination");
48
49   /** Qualified name of the forced termination fault. */
50   public static final QName JavaDoc Q_FORCED_TERMINATION = new QName JavaDoc(BpelConstants.NS_BPWS, "forcedTermination");
51   
52   public static final String JavaDoc NORMAL_FLOW_TOKEN = "normalFlow";
53   public static final String JavaDoc IMPLICIT_TOKEN = "implicit";
54   public static final String JavaDoc EVENTS_TOKEN = "events";
55   public static final String JavaDoc EVENT_TOKEN = "event";
56   
57   private Map JavaDoc variables = new HashMap JavaDoc();
58   private Map JavaDoc partnerLinks = new HashMap JavaDoc();
59   private Map JavaDoc correlationSets = new HashMap JavaDoc();
60
61   private ScopeHandler compensationHandler;
62   private ScopeHandler terminationHandler;
63   private Collection JavaDoc messageHandlers = new HashSet JavaDoc();
64   private Collection JavaDoc alarmHandlers = new HashSet JavaDoc();
65   private List JavaDoc faultHandlers = new ArrayList JavaDoc();
66   private ScopeHandler catchAllHandler;
67   
68   private boolean isolated;
69   private boolean implicit = false;
70
71   public Scope() {
72     super();
73   }
74   
75   public Scope(String JavaDoc name) {
76     super(name);
77   }
78
79   //FIXME remove id code when persistence is ready
80
private long id;
81   
82   public void setId(long id) {
83     this.id = id;
84   }
85   
86   public long getId() {
87     return id;
88   }
89   
90   // behaviour methods /////////////////////////////////////////////////////////////////////////////
91

92   public void execute(ExecutionContext context) {
93     //TODO multiple-scope behavior
94
Token scopeToken = new Token(context.getToken(), name);
95     initScopeData(scopeToken);
96
97     enableEvents(scopeToken);
98     getRoot().enter(createScopeContext(scopeToken));
99   }
100   
101   public void setNegativeLinkStatus(Token token) {
102     getRoot().setNegativeLinkStatus(token);
103     super.setNegativeLinkStatus(token);
104   }
105   
106   public void complete(ScopeInstance parent) {
107     //disableTriggers(parent);
108
Token token = parent.getToken();
109     token.getNode().leave(new ExecutionContext(token));
110   }
111
112   public void initScopeData(Token token) {
113     // scope state
114
ScopeInstance.create(token);
115
116     // variables
117
for(Iterator JavaDoc it = variables.values().iterator(); it.hasNext();) {
118       ((VariableDefinition) it.next()).createInstance(token);
119     }
120     // correlation sets
121
for(Iterator JavaDoc it = correlationSets.values().iterator(); it.hasNext();) {
122       ((CorrelationSetDefinition) it.next()).createInstance(token);
123     }
124     // partner links
125
for(Iterator JavaDoc it = partnerLinks.values().iterator(); it.hasNext();) {
126       ((PartnerLinkDefinition) it.next()).createInstance(token);
127     }
128   }
129
130   public void disableEvents(Token eventToken) {
131     for(Iterator JavaDoc it = messageHandlers.iterator(); it.hasNext();)
132       ((MessageHandler)it.next()).getReceiver().close(eventToken);
133     
134     for(Iterator JavaDoc it = alarmHandlers.iterator(); it.hasNext();)
135       ((AlarmHandler)it.next()).getAlarm().cancelTimer(eventToken);
136   }
137   
138   public void enableEvents(Token scopeToken) {
139     if ( !messageHandlers.isEmpty() || !alarmHandlers.isEmpty() ) {
140       Token eventToken = new Token(scopeToken, EVENTS_TOKEN);
141       
142       //a child has to be created to avoid that the completion of child events
143
//propagates token.end notification when the scope instance is still
144
//in normal execution
145
new Token(eventToken, IMPLICIT_TOKEN);
146        
147       for(Iterator JavaDoc it = messageHandlers.iterator(); it.hasNext();)
148         ((MessageHandler)it.next()).getReceiver().receive(eventToken);
149        
150       for(Iterator JavaDoc it = alarmHandlers.iterator(); it.hasNext();)
151         ((AlarmHandler)it.next()).getAlarm().startTimer(eventToken);
152     }
153   }
154   
155   public ExecutionContext createScopeContext(Token scopeToken) {
156     Token normalFlowToken = new Token(scopeToken, NORMAL_FLOW_TOKEN);
157     //a child has to be created to avoid that the propagation of token.end
158
//notification (consequence of a scope completion) terminates its parent
159
//scope
160
new Token(scopeToken, IMPLICIT_TOKEN);
161     return new ExecutionContext(normalFlowToken);
162   }
163   
164   /**{@inheritDoc}*/
165   public void accept(BpelVisitor visitor) {
166     visitor.visit(this);
167   }
168   
169   // composite activity override /////////////////////////////////////////////////////////////////////////////
170

171   public VariableDefinition findVariable(String JavaDoc varName) {
172     VariableDefinition variable = getVariable(varName);
173     return variable != null ? variable : super.findVariable(varName);
174   }
175   
176   public CorrelationSetDefinition findCorrelationSet(String JavaDoc csName) {
177     CorrelationSetDefinition cs = getCorrelationSet(csName);
178     return cs != null ? cs : super.findCorrelationSet(csName);
179   }
180   
181   public PartnerLinkDefinition findPartnerLink(String JavaDoc plinkName) {
182     PartnerLinkDefinition plink = getPartnerLink(plinkName);
183     return plink != null ? plink : super.findPartnerLink(plinkName);
184   }
185   
186   // jbpm override /////////////////////////////////////////////////////////////////////////////
187

188   public void raiseException(Throwable JavaDoc exception, ExecutionContext executionContext) throws DelegationException {
189     if(exception instanceof Fault) {
190       Token token = executionContext.getToken();
191       ScopeInstance.get(token).faulted((Fault)exception);
192     }
193     else {
194       super.raiseException(exception, executionContext);
195     }
196   }
197   
198   //scope properties /////////////////////////////////////////////////////////////////////////////
199

200   public Activity getRoot() {
201     return root;
202   }
203   
204   public void setRoot(Activity root) {
205     this.root = root;
206   }
207
208   public void addVariable(VariableDefinition variable) {
209     variables.put(variable.getName(), variable);
210   }
211   
212   /**
213    * Gets the variables defined in scope.
214    * @return a map of <name, variable> entries
215    */

216   public Map JavaDoc getVariables() {
217     return variables;
218   }
219
220   public void setVariables(Map JavaDoc variables) {
221     this.variables = variables;
222   }
223   
224   public VariableDefinition getVariable(String JavaDoc variableName) {
225     return (VariableDefinition) variables.get(variableName);
226   }
227
228   public void addCorrelationSet(CorrelationSetDefinition correlation) {
229     correlationSets.put(correlation.getName(), correlation);
230   }
231   
232   /**
233    * Gets the correlation set with the given name. Only checks correlation sets
234    * defined in this scope.
235    * @param correlationSetName the correlation set name
236    * @return a correlation set whose name matches the argument
237    */

238   public CorrelationSetDefinition getCorrelationSet(String JavaDoc correlationSetName) {
239     return (CorrelationSetDefinition) correlationSets.get(correlationSetName);
240   }
241
242   public void setCorrelationSets(Map JavaDoc correlationSets) {
243     this.correlationSets = correlationSets;
244   }
245   
246   public Collection JavaDoc getPartnerLinks() {
247     return partnerLinks.values();
248   }
249   
250   public void setPartnerLinks(Map JavaDoc partnerLinks) {
251     this.partnerLinks = partnerLinks;
252   }
253   
254   public void addPartnerLink(PartnerLinkDefinition partnerLink) {
255     partnerLinks.put(partnerLink.getName(), partnerLink);
256   }
257   
258   public PartnerLinkDefinition getPartnerLink(String JavaDoc plinkName) {
259     return (PartnerLinkDefinition) partnerLinks.get(plinkName);
260   }
261   
262   
263   public void addFaultHandler(FaultHandler faultHandler) {
264     faultHandler.compositeActivity = this;
265     faultHandlers.add(faultHandler);
266   }
267   
268   /**
269    * Selects a handler for the given fault. The handler is selected as follows.
270    * <ul>
271    * <li>in the case of faults thrown without associated data, select a
272    * handler with a matching faultName and no faultVariable</li>
273    * <li>in the case of faults thrown with associated data, select a handler
274    * with a matching faultName and no faultVariable; if there is no such
275    * handler then select a handler with a matching faultVariable and no
276    * faultName</li>
277    * <li>if no handler has been selected, select the catchAll handler if it
278    * exists</li>
279    * </ul>
280    * @param fault the fault to handle
281    * @return the selected fault handler, or <code>null</code> if no handler is
282    * able to catch the fault
283    */

284   public ScopeHandler getFaultHandler(Fault fault) {
285     ScopeHandler handler;
286     QName JavaDoc faultName = fault.getName();
287     VariableTypeInfo faultTypeInfo = fault.getTypeInfo();
288     
289     if (faultTypeInfo == null) {
290       handler = findFaultHandler(faultName);
291     }
292     else {
293       handler = findFaultHandler(faultTypeInfo, faultName);
294       if (handler == null) {
295         handler = findFaultHandler(faultTypeInfo);
296       }
297     }
298     if (handler == null) {
299       handler = catchAllHandler;
300     }
301     return handler;
302   }
303
304   /**
305    * Finds a handler for a fault thrown without associated data. For each
306    * handler <i>h</i> with a matching faultName:
307    * <ul>
308    * <li>if <i>h</i> does not specify a faultVariable then <i>h</i> is
309    * selected</li>
310    * <li>otherwise, no handler is selected</li>
311    * </ul>
312    * @param faultName the qualified name of the fault
313    * @return the selected fault handler, or <code>null</code> if no handler is
314    * able to catch the fault
315    */

316   protected FaultHandler findFaultHandler(QName JavaDoc faultName) {
317     Iterator JavaDoc faultHandlerIt = faultHandlers.iterator();
318     while (faultHandlerIt.hasNext()) {
319       FaultHandler handler = (FaultHandler) faultHandlerIt.next();
320       if (faultName.equals(handler.getFaultName()) &&
321           handler.getFaultVariable() == null) {
322         // current handler has a matching name and no fault variable, select it
323
return handler;
324       }
325     }
326     return null;
327   }
328   
329   /**
330    * Finds a handler for a fault thrown with associated data among handlers
331    * with a faultName. For each handler <i>h</i> with a matching faultName:
332    * <ul>
333    * <li>if <i>h</i> has a faultVariable whose type matches the type of the
334    * fault data then <i>h</i> is selected</li>
335    * <li>otherwise if the type of fault data is a WSDL message which contains
336    * a single part defined by an element, and <i>h</i> has a faultVariable
337    * whose type matches the type of the element used to define the part
338    * then <i>h</i> is selected</li>
339    * <li>otherwise if <i>h</i> does not specify a faultVariable then <i>h</i>
340    * is selected</li>
341    * </ul>
342    * @param faultTypeInfo
343    * @param faultName the qualified name of the fault
344    * @return the selected fault handler, or <code>null</code> if no handler is
345    * able to catch the fault
346    */

347   protected FaultHandler findFaultHandler(VariableTypeInfo faultTypeInfo, QName JavaDoc faultName) {
348     FaultHandler selectedHandler = null;
349     Iterator JavaDoc handlerIt = faultHandlers.iterator();
350     while (handlerIt.hasNext()) {
351       FaultHandler handler = (FaultHandler) handlerIt.next();
352       if (!faultName.equals(handler.getFaultName())) {
353         // current handler does not have a matching name, skip it
354
continue;
355       }
356       VariableDefinition handlerVariable = handler.getFaultVariable();
357       if (handlerVariable != null) {
358         VariableTypeInfo handlerTypeInfo = handlerVariable.getTypeInfo();
359         if (handlerTypeInfo.equals(faultTypeInfo)) {
360           /* current handler matches exactly the fault type; it has the highest
361            * priority, select it and stop the search */

362           selectedHandler = handler;
363           break;
364         }
365         else if (faultTypeInfo instanceof MessageTypeInfo &&
366             handlerTypeInfo instanceof ElementTypeInfo) {
367           // fault data is a WSDL message, and the handler has an element variable
368
Message message = ((MessageTypeInfo) faultTypeInfo).getMessage();
369           QName JavaDoc elementName = WsdlUtil.getDocLitElementName(message);
370           // do the handler element and the message part element match?
371
if (handlerTypeInfo.getName().equals(elementName)) {
372             /* current handler matches the element, select it but keep looking for
373              * a exact type match */

374             selectedHandler = handler;
375           }
376         }
377       }
378       else if (selectedHandler == null) {
379         /* this handler does not specify a variable, select it only if no other
380          * handler (of higher priority) has been selected */

381         selectedHandler = handler;
382       }
383     }
384     return selectedHandler;
385   }
386
387   /**
388    * Finds a handler for a fault thrown with associated data among handlers
389    * without a faultName. For each handler <i>h</i> without a faultName:
390    * <ul>
391    * <li>if <i>h</i> has a faultVariable whose type matches the type of the
392    * fault data then <i>h</i> is selected</li>
393    * <li>otherwise if the type of fault data is a WSDL message which contains
394    * a single part defined by an element, and <i>h</i> has a faultVariable
395    * whose type matches the type of the element used to define the part
396    * then <i>h</i> is selected</li>
397    * </ul>
398    * @param faultName the qualified name of the fault
399    * @param faultTypeInfo fault data type information
400    * @return the selected fault handler, or <code>null</code> if no handler is
401    * able to catch the fault
402    */

403   protected FaultHandler findFaultHandler(VariableTypeInfo faultTypeInfo) {
404     FaultHandler selectedHandler = null;
405     Iterator JavaDoc handlerIt = faultHandlers.iterator();
406     while (handlerIt.hasNext()) {
407       FaultHandler handler = (FaultHandler) handlerIt.next();
408       if (handler.getFaultName() != null) {
409         // current handler has a name, skip it
410
continue;
411       }
412       // current handler must have a fault variable since it has no fault name
413
VariableTypeInfo handlerTypeInfo = handler.getFaultVariable().getTypeInfo();
414       if (handlerTypeInfo.equals(faultTypeInfo)) {
415         /* current handler matches the fault type; it has the highest priority,
416          * select it and stop the search */

417         selectedHandler = handler;
418         break;
419       }
420       else if (faultTypeInfo instanceof MessageTypeInfo &&
421           handlerTypeInfo instanceof ElementTypeInfo) {
422         // fault data is a WSDL message, and the handler has an element variable
423
Message message = ((MessageTypeInfo) faultTypeInfo).getMessage();
424         QName JavaDoc elementName = WsdlUtil.getDocLitElementName(message);
425         // do the handler element and the message part element match?
426
if (handlerTypeInfo.getName().equals(elementName)) {
427           /* current handler matches the element, select it but keep looking for
428            * exact type matches */

429           selectedHandler = handler;
430         }
431       }
432     }
433     return selectedHandler;
434   }
435
436   public List JavaDoc getFaultHandlers() {
437     return faultHandlers;
438   }
439   
440   public Collection JavaDoc getMessageHandlers() {
441     return messageHandlers;
442   }
443   
444   public void addMessageHandler(MessageHandler messageHandler) {
445     messageHandler.compositeActivity = this;
446     messageHandlers.add(messageHandler);
447   }
448   
449   public Collection JavaDoc getAlarmHandlers() {
450     return alarmHandlers;
451   }
452   
453   public void addAlarmHandler(AlarmHandler alarmHandler) {
454     alarmHandler.compositeActivity = this;
455     alarmHandlers.add(alarmHandler);
456   }
457   
458   public void setHandler(HandlerType type, ScopeHandler handler) {
459     ScopeHandler previousHandler = null;
460     handler.compositeActivity = this;
461
462     if (type == COMPENSATION) {
463       previousHandler = compensationHandler;
464       compensationHandler = handler;
465     } else if (type == CATCH_ALL) {
466       previousHandler = catchAllHandler;
467       catchAllHandler = handler;
468     } else if (type == TERMINATION) {
469       previousHandler = terminationHandler;
470       terminationHandler = handler;
471     }
472     
473     if(previousHandler != null) previousHandler.compositeActivity = null;
474   }
475   
476   public ScopeHandler getHandler(HandlerType type) {
477     if (type == COMPENSATION) {
478       return compensationHandler;
479     } else if (type == CATCH_ALL) {
480       return catchAllHandler;
481     } else if (type == TERMINATION) {
482       return terminationHandler;
483     }
484
485     return null;
486   }
487   
488   //local scope properties //////////////////////////////////////////////////////////////////////
489

490   public boolean isIsolated() {
491     return isolated;
492   }
493   
494   public void setIsolated(boolean isolated) {
495     this.isolated = isolated;
496   }
497   
498   public void setImplicit(boolean implicit) {
499     this.implicit = implicit;
500   }
501   
502   public boolean isImplicit() {
503     return implicit;
504   }
505   
506   /** Enumerates the handler types a scope can provide. */
507   public static class HandlerType {
508     
509     private final String JavaDoc name;
510
511     /**
512      * Enumeration constructor.
513      * @param name the desired textual representation.
514      */

515     HandlerType(String JavaDoc name) {
516       this.name = name;
517     }
518
519     /**
520      * Returns a textual representation of this enumeration element.
521      * @return a string that identifies the element.
522      */

523     public String JavaDoc toString() {
524       return name;
525     }
526   }
527
528   // children management /////////////////////////////////////////////////////////////////////////////
529

530   /**{@inheritDoc}*/
531   public Node addNode(Node node) {
532     root = (Activity) node;
533     root.compositeActivity = this;
534     return root;
535   }
536
537   /**{@inheritDoc}*/
538   public Node removeNode(Node node) {
539     if(root.equals(node)) {
540       root.compositeActivity = null;
541       root = null;
542     }
543     
544     return node;
545   }
546   
547   /**{@inheritDoc}*/
548   public void reorderNode(int oldIndex, int newIndex) {
549     //nothing to do
550
}
551   
552   /**{@inheritDoc}*/
553   public List JavaDoc getNodes() {
554     if(nodes == null && root!=null) {
555       nodes = new ArrayList JavaDoc();
556       nodes.add(root);
557     }
558     return nodes;
559   }
560 }
Popular Tags