Source Code Cross Referenced for ProcDefValidator.java in  » Workflow-Engines » wfmopen-2.1.1 » de » danet » an » workflow » domain » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Workflow Engines » wfmopen 2.1.1 » de.danet.an.workflow.domain 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * This file is part of the WfMOpen project.
0003:         * Copyright (C) 2001-2003 Danet GmbH (www.danet.de), GS-AN.
0004:         * All rights reserved.
0005:         *
0006:         * This program is free software; you can redistribute it and/or modify
0007:         * it under the terms of the GNU General Public License as published by
0008:         * the Free Software Foundation; either version 2 of the License, or
0009:         * (at your option) any later version.
0010:         *
0011:         * This program is distributed in the hope that it will be useful,
0012:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014:         * GNU General Public License for more details.
0015:         *
0016:         * You should have received a copy of the GNU General Public License
0017:         * along with this program; if not, write to the Free Software
0018:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0019:         *
0020:         * $Id: ProcDefValidator.java,v 1.13 2007/05/03 21:58:19 mlipp Exp $
0021:         *
0022:         * $Log: ProcDefValidator.java,v $
0023:         * Revision 1.13  2007/05/03 21:58:19  mlipp
0024:         * Internal refactoring for making better use of local EJBs.
0025:         *
0026:         * Revision 1.12  2007/02/27 14:34:16  drmlipp
0027:         * Some refactoring to reduce cyclic dependencies.
0028:         *
0029:         * Revision 1.11  2006/11/19 21:53:47  mlipp
0030:         * Finished support for native Java types.
0031:         *
0032:         * Revision 1.10  2006/11/19 11:16:35  mlipp
0033:         * Made ExternalReference an interface.
0034:         *
0035:         * Revision 1.9  2006/11/17 21:40:36  mlipp
0036:         * Added Java type tests.
0037:         *
0038:         * Revision 1.8  2006/11/17 16:16:12  drmlipp
0039:         * Started support for Java native types.
0040:         *
0041:         * Revision 1.7  2006/09/29 12:32:08  drmlipp
0042:         * Consistently using WfMOpen as projct name now.
0043:         *
0044:         * Revision 1.6  2006/03/08 14:46:43  drmlipp
0045:         * Synchronized with 1.3.3p5.
0046:         *
0047:         * Revision 1.5  2005/11/09 16:14:01  drmlipp
0048:         * Fixed jaxen problems.
0049:         *
0050:         * Revision 1.4  2005/08/23 14:11:56  drmlipp
0051:         * Synchronized with 1.3.1p5.
0052:         *
0053:         * Revision 1.1.1.5.6.3  2005/08/23 13:27:26  drmlipp
0054:         * Fixed problem with not dinstinguished process local application
0055:         * declarations.
0056:         *
0057:         * Revision 1.3  2005/04/22 15:11:02  drmlipp
0058:         * Merged changes from 1.3 branch up to 1.3p15.
0059:         *
0060:         * Revision 1.1.1.5.6.2  2005/04/19 09:32:17  drmlipp
0061:         * Moved warning about non-standard behaviour to proper place and made
0062:         * extended attribute specification more flexible.
0063:         *
0064:         * Revision 1.2  2005/02/04 14:25:26  drmlipp
0065:         * Synchronized with 1.3rc2.
0066:         *
0067:         * Revision 1.1.1.5.6.1  2005/02/03 13:02:46  drmlipp
0068:         * Moved warning about indexed formal parameters to process definition
0069:         * import.
0070:         *
0071:         * Revision 1.1.1.5  2004/08/18 15:17:38  drmlipp
0072:         * Update to 1.2
0073:         *
0074:         * Revision 1.52  2004/03/25 14:41:47  lipp
0075:         * Added possibility to specify actual parameters as XML.
0076:         *
0077:         * Revision 1.51  2004/03/18 12:53:00  lipp
0078:         * Support for XML as actual parameter.
0079:         *
0080:         * Revision 1.50  2004/01/19 12:30:58  lipp
0081:         * SchemaType now supported properly.
0082:         *
0083:         * Revision 1.49  2003/09/20 19:24:48  lipp
0084:         * Cannot really verify duration conditions.
0085:         *
0086:         * Revision 1.48  2003/09/19 15:19:10  lipp
0087:         * Using proper parser now.
0088:         *
0089:         * Revision 1.47  2003/09/17 10:39:52  lipp
0090:         * Reduced number of client side classes.
0091:         *
0092:         * Revision 1.46  2003/09/08 15:37:18  lipp
0093:         * Introduced deadline definition and suspend tracking.
0094:         *
0095:         * Revision 1.45  2003/07/11 10:49:02  huaiyang
0096:         * Fix the tip error with the error key.
0097:         *
0098:         * Revision 1.44  2003/07/11 10:30:07  huaiyang
0099:         * Error messages further improved.
0100:         *
0101:         * Revision 1.43  2003/07/10 12:43:30  huaiyang
0102:         * improve the error info.
0103:         *
0104:         * Revision 1.42  2003/07/04 10:56:14  huaiyang
0105:         * Performer can be expression in form of DataField in type PERFORMER.
0106:         *
0107:         * Revision 1.41  2003/06/27 08:51:45  lipp
0108:         * Fixed copyright/license information.
0109:         *
0110:         * Revision 1.40  2003/06/22 20:24:14  lipp
0111:         * Fixed argument type checking.
0112:         *
0113:         * Revision 1.39  2003/06/04 07:47:13  huaiyang
0114:         * refactor the method of valiadateSubFlow.
0115:         *
0116:         * Revision 1.38  2003/06/03 15:36:43  huaiyang
0117:         * Fix the error and add the validating of tool param type.
0118:         *
0119:         * Revision 1.37  2003/06/03 13:36:11  lipp
0120:         * Disabled faulty test.
0121:         *
0122:         * Revision 1.36  2003/06/03 11:27:56  huaiyang
0123:         * validate the type of formal- and actualParameters of subflow.
0124:         *
0125:         * Revision 1.35  2003/05/28 15:11:34  lipp
0126:         * Removed excessive warning on emtpy activity sets.
0127:         *
0128:         * Revision 1.34  2003/05/28 11:16:07  lipp
0129:         * Fixed message text.
0130:         *
0131:         * Revision 1.33  2003/05/28 07:51:26  huaiyang
0132:         * Modify the algorithm to check loop activities.
0133:         *
0134:         * Revision 1.32  2003/05/26 14:31:58  huaiyang
0135:         * add the check of loop activities.
0136:         *
0137:         * Revision 1.31  2003/05/26 12:42:03  huaiyang
0138:         * add the validation of script.
0139:         *
0140:         * Revision 1.30  2003/05/20 12:04:54  huaiyang
0141:         * new error message for not matched mode of formal- and actualParam.
0142:         *
0143:         * Revision 1.29  2003/05/15 13:50:19  huaiyang
0144:         * Check if actual parameters is defined as formal parameters.
0145:         *
0146:         * Revision 1.28  2003/05/15 13:14:45  huaiyang
0147:         * Check if the mode of formal and actual parameters matched.
0148:         *
0149:         * Revision 1.27  2003/05/13 08:37:15  huaiyang
0150:         * add the check of OUT- and INOUT- actual parameter in calling
0151:         * subflow.
0152:         *
0153:         * Revision 1.26  2003/05/12 10:39:02  lipp
0154:         * Fixed actual paramter check.
0155:         *
0156:         * Revision 1.25  2003/05/12 09:13:43  huaiyang
0157:         * add the validating of priority of process and activity.
0158:         *
0159:         * Revision 1.24  2003/05/08 14:54:23  huaiyang
0160:         * add the checking of empty activity set.
0161:         *
0162:         * Revision 1.23  2003/05/08 13:36:41  huaiyang
0163:         * function of validate subflow added.
0164:         *
0165:         * Revision 1.22  2003/05/06 13:21:30  lipp
0166:         * Resolved cyclic dependency.
0167:         *
0168:         * Revision 1.21  2003/04/24 19:47:50  lipp
0169:         * Removed dependency between general util and workflow api.
0170:         *
0171:         * Revision 1.20  2003/04/24 15:08:14  lipp
0172:         * Reading ApplicationDefinitiosn from SAX now.
0173:         *
0174:         * Revision 1.19  2003/03/31 16:50:28  huaiyang
0175:         * Logging using common-logging.
0176:         *
0177:         * Revision 1.18  2003/03/28 14:42:35  lipp
0178:         * Moved some code to XPDLUtil.
0179:         *
0180:         * Revision 1.17  2003/03/28 12:44:08  lipp
0181:         * Moved XPDL related constants to XPDLUtil.
0182:         *
0183:         * Revision 1.16  2003/03/27 10:45:37  lipp
0184:         * Renamed activity implementation classes for clarity.
0185:         *
0186:         * Revision 1.15  2003/03/25 17:16:08  lipp
0187:         * Fixed test.
0188:         *
0189:         * Revision 1.14  2003/03/07 14:11:10  huaiyang
0190:         * optimize the initialization of all the xpath.
0191:         *
0192:         * Revision 1.13  2003/03/07 08:01:02  huaiyang
0193:         * use workflow.util.CollectingErrorHandler to collect errors.
0194:         *
0195:         * Revision 1.12  2003/03/04 13:44:03  huaiyang
0196:         * add the method of validateBlockActivity.
0197:         *
0198:         * Revision 1.11  2002/12/19 21:37:43  lipp
0199:         * Reorganized interfaces.
0200:         *
0201:         * Revision 1.10  2002/12/03 13:49:16  huaiyang
0202:         * Add the check of otherwise condition.
0203:         *
0204:         * Revision 1.9  2002/11/25 09:28:29  huaiyang
0205:         * Bug with checking double application Id fixed.
0206:         *
0207:         * Revision 1.8  2002/11/13 09:14:56  huaiyang
0208:         * Remove obsolete debug message.
0209:         *
0210:         * Revision 1.7  2002/11/12 14:15:36  huaiyang
0211:         * Validate the transition restrictions of activity.
0212:         *
0213:         * Revision 1.6  2002/11/06 12:14:48  huaiyang
0214:         * Add the method of validateExtendedAttributes.
0215:         *
0216:         * Revision 1.5  2002/11/04 10:56:59  huaiyang
0217:         * Added the validating of transition for activitySet.
0218:         *
0219:         * Revision 1.4  2002/11/01 13:09:13  huaiyang
0220:         * Bug with validating activityset fixed.
0221:         *
0222:         * Revision 1.3  2002/11/01 12:21:30  huaiyang
0223:         * Validating of activity set added.
0224:         *
0225:         * Revision 1.2  2002/10/06 20:14:38  lipp
0226:         * Updated argument handling.
0227:         *
0228:         * Revision 1.1  2002/09/27 12:44:55  lipp
0229:         * Moved validation to a separate class.
0230:         *
0231:         */
0232:        package de.danet.an.workflow.domain;
0233:
0234:        import java.io.IOException;
0235:        import java.io.Serializable;
0236:        import java.io.StringReader;
0237:
0238:        import java.util.ArrayList;
0239:        import java.util.Collection;
0240:        import java.util.Collections;
0241:        import java.util.HashMap;
0242:        import java.util.Iterator;
0243:        import java.util.List;
0244:        import java.util.Map;
0245:        import java.util.Set;
0246:
0247:        import javax.xml.parsers.ParserConfigurationException;
0248:        import javax.xml.parsers.SAXParser;
0249:        import javax.xml.parsers.SAXParserFactory;
0250:
0251:        import org.jaxen.JaxenException;
0252:        import org.jaxen.XPath;
0253:        import org.jaxen.jdom.JDOMXPath;
0254:        import org.jdom.Document;
0255:        import org.jdom.Element;
0256:        import org.jdom.JDOMException;
0257:        import org.jdom.Namespace;
0258:        import org.jdom.output.SAXOutputter;
0259:        import org.xml.sax.ContentHandler;
0260:        import org.xml.sax.InputSource;
0261:        import org.xml.sax.SAXException;
0262:        import org.xml.sax.XMLReader;
0263:
0264:        import de.danet.an.util.sax.HandlerStack;
0265:
0266:        import de.danet.an.workflow.util.CollectingErrorHandler;
0267:        import de.danet.an.workflow.util.SAXEventBufferImpl;
0268:        import de.danet.an.workflow.util.XPDLUtil;
0269:
0270:        import de.danet.an.workflow.api.ExternalReference;
0271:        import de.danet.an.workflow.api.FormalParameter;
0272:        import de.danet.an.workflow.api.PrioritizedMessage;
0273:
0274:        import de.danet.an.workflow.internalapi.ExtExecutionObjectLocal;
0275:
0276:        /**
0277:         * This class performes validation methods for a process defintion
0278:         * package.
0279:         *
0280:         * @author <a href="mailto:lipp@danet.de"></a>
0281:         * @version $Revision: 1.13 $
0282:         */
0283:        public class ProcDefValidator {
0284:            /**
0285:             * logger of this class.
0286:             */
0287:            static final org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory
0288:                    .getLog(ProcDefValidator.class);
0289:
0290:            // The defined data fields 
0291:            private transient Map procdataMap = null;
0292:            private transient List dataFieldsList = null;
0293:
0294:            // The defined applications 
0295:            private transient Map applicationDefs = null;
0296:
0297:            // the bundle base for all the error key.
0298:            private String bundleBase = "ImportMessages";
0299:
0300:            // all the xpath used in the validation
0301:            private XPath processPath = null;
0302:            private XPath actSetPath = null;
0303:            private XPath actPath = null;
0304:            private XPath alltranrefsPath = null;
0305:            private XPath splitXPath = null;
0306:            private XPath tranrefsPath = null;
0307:            private XPath transPath = null;
0308:            private XPath toolPath = null;
0309:            private XPath subFlowPath = null;
0310:            private XPath partPath = null;
0311:            private XPath scriptPath = null;
0312:            private XPath procpartPath = null;
0313:            private XPath procApplPath = null;
0314:            private XPath applPath = null;
0315:            private XPath toolAgentClassPath = null;
0316:            private XPath extAttrPath = null;
0317:            private XPath procExtAttrPath = null;
0318:            private XPath dataFieldPath = null;
0319:            private XPath procDataFieldPath = null;
0320:            private XPath dataTypePath = null;
0321:            private XPath procFormalParamsPath = null;
0322:            private XPath procPriorityPath = null;
0323:            private XPath actualParamsPath = null;
0324:            private XPath formalParamsPath = null;
0325:            private XPath indexedParamsPath = null;
0326:
0327:            /**
0328:             * This class is used to save the value and data type of the proc
0329:             * data.
0330:             */
0331:            private class ProcData {
0332:                public Object value;
0333:                public Element dataType;
0334:
0335:                public ProcData(Object value, Element dataType) {
0336:                    this .value = value;
0337:                    this .dataType = dataType;
0338:                }
0339:            }
0340:
0341:            /**
0342:             * This class is used to save the ActualParameters and its responding 
0343:             * data type of the tool.
0344:             */
0345:            private class ToolInfo {
0346:                public String[] actualParams;
0347:
0348:                public ToolInfo(String[] actualParams) {
0349:                    this .actualParams = actualParams;
0350:                }
0351:            }
0352:
0353:            /**
0354:             * Validate a process definition package.
0355:             * @param doc the JDOM <code>Document</code> to check.
0356:             * @param eh the <code>CollectingErrorHandler</code> to which
0357:             * error messages should be added.
0358:             * @exception JDOMException if an error occurs
0359:             * @exception JaxenException if an error occurs
0360:             */
0361:            public void validate(Document doc, CollectingErrorHandler eh)
0362:                    throws JDOMException, JaxenException {
0363:                // initialize all the xpath
0364:                init();
0365:                // validate it
0366:                validateHeaderDefinition(doc, eh);
0367:                validateProcessDefinition(doc, eh);
0368:            }
0369:
0370:            private void init() throws JDOMException, JaxenException {
0371:                processPath = buildJDOMXPath("/xpdl:Package/xpdl:WorkflowProcesses/xpdl:WorkflowProcess");
0372:                actSetPath = buildJDOMXPath("xpdl:ActivitySets/xpdl:ActivitySet");
0373:                actPath = buildJDOMXPath("xpdl:Activities/xpdl:Activity");
0374:                tranrefsPath = buildJDOMXPath("xpdl:TransitionRefs/xpdl:TransitionRef");
0375:                alltranrefsPath = buildJDOMXPath("descendant::xpdl:TransitionRefs/xpdl:TransitionRef");
0376:                splitXPath = buildJDOMXPath("xpdl:TransitionRestrictions/xpdl:TransitionRestriction"
0377:                        + "/xpdl:Split[@Type='XOR']");
0378:                transPath = buildJDOMXPath("xpdl:Transitions/xpdl:Transition");
0379:                toolPath = buildJDOMXPath("xpdl:Implementation/xpdl:Tool");
0380:                subFlowPath = buildJDOMXPath("xpdl:Implementation/xpdl:SubFlow");
0381:                partPath = buildJDOMXPath("/xpdl:Package/xpdl:Participants/xpdl:Participant");
0382:                scriptPath = buildJDOMXPath("/xpdl:Package/xpdl:Script");
0383:                procpartPath = buildJDOMXPath("xpdl:Participants/xpdl:Participant");
0384:                applPath = buildJDOMXPath("/xpdl:Package/xpdl:Applications/xpdl:Application");
0385:                procApplPath = buildJDOMXPath("xpdl:Applications/xpdl:Application");
0386:                toolAgentClassPath = buildJDOMXPath("xpdl:ExtendedAttributes"
0387:                        + "/xpdl:ExtendedAttribute[@Name=\"Implementation\"]"
0388:                        + "/vx:ToolAgent/@Class");
0389:                extAttrPath = buildJDOMXPath("/xpdl:Package/xpdl:ExtendedAttributes");
0390:                procExtAttrPath = buildJDOMXPath("xpdl:ExtendedAttributes");
0391:                dataFieldPath = buildJDOMXPath("/xpdl:Package/xpdl:DataFields/xpdl:DataField");
0392:                procDataFieldPath = buildJDOMXPath("xpdl:DataFields/xpdl:DataField");
0393:                dataTypePath = buildJDOMXPath("xpdl:DataType/xpdl:BasicType");
0394:                procFormalParamsPath = buildJDOMXPath("/xpdl:Package/xpdl:WorkflowProcesses/xpdl:WorkflowProcess"
0395:                        + "/xpdl:FormalParameters/xpdl:FormalParameter");
0396:                procPriorityPath = buildJDOMXPath("xpdl:ProcessHeader/xpdl:Priority");
0397:                actualParamsPath = buildJDOMXPath("xpdl:ActualParameters/xpdl:ActualParameter");
0398:                formalParamsPath = buildJDOMXPath("xpdl:FormalParameters/xpdl:FormalParameter");
0399:                indexedParamsPath = buildJDOMXPath("xpdl:FormalParameters/xpdl:FormalParameter/@Index");
0400:            }
0401:
0402:            private XPath buildJDOMXPath(String pathString)
0403:                    throws JDOMException, JaxenException {
0404:                XPath path = new JDOMXPath(pathString);
0405:                path.addNamespace("xpdl", XPDLUtil.XPDL_NS);
0406:                path.addNamespace("vx", XPDLUtil.XPDL_EXTN_NS);
0407:                return path;
0408:            }
0409:
0410:            private void validateHeaderDefinition(Document doc,
0411:                    CollectingErrorHandler eh) throws JDOMException,
0412:                    JaxenException {
0413:                validateScript(doc, eh);
0414:                validateApplDefs(doc, eh);
0415:                validateExtendedAttributes(doc, null, eh);
0416:            }
0417:
0418:            private void validateScript(Document doc, CollectingErrorHandler eh)
0419:                    throws JDOMException, JaxenException {
0420:                // supported scripts and its version
0421:                String javascript = "text/javascript", jsversion = "1.5";
0422:                String ecmascript = "text/ecmascript", esversion = "3rd Edition";
0423:                // parse
0424:                Element script = (Element) scriptPath.selectSingleNode(doc);
0425:                if (script == null) {
0426:                    return;
0427:                }
0428:                String type = script.getAttributeValue("Type");
0429:                String version = script.getAttributeValue("Version");
0430:                if (version == null) {
0431:                    if (!type.equals(javascript) && !type.equals(ecmascript)) {
0432:                        String[] errdatas = { type };
0433:                        eh.add(new PrioritizedMessage(
0434:                                PrioritizedMessage.Priority.ERROR, bundleBase
0435:                                        + "#package.script.type.unsupported",
0436:                                errdatas));
0437:                    }
0438:                    return;
0439:                } else {
0440:                    if ((type.equals(javascript) && (version.equals(jsversion)))
0441:                            || (type.equals(ecmascript) && (version
0442:                                    .equals(esversion)))) {
0443:                        return;
0444:                    } else {
0445:                        String[] errdts = { type, version };
0446:                        eh
0447:                                .add(new PrioritizedMessage(
0448:                                        PrioritizedMessage.Priority.ERROR,
0449:                                        bundleBase
0450:                                                + "#package.script.version.unsupported",
0451:                                        errdts));
0452:                    }
0453:                }
0454:            }
0455:
0456:            private boolean validateProcessDefinition(Document doc,
0457:                    CollectingErrorHandler eh) throws JDOMException,
0458:                    JaxenException {
0459:                boolean faultless = true;
0460:                List processIds = new ArrayList();
0461:                Iterator processListIterator = processPath.selectNodes(doc)
0462:                        .iterator();
0463:                while (processListIterator.hasNext()) {
0464:                    Element process = (Element) processListIterator.next();
0465:                    String id = process.getAttributeValue("Id");
0466:                    //validatePriority
0467:                    validatePriority(id, (Element) procPriorityPath
0468:                            .selectSingleNode(process),
0469:                            "procdef.header.priority.notallowed", id, eh);
0470:                    //validateUniqueProcessId	
0471:                    processIds.add(id);
0472:                    //validateUniqueActivityId
0473:                    validateData(doc, process, eh);
0474:                    validateActivities(doc, process, eh);
0475:                    //validateUniqueTransitionId
0476:                    validateTransition(process, eh);
0477:                    //validateExtendedAttributes
0478:                    validateExtendedAttributes(null, process, eh);
0479:                }
0480:                String duplicate = findDuplicate(processIds);
0481:                if (duplicate != null) {
0482:                    faultless = false;
0483:                    String[] errdatas = { duplicate };
0484:                    eh.add(new PrioritizedMessage(
0485:                            PrioritizedMessage.Priority.ERROR, bundleBase
0486:                                    + "#procdef.process.ununique", errdatas));
0487:                }
0488:                return faultless;
0489:            }
0490:
0491:            private void validateData(Document doc, Element process,
0492:                    CollectingErrorHandler eh) throws JaxenException {
0493:                Map pd = procdatas(doc, process, eh);
0494:                for (Iterator i = pd.entrySet().iterator(); i.hasNext();) {
0495:                    Map.Entry e = (Map.Entry) i.next();
0496:                    Object type = XPDLUtil.extractDataType(((ProcData) e
0497:                            .getValue()).dataType);
0498:                    if ((type instanceof  ExternalReference)
0499:                            && XPDLUtil.isJavaType((ExternalReference) type)) {
0500:                        String[] errdatas = { ((ExternalReference) type)
0501:                                .location().getPath() };
0502:                        try {
0503:                            Class jType = XPDLUtil
0504:                                    .getJavaType((ExternalReference) type);
0505:                            if (!(jType.isInterface() || Serializable.class
0506:                                    .isAssignableFrom(jType))) {
0507:                                eh
0508:                                        .add(new PrioritizedMessage(
0509:                                                PrioritizedMessage.Priority.ERROR,
0510:                                                bundleBase
0511:                                                        + "#procdef.data.notSerializable",
0512:                                                errdatas));
0513:                            }
0514:                        } catch (ClassNotFoundException ee) {
0515:                            eh.add(new PrioritizedMessage(
0516:                                    PrioritizedMessage.Priority.ERROR,
0517:                                    bundleBase
0518:                                            + "#procdef.data.invalidJavaType",
0519:                                    errdatas));
0520:                        }
0521:                    }
0522:                }
0523:
0524:            }
0525:
0526:            private void validateActivities(Document doc, Element process,
0527:                    CollectingErrorHandler eh) throws JDOMException,
0528:                    JaxenException {
0529:                List activitySetList = actSetPath.selectNodes(process);
0530:                // validateUniqueActivityId
0531:                doValidateActivities(doc, process,
0532:                        actPath.selectNodes(process), activitySetList, null,
0533:                        false, eh);
0534:                // validateUniqueActivityId in ActivitySet
0535:                Iterator activitySetIterator = activitySetList.iterator();
0536:                while (activitySetIterator.hasNext()) {
0537:                    Element actSetElem = (Element) activitySetIterator.next();
0538:                    List acts = actPath.selectNodes(actSetElem);
0539:                    if (acts.size() == 0) {
0540:                        // empty activity set
0541:                        String actSetId = actSetElem.getAttributeValue("Id");
0542:                        String processId = process.getAttributeValue("Id");
0543:                        String[] errDatas = { processId, actSetId };
0544:                        eh.add(new PrioritizedMessage(
0545:                                PrioritizedMessage.Priority.ERROR, bundleBase
0546:                                        + "#procdef.process.activityset.empty",
0547:                                errDatas));
0548:                        return;
0549:                    } else {
0550:                        doValidateActivities(doc, process, acts,
0551:                                activitySetList, actSetElem, true, eh);
0552:                    }
0553:                }
0554:            }
0555:
0556:            // Validate activity of a process or what included in activitySet. If 
0557:            // isIncludedInActivitySet is set to true, then activitySet Element must be
0558:            // given.
0559:            private void doValidateActivities(Document doc, Element process,
0560:                    Collection acts, List activitySetList, Element actSetElem,
0561:                    boolean isIncludedInActivitySet, CollectingErrorHandler eh)
0562:                    throws JDOMException, JaxenException {
0563:                Namespace namespace = Namespace.getNamespace("xpdl",
0564:                        XPDLUtil.XPDL_NS);
0565:                List activityIds = new ArrayList();
0566:                List participantIdList = validateParticipants(doc, process, eh);
0567:                String processId = process.getAttributeValue("Id");
0568:                // Validate existence of the referenced transitionRef
0569:                List transitionIds = getTransitionIds(process, actSetElem,
0570:                        isIncludedInActivitySet);
0571:                Iterator activitiesIterator = acts.iterator();
0572:                while (activitiesIterator.hasNext()) {
0573:                    Element activity = (Element) activitiesIterator.next();
0574:                    String id = activity.getAttributeValue("Id");
0575:                    //validatePriority
0576:                    validatePriority(processId, (Element) activity.getChild(
0577:                            "Priority", namespace),
0578:                            "procdef.activity.priority.notallowed", id, eh);
0579:                    validateDeadlines(processId, activity, eh);
0580:                    //validateId
0581:                    activityIds.add(id);
0582:                    // validate the included BlockActivity.
0583:                    validateBlockActivity(processId, activitySetList,
0584:                            actSetElem, activity, eh);
0585:                    // collects all transition ref id in activity.
0586:                    Iterator transRefIterator = alltranrefsPath.selectNodes(
0587:                            activity).iterator();
0588:                    while (transRefIterator.hasNext()) {
0589:                        Element transRefElem = (Element) transRefIterator
0590:                                .next();
0591:                        String transRefId = transRefElem
0592:                                .getAttributeValue("Id");
0593:                        if (!transitionIds.contains(transRefId)) {
0594:                            eh.add(new PrioritizedMessage(
0595:                                    PrioritizedMessage.Priority.ERROR,
0596:                                    bundleBase
0597:                                            + "#procdef.transitionid.notfound",
0598:                                    new Object[] { transRefId, processId }));
0599:                        }
0600:                    }
0601:                    validateTranstionRestrictions(process, actSetElem,
0602:                            activity, isIncludedInActivitySet, eh);
0603:                    validateImplementation(doc, process, activity, eh);
0604:                    //validate if the referenced participant defined and unique. 
0605:                    validatePerformer(processId, activity, participantIdList,
0606:                            eh);
0607:                }
0608:                String duplicate = findDuplicate(activityIds);
0609:                if (duplicate != null) {
0610:                    String errorKey = null;
0611:                    String activitySetId = null;
0612:                    if (isIncludedInActivitySet) {
0613:                        errorKey = "procdef.activityset.activity.ununique";
0614:                        activitySetId = actSetElem.getAttributeValue("Id");
0615:                    } else {
0616:                        errorKey = "procdef.activity.ununique";
0617:                    }
0618:                    String[] errdatas = { duplicate, processId, activitySetId };
0619:                    eh.add(new PrioritizedMessage(
0620:                            PrioritizedMessage.Priority.ERROR, bundleBase + "#"
0621:                                    + errorKey, errdatas));
0622:                }
0623:            }
0624:
0625:            private void validateDeadlines(String processId, Element actEl,
0626:                    CollectingErrorHandler eh) throws JDOMException {
0627:                Namespace namespace = Namespace.getNamespace("xpdl",
0628:                        XPDLUtil.XPDL_NS);
0629:                List dls = actEl.getChildren("Deadline", namespace);
0630:                for (Iterator i = dls.iterator(); i.hasNext();) {
0631:                    Element dl = (Element) i.next();
0632:                    String exep = dl.getChildText("ExceptionName", namespace);
0633:                    if (exep == null || exep.length() == 0) {
0634:                        eh
0635:                                .add(new PrioritizedMessage(
0636:                                        PrioritizedMessage.Priority.ERROR,
0637:                                        bundleBase
0638:                                                + "#procdef.activity.deadline.noException",
0639:                                        new Object[] { processId,
0640:                                                actEl.getAttributeValue("Id") }));
0641:                    }
0642:                    String cond = dl.getChildText("DeadlineCondition",
0643:                            namespace);
0644:                    if (cond == null || cond.length() == 0) {
0645:                        eh
0646:                                .add(new PrioritizedMessage(
0647:                                        PrioritizedMessage.Priority.ERROR,
0648:                                        bundleBase
0649:                                                + "#procdef.activity.deadline.noCondition",
0650:                                        new Object[] { processId,
0651:                                                actEl.getAttributeValue("Id") }));
0652:                        continue;
0653:                    }
0654:                }
0655:            }
0656:
0657:            private void validateBlockActivity(String processId,
0658:                    List activitySetList, Element actSetElement,
0659:                    Element activity, CollectingErrorHandler eh)
0660:                    throws JDOMException, JaxenException {
0661:                Namespace namespace = Namespace.getNamespace("xpdl",
0662:                        XPDLUtil.XPDL_NS);
0663:                Element blockActivity = activity.getChild("BlockActivity",
0664:                        namespace);
0665:                if (blockActivity == null) {
0666:                    // no block activity defined in this activity 
0667:                    return;
0668:                }
0669:                String blockActivityId = blockActivity
0670:                        .getAttributeValue("BlockId");
0671:                String activityId = activity.getAttributeValue("Id");
0672:                String[] errdatas = { activityId, blockActivityId, processId };
0673:                if ((actSetElement != null)
0674:                        && blockActivityId.equals(actSetElement
0675:                                .getAttributeValue("Id"))) {
0676:                    // the given activity included his super activity set as block 
0677:                    // activity.
0678:                    eh
0679:                            .add(new PrioritizedMessage(
0680:                                    PrioritizedMessage.Priority.ERROR,
0681:                                    bundleBase
0682:                                            + "#procdef.activityset.activity.includeitself",
0683:                                    errdatas));
0684:                    return;
0685:                }
0686:                if (activitySetList != null) {
0687:                    boolean validActivitySet = false;
0688:                    Iterator i = activitySetList.iterator();
0689:                    while (i.hasNext()) {
0690:                        Element actSet = (Element) i.next();
0691:                        if (actSet.getAttributeValue("Id").equals(
0692:                                blockActivityId)) {
0693:                            validActivitySet = true;
0694:                            break;
0695:                        }
0696:                    }
0697:                    if (!validActivitySet) {
0698:                        // included BlockActivity not found in the defined
0699:                        // activity set
0700:                        eh
0701:                                .add(new PrioritizedMessage(
0702:                                        PrioritizedMessage.Priority.ERROR,
0703:                                        bundleBase
0704:                                                + "#procdef.activity.activityset.invalid",
0705:                                        errdatas));
0706:                        return;
0707:                    }
0708:                }
0709:            }
0710:
0711:            private void validateTranstionRestrictions(Element process,
0712:                    Element actSet, Element activity,
0713:                    boolean isIncludedInActivitySet, CollectingErrorHandler eh)
0714:                    throws JDOMException, JaxenException {
0715:                List transRefIds = new ArrayList();
0716:                Element toBeSelectedNode = isIncludedInActivitySet ? actSet
0717:                        : process;
0718:                String toBeSelectedNodeId = toBeSelectedNode
0719:                        .getAttributeValue("Id");
0720:                String actId = activity.getAttributeValue("Id");
0721:                Namespace namespace = Namespace.getNamespace("xpdl",
0722:                        XPDLUtil.XPDL_NS);
0723:                Element splitElement = (Element) splitXPath
0724:                        .selectSingleNode(activity);
0725:                if (splitElement == null) {
0726:                    return;
0727:                }
0728:                List transRefList = tranrefsPath.selectNodes(splitElement);
0729:                String[] errdatas = { actId, toBeSelectedNodeId };
0730:                if (transRefList.size() == 0) {
0731:                    eh
0732:                            .add(new PrioritizedMessage(
0733:                                    PrioritizedMessage.Priority.ERROR,
0734:                                    bundleBase
0735:                                            + "#procdef.activity.split.transition.notdefined",
0736:                                    new Object[] { actId, toBeSelectedNodeId }));
0737:                    return;
0738:                }
0739:                Iterator transRefIterator = transRefList.iterator();
0740:                while (transRefIterator.hasNext()) {
0741:                    Element transRef = (Element) transRefIterator.next();
0742:                    transRefIds.add(transRef.getAttributeValue("Id"));
0743:                }
0744:                // find out all transitions with the fromAct same as the actId.
0745:                String notCompleteErrKey = isIncludedInActivitySet ? "#procdef.activityset.split.transition.notcomplete"
0746:                        : "#procdef.activity.split.transition.notcomplete";
0747:                List transList = transPath.selectNodes(toBeSelectedNode);
0748:                Iterator transIterator = transList.iterator();
0749:                while (transIterator.hasNext()) {
0750:                    Element transElem = (Element) transIterator.next();
0751:                    String fromId = transElem.getAttributeValue("From");
0752:                    String transId = transElem.getAttributeValue("Id");
0753:                    if (fromId.equals(actId) && !transRefIds.contains(transId)) {
0754:                        eh.add(new PrioritizedMessage(
0755:                                PrioritizedMessage.Priority.ERROR, bundleBase
0756:                                        + notCompleteErrKey, new Object[] {
0757:                                        actId, transId, toBeSelectedNodeId }));
0758:                    }
0759:                }
0760:                // Find out if any referenced transition with the condition of 
0761:                // OTHERWISE is listed at the end of TransitionRestrictions of 
0762:                // Activiity; if not, needs to be sorted and throws warning.
0763:                validateTransitionRestrictionsCondition(transRefList,
0764:                        transList, eh);
0765:            }
0766:
0767:            // Find out if any referenced transition with the condition of 
0768:            // OTHERWISE is listed at the end of TransitionRestrictions of 
0769:            // Activiity; if not, needs to be sorted and throws warning.
0770:            private void validateTransitionRestrictionsCondition(
0771:                    List transRefList, List transList, CollectingErrorHandler eh) {
0772:                int index = 0;
0773:                boolean foundIt = false;
0774:                Element transRef = null;
0775:                for (Iterator i = transRefList.iterator(); i.hasNext(); index++) {
0776:                    transRef = (Element) i.next();
0777:                    Element condition = condition(transList, transRef
0778:                            .getAttributeValue("Id"));
0779:                    if (condition == null) {
0780:                        continue;
0781:                    }
0782:                    if (condition.getAttributeValue("Type") != null
0783:                            && condition.getAttributeValue("Type").equals(
0784:                                    "OTHERWISE")) {
0785:                        foundIt = true;
0786:                        break;
0787:                    }
0788:                }
0789:                if (!foundIt || (index == transRefList.size() - 1)) {
0790:                    return;
0791:                }
0792:                eh.add(new PrioritizedMessage(PrioritizedMessage.Priority.WARN,
0793:                        bundleBase + "#procdef.transition.otherwise.notatend"));
0794:            }
0795:
0796:            private Element condition(List transList, String transId) {
0797:                Namespace namespace = Namespace.getNamespace("xpdl",
0798:                        XPDLUtil.XPDL_NS);
0799:                Element condition = null;
0800:                for (Iterator i = transList.iterator(); i.hasNext();) {
0801:                    Element tran = (Element) i.next();
0802:                    if (tran.getAttributeValue("Id").equals(transId)) {
0803:                        condition = tran.getChild("Condition", namespace);
0804:                        break;
0805:                    }
0806:                }
0807:                return condition;
0808:            }
0809:
0810:            private boolean validateImplementation(Document doc,
0811:                    Element process, Element activity, CollectingErrorHandler eh)
0812:                    throws JDOMException, JaxenException {
0813:                if (toolPath.selectNodes(activity).size() != 0) {
0814:                    // Tool as Implementation 
0815:                    return validateTools(doc, process, activity, eh);
0816:                } else if (subFlowPath.selectNodes(activity).size() != 0) {
0817:                    // SubFlow as Implementation
0818:                    return validateSubFlow(doc, process, activity, eh);
0819:                } else {
0820:                    return true;
0821:                }
0822:            }
0823:
0824:            private boolean validateTools(Document doc, Element process,
0825:                    Element activity, CollectingErrorHandler eh)
0826:                    throws JDOMException, JaxenException {
0827:                // initialize the lists to be compared
0828:                List formalParamsDataTypeList = new ArrayList();
0829:                Set applicationIds = applicationDefs.keySet();
0830:                String processId = process.getAttributeValue("Id");
0831:                String activityId = activity.getAttributeValue("Id");
0832:                boolean faultless = true;
0833:                // Map of tool id and its actual parameters.
0834:                Map tools = new HashMap();
0835:                Iterator toolIterator = toolPath.selectNodes(activity)
0836:                        .iterator();
0837:                while (toolIterator.hasNext()) {
0838:                    Element toolElem = (Element) toolIterator.next();
0839:                    String toolId = toolElem.getAttributeValue("Id");
0840:                    if (toolId != null) {
0841:                        List apList = new ArrayList();
0842:                        Iterator apsIt = actualParamsPath.selectNodes(toolElem)
0843:                                .iterator();
0844:                        while (apsIt.hasNext()) {
0845:                            String ap = ((Element) apsIt.next()).getTextTrim();
0846:                            apList.add(ap);
0847:                        }
0848:                        tools.put(toolId, new ToolInfo((String[]) apList
0849:                                .toArray(new String[apList.size()])));
0850:                        // Validate existence of the referenced ToolId
0851:                        if (!applicationIds.contains(toolId)
0852:                                && !(applicationIds.contains(new PSK(processId,
0853:                                        toolId)))) {
0854:                            faultless = false;
0855:                            eh.add(new PrioritizedMessage(
0856:                                    PrioritizedMessage.Priority.ERROR,
0857:                                    bundleBase + "#procdef.tool.notfound",
0858:                                    new Object[] { toolId, activityId,
0859:                                            processId }));
0860:                        }
0861:                    }
0862:                }
0863:
0864:                Iterator toolsIterator = tools.keySet().iterator();
0865:                while (toolsIterator.hasNext()) {
0866:                    String tid = (String) toolsIterator.next();
0867:                    String[] actualParams = ((ToolInfo) tools.get(tid)).actualParams;
0868:                    // reference to process local tool?
0869:                    ApplicationDefinition applDef = (ApplicationDefinition) applicationDefs
0870:                            .get(new PSK(processId, tid));
0871:                    // reference to package level tool?
0872:                    if (applDef == null) {
0873:                        applDef = (ApplicationDefinition) applicationDefs
0874:                                .get(tid);
0875:                    }
0876:                    // the referenced tool is invalid.
0877:                    if (applDef == null) {
0878:                        return false;
0879:                    }
0880:                    FormalParameter[] formalParams = applDef.formalParameters();
0881:                    // check the match of formal parameters and actual parameters
0882:                    if (actualParams.length != formalParams.length) {
0883:                        eh
0884:                                .add(new PrioritizedMessage(
0885:                                        PrioritizedMessage.Priority.ERROR,
0886:                                        bundleBase
0887:                                                + "#procdef.toolimpl.params.notmatched",
0888:                                        new Object[] { tid, activityId,
0889:                                                processId }));
0890:                        return false;
0891:                    }
0892:                    // verify the actual parameters have been defined in data fields.
0893:                    for (int i = 0; i < actualParams.length; i++) {
0894:                        String actParam = actualParams[i];
0895:                        if (procdataMap.containsKey(actParam)) {
0896:                            boolean compat = true;
0897:                            if (formalParams[i].mode().equals(
0898:                                    FormalParameter.Mode.IN)
0899:                                    || formalParams[i].mode().equals(
0900:                                            FormalParameter.Mode.INOUT)) {
0901:                                compat = typeCompatible(
0902:                                        formalParams[i].type(),
0903:                                        XPDLUtil
0904:                                                .extractDataType(((ProcData) procdataMap
0905:                                                        .get(actParam)).dataType));
0906:                            }
0907:                            if (formalParams[i].mode().equals(
0908:                                    FormalParameter.Mode.OUT)
0909:                                    || formalParams[i].mode().equals(
0910:                                            FormalParameter.Mode.INOUT)) {
0911:                                compat = typeCompatible(
0912:                                        XPDLUtil
0913:                                                .extractDataType(((ProcData) procdataMap
0914:                                                        .get(actParam)).dataType),
0915:                                        formalParams[i].type());
0916:                            }
0917:                            if (!compat) {
0918:                                eh
0919:                                        .add(new PrioritizedMessage(
0920:                                                PrioritizedMessage.Priority.ERROR,
0921:                                                bundleBase
0922:                                                        + "#procdef.toolimpl.paramsdatatype.notmatched",
0923:                                                new Object[] { tid, activityId,
0924:                                                        processId, actParam }));
0925:                                return false;
0926:                            }
0927:                        } else {
0928:                            if (formalParams[i].mode() != FormalParameter.Mode.IN) {
0929:                                eh
0930:                                        .add(new PrioritizedMessage(
0931:                                                PrioritizedMessage.Priority.ERROR,
0932:                                                bundleBase
0933:                                                        + "#procdef.toolimpl.params.datanotfound",
0934:                                                new Object[] { actParam, tid,
0935:                                                        activityId, processId }));
0936:                                return false;
0937:                            }
0938:                            if (XPDLUtil.isXMLType(formalParams[i].type())) {
0939:                                String res = notXMLOrValid(actParam);
0940:                                if (res != null) {
0941:                                    eh
0942:                                            .add(new PrioritizedMessage(
0943:                                                    PrioritizedMessage.Priority.ERROR,
0944:                                                    bundleBase
0945:                                                            + "#procdef.toolimpl.params.invalidXML",
0946:                                                    new Object[] { actParam,
0947:                                                            tid, activityId,
0948:                                                            processId, res }));
0949:                                    return false;
0950:                                }
0951:                            }
0952:                        }
0953:                    }
0954:                }
0955:                return faultless;
0956:            }
0957:
0958:            private boolean validateSubFlow(Document doc, Element process,
0959:                    Element activity, CollectingErrorHandler eh)
0960:                    throws JDOMException, JaxenException {
0961:                Namespace xpdlns = Namespace.getNamespace(XPDLUtil.XPDL_NS);
0962:                Map processMap = processMap(doc);
0963:                String activityId = activity.getAttributeValue("Id");
0964:                String processId = process.getAttributeValue("Id");
0965:                Element subFlowElem = (Element) subFlowPath
0966:                        .selectSingleNode(activity);
0967:                if (subFlowElem == null) {
0968:                    return true;
0969:                }
0970:                String subFlowId = subFlowElem.getAttributeValue("Id");
0971:                // check if this subflow is defined.
0972:                if (!processMap.keySet().contains(subFlowId)) {
0973:                    eh.add(new PrioritizedMessage(
0974:                            PrioritizedMessage.Priority.ERROR, bundleBase
0975:                                    + "#procdef.activity.subflow.notfound",
0976:                            new Object[] { activityId, subFlowId, processId }));
0977:                    return false;
0978:                }
0979:                // check if the formal params of the called process in the type of
0980:                // OUT and INOUT reference the datafields or formal params in the 
0981:                // calling process.
0982:                // find out all the actual parameters of the calling process.
0983:                List actualParams = new ArrayList();
0984:                Iterator actualParamsIt = actualParamsPath.selectNodes(
0985:                        subFlowElem).iterator();
0986:                while (actualParamsIt.hasNext()) {
0987:                    String apm = ((Element) actualParamsIt.next()).getText();
0988:                    actualParams.add(apm);
0989:                }
0990:                // Map of id and its mode
0991:                Map callerFpMap = new HashMap();
0992:                List formalParamsList = formalParamsPath.selectNodes(process);
0993:                Iterator formalParamsIt = formalParamsList.iterator();
0994:                while (formalParamsIt.hasNext()) {
0995:                    Element fm = (Element) formalParamsIt.next();
0996:                    String fmId = fm.getAttributeValue("Id");
0997:                    callerFpMap.put(fmId, fm.getAttributeValue("Mode"));
0998:                }
0999:                // find out all the formal parameters of the called process.
1000:                Element subFlowProc = (Element) processMap.get(subFlowId);
1001:                List subFlowFormalParams = formalParamsPath
1002:                        .selectNodes(subFlowProc);
1003:                if (subFlowFormalParams.size() != actualParams.size()) {
1004:                    eh
1005:                            .add(new PrioritizedMessage(
1006:                                    PrioritizedMessage.Priority.ERROR,
1007:                                    bundleBase
1008:                                            + "#procdef.activity.subflow.params.notmatched",
1009:                                    new Object[] { activityId, subFlowId,
1010:                                            processId }));
1011:                    return false;
1012:                }
1013:                int index = 0;
1014:                for (Iterator formParamIter = subFlowFormalParams.iterator(); formParamIter
1015:                        .hasNext(); index++) {
1016:                    Element fpElem = (Element) formParamIter.next();
1017:                    FormalParameter fp = new FormalParameter(fpElem
1018:                            .getAttributeValue("Id"), Integer.toString(index),
1019:                            FormalParameter.Mode.fromString(fpElem
1020:                                    .getAttributeValue("Mode")), XPDLUtil
1021:                                    .extractDataType(fpElem.getChild(
1022:                                            "DataType", xpdlns)));
1023:                    String actParam = ((String) actualParams.get(index)).trim();
1024:                    if (callerFpMap.containsKey(actParam)) {
1025:                        // check the mode of the formal parameter of the calling 
1026:                        // process
1027:                        String callerParamMode = (String) callerFpMap
1028:                                .get(actParam);
1029:                        if (callerParamMode.indexOf(fp.mode().toString()) == -1) {
1030:                            eh
1031:                                    .add(new PrioritizedMessage(
1032:                                            PrioritizedMessage.Priority.ERROR,
1033:                                            bundleBase
1034:                                                    + "#procdef.activity.subflow.parammode.notmatched",
1035:                                            new Object[] { subFlowId, actParam,
1036:                                                    callerParamMode,
1037:                                                    fp.mode().toString(),
1038:                                                    activityId, processId }));
1039:                            return false;
1040:                        }
1041:                    }
1042:                    if (procdataMap.containsKey(actParam)) {
1043:                        boolean compat = true;
1044:                        if (fp.mode().equals(FormalParameter.Mode.IN)
1045:                                || fp.mode().equals(FormalParameter.Mode.INOUT)) {
1046:                            compat = typeCompatible(fp.type(), XPDLUtil
1047:                                    .extractDataType(((ProcData) procdataMap
1048:                                            .get(actParam)).dataType));
1049:                        }
1050:                        if (fp.mode().equals(FormalParameter.Mode.OUT)
1051:                                || fp.mode().equals(FormalParameter.Mode.INOUT)) {
1052:                            compat = compat
1053:                                    && typeCompatible(
1054:                                            XPDLUtil
1055:                                                    .extractDataType(((ProcData) procdataMap
1056:                                                            .get(actParam)).dataType),
1057:                                            fp.type());
1058:                        }
1059:                        if (!compat) {
1060:                            String[] errDatas = { subFlowId, activityId,
1061:                                    processId };
1062:                            eh.add(new PrioritizedMessage(
1063:                                    PrioritizedMessage.Priority.ERROR,
1064:                                    bundleBase + "#procdef.activity.subflow"
1065:                                            + ".paramdatatype.notmatched",
1066:                                    errDatas));
1067:                            return false;
1068:                        }
1069:                    } else {
1070:                        if (fp.mode() != FormalParameter.Mode.IN) {
1071:                            eh
1072:                                    .add(new PrioritizedMessage(
1073:                                            PrioritizedMessage.Priority.ERROR,
1074:                                            bundleBase
1075:                                                    + "#procdef.activity.subflow.datanotfound",
1076:                                            new Object[] { subFlowId, actParam,
1077:                                                    activityId, processId }));
1078:                            return false;
1079:                        }
1080:                        if (XPDLUtil.isXMLType(fp.type())) {
1081:                            String res = notXMLOrValid(actParam);
1082:                            if (res != null) {
1083:                                eh
1084:                                        .add(new PrioritizedMessage(
1085:                                                PrioritizedMessage.Priority.ERROR,
1086:                                                bundleBase
1087:                                                        + "#procdef.subflow.params.invalidXML",
1088:                                                new Object[] { subFlowId,
1089:                                                        actParam, activityId,
1090:                                                        processId, res }));
1091:                                return false;
1092:                            }
1093:                        }
1094:                    }
1095:                }
1096:                return true;
1097:            }
1098:
1099:            private String notXMLOrValid(String text) {
1100:                String src = text.trim();
1101:                if (src.length() == 0 || src.charAt(0) != '<') {
1102:                    return null;
1103:                }
1104:                if (src.startsWith("<>") && src.endsWith("</>")) {
1105:                    src = src.substring(2, src.length() - 3);
1106:                }
1107:                try {
1108:                    SAXParserFactory pf = SAXParserFactory.newInstance();
1109:                    pf.setValidating(false);
1110:                    SAXParser parser = pf.newSAXParser();
1111:                    XMLReader reader = parser.getXMLReader();
1112:                    // Parse the file
1113:                    InputSource inSrc = new InputSource(new StringReader(
1114:                            "<temporary-root>" + src + "</temporary-root>"));
1115:                    reader.parse(inSrc);
1116:                } catch (SAXException e) {
1117:                    return e.getMessage();
1118:                } catch (IOException e) {
1119:                    return e.getMessage();
1120:                } catch (ParserConfigurationException e) {
1121:                    String s = "Cannot read XPDL: " + e.getMessage();
1122:                    logger.fatal(s, e);
1123:                    throw new IllegalStateException(s);
1124:                }
1125:                return null;
1126:            }
1127:
1128:            private boolean typeCompatible(Object aType, Object bType) {
1129:                if (XPDLUtil.isXMLType(aType) && XPDLUtil.isXMLType(bType)) {
1130:                    return true;
1131:                } else if ((aType instanceof  ExternalReference)
1132:                        && (bType instanceof  ExternalReference)) {
1133:                    if (XPDLUtil.isJavaType((ExternalReference) aType) != XPDLUtil
1134:                            .isJavaType((ExternalReference) bType)) {
1135:                        return false;
1136:                    }
1137:                    if (XPDLUtil.isJavaType((ExternalReference) aType)) {
1138:                        try {
1139:                            Class aJType = XPDLUtil
1140:                                    .getJavaType((ExternalReference) aType);
1141:                            Class bJType = XPDLUtil
1142:                                    .getJavaType((ExternalReference) bType);
1143:                            return aJType.isAssignableFrom(bJType);
1144:                        } catch (ClassNotFoundException e) {
1145:                            logger.error("Class no longer loadable: "
1146:                                    + e.getMessage());
1147:                        }
1148:                        return false;
1149:                    }
1150:                    // for the time being, assume all other external references
1151:                    // to be compatible
1152:                    return true;
1153:                } else if (aType.equals(bType)) {
1154:                    // Basic type
1155:                    return true;
1156:                } else {
1157:                    logger.debug(aType + " is not compatible with " + bType);
1158:                    return false;
1159:                }
1160:            }
1161:
1162:            private boolean validatePerformer(String processId,
1163:                    Element activity, List participantIdList,
1164:                    CollectingErrorHandler eh) throws JDOMException,
1165:                    JaxenException {
1166:                boolean faultless = true;
1167:                Namespace namespace = Namespace.getNamespace("xpdl",
1168:                        XPDLUtil.XPDL_NS);
1169:                String performer = activity
1170:                        .getChildText("Performer", namespace);
1171:                String id = activity.getAttributeValue("Id");
1172:                if ((performer != null)
1173:                        && !participantIdList.contains(performer)) {
1174:                    // check if this performer is definiert in the data fields
1175:                    faultless = false;
1176:                    for (Iterator i = dataFieldsList.iterator(); i.hasNext();) {
1177:                        Element elem = (Element) i.next();
1178:                        String elemId = elem.getAttributeValue("Id");
1179:                        Element dte = elem.getChild("DataType", namespace);
1180:                        if (elemId.equals(performer)) {
1181:                            Element dtb = dte.getChild("BasicType", namespace);
1182:                            if ((dtb != null)
1183:                                    && ("PERFORMER".equals(dtb
1184:                                            .getAttributeValue("Type")))) {
1185:                                return true;
1186:                            }
1187:                        }
1188:                    }
1189:                    eh.add(new PrioritizedMessage(
1190:                            PrioritizedMessage.Priority.ERROR, bundleBase
1191:                                    + "#procdef.performer.notfound",
1192:                            new Object[] { performer, id, processId }));
1193:                }
1194:                return faultless;
1195:            }
1196:
1197:            private List validateParticipants(Document doc, Element process,
1198:                    CollectingErrorHandler eh) throws JDOMException,
1199:                    JaxenException {
1200:                // some jaxen versions return an immutable list
1201:                List partiList = new ArrayList(partPath.selectNodes(doc));
1202:                partiList.addAll(procpartPath.selectNodes(process));
1203:                String processId = process.getAttributeValue("Id");
1204:                List partiIdList = new ArrayList();
1205:                Iterator partiInterator = partiList.iterator();
1206:                while (partiInterator.hasNext()) {
1207:                    Element pd = (Element) partiInterator.next();
1208:                    partiIdList.add(pd.getAttributeValue("Id"));
1209:                }
1210:                String duplicate = findDuplicate(partiIdList);
1211:                if (duplicate != null) {
1212:                    String[] errdatas = { duplicate };
1213:                    eh
1214:                            .add(new PrioritizedMessage(
1215:                                    PrioritizedMessage.Priority.ERROR,
1216:                                    bundleBase
1217:                                            + "#procdef.participant.ununique",
1218:                                    errdatas));
1219:                }
1220:                return partiIdList;
1221:            }
1222:
1223:            private void validateTransition(Element process,
1224:                    CollectingErrorHandler eh) throws JDOMException,
1225:                    JaxenException {
1226:                // Validate unique transition id and loop activies
1227:                doValidateTransition(process, transPath.selectNodes(process),
1228:                        null, false, eh);
1229:                // validate unique transition id and loop activies in ActivitySet
1230:                Iterator activitySetIterator = actSetPath.selectNodes(process)
1231:                        .iterator();
1232:                while (activitySetIterator.hasNext()) {
1233:                    Element actSetElem = (Element) activitySetIterator.next();
1234:                    doValidateTransition(process, transPath
1235:                            .selectNodes(actSetElem), actSetElem, true, eh);
1236:                }
1237:            }
1238:
1239:            // Validate transition of a process or what included in activitySet. If 
1240:            // isIncludedInActivitySet is set to true, then activitySet Element must be
1241:            // given.
1242:            private boolean doValidateTransition(Element process,
1243:                    Collection trans, Element actSetElem,
1244:                    boolean isIncludedInActivitySet, CollectingErrorHandler eh)
1245:                    throws JDOMException, JaxenException {
1246:                boolean faultless = true;
1247:                String actSetElemId = null;
1248:                if (isIncludedInActivitySet) {
1249:                    actSetElemId = actSetElem.getAttributeValue("Id");
1250:                }
1251:                List activityIds = getActivityIds(process, actSetElem,
1252:                        isIncludedInActivitySet);
1253:                List transitionIds = new ArrayList();
1254:                List transitionTos = new ArrayList();
1255:                String processId = process.getAttributeValue("Id");
1256:                Iterator activitiesIterator = trans.iterator();
1257:                while (activitiesIterator.hasNext()) {
1258:                    Element transition = (Element) activitiesIterator.next();
1259:                    String transitionId = transition.getAttributeValue("Id");
1260:                    transitionIds.add(transitionId);
1261:                    String transitionFrom = transition
1262:                            .getAttributeValue("From");
1263:                    String transitionTo = transition.getAttributeValue("To");
1264:                    transitionTos.add(transitionTo);
1265:                    String errTransition = null;
1266:                    // Validate existence of the referenced activityId
1267:                    if (!activityIds.contains(transitionFrom)) {
1268:                        errTransition = transitionFrom;
1269:                    } else if (!activityIds.contains(transitionTo)) {
1270:                        errTransition = transitionTo;
1271:                    }
1272:                    if (errTransition != null) {
1273:                        faultless = false;
1274:                        String errKey1 = "#procdef.transition.activityid.notfound";
1275:                        if (isIncludedInActivitySet) {
1276:                            errKey1 = "#procdef.activityset.transition.activityid.notfound";
1277:                        }
1278:                        eh.add(new PrioritizedMessage(
1279:                                PrioritizedMessage.Priority.ERROR, bundleBase
1280:                                        + errKey1, new Object[] {
1281:                                        errTransition, transitionId, processId,
1282:                                        actSetElemId }));
1283:                    }
1284:                }
1285:                String duplicate = findDuplicate(transitionIds);
1286:                String[] errdatas = { duplicate, processId, actSetElemId };
1287:                if (duplicate != null) {
1288:                    faultless = false;
1289:                    String errKey = "#procdef.transition.ununique";
1290:                    if (isIncludedInActivitySet) {
1291:                        errKey = "#procdef.activityset.transition.ununique";
1292:                    }
1293:                    eh.add(new PrioritizedMessage(
1294:                            PrioritizedMessage.Priority.ERROR, bundleBase
1295:                                    + errKey, errdatas));
1296:                }
1297:                int activityCount = activityIds.size();
1298:                // Validate loop activities
1299:                if (activityCount > 0) {
1300:                    activityIds.removeAll(transitionTos);
1301:                    if (activityIds.size() == 0) {
1302:                        faultless = false;
1303:                        eh.add(new PrioritizedMessage(
1304:                                PrioritizedMessage.Priority.WARN, bundleBase
1305:                                        + "#procdef.transition.noentry",
1306:                                errdatas));
1307:                    }
1308:                }
1309:                return faultless;
1310:            }
1311:
1312:            /**
1313:             * Extracts all the applications definition in the package and
1314:             * in this process and use it to generate a Map of ids and  
1315:             * <code>ApplicationDefinition</code>. 
1316:             * @return a Map of ids and <code>ApplicationDefinition</code>. 
1317:             */
1318:            private void validateApplDefs(Document doc,
1319:                    CollectingErrorHandler eh) throws JaxenException {
1320:                applicationDefs = new HashMap();
1321:
1322:                // package level definitions
1323:                List applList = applPath.selectNodes(doc);
1324:                List appIdList = new ArrayList();
1325:                for (Iterator itr = applList.iterator(); itr.hasNext();) {
1326:                    Element appl = (Element) itr.next();
1327:                    validateApplDef(eh, appIdList, appl, null);
1328:                }
1329:                String duplicate = findDuplicate(appIdList);
1330:                if (duplicate != null) {
1331:                    String[] errdatas = { duplicate };
1332:                    eh
1333:                            .add(new PrioritizedMessage(
1334:                                    PrioritizedMessage.Priority.ERROR,
1335:                                    bundleBase
1336:                                            + "#procdef.application.ununique",
1337:                                    errdatas));
1338:                }
1339:
1340:                // process level definitons
1341:                List processes = processes(doc);
1342:                for (Iterator i = processes.iterator(); i.hasNext();) {
1343:                    Element proc = (Element) i.next();
1344:                    String procId = proc.getAttributeValue("Id");
1345:                    // some versions of jaxen return an immutable list
1346:                    List procApplList = new ArrayList(procApplPath
1347:                            .selectNodes(proc));
1348:                    procApplList.addAll(applList);
1349:                    appIdList = new ArrayList();
1350:                    for (Iterator itr = procApplList.iterator(); itr.hasNext();) {
1351:                        Element appl = (Element) itr.next();
1352:                        validateApplDef(eh, appIdList, appl, procId);
1353:                    }
1354:                    duplicate = findDuplicate(appIdList);
1355:                    if (duplicate != null) {
1356:                        String[] errdatas = { duplicate };
1357:                        eh.add(new PrioritizedMessage(
1358:                                PrioritizedMessage.Priority.ERROR, bundleBase
1359:                                        + "#procdef.application.ununique",
1360:                                errdatas));
1361:                    }
1362:                }
1363:            }
1364:
1365:            /**
1366:             * @param eh
1367:             * @param appIdList
1368:             * @param appl
1369:             * @throws JaxenException
1370:             */
1371:            private void validateApplDef(CollectingErrorHandler eh,
1372:                    List appIdList, Element appl, String procId)
1373:                    throws JaxenException {
1374:                String tac = toolAgentClassPath.stringValueOf(appl);
1375:                if (tac == null || tac.length() == 0) {
1376:                    eh.add(new PrioritizedMessage(
1377:                            PrioritizedMessage.Priority.ERROR, bundleBase
1378:                                    + "#procdef.application.toolAgentClass",
1379:                            new String[] { appl.getAttributeValue("Id") }));
1380:                }
1381:                try {
1382:                    ApplicationDefinition ad = new ApplicationDefinition();
1383:                    subtreeToSAX(appl, ad.saxInitializer());
1384:                    applicationDefs.put(procId == null ? (Object) ad.id()
1385:                            : new PSK(procId, ad.id()), ad);
1386:                    appIdList.add(ad.id());
1387:                    List indexedParams = indexedParamsPath.selectNodes(appl);
1388:                    if (indexedParams.size() > 0) {
1389:                        String[] errdatas = { ad.id() };
1390:                        eh
1391:                                .add(new PrioritizedMessage(
1392:                                        PrioritizedMessage.Priority.WARN,
1393:                                        bundleBase
1394:                                                + "#procdef.application.indexedParameter",
1395:                                        new String[] { ad.id() }));
1396:                    }
1397:                } catch (IllegalArgumentException ex) {
1398:                    eh
1399:                            .add(new PrioritizedMessage(
1400:                                    PrioritizedMessage.Priority.ERROR, ex
1401:                                            .getMessage()));
1402:                }
1403:            }
1404:
1405:            /**
1406:             * Extracts all the applications definition in the package and
1407:             * in this process and use it to generate a Map of ids and  
1408:             * <code>ApplicationDefinition</code>. 
1409:             * @return a Map of ids and <code>ApplicationDefinition</code>. 
1410:             */
1411:            private void validateExtendedAttributes(Document doc,
1412:                    Element process, CollectingErrorHandler eh)
1413:                    throws JaxenException {
1414:                Element extendedAttrs = null;
1415:                if (doc != null) {
1416:                    extendedAttrs = (Element) extAttrPath.selectSingleNode(doc);
1417:                } else if (process != null) {
1418:                    extendedAttrs = (Element) procExtAttrPath
1419:                            .selectSingleNode(process);
1420:                }
1421:                if (extendedAttrs == null) {
1422:                    return;
1423:                }
1424:                Namespace namespace = Namespace.getNamespace(XPDLUtil.XPDL_NS);
1425:                List extendedAttrList = extendedAttrs.getChildren(
1426:                        "ExtendedAttribute", namespace);
1427:                Iterator iterator = extendedAttrList.iterator();
1428:                while (iterator.hasNext()) {
1429:                    Element extendedAttr = (Element) iterator.next();
1430:                    String extendedAttrName = extendedAttr
1431:                            .getAttributeValue("Name");
1432:                    // Check if the extendedAttribute is in MANUAL/AUTOMATIC/COMPLETED.
1433:                    if (extendedAttrName.equals("RemoveClosedProcess")) {
1434:                        String val = extendedAttr.getAttributeValue("Value");
1435:                        if (val == null) {
1436:                            val = extendedAttr.getTextTrim();
1437:                        }
1438:                        if (!val.equals("AUTOMATIC") && !val.equals("MANUAL")
1439:                                && !val.equals("COMPLETED")) {
1440:                            eh
1441:                                    .add(new PrioritizedMessage(
1442:                                            PrioritizedMessage.Priority.ERROR,
1443:                                            bundleBase
1444:                                                    + "#procdef.extendedattr.value.notallowed",
1445:                                            new String[] { extendedAttrName,
1446:                                                    val }));
1447:                        }
1448:                    } else if (extendedAttrName.equals("AuditEventSelection")) {
1449:                        String val = extendedAttr.getAttributeValue("Value");
1450:                        if (val == null) {
1451:                            val = extendedAttr.getTextTrim();
1452:                        }
1453:                        if (!val.equals("AllEvents")
1454:                                && !val.equals("StateEventsOnly")
1455:                                && !val.equals("ProcessClosedEventsOnly")
1456:                                && !val.equals("NoEvents")) {
1457:                            eh
1458:                                    .add(new PrioritizedMessage(
1459:                                            PrioritizedMessage.Priority.ERROR,
1460:                                            bundleBase
1461:                                                    + "#procdef.extendedattr.value.notallowed",
1462:                                            new String[] { extendedAttrName,
1463:                                                    val }));
1464:                        }
1465:                        if (process == null) {
1466:                            eh.add(new PrioritizedMessage(
1467:                                    PrioritizedMessage.Priority.WARN,
1468:                                    bundleBase
1469:                                            + "#package.nonstandard.auditing"));
1470:                        } else {
1471:                            eh.add(new PrioritizedMessage(
1472:                                    PrioritizedMessage.Priority.WARN,
1473:                                    bundleBase
1474:                                            + "#process.nonstandard.auditing",
1475:                                    new String[] { process
1476:                                            .getAttributeValue("Id") }));
1477:                        }
1478:                    } else if (extendedAttrName.equals("StoreAuditEvents")) {
1479:                        String val = extendedAttr.getAttributeValue("Value");
1480:                        if (val == null) {
1481:                            val = extendedAttr.getTextTrim();
1482:                        }
1483:                        if (!val.equalsIgnoreCase("true")) {
1484:                            if (process == null) {
1485:                                eh
1486:                                        .add(new PrioritizedMessage(
1487:                                                PrioritizedMessage.Priority.WARN,
1488:                                                bundleBase
1489:                                                        + "#package.nonstandard.logging"));
1490:                            } else {
1491:                                eh
1492:                                        .add(new PrioritizedMessage(
1493:                                                PrioritizedMessage.Priority.WARN,
1494:                                                bundleBase
1495:                                                        + "#process.nonstandard.logging",
1496:                                                new String[] { process
1497:                                                        .getAttributeValue("Id") }));
1498:                            }
1499:                        }
1500:                    }
1501:                }
1502:            }
1503:
1504:            private void validatePriority(String processId, Element priority,
1505:                    String errorKey, String errorText, CollectingErrorHandler eh)
1506:                    throws JDOMException {
1507:                if (priority == null) {
1508:                    return;
1509:                }
1510:                String priorityStr = null;
1511:                try {
1512:                    priorityStr = priority.getText();
1513:                    if (priorityStr == null) {
1514:                        return;
1515:                    } else {
1516:                        priorityStr = priorityStr.trim();
1517:                    }
1518:                    ExtExecutionObjectLocal.Priority.fromInt(Integer
1519:                            .parseInt(priorityStr.trim()));
1520:                } catch (Exception e) {
1521:                    String[] errdatas = { errorText, priorityStr, processId };
1522:                    eh.add(new PrioritizedMessage(
1523:                            PrioritizedMessage.Priority.ERROR, bundleBase + "#"
1524:                                    + errorKey, errdatas));
1525:                }
1526:            }
1527:
1528:            private List getActivityIds(Element process, Element actSet,
1529:                    boolean isIncludedInActivitySet) throws JDOMException,
1530:                    JaxenException {
1531:                List activityIds = new ArrayList();
1532:                Element toBeSelectedNode = isIncludedInActivitySet ? actSet
1533:                        : process;
1534:                Iterator activitiesIterator = actPath.selectNodes(
1535:                        toBeSelectedNode).iterator();
1536:                while (activitiesIterator.hasNext()) {
1537:                    Element activity = (Element) activitiesIterator.next();
1538:                    activityIds.add(activity.getAttributeValue("Id"));
1539:                }
1540:                return activityIds;
1541:            }
1542:
1543:            private List getTransitionIds(Element process, Element actSet,
1544:                    boolean isIncludedInActivitySet) throws JDOMException,
1545:                    JaxenException {
1546:                List transitionIds = new ArrayList();
1547:                Element toBeSelectedNode = isIncludedInActivitySet ? actSet
1548:                        : process;
1549:                Iterator transIterator = transPath
1550:                        .selectNodes(toBeSelectedNode).iterator();
1551:                while (transIterator.hasNext()) {
1552:                    Element transElem = (Element) transIterator.next();
1553:                    transitionIds.add(transElem.getAttributeValue("Id"));
1554:                }
1555:                return transitionIds;
1556:            }
1557:
1558:            // Get all the data fields defined in the package header and 
1559:            // in the given process.
1560:            private Map procdatas(Document doc, Element process,
1561:                    CollectingErrorHandler eh) throws JaxenException {
1562:                procdataMap = new HashMap();
1563:                List docDataFields = dataFieldPath.selectNodes(doc);
1564:                List procDataFields = procDataFieldPath.selectNodes(process);
1565:                if (dataFieldsList == null) {
1566:                    dataFieldsList = new ArrayList();
1567:                    dataFieldsList.addAll(docDataFields);
1568:                    dataFieldsList.addAll(procDataFields);
1569:                }
1570:                // determine all DataFields defined in the package header
1571:                extractDataFields(docDataFields, procdataMap, eh);
1572:                // determine all DataFields defined in the process
1573:                extractDataFields(procDataFields, procdataMap, eh);
1574:                // add formal parameters
1575:                Namespace xpdlns = Namespace.getNamespace(XPDLUtil.XPDL_NS);
1576:                Iterator iterator = procFormalParamsPath.selectNodes(doc)
1577:                        .iterator();
1578:                while (iterator.hasNext()) {
1579:                    Element elem = (Element) iterator.next();
1580:                    String id = elem.getAttributeValue("Id");
1581:                    procdataMap.put(id, new ProcData(null, elem.getChild(
1582:                            "DataType", xpdlns)));
1583:                }
1584:                return procdataMap;
1585:            }
1586:
1587:            /**
1588:             * Extract the defined data fields and put them in the procDataMap.
1589:             * @param dataFieldsList list of data field. 
1590:             * @param procDataMap map with extracted data/value. 
1591:             */
1592:            private void extractDataFields(List dataFieldsList,
1593:                    Map procDataMap, CollectingErrorHandler eh)
1594:                    throws JaxenException {
1595:                Namespace xpdlns = Namespace.getNamespace(XPDLUtil.XPDL_NS);
1596:                Iterator iterator = dataFieldsList.iterator();
1597:                while (iterator.hasNext()) {
1598:                    Element elem = (Element) iterator.next();
1599:                    String id = elem.getAttributeValue("Id");
1600:                    Element dte = elem.getChild("DataType", xpdlns);
1601:                    Element ve = elem.getChild("InitialValue", xpdlns);
1602:                    try {
1603:                        procdataMap.put(id, new ProcData(XPDLUtil.extractValue(
1604:                                dte, ve), dte));
1605:                    } catch (IllegalArgumentException e) {
1606:                        eh.add(new PrioritizedMessage(
1607:                                PrioritizedMessage.Priority.ERROR, bundleBase
1608:                                        + "#procdef.data.cannotInit",
1609:                                new Object[] { id, e.getMessage() }));
1610:                        continue;
1611:                    }
1612:                }
1613:            }
1614:
1615:            /**
1616:             * Returns the Map of the Ids and element of all the process of the whole 
1617:             * xpdl doc.
1618:             */
1619:            private Map processMap(Document doc) throws JaxenException {
1620:                Map processMap = new HashMap();
1621:                for (Iterator i = processes(doc).iterator(); i.hasNext();) {
1622:                    Element proc = (Element) i.next();
1623:                    processMap.put(proc.getAttributeValue("Id"), proc);
1624:                }
1625:                return processMap;
1626:            }
1627:
1628:            /**
1629:             * Returns the list of all process elements of the whole xpdl doc.
1630:             */
1631:            private List processes(Document doc) throws JaxenException {
1632:                return processPath.selectNodes(doc);
1633:            }
1634:
1635:            /**
1636:             * Used to find the duplicate in the list. If found, returns the duplicate 
1637:             * in String; if not, returns null;
1638:             */
1639:            private String findDuplicate(List ids) {
1640:                if (ids.size() < 2) {
1641:                    return null;
1642:                }
1643:                Collections.sort(ids);
1644:                for (int i = 1; i < ids.size(); i++) {
1645:                    if (((String) ids.get(i)).equals((String) ids.get(i - 1))) {
1646:                        return (String) ids.get(i);
1647:                    }
1648:                }
1649:                return null;
1650:            }
1651:
1652:            private void subtreeToSAX(Element e, ContentHandler h) {
1653:                try {
1654:                    SAXEventBufferImpl buf = new SAXEventBufferImpl();
1655:                    SAXOutputter out = new SAXOutputter(buf);
1656:                    out.output(new Document((Element) e.clone()));
1657:                    HandlerStack hs = new HandlerStack(h);
1658:                    buf.emit(hs.contentHandler());
1659:                } catch (JDOMException ex) {
1660:                    throw new IllegalArgumentException(ex.getMessage());
1661:                } catch (SAXException ex) {
1662:                    throw new IllegalArgumentException(ex.getMessage());
1663:                }
1664:            }
1665:
1666:            // Process Scoped Key
1667:            private class PSK {
1668:                private String processId;
1669:                private String key;
1670:
1671:                public PSK(String pId, String key) {
1672:                    processId = pId;
1673:                    this .key = key;
1674:                }
1675:
1676:                /**
1677:                 * Describe <code>equals</code> method here.
1678:                 *
1679:                 * @param object an <code>Object</code> value
1680:                 * @return a <code>boolean</code> value
1681:                 */
1682:                public boolean equals(Object object) {
1683:                    if (!(object instanceof  PSK)) {
1684:                        return false;
1685:                    }
1686:                    PSK other = (PSK) object;
1687:                    return processId.equals(other.processId)
1688:                            && key.equals(other.key);
1689:                }
1690:
1691:                /**
1692:                 * Describe <code>hashCode</code> method here.
1693:                 *
1694:                 * @return an <code>int</code> value
1695:                 */
1696:                public int hashCode() {
1697:                    return processId.hashCode() ^ key.hashCode();
1698:                }
1699:            }
1700:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.