KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jbpm > bpel > xml > BpelReader


1 package org.jbpm.bpel.xml;
2
3 import java.io.ByteArrayInputStream JavaDoc;
4 import java.io.IOException JavaDoc;
5 import java.util.Arrays JavaDoc;
6 import java.util.HashMap JavaDoc;
7 import java.util.HashSet JavaDoc;
8 import java.util.Iterator JavaDoc;
9 import java.util.List JavaDoc;
10 import java.util.Map JavaDoc;
11 import java.util.Set JavaDoc;
12
13 import javax.wsdl.Definition;
14 import javax.wsdl.Message;
15 import javax.wsdl.Operation;
16 import javax.wsdl.OperationType;
17 import javax.wsdl.PortType;
18 import javax.wsdl.WSDLException;
19 import javax.wsdl.xml.WSDLReader;
20 import javax.xml.namespace.QName JavaDoc;
21 import javax.xml.parsers.DocumentBuilder JavaDoc;
22 import javax.xml.transform.Transformer JavaDoc;
23 import javax.xml.transform.TransformerException JavaDoc;
24 import javax.xml.transform.dom.DOMResult JavaDoc;
25 import javax.xml.transform.dom.DOMSource JavaDoc;
26
27 import org.apache.commons.collections.Predicate;
28 import org.apache.commons.collections.iterators.FilterIterator;
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.w3c.dom.Attr JavaDoc;
32 import org.w3c.dom.Document JavaDoc;
33 import org.w3c.dom.Element JavaDoc;
34 import org.w3c.dom.Node JavaDoc;
35 import org.xml.sax.InputSource JavaDoc;
36 import org.xml.sax.SAXException JavaDoc;
37
38 import org.jbpm.bpel.data.def.ElementTypeInfo;
39 import org.jbpm.bpel.data.def.MessageTypeInfo;
40 import org.jbpm.bpel.data.def.SchemaTypeInfo;
41 import org.jbpm.bpel.data.def.Snippet;
42 import org.jbpm.bpel.data.def.VariableDefinition;
43 import org.jbpm.bpel.data.def.VariableTypeInfo;
44 import org.jbpm.bpel.data.def.Snippet.Use;
45 import org.jbpm.bpel.def.Activity;
46 import org.jbpm.bpel.def.AlarmHandler;
47 import org.jbpm.bpel.def.BpelDefinition;
48 import org.jbpm.bpel.def.CompositeActivity;
49 import org.jbpm.bpel.def.FaultHandler;
50 import org.jbpm.bpel.def.Import;
51 import org.jbpm.bpel.def.ImportsDefinition;
52 import org.jbpm.bpel.def.MessageHandler;
53 import org.jbpm.bpel.def.Scope;
54 import org.jbpm.bpel.def.ScopeHandler;
55 import org.jbpm.bpel.def.Import.Type;
56 import org.jbpm.bpel.service.def.Correlation;
57 import org.jbpm.bpel.service.def.CorrelationSetDefinition;
58 import org.jbpm.bpel.service.def.Correlations;
59 import org.jbpm.bpel.service.def.PartnerLinkDefinition;
60 import org.jbpm.bpel.service.def.Receiver;
61 import org.jbpm.bpel.service.def.Correlation.Initiate;
62 import org.jbpm.bpel.timer.def.Alarm;
63 import org.jbpm.bpel.wsdl.def.PartnerLinkType;
64 import org.jbpm.bpel.wsdl.def.Property;
65 import org.jbpm.bpel.wsdl.def.PropertyAlias;
66 import org.jbpm.bpel.wsdl.def.PartnerLinkType.Role;
67 import org.jbpm.bpel.wsdl.util.WsdlUtil;
68 import org.jbpm.bpel.xml.util.NodeUtil;
69 import org.jbpm.jpdl.par.ProcessArchive;
70 import org.jbpm.jpdl.xml.Problem;
71
72 import com.ibm.wsdl.util.xml.DOMUtils;
73
74 /**
75  * @author Juan Cantú
76  * @author Alejandro Guízar
77  * @version $Revision: 1.27 $ $Date: 2005/06/23 20:45:04 $
78  */

79 public class BpelReader {
80   
81   private Map JavaDoc activityReaders;
82   private DocumentBuilder JavaDoc builder;
83   private Transformer JavaDoc bpelUpgrader;
84   private ProblemHandler problemHandler = new ProblemCollector();
85   
86   private static final BpelReader INSTANCE = new BpelReader();
87   private static final String JavaDoc BPEL_1_1_TEMPLATE = "bpel-1-1-converter.xsl";
88   private static final Log log = LogFactory.getLog(BpelReader.class);
89
90   protected BpelReader() {
91     initializeActivityParsers();
92     builder = NodeUtil.getDocumentBuilder();
93     bpelUpgrader = NodeUtil.createUpgrader(BpelReader.class.getResource(BPEL_1_1_TEMPLATE));
94   }
95   
96   /**
97    * Reads the bpel definition from the given input source
98    * @param input the input source where the bpel archive is located
99    * @param processDefinition
100    */

101   public void read(BpelDefinition processDefinition, InputSource JavaDoc input) {
102     try {
103       //parse bpel document using an error handler that collects validation problems
104
String JavaDoc location = input.getSystemId();
105       ErrorHandlerAdapter validationHandler = new ErrorHandlerAdapter(getProblemHandler());
106       builder.setErrorHandler(validationHandler);
107       Document JavaDoc bpelDocument = builder.parse(input);
108       if( !validationHandler.hasErrors() ) {
109         ImportWsdlLocator wsdlLocator = null;
110         if (location != null) {
111           wsdlLocator = new ImportWsdlLocator(location);
112           wsdlLocator.setProblemHandler(getProblemHandler());
113           processDefinition.setLocation(location);
114         }
115         read(processDefinition, bpelDocument.getDocumentElement(), wsdlLocator);
116       }
117     }
118     catch (SAXException JavaDoc e) {
119       getProblemHandler().add(
120           new Problem( Problem.LEVEL_ERROR, "bpel document contains invalid xml", e) );
121     }
122     catch (IOException JavaDoc e) {
123       getProblemHandler().add(
124           new Problem( Problem.LEVEL_ERROR, "bpel document is not readable", e) );
125     }
126   }
127
128   /**
129    * Reads the bpel definition from the given process archive
130    * @param archive the process archive where the definition is located
131    * @param processDefinition
132    */

133   public void read(BpelDefinition processDefinition, ProcessArchive archive) {
134     String JavaDoc location = processDefinition.getLocation();
135     byte[] bpelEntry = archive.removeEntry(location);
136     if (bpelEntry == null) {
137       getProblemHandler().add(
138           new Problem(Problem.LEVEL_ERROR, "bpel document not found") );
139       return;
140     }
141     try {
142       ErrorHandlerAdapter validationHandler = new ErrorHandlerAdapter(getProblemHandler());
143       builder.setErrorHandler(validationHandler);
144       Document JavaDoc bpelDocument = builder.parse(new ByteArrayInputStream JavaDoc(bpelEntry));
145       if( !validationHandler.hasErrors() ) {
146         ImportWsdlLocator wsdlLocator = new ArchiveWsdlLocator(location, archive);
147         wsdlLocator.setProblemHandler(getProblemHandler());
148         read(processDefinition, bpelDocument.getDocumentElement(), wsdlLocator);
149       }
150     }
151     catch (SAXException JavaDoc e) {
152       getProblemHandler().add(
153           new Problem( Problem.LEVEL_ERROR, "bpel document contains invalid xml", e) );
154     }
155     catch (IOException JavaDoc e) {
156       getProblemHandler().add(
157           new Problem( Problem.LEVEL_ERROR, "bpel document is not readable", e) );
158     }
159   }
160   
161   protected void read(BpelDefinition process, Element JavaDoc processElem, ImportWsdlLocator wsdlLocator) {
162     if (!BpelConstants.NS_BPWS.equals(processElem.getNamespaceURI())) {
163       //a transformation needs to be applied to the document
164
Document JavaDoc newProcessDoc = builder.newDocument();
165       ErrorListenerAdapter transformHandler = new ErrorListenerAdapter(getProblemHandler());
166       bpelUpgrader.setErrorListener(transformHandler);
167       try {
168         bpelUpgrader.transform(
169             new DOMSource JavaDoc(processElem.getOwnerDocument()), new DOMResult JavaDoc(newProcessDoc));
170       }
171       catch (TransformerException JavaDoc e) {
172         transformHandler.error(e);
173       }
174       //if transformation caused errors, stop reading
175
if(transformHandler.hasErrors()) return;
176       log.debug("upgraded bpel document: " + process.getLocation());
177       processElem = newProcessDoc.getDocumentElement();
178     }
179
180     // get attributes in the process element, including query language
181
readTopLevelAttributes(processElem, process);
182     // read imported documents
183
ImportsDefinition imports = process.getImports();
184     readImports(processElem, imports, wsdlLocator);
185     // if our wsdl locator has errors, stop reading
186
if( wsdlLocator.hasErrors() ) return;
187     
188     try {
189       // registration gets the query language from the process definition
190
registerPropertyAliases(imports);
191       // finally read the top-level scope
192
readScope(processElem, process.getScope());
193     }
194     catch(BpelException e) {
195       getProblemHandler().add( new Problem(Problem.LEVEL_ERROR, "bpel process is invalid.", e) );
196     }
197   }
198   
199   public void registerPropertyAliases(ImportsDefinition importsDef) {
200     List JavaDoc imports = importsDef.getImports();
201     // easy way out (necessary)
202
if (imports == null) return;
203     // get the process-level query language
204
BpelDefinition process = (BpelDefinition) importsDef.getProcessDefinition();
205     String JavaDoc queryLanguage = process != null ? process.getQueryLanguage() : BpelConstants.URN_XPATH_1_0;
206     // register property aliases in each wsdl document
207
for (int i = 0, n = imports.size(); i < n; i++) {
208       Import imp = (Import) imports.get(i);
209       if (imp.getType().equals(Type.WSDL)) {
210         registerPropertyAliases(importsDef, (Definition) imp.getDocument(), queryLanguage);
211       }
212     }
213   }
214   
215   private void registerPropertyAliases(ImportsDefinition importsDef, Definition def, String JavaDoc queryLanguage) {
216     // first deal with local extensibility elements...
217
Iterator JavaDoc extensionIt = def.getExtensibilityElements().iterator();
218     while (extensionIt.hasNext()) {
219       Object JavaDoc extension = extensionIt.next();
220       if (extension instanceof PropertyAlias) {
221         PropertyAlias alias = (PropertyAlias) extension;
222         // parse query
223
Snippet query = alias.getQuery();
224         if (query.getLanguage() == null) {
225           query.setLanguage(queryLanguage);
226         }
227         try {
228           query.parseScript();
229         }
230         catch(BpelException e) {
231           Problem problem = new Problem(Problem.LEVEL_ERROR,
232               "unable to parse property alias query", e);
233           problem.setResource(def.getDocumentBaseURI());
234           getProblemHandler().add(problem);
235         }
236         // move property alias to message
237
MessageTypeInfo message = importsDef.getMessageTypeInfo(alias.getMessage().getQName());
238         message.addPropertyAlias(alias);
239       }
240     }
241     // ...then deal with imported definitions
242
Iterator JavaDoc importsIter = def.getImports().values().iterator();
243     while (importsIter.hasNext()) {
244       List JavaDoc imports = (List JavaDoc) importsIter.next();
245       for (int i = 0, n = imports.size(); i < n; i++) {
246         javax.wsdl.Import imp = (javax.wsdl.Import) imports.get(i);
247         registerPropertyAliases(importsDef, imp.getDefinition(), queryLanguage);
248       }
249     }
250   }
251   
252   
253   // process properties //////////////////////////////////////////////////////////////
254

255   public void readTopLevelAttributes(Element JavaDoc processElem, BpelDefinition process) {
256     // name & namespace
257
process.setName(processElem.getAttribute(BpelConstants.ATTR_NAME));
258     process.setTargetNamespace(processElem.getAttribute(BpelConstants.ATTR_TARGET_NAMESPACE));
259     // query & expression language
260
process.setQueryLanguage(NodeUtil.getAttribute(processElem, BpelConstants.ATTR_QUERY_LANGUAGE));
261     process.setExpressionLanguage(NodeUtil.getAttribute(processElem, BpelConstants.ATTR_EXPRESSION_LANGUAGE));
262     // suppress join failure
263
Attr JavaDoc suppressAttr = processElem.getAttributeNode(BpelConstants.ATTR_SUPPRESS_JOIN_FAILURE);
264     Boolean JavaDoc suppressValue = readTBoolean(suppressAttr, Boolean.FALSE);
265     process.getScope().setSuppressJoinFailure(suppressValue);
266     // abstract process
267
Attr JavaDoc abstractAttr = processElem.getAttributeNode(BpelConstants.ATTR_ABSTRACT_PROCESS);
268     Boolean JavaDoc abstractValue = readTBoolean(abstractAttr, Boolean.FALSE);
269     process.setAbstractProcess(abstractValue.booleanValue());
270     // enable instance compensation
271
Attr JavaDoc compensationAttr = processElem.getAttributeNode(BpelConstants.ATTR_INSTANCE_COMPENSATION);
272     Boolean JavaDoc compensationValue = readTBoolean(compensationAttr, Boolean.FALSE);
273     process.setEnableInstanceCompensation(compensationValue.booleanValue());
274   }
275   
276   public void readImports(Element JavaDoc processElem, ImportsDefinition imports,
277       ImportWsdlLocator wsdlLocator) {
278     Iterator JavaDoc importElemIt = NodeUtil.getElements(processElem, BpelConstants.NS_BPWS, BpelConstants.ELEM_IMPORT);
279     while (importElemIt.hasNext()) {
280       Import imp = readImport((Element JavaDoc) importElemIt.next());
281       if (Import.Type.WSDL.equals(imp.getType())) {
282         readWsdlDocument(imp, wsdlLocator);
283       }
284       imports.addImport(imp);
285     }
286   }
287   
288   public Import readImport(Element JavaDoc importElem) {
289     Import imp = new Import();
290     imp.setNamespace(importElem.getAttribute(BpelConstants.ATTR_NAMESPACE));
291     imp.setLocation(importElem.getAttribute(BpelConstants.ATTR_LOCATION));
292     imp.setType(Import.Type.valueOf(importElem.getAttribute(BpelConstants.ATTR_IMPORT_TYPE)));
293     return imp;
294   }
295   
296   public void readWsdlDocument(Import imp, ImportWsdlLocator wsdlLocator) {
297     String JavaDoc location = imp.getLocation();
298     wsdlLocator.resolveBaseURI(location);
299     WSDLReader reader = WsdlUtil.getFactory().newWSDLReader();
300     // read imported WSDL document
301
Definition def;
302     try {
303       log.debug("read wsdl document: " + location);
304       def = reader.readWSDL(wsdlLocator);
305       // validate the definitions belong to the import's namespace
306
if (!def.getTargetNamespace().equals(imp.getNamespace())) {
307         Problem problem = new Problem(Problem.LEVEL_ERROR,
308             "imported definitions do not belong to the import's namespace");
309         problem.setResource(def.getDocumentBaseURI());
310         getProblemHandler().add(problem);
311       }
312       imp.setDocument(def);
313     }
314     catch (WSDLException e) {
315       Problem problem = new Problem(Problem.LEVEL_ERROR, "could not read wsdl document", e);
316       problem.setResource(location);
317       getProblemHandler().add(problem);
318     }
319   }
320
321   
322   // general properties //////////////////////////////////////////////////////////////
323

324   public Boolean JavaDoc readTBoolean(Attr JavaDoc attribute, Boolean JavaDoc defaultValue) {
325     if (attribute == null) {
326       return defaultValue;
327     }
328     String JavaDoc text = attribute.getValue();
329     return Boolean.valueOf( BpelConstants.YES.equalsIgnoreCase(text) );
330   }
331   
332   public Snippet readExpression(Element JavaDoc enclosingElement, CompositeActivity parent, Use use) {
333     // expression
334
Snippet expr = new Snippet();
335     expr.setText(DOMUtils.getChildCharacterData(enclosingElement));
336     expr.setNamespaces(NodeUtil.getNamespaceDeclarations(enclosingElement));
337     expr.setUse(use);
338     // language
339
String JavaDoc language = NodeUtil.getAttribute(enclosingElement, BpelConstants.ATTR_EXPRESSION_LANGUAGE);
340     if (language == null) {
341       BpelDefinition process = parent.getBpelDefinition();
342       if (use == Use.EXPRESSION || use == Use.JOIN_CONDITION) {
343         language = process.getExpressionLanguage();
344       }
345       else if (use == Use.QUERY || use == Use.PROPERTY_ALIAS) {
346         language = process.getQueryLanguage();
347       }
348     }
349     expr.setLanguage(language);
350     // parsing
351
try {
352       expr.parseScript();
353       return expr;
354     }
355     catch (BpelException e) {
356       getProblemHandler().add(
357           new Problem( Problem.LEVEL_ERROR, "unable to read expression.", e) );
358       return null;
359     }
360   }
361   
362   public Snippet readExpression(Element JavaDoc enclosingElement, CompositeActivity parent) {
363     return readExpression(enclosingElement, parent, Use.EXPRESSION);
364   }
365   
366   // scope definition properties //////////////////////////////////////////////////////////////
367

368   public void readScope(Element JavaDoc scopeElem, Scope scope) {
369     // variables
370
Element JavaDoc variablesElem = NodeUtil.getElement(scopeElem, BpelConstants.NS_BPWS, BpelConstants.ELEM_VARIABLES );
371     if (variablesElem != null ) scope.setVariables ( readVariables(variablesElem, scope) );
372     
373     // partner links
374
Element JavaDoc partnerLinksElem = NodeUtil.getElement( scopeElem, BpelConstants.NS_BPWS, BpelConstants.ELEM_PARTNER_LINKS );
375     if (partnerLinksElem != null ) scope.setPartnerLinks( readPartnerLinks(partnerLinksElem, scope) );
376     
377     // correlation sets
378
Element JavaDoc setsElem = NodeUtil.getElement( scopeElem, BpelConstants.NS_BPWS, BpelConstants.ELEM_CORRELATION_SETS );
379     if (setsElem != null ) scope.setCorrelationSets( readCorrelationSets(setsElem, scope) );
380     
381     // activity
382
Element JavaDoc activityElem = getActivityElement(scopeElem);
383     readActivity(activityElem, scope);
384     
385     // fault handlers
386
Element JavaDoc faultHandlerElem = NodeUtil.getElement(scopeElem, BpelConstants.NS_BPWS, BpelConstants.ELEM_FAULT_HANDLERS );
387     if( faultHandlerElem != null ) readFaultHandlers(faultHandlerElem, scope);
388     
389     // compensation handler
390
Element JavaDoc compHandlerElem = NodeUtil.getElement(scopeElem, BpelConstants.NS_BPWS, BpelConstants.ELEM_COMPENSATION_HANDLER );
391     if( compHandlerElem != null ) readHandler(compHandlerElem, scope, Scope.COMPENSATION);
392     
393     // event handlers
394
Element JavaDoc eventHandlerElem = NodeUtil.getElement(scopeElem, BpelConstants.NS_BPWS, BpelConstants.ELEM_EVENT_HANDLERS );
395     if( eventHandlerElem != null ) readEventHandlers(eventHandlerElem, scope);
396     
397     // termination handler
398
Element JavaDoc termHandlerElem = NodeUtil.getElement(scopeElem, BpelConstants.NS_BPWS, BpelConstants.ELEM_TERMINATION_HANDLER );
399     if( termHandlerElem != null ) readHandler(termHandlerElem, scope, Scope.TERMINATION);
400   }
401  
402   public void readHandler(Element JavaDoc element, Scope scope, Scope.HandlerType type) {
403     ScopeHandler handler = new ScopeHandler();
404     scope.setHandler(type, handler);
405     Element JavaDoc activityElement = getActivityElement(element);
406     handler.setActivity(readActivity(activityElement, handler));
407   }
408   
409   public void readFaultHandlers(Element JavaDoc faultHandlerElem, Scope scope) {
410     //load catchAll
411
Element JavaDoc catchAllElem = NodeUtil.getElement(faultHandlerElem, BpelConstants.NS_BPWS, BpelConstants.ELEM_CATCH_ALL );
412     if( catchAllElem != null ) {
413       readHandler(catchAllElem, scope, Scope.CATCH_ALL);
414     }
415     
416     Iterator JavaDoc catchElemIt = NodeUtil.getElements(faultHandlerElem, BpelConstants.NS_BPWS, BpelConstants.ELEM_CATCH);
417     while (catchElemIt.hasNext()) {
418       Element JavaDoc catchElement = (Element JavaDoc) catchElemIt.next();
419       readFaultHandler( catchElement, scope );
420     }
421   }
422   
423   public void readFaultHandler(Element JavaDoc catchElement, Scope scope) {
424     FaultHandler faultHandler = new FaultHandler();
425     scope.addFaultHandler(faultHandler);
426     Element JavaDoc activityElement = getActivityElement(catchElement);
427     faultHandler.setActivity(readActivity(activityElement, faultHandler));
428     
429     /*These valid configurations for a faultHandler are:
430      *-Catching faults without data:
431      * (faultName)
432      *-Catching faults with data:
433      * (faultName AND (elementType OR messageType)) , faultVariable?
434      * (faultVariable AND (elementType OR messageType))*/

435     
436     String JavaDoc faultNameStr = NodeUtil.getAttribute(catchElement, BpelConstants.ATTR_FAULT_NAME);
437     if( faultNameStr != null) {
438       QName JavaDoc faultName = NodeUtil.getQName(faultNameStr, catchElement);
439       faultHandler.setFaultName(faultName);
440     }
441     String JavaDoc variableName = NodeUtil.getAttribute(catchElement, BpelConstants.ATTR_FAULT_VARIABLE);
442     boolean hasName = faultHandler.getFaultName() != null;
443     if( variableName == null && !hasName) {
444       getProblemHandler().add(
445           new LocalizedProblem( Problem.LEVEL_ERROR,
446               "catch must specify either a faultName or a faultVariable", catchElement ) );
447       return;
448     }
449     VariableTypeInfo faultTypeInfo = null;
450     ImportsDefinition imports = scope.getBpelDefinition().getImports();
451     String JavaDoc faultMessageType = NodeUtil.getAttribute(catchElement, BpelConstants.ATTR_FAULT_MESSAGE_TYPE);
452     String JavaDoc faultElement = NodeUtil.getAttribute(catchElement, BpelConstants.ATTR_FAULT_ELEMENT);
453     if( faultMessageType != null ) {
454       //fault message type
455
if(faultElement != null) {
456         getProblemHandler().add(
457             new LocalizedProblem( Problem.LEVEL_ERROR,
458                 "faultMessageType and faultElement can't be both present", catchElement ) );
459       }
460       faultTypeInfo = getMessageTypeInfo(catchElement, faultMessageType, imports);
461     }
462     else if( faultElement != null ) {
463       //fault element
464
faultTypeInfo = getElementTypeInfo(catchElement, faultElement, imports);
465     }
466     
467     if(variableName != null) {
468       //faultVariable
469
if(faultTypeInfo == null) {
470         throw new BpelException("catch must specify either a faultMessageType or a faultElement", catchElement);
471       }
472       VariableDefinition variable = new VariableDefinition(variableName);
473       variable.setTypeInfo(faultTypeInfo);
474       faultHandler.setFaultVariable(variable);
475     }
476   }
477   
478   public void readEventHandlers(Element JavaDoc eventHandlerElem, Scope scope) {
479     //onEvents
480
Iterator JavaDoc eventElemIt = NodeUtil.getElements(eventHandlerElem, BpelConstants.NS_BPWS, BpelConstants.ELEM_ON_EVENT);
481     while (eventElemIt.hasNext()) {
482       Element JavaDoc eventElem = (Element JavaDoc) eventElemIt.next();
483       MessageHandler handler = new MessageHandler();
484       scope.addMessageHandler(handler);
485       //read variable if message type is present (support for bpel 1.1)
486
String JavaDoc messageType = NodeUtil.getAttribute(eventElem, BpelConstants.ATTR_MESSAGE_TYPE);
487       if(messageType != null) {
488         VariableDefinition variable = new VariableDefinition();
489         // name
490
String JavaDoc name = NodeUtil.getAttribute(eventElem, BpelConstants.ATTR_VARIABLE);
491         variable.setName(name);
492         // type info
493
VariableTypeInfo typeInfo = getMessageTypeInfo(eventElem, messageType, scope.getBpelDefinition().getImports());
494         variable.setTypeInfo(typeInfo);
495         handler.setVariableDefinition(variable);
496       }
497       //correlation sets
498
Element JavaDoc setsElem = NodeUtil.getElement( eventElem, BpelConstants.NS_BPWS, BpelConstants.ELEM_CORRELATION_SETS );
499       if (setsElem != null ) handler.setCorrelationSets( readCorrelationSets(setsElem, scope) );
500       //activity
501
Element JavaDoc activityElem = getActivityElement(eventElem);
502       readActivity(activityElem, handler);
503       //message attributes
504
Receiver receiver = readReceiver(eventElem, handler);
505       receiver.setInboundMessageActivity( handler );
506       handler.setReceiver(receiver);
507     }
508     //onAlarms
509
Iterator JavaDoc alarmElemIt = NodeUtil.getElements(eventHandlerElem, BpelConstants.NS_BPWS, BpelConstants.ELEM_ON_ALARM);
510     while (alarmElemIt.hasNext()) {
511       AlarmHandler handler = new AlarmHandler();
512       scope.addAlarmHandler(handler);
513       Element JavaDoc alarmElem = (Element JavaDoc) alarmElemIt.next();
514       Element JavaDoc activityElem = getActivityElement(alarmElem);
515       readActivity(activityElem, handler);
516       Alarm alarm = readAlarm(alarmElem, handler);
517       alarm.setAlarmActivity(handler);
518       handler.setAlarm(alarm);
519     }
520   }
521   
522   public Map JavaDoc readVariables(Element JavaDoc variablesElem, CompositeActivity parent) {
523     Map JavaDoc variables = new HashMap JavaDoc();
524     ImportsDefinition imports = parent.getBpelDefinition().getImports();
525     Iterator JavaDoc variableElemIt = NodeUtil.getElements(variablesElem, BpelConstants.NS_BPWS, BpelConstants.ELEM_VARIABLE);
526     while (variableElemIt.hasNext()) {
527       Element JavaDoc variableElem = (Element JavaDoc) variableElemIt.next();
528       VariableDefinition variable = readVariable(variableElem, imports);
529       String JavaDoc variableName = variable.getName();
530       if( variables.containsKey(variableName) ) {
531         getProblemHandler().add(
532             new LocalizedProblem( Problem.LEVEL_ERROR, "duplicate local name", variableElem ) );
533       }
534       else {
535         variables.put(variableName, variable);
536       }
537     }
538     return variables;
539   }
540   
541   public VariableDefinition readVariable(Element JavaDoc variableElem, ImportsDefinition imports) {
542     VariableDefinition variable = new VariableDefinition();
543     // name
544
String JavaDoc name = NodeUtil.getAttribute(variableElem, BpelConstants.ATTR_NAME);
545     variable.setName(name);
546     // type info
547
VariableTypeInfo typeInfo = getTypeInfo(variableElem, imports);
548     variable.setTypeInfo(typeInfo);
549     return variable;
550   }
551    
552   private VariableTypeInfo getTypeInfo(Element JavaDoc variableElem, ImportsDefinition imports) {
553     VariableTypeInfo typeInfo;
554     
555     String JavaDoc type = NodeUtil.getAttribute(variableElem, BpelConstants.ATTR_TYPE);
556     String JavaDoc messageType = NodeUtil.getAttribute(variableElem, BpelConstants.ATTR_MESSAGE_TYPE);
557     String JavaDoc element = NodeUtil.getAttribute(variableElem, BpelConstants.ATTR_ELEMENT);
558
559     if (messageType != null) {
560       if (type != null || element != null) {
561         getProblemHandler().add(
562             new LocalizedProblem( Problem.LEVEL_ERROR, "more than one type specifier is used", variableElem ) );
563       }
564       typeInfo = getMessageTypeInfo(variableElem, messageType, imports);
565     }
566     
567     else if (type != null) {
568       if (element != null) {
569         getProblemHandler().add(
570             new LocalizedProblem( Problem.LEVEL_ERROR, "more than one type specifier is used", variableElem ) );
571       }
572       typeInfo = getSchemaTypeInfo(variableElem, type, imports);
573     }
574     else if (element != null) {
575       typeInfo = getElementTypeInfo(variableElem, element, imports);
576     }
577     else {
578       throw new BpelException("no type specifier is used", variableElem);
579     }
580     return typeInfo;
581   }
582   
583   private MessageTypeInfo getMessageTypeInfo(Element JavaDoc parent, String JavaDoc messageType, ImportsDefinition imports) {
584     QName JavaDoc qname = NodeUtil.getQName(messageType, parent);
585     MessageTypeInfo typeInfo = imports.getMessageTypeInfo(qname);
586     if (typeInfo == null) {
587       throw new BpelException("message type " + messageType + " not found", parent);
588     }
589     return typeInfo;
590   }
591   
592   private ElementTypeInfo getElementTypeInfo(Element JavaDoc parent, String JavaDoc elementType, ImportsDefinition imports) {
593     QName JavaDoc qname = NodeUtil.getQName(elementType, parent);
594     ElementTypeInfo typeInfo = imports.getElementTypeInfo(qname);
595     if (typeInfo == null) {
596       throw new BpelException("element type " + elementType + " not found", parent);
597     }
598     return typeInfo;
599   }
600
601   private SchemaTypeInfo getSchemaTypeInfo(Element JavaDoc parent, String JavaDoc schemaType, ImportsDefinition imports) {
602     QName JavaDoc qname = NodeUtil.getQName(schemaType, parent);
603     SchemaTypeInfo typeInfo = imports.getSchemaTypeInfo(qname);
604     if (typeInfo == null) {
605       throw new BpelException("schema type " + schemaType + " not found", parent);
606     }
607     return typeInfo;
608   }
609   
610   // service properties //////////////////////////////////////////////////////////////
611

612   public Map JavaDoc readCorrelationSets(Element JavaDoc setsElem, CompositeActivity superState) {
613     Map JavaDoc correlationSets = new HashMap JavaDoc();
614     ImportsDefinition imports = superState.getBpelDefinition().getImports();
615     Iterator JavaDoc setElemIt = NodeUtil.getElements(setsElem, BpelConstants.NS_BPWS, BpelConstants.ELEM_CORRELATION_SET);
616     while (setElemIt.hasNext()) {
617       Element JavaDoc setElem = (Element JavaDoc) setElemIt.next();
618       CorrelationSetDefinition set = readCorrelationSet(setElem, imports);
619       String JavaDoc setName = set.getName();
620       if (correlationSets.containsKey(setName)) {
621         getProblemHandler().add(
622             new LocalizedProblem( Problem.LEVEL_ERROR, "duplicate local name", setElem ) );
623       }
624       else {
625         correlationSets.put(setName, set);
626       }
627     }
628     return correlationSets;
629   }
630   
631   public CorrelationSetDefinition readCorrelationSet(Element JavaDoc setElem, ImportsDefinition imports) {
632     CorrelationSetDefinition set = new CorrelationSetDefinition();
633     // properties
634
String JavaDoc[] propertyNames = setElem.getAttribute(BpelConstants.ATTR_PROPERTIES).split("\\s");
635     for (int p = 0; p < propertyNames.length; p++) {
636       String JavaDoc propertyName = propertyNames[p];
637       Property property = imports.getProperty(NodeUtil.getQName(propertyName, setElem));
638       if (property == null) {
639         throw new BpelException("property not found: " + propertyName, setElem);
640       }
641       set.addProperty(property);
642     }
643     // name
644
set.setName(setElem.getAttribute(BpelConstants.ATTR_NAME));
645     return set;
646   }
647   
648   public Map JavaDoc readPartnerLinks(Element JavaDoc partnerLinksElem, CompositeActivity parent) {
649     Map JavaDoc partnerLinks = new HashMap JavaDoc();
650     Iterator JavaDoc partnerLinkElemIt = NodeUtil.getElements(partnerLinksElem, BpelConstants.NS_BPWS, BpelConstants.ELEM_PARTNER_LINK);
651     while (partnerLinkElemIt.hasNext()) {
652       Element JavaDoc partnerLinkElem = (Element JavaDoc) partnerLinkElemIt.next();
653       PartnerLinkDefinition partnerLink = readPartnerLink(partnerLinkElem, parent);
654       String JavaDoc plinkName = partnerLink.getName();
655       if ( partnerLinks.containsKey(plinkName) ) {
656         getProblemHandler().add(
657             new LocalizedProblem( Problem.LEVEL_ERROR, "duplicate local name", partnerLinkElem ) );
658       }
659       else {
660         partnerLinks.put(plinkName, partnerLink);
661       }
662     }
663     return partnerLinks;
664   }
665   
666   public PartnerLinkDefinition readPartnerLink(Element JavaDoc partnerLinkElem, CompositeActivity parent) {
667     PartnerLinkDefinition partnerLink = new PartnerLinkDefinition();
668     // partner link type
669
String JavaDoc typeName = partnerLinkElem.getAttribute(BpelConstants.ATTR_PARTNER_LINK_TYPE);
670     QName JavaDoc typeQName = NodeUtil.getQName(typeName, partnerLinkElem);
671     PartnerLinkType type = parent.getBpelDefinition().getImports().getPartnerLinkType(typeQName);
672     if (type == null) {
673       throw new BpelException("partner link type not found", partnerLinkElem);
674     }
675     partnerLink.setPartnerLinkType(type);
676     
677     String JavaDoc myRoleName = NodeUtil.getAttribute(partnerLinkElem, BpelConstants.ATTR_MY_ROLE);
678     String JavaDoc partnerRoleName = NodeUtil.getAttribute(partnerLinkElem, BpelConstants.ATTR_PARTNER_ROLE);
679     
680     // first role
681
boolean partnerRoleIsFirst;
682     Role role = type.getFirstRole();
683     String JavaDoc roleName = role.getName();
684     if (roleName.equals(myRoleName)) {
685       partnerLink.setMyRole(role);
686       partnerRoleIsFirst = false;
687     }
688     else if (roleName.equals(partnerRoleName)) {
689       partnerLink.setPartnerRole(role);
690       partnerRoleIsFirst = true;
691     }
692     else {
693       throw new BpelException("neither myRole nor partnerRole match the first role", partnerLinkElem);
694     }
695     // second role
696
role = type.getSecondRole();
697     if (role != null) {
698       roleName = role.getName();
699       if (partnerRoleIsFirst) {
700         if (!roleName.equals(myRoleName)) {
701           throw new BpelException("partnerRole matches the first role, " +
702               "but myRole does not match the second one", partnerLinkElem);
703         }
704         partnerLink.setMyRole(role);
705       }
706       else {
707         if (!roleName.equals(partnerRoleName)) {
708           throw new BpelException("myRole matches the first role, " +
709               "but partnerRole does not match the second one", partnerLinkElem);
710         }
711         partnerLink.setPartnerRole(role);
712       }
713     }
714     else if (partnerRoleIsFirst ? myRoleName != null : partnerRoleName != null) {
715       throw new BpelException("both myRole and partnerRole are specified, " +
716           "but there is only one role", partnerLinkElem);
717     }
718     // FIXME id should be set by the database
719
partnerLink.setId(partnerLink.hashCode());
720     // name
721
partnerLink.setName(partnerLinkElem.getAttribute(BpelConstants.ATTR_NAME));
722     return partnerLink;
723   }
724   
725   public Receiver readReceiver(Element JavaDoc receiverElem, CompositeActivity parent) {
726     Receiver receiver = new Receiver();
727     // partner link
728
String JavaDoc plinkName = receiverElem.getAttribute( BpelConstants.ATTR_PARTNER_LINK );
729     PartnerLinkDefinition partnerLink = parent.findPartnerLink(plinkName);
730     if (partnerLink == null) {
731       getProblemHandler().add(
732           new LocalizedProblem( Problem.LEVEL_ERROR, "partner link not found", receiverElem ) );
733       return null;
734     }
735     receiver.setPartnerLink( partnerLink );
736     // port type
737
PortType portType = getPortType(receiverElem, partnerLink.getMyRole());
738     // operation
739
Operation operation = getOperation(receiverElem, portType);
740     receiver.setOperation( operation );
741     // variable
742
VariableDefinition variable = getVariable(receiverElem, BpelConstants.ATTR_VARIABLE, parent,