Source Code Cross Referenced for InstanceResponseGenerator.java in  » Workflow-Engines » wfmopen-2.1.1 » de » danet » an » workflow » clients » wfxml » 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.clients.wfxml 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * This file is part of the WfMOpen project.
0003:         * Copyright (C) 2001-2006 Danet GmbH (www.danet.de), BU BTS.
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: InstanceResponseGenerator.java,v 1.12 2007/03/29 11:46:54 schnelle Exp $
0021:         *
0022:         * $Log: InstanceResponseGenerator.java,v $
0023:         * Revision 1.12  2007/03/29 11:46:54  schnelle
0024:         * Reactivated ASAPException to propagate ASAP error messages in cases of an invalid key, a missing resource or an invalid factory.
0025:         *
0026:         * Revision 1.11  2007/03/27 21:59:42  mlipp
0027:         * Fixed lots of checkstyle warnings.
0028:         *
0029:         * Revision 1.10  2007/03/01 12:32:57  schnelle
0030:         * Enhanced Instance.SetProperties to process ContextData.
0031:         *
0032:         * Revision 1.9  2007/02/16 21:00:21  mlipp
0033:         * Fixed some null pointer problems.
0034:         *
0035:         * Revision 1.8  2007/02/01 13:44:43  schnelle
0036:         * Using namespace for factory schemas that do not contain '&'.
0037:         *
0038:         * Revision 1.7  2007/02/01 12:38:36  schnelle
0039:         * Use of encoded key for properties.
0040:         *
0041:         * Revision 1.6  2007/01/31 22:55:36  mlipp
0042:         * Some more refactoring and fixes of problems introduced by refactoring.
0043:         *
0044:         * Revision 1.5  2007/01/31 14:53:06  schnelle
0045:         * Small corrections wvaluating the resource reference.
0046:         *
0047:         * Revision 1.4  2007/01/31 12:24:06  drmlipp
0048:         * Design revisited.
0049:         *
0050:         * Revision 1.3  2007/01/30 15:07:37  schnelle
0051:         * Filtering of all instances for the current factory in a list instances request.
0052:         *
0053:         * Revision 1.2  2007/01/30 11:56:14  drmlipp
0054:         * Merged Wf-XML branch.
0055:         *
0056:         * Revision 1.1.2.23  2007/01/29 15:04:19  schnelle
0057:         * Renaming of Observer to ObserverRegistry and URIDecoder to ResourceReference.
0058:         *
0059:         * Revision 1.1.2.22  2007/01/29 13:40:30  schnelle
0060:         * Storing of the sender base in the servlet context.
0061:         *
0062:         * Revision 1.1.2.21  2007/01/29 13:10:27  drmlipp
0063:         * Using utilities method for timestamp convertion.
0064:         *
0065:         * Revision 1.1.2.20  2007/01/24 11:46:35  schnelle
0066:         * Moved wsdl files and xsd files intot resources subdirectory.
0067:         *
0068:         * Revision 1.1.2.19  2007/01/24 10:56:50  schnelle
0069:         * Prepared return of a result for aobservers.
0070:         *
0071:         * Revision 1.1.2.18  2007/01/24 09:28:53  schnelle
0072:         * Returning result data for the instance.
0073:         *
0074:         * Revision 1.1.2.17  2007/01/19 15:01:59  schnelle
0075:         * Returning context data at instance getproperties.
0076:         *
0077:         * Revision 1.1.2.16  2007/01/19 12:34:56  schnelle
0078:         * Moved generation and decoding of the URI that is used as the receiver key to new class URIDecoder.
0079:         *
0080:         * Revision 1.1.2.15  2007/01/16 11:05:42  schnelle
0081:         * Refactoring: Moved subscription handling methods to own class.
0082:         *
0083:         * Revision 1.1.2.14  2007/01/11 11:37:10  schnelle
0084:         * Added subscription if an oberver key is given in the creation of a process.
0085:         *
0086:         * Revision 1.1.2.13  2007/01/10 14:48:18  schnelle
0087:         * Checked if a subscription already exists, before storing the observer in the database.
0088:         *
0089:         * Revision 1.1.2.12  2007/01/10 14:16:52  schnelle
0090:         * Implemented unsubscribe.
0091:         *
0092:         * Revision 1.1.2.11  2007/01/10 13:41:27  schnelle
0093:         * Implemented subscribe.
0094:         *
0095:         * Revision 1.1.2.10  2007/01/10 09:03:43  schnelle
0096:         * Implemented set properties methods.
0097:         *
0098:         * Revision 1.1.2.9  2006/12/20 13:32:24  schnelle
0099:         * Basic implementato of GetProperties for Instance and Activity.
0100:         *
0101:         * Revision 1.1.2.8  2006/12/18 14:41:02  schnelle
0102:         * Preparatation for individual schema definition for each getproperties request.
0103:         *
0104:         * Revision 1.1.2.7  2006/12/14 08:50:21  schnelle
0105:         * Implemented CompleteActivity.
0106:         *
0107:         * Revision 1.1.2.6  2006/12/13 11:23:48  schnelle
0108:         * Implemented instance ListActivities.
0109:         *
0110:         * Revision 1.1.2.5  2006/12/12 13:24:38  schnelle
0111:         * Introduction of ASAPException to provide a detailed mesage.
0112:         *
0113:         * Revision 1.1.2.4  2006/12/12 11:41:21  schnelle
0114:         * Implemented state mapping of omg states to asap states.
0115:         *
0116:         * Revision 1.1.2.3  2006/12/12 09:34:35  schnelle
0117:         * Implemented ChangeState for Instance.
0118:         *
0119:         * Revision 1.1.2.2  2006/12/11 11:05:34  schnelle
0120:         * Added template methods for all requests.
0121:         *
0122:         * Revision 1.1.2.1  2006/11/28 12:20:10  schnelle
0123:         * Creation of a separate class to handle the issues for a specific resource.
0124:         *
0125:         * Revision 1.1.2.2  2006/11/27 15:41:55  schnelle
0126:         * Introducing some constants for request and response identification.
0127:         *
0128:         * Revision 1.1.2.1  2006/11/24 12:19:13  schnelle
0129:         * Separtion of response generation into ResponseGenerator class.
0130:         *
0131:         */
0132:        package de.danet.an.workflow.clients.wfxml;
0133:
0134:        import java.rmi.RemoteException;
0135:        import java.sql.SQLException;
0136:        import java.text.ParseException;
0137:        import java.util.Collection;
0138:        import java.util.Date;
0139:        import java.util.Iterator;
0140:        import java.util.NoSuchElementException;
0141:
0142:        import javax.xml.soap.MessageFactory;
0143:        import javax.xml.soap.Name;
0144:        import javax.xml.soap.SOAPBody;
0145:        import javax.xml.soap.SOAPBodyElement;
0146:        import javax.xml.soap.SOAPElement;
0147:        import javax.xml.soap.SOAPEnvelope;
0148:        import javax.xml.soap.SOAPException;
0149:        import javax.xml.soap.SOAPHeader;
0150:        import javax.xml.soap.SOAPHeaderElement;
0151:        import javax.xml.soap.SOAPMessage;
0152:        import javax.xml.transform.TransformerException;
0153:
0154:        import org.xml.sax.SAXException;
0155:
0156:        import de.danet.an.util.XMLUtil;
0157:        import de.danet.an.workflow.api.Activity;
0158:        import de.danet.an.workflow.api.DefaultProcessData;
0159:        import de.danet.an.workflow.api.InvalidKeyException;
0160:        import de.danet.an.workflow.api.Process;
0161:        import de.danet.an.workflow.api.ProcessDefinition;
0162:        import de.danet.an.workflow.api.ProcessDirectory;
0163:        import de.danet.an.workflow.api.SAXEventBuffer;
0164:        import de.danet.an.workflow.api.WorkflowService;
0165:        import de.danet.an.workflow.assignment.Assignment;
0166:        import de.danet.an.workflow.clients.wfxml.ObserverRegistry.ObserverInfo;
0167:        import de.danet.an.workflow.omgcore.HistoryNotAvailableException;
0168:        import de.danet.an.workflow.omgcore.InvalidDataException;
0169:        import de.danet.an.workflow.omgcore.InvalidStateException;
0170:        import de.danet.an.workflow.omgcore.ProcessData;
0171:        import de.danet.an.workflow.omgcore.ProcessDataInfo;
0172:        import de.danet.an.workflow.omgcore.ResultNotAvailableException;
0173:        import de.danet.an.workflow.omgcore.TransitionNotAllowedException;
0174:        import de.danet.an.workflow.omgcore.UpdateNotAllowedException;
0175:        import de.danet.an.workflow.omgcore.WfAuditEvent;
0176:        import de.danet.an.workflow.omgcore.WfCreateProcessAuditEvent;
0177:        import de.danet.an.workflow.omgcore.WfProcess;
0178:        import de.danet.an.workflow.omgcore.WfResource;
0179:        import de.danet.an.workflow.omgcore.WfStateAuditEvent;
0180:
0181:        /**
0182:         * This class provides the methods of an {@link AbstractResponseGenerator}
0183:         * that are relevant for the instance.
0184:         *
0185:         * <p>
0186:         * The <em>Instance</em> resource is the actual "performance of work"; it is the
0187:         * process instance. It embodies the context information that distinguishes one 
0188:         * process instance from another. Some people call this a "case". A process 
0189:         * instance resource can be used only once: it is created, then it can be 
0190:         * started, it can be paused, resumed, terminated. If things go normally, it 
0191:         * will eventually complete.
0192:         * </p>
0193:         * 
0194:         * @author Dirk Schnelle
0195:         *
0196:         */
0197:        class InstanceResponseGenerator extends AbstractResponseGenerator {
0198:            /** Logger instance. */
0199:            private static final org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory
0200:                    .getLog(InstanceResponseGenerator.class);
0201:
0202:            /**
0203:             * Constructs a new object.
0204:             *
0205:             * @param observerRegistry the observer registry. 
0206:             * @param wfs Reference to the workflow engine.
0207:             * @param resRef the resource reference.
0208:             */
0209:            public InstanceResponseGenerator(ObserverRegistry observerRegistry,
0210:                    WorkflowService wfs, ResourceReference resRef) {
0211:                super (observerRegistry, wfs, resRef);
0212:            }
0213:
0214:            /* (non-Javadoc)
0215:             * @see de.danet.an.workflow.clients.wfxml.AbstractResponseGenerator
0216:             */
0217:            public void evaluate(SOAPMessage reqMsg, SOAPMessage respMsg)
0218:                    throws SOAPException, RemoteException {
0219:                SOAPBodyElement actionElement = getActionElement(reqMsg);
0220:
0221:                String actName = actionElement.getElementName().getLocalName();
0222:
0223:                if (actName.equals(Consts.GET_PROPERTIES_REQUEST)) {
0224:                    getInstanceProperties(reqMsg, respMsg);
0225:                } else if (actName.equals(Consts.SET_PROPERTIES_REQUEST)) {
0226:                    setInstanceProperties(actionElement, reqMsg, respMsg);
0227:                } else if (actName.equals(Consts.SUBSCRIBE_REQUEST)) {
0228:                    subscribe(actionElement, reqMsg, respMsg);
0229:                } else if (actName.equals(Consts.UNSUBSCRIBE_REQUEST)) {
0230:                    unsubscribe(actionElement, reqMsg, respMsg);
0231:                } else if (actName.equals(Consts.LIST_ACTIVITIES_REQUEST)) {
0232:                    listActivities(reqMsg, respMsg);
0233:                } else if (actName.equals(Consts.CHANGE_STATE_REQUEST)) {
0234:                    changeState(actionElement, reqMsg, respMsg);
0235:                } else if (actName.equals(Consts.TERMINATE_REQUEST)) {
0236:                    terminate(reqMsg, respMsg);
0237:                } else {
0238:                    if (logger.isDebugEnabled()) {
0239:                        logger.debug("unknown action '" + actName + "'");
0240:                    }
0241:
0242:                    FaultUtils.setFault(respMsg,
0243:                            ASAPException.ASAP_INVALID_OPERATION_SPECIFICATION,
0244:                            getResourceName() + ": Unknown action \"" + actName
0245:                                    + "\".");
0246:                }
0247:            }
0248:
0249:            /* (non-Javadoc)
0250:             * @see de.danet.an.workflow.clients.wfxml.AbstractResponseGenerator#getSender()
0251:             */
0252:            protected String getResourceName() {
0253:                return RESOURCE_INSTANCE;
0254:            }
0255:
0256:            /**
0257:             * Creates a response that contains properties of the process instance.
0258:             * 
0259:             * @param reqMsg the request message.
0260:             * @param respMsg the response message
0261:             * @throws SOAPException
0262:             *         error evaluating the request or constructing the response.
0263:             * @throws RemoteException
0264:             *         error accessing the workflow engine.
0265:             */
0266:            private void getInstanceProperties(SOAPMessage reqMsg,
0267:                    SOAPMessage respMsg) throws SOAPException, RemoteException {
0268:                if (logger.isDebugEnabled()) {
0269:                    logger.debug("get instance properties...");
0270:                }
0271:
0272:                String receiverKey = getHeaderValue(reqMsg, Consts.RECEIVER_KEY);
0273:
0274:                Process proc = null;
0275:                try {
0276:                    proc = (Process) getProcess(receiverKey);
0277:                } catch (InvalidKeyException e) {
0278:                    FaultUtils.setFault(respMsg,
0279:                            ASAPException.ASAP_INVALID_INSTANCE_KEY, e
0280:                                    .getMessage());
0281:
0282:                    return;
0283:                } catch (NoSuchElementException e) {
0284:                    FaultUtils.setFault(respMsg,
0285:                            ASAPException.ASAP_INVALID_INSTANCE_KEY, e
0286:                                    .getMessage());
0287:
0288:                    return;
0289:                }
0290:
0291:                SOAPBodyElement propsNode = createAsapResponseNode(respMsg,
0292:                        Consts.GET_PROPERTIES_RESPONSE);
0293:
0294:                try {
0295:                    appendInstanceProperties(respMsg, receiverKey, proc,
0296:                            propsNode);
0297:                } catch (ResultNotAvailableException e) {
0298:                    FaultUtils.setFault(respMsg, e);
0299:
0300:                    return;
0301:                }
0302:            }
0303:
0304:            /**
0305:             * Reads the properties from the process instance and appends them to the 
0306:             * parent.
0307:             * @param respMsg the response message.
0308:             * @param receiverKey this activity instance
0309:             * @param parent the parent node of the response message.
0310:             * @param proc the process
0311:             * @throws SOAPException
0312:             *         error appending to the parent node
0313:             * @throws RemoteException
0314:             *         error accessing the process
0315:             * @throws SAXException 
0316:             * @throws TransformerException 
0317:             * @throws ResultNotAvailableException 
0318:             */
0319:            private void appendInstanceProperties(SOAPMessage respMsg,
0320:                    String receiverKey, Process proc, SOAPBodyElement propsNode)
0321:                    throws SOAPException, RemoteException,
0322:                    ResultNotAvailableException {
0323:                SOAPElement keyNode = propsNode.addChildElement("Key",
0324:                        Consts.ASAP_PREFIX);
0325:                keyNode.addTextNode(getResourceReference().getResourceKey());
0326:                SOAPElement state = propsNode.addChildElement("State",
0327:                        Consts.ASAP_PREFIX);
0328:                String procState = proc.state();
0329:                state.addTextNode(StateMapper.omg2asapState(procState));
0330:                SOAPElement nameNode = propsNode.addChildElement("Name",
0331:                        Consts.ASAP_PREFIX);
0332:                nameNode.addTextNode(proc.name());
0333:                SOAPElement subjectNode = propsNode.addChildElement("Subject",
0334:                        Consts.ASAP_PREFIX);
0335:                if (proc.description() != null) {
0336:                    subjectNode.addTextNode(proc.description());
0337:                }
0338:                SOAPElement descNode = propsNode.addChildElement("Description",
0339:                        Consts.ASAP_PREFIX);
0340:                if (proc.description() != null) {
0341:                    descNode.addTextNode(proc.description());
0342:                }
0343:                SOAPElement factoryKey = propsNode.addChildElement(
0344:                        "FactoryKey", Consts.ASAP_PREFIX);
0345:                ResourceReference procDefRes = new ResourceReference(
0346:                        getResourceReference().getBaseUrl(), proc
0347:                                .processDefinition());
0348:                factoryKey.addTextNode(procDefRes.getResourceKey());
0349:
0350:                appendObservers(respMsg, proc, propsNode);
0351:                appendHistory(respMsg, proc, propsNode);
0352:                appendContextData(respMsg, proc, propsNode);
0353:                appendResultData(respMsg, proc, propsNode);
0354:            }
0355:
0356:            /**
0357:             * Appends the list of observers to the given node in a properties request. 
0358:             * @param respMsg the message to send
0359:             * @param proc the related process
0360:             * @param propsNode the parent node
0361:             * @throws RemoteException
0362:             *         Error accessing the workflow engine
0363:             * @throws SOAPException
0364:             *         Error creating the message
0365:             */
0366:            private void appendObservers(SOAPMessage respMsg, Process proc,
0367:                    SOAPBodyElement propsNode) throws RemoteException,
0368:                    SOAPException {
0369:                Collection observers;
0370:                try {
0371:                    ObserverRegistry obs = getObserverRegistry();
0372:                    ProcessDefinition procdef = proc.processDefinition();
0373:                    observers = obs.getObservers(procdef.packageId(), procdef
0374:                            .processId(), proc.key());
0375:                } catch (SQLException e) {
0376:                    FaultUtils.setFault(respMsg, e);
0377:                    return;
0378:                }
0379:
0380:                if (observers.size() > 0) {
0381:                    SOAPElement observersNode = propsNode.addChildElement(
0382:                            "Observers", Consts.ASAP_PREFIX);
0383:                    Iterator iterator = observers.iterator();
0384:                    while (iterator.hasNext()) {
0385:                        ObserverInfo observerInfo = (ObserverInfo) iterator
0386:                                .next();
0387:                        SOAPElement observerKey = observersNode
0388:                                .addChildElement("ObserverKey",
0389:                                        Consts.ASAP_PREFIX);
0390:                        observerKey.addTextNode(observerInfo.getObserverKey());
0391:
0392:                    }
0393:                }
0394:            }
0395:
0396:            /**
0397:             * Appends the history of the process to the given node in a properties 
0398:             * request. 
0399:             * @param respMsg the message to send
0400:             * @param proc the related process
0401:             * @param propsNode the parent node
0402:             * @throws RemoteException
0403:             *         Error accessing the workflow engine
0404:             * @throws SOAPException
0405:             *         Error creating the message
0406:             */
0407:            private void appendHistory(SOAPMessage respMsg, Process proc,
0408:                    SOAPBodyElement propsNode) throws RemoteException,
0409:                    SOAPException {
0410:                SOAPElement historyNode = propsNode.addChildElement("History",
0411:                        Consts.ASAP_PREFIX);
0412:
0413:                Collection history;
0414:                try {
0415:                    history = proc.history();
0416:                } catch (HistoryNotAvailableException e) {
0417:                    // well, if there is nothing to append...
0418:                    return;
0419:                }
0420:                Iterator iterator = history.iterator();
0421:                while (iterator.hasNext()) {
0422:                    WfAuditEvent event = (WfAuditEvent) iterator.next();
0423:
0424:                    String asapEventType = getAsapEventType(event);
0425:                    if (asapEventType == null) {
0426:                        continue;
0427:                    }
0428:
0429:                    SOAPElement eventNode = historyNode.addChildElement(
0430:                            "Event", Consts.ASAP_PREFIX);
0431:                    Date date = event.timeStamp();
0432:                    SOAPElement timeNode = eventNode.addChildElement("Time",
0433:                            Consts.ASAP_PREFIX);
0434:                    timeNode.addTextNode(XMLUtil.toXsdGMTDateTime(date));
0435:                    SOAPElement type = eventNode.addChildElement("EventType",
0436:                            Consts.ASAP_PREFIX);
0437:                    type.addTextNode(asapEventType);
0438:                    SOAPElement sourceKey = eventNode.addChildElement(
0439:                            "SourceKey", Consts.ASAP_PREFIX);
0440:                    sourceKey.addTextNode("");
0441:                    SOAPElement details = eventNode.addChildElement("Details",
0442:                            Consts.ASAP_PREFIX);
0443:                    details.addTextNode("");
0444:                    String newState;
0445:                    String oldState;
0446:
0447:                    if (event instanceof  WfCreateProcessAuditEvent) {
0448:                        // The old state is not defined, and we are not allowed to
0449:                        // add an empty string.
0450:                        oldState = "open.notrunning";
0451:                        newState = "open.notrunning";
0452:                    } else {
0453:                        WfStateAuditEvent stateEvent = (WfStateAuditEvent) event;
0454:                        oldState = StateMapper.omg2asapState(stateEvent
0455:                                .oldState());
0456:                        newState = StateMapper.omg2asapState(stateEvent
0457:                                .newState());
0458:                    }
0459:                    SOAPElement oldStateNode = eventNode.addChildElement(
0460:                            "OldState", Consts.ASAP_PREFIX);
0461:                    oldStateNode.addTextNode(oldState);
0462:                    SOAPElement newStateNode = eventNode.addChildElement(
0463:                            "NewState", Consts.ASAP_PREFIX);
0464:                    newStateNode.addTextNode(newState);
0465:
0466:                }
0467:            }
0468:
0469:            /**
0470:             * Gets the ASAP description for the {@link WfAuditEvent}.
0471:             * @param event the event
0472:             * @return ASAP representation of the event or <code>null</null>
0473:             * if no corresponding ASAP event exists..
0474:             */
0475:            private String getAsapEventType(WfAuditEvent event) {
0476:                String type = event.eventType();
0477:                if (type.equals(WfAuditEvent.PROCESS_CREATED)) {
0478:                    return "InstanceCreated";
0479:                }
0480:
0481:                if (type.equals(WfAuditEvent.PROCESS_STATE_CHANGED)) {
0482:                    return "StateChanged";
0483:                }
0484:                return null;
0485:            }
0486:
0487:            /**
0488:             * Appends the context data to the given node in a properties request. 
0489:             * @param respMsg the message to send
0490:             * @param proc the related process
0491:             * @param propsNode the parent node
0492:             * @throws RemoteException
0493:             *         Error accessing the workflow engine
0494:             * @throws SOAPException
0495:             *         Error creating the message
0496:             * @throws SAXException 
0497:             * @throws TransformerException 
0498:             */
0499:            private void appendContextData(SOAPMessage respMsg, Process proc,
0500:                    SOAPBodyElement propsNode) throws RemoteException,
0501:                    SOAPException {
0502:                SOAPElement contextData = propsNode.addChildElement(
0503:                        "ContextData", Consts.ASAP_PREFIX);
0504:
0505:                contextData.addNamespaceDeclaration(Consts.CD_PREFIX,
0506:                        getResourceReference().getNamespace());
0507:
0508:                ProcessData context = proc.processContext();
0509:
0510:                Iterator iterator = context.keySet().iterator();
0511:                while (iterator.hasNext()) {
0512:                    String name = (String) iterator.next();
0513:                    Object value = context.get(name);
0514:                    SOAPElement dataNode = contextData.addChildElement(name,
0515:                            Consts.CD_PREFIX);
0516:                    maybeAddObjectAsTextNode(respMsg, value, dataNode);
0517:                }
0518:            }
0519:
0520:            /**
0521:             * Appends the result data to the given node in a properties request. 
0522:             * @param respMsg the message to send
0523:             * @param proc the related process
0524:             * @param propsNode the parent node
0525:             * @throws RemoteException
0526:             *         Error accessing the workflow engine
0527:             * @throws SOAPException
0528:             *         Error creating the message
0529:             * @throws ResultNotAvailableException 
0530:             * @throws SAXException 
0531:             * @throws TransformerException 
0532:             */
0533:            private void appendResultData(SOAPMessage respMsg, Process proc,
0534:                    SOAPBodyElement propsNode) throws RemoteException,
0535:                    SOAPException, ResultNotAvailableException {
0536:                SOAPElement resultData = propsNode.addChildElement(
0537:                        "ResultData", Consts.ASAP_PREFIX);
0538:
0539:                ProcessDefinition procdef = proc.processDefinition();
0540:                ProcessDataInfo resultSignature = procdef.resultSignature();
0541:
0542:                resultData.addNamespaceDeclaration(Consts.RS_PREFIX,
0543:                        getResourceReference().getNamespace());
0544:
0545:                ProcessData result;
0546:                result = proc.result();
0547:
0548:                Iterator iterator = resultSignature.keySet().iterator();
0549:                while (iterator.hasNext()) {
0550:                    String name = (String) iterator.next();
0551:                    Object value = result.get(name);
0552:                    SOAPElement dataNode = resultData.addChildElement(name,
0553:                            Consts.RS_PREFIX);
0554:                    maybeAddObjectAsTextNode(respMsg, value, dataNode);
0555:                }
0556:            }
0557:
0558:            /**
0559:             * Adds the given <code>value</code> as a text node (XSD conform), if it
0560:             * not <code>null</code>. 
0561:             * @param message the current message.
0562:             * @param value the object to add.
0563:             * @param parent the parent node.
0564:             * @throws SOAPException
0565:             * @throws TransformerException
0566:             * @throws SAXException
0567:             */
0568:            private void maybeAddObjectAsTextNode(SOAPMessage message,
0569:                    Object value, SOAPElement parent) throws SOAPException {
0570:                if (value == null) {
0571:                    return;
0572:                }
0573:
0574:                if (value instanceof  org.w3c.dom.Element) {
0575:                    importW3CNodeAsChild(parent, (org.w3c.dom.Element) value);
0576:                } else if (value instanceof  SAXEventBuffer) {
0577:                    importSAXAsChild(message, parent, (SAXEventBuffer) value);
0578:                } else {
0579:                    String text;
0580:                    if (value instanceof  Date) {
0581:                        text = XMLUtil.toXsdGMTDateTime((Date) value);
0582:                    } else {
0583:                        text = value.toString();
0584:                    }
0585:                    parent.addTextNode(text);
0586:                }
0587:            }
0588:
0589:            /**
0590:             * Sets properties of the process.
0591:             * @param action the action element.
0592:             * @param reqMsg the request message.
0593:             * @param respMsg the response message
0594:             * @throws SOAPException
0595:             *         error evaluating the request or constructing the response.
0596:             * @throws RemoteException
0597:             *         error accessing the workflow engine.
0598:             */
0599:            private void setInstanceProperties(SOAPElement action,
0600:                    SOAPMessage reqMsg, SOAPMessage respMsg)
0601:                    throws SOAPException, RemoteException {
0602:                if (logger.isDebugEnabled()) {
0603:                    logger.debug("set instance properties...");
0604:                }
0605:
0606:                String receiverKey = getHeaderValue(reqMsg, Consts.RECEIVER_KEY);
0607:
0608:                Process proc = null;
0609:                try {
0610:                    proc = (Process) getProcess(receiverKey);
0611:                } catch (InvalidKeyException e) {
0612:                    FaultUtils.setFault(respMsg,
0613:                            ASAPException.ASAP_INVALID_INSTANCE_KEY, e
0614:                                    .getMessage());
0615:
0616:                    return;
0617:                } catch (NoSuchElementException e) {
0618:                    FaultUtils.setFault(respMsg,
0619:                            ASAPException.ASAP_INVALID_INSTANCE_KEY, e
0620:                                    .getMessage());
0621:
0622:                    return;
0623:                }
0624:
0625:                String description = getChildsTextContent(action, "Description");
0626:                if (description != null) {
0627:                    proc.setDescription(description);
0628:                }
0629:
0630:                SOAPElement data = findChildNode(action, "Data");
0631:                if (data != null) {
0632:                    ProcessDefinition procdef = proc.processDefinition();
0633:                    ProcessData procData;
0634:                    try {
0635:                        procData = getProcessData(procdef, data);
0636:                        proc.setProcessContext(procData);
0637:                    } catch (ParseException e) {
0638:                        FaultUtils.setFault(respMsg,
0639:                                ASAPException.ASAP_INVALID_INSTANCE_KEY, e
0640:                                        .getMessage());
0641:
0642:                        return;
0643:                    } catch (InvalidDataException e) {
0644:                        FaultUtils.setFault(respMsg,
0645:                                ASAPException.ASAP_INVALID_INSTANCE_KEY, e
0646:                                        .getMessage());
0647:
0648:                        return;
0649:                    } catch (UpdateNotAllowedException e) {
0650:                        FaultUtils.setFault(respMsg,
0651:                                ASAPException.ASAP_INVALID_INSTANCE_KEY, e
0652:                                        .getMessage());
0653:
0654:                        return;
0655:                    }
0656:                }
0657:
0658:                SOAPBodyElement propsNode = createAsapResponseNode(respMsg,
0659:                        Consts.SET_PROPERTIES_RESPONSE);
0660:
0661:                try {
0662:                    appendInstanceProperties(respMsg, receiverKey, proc,
0663:                            propsNode);
0664:                } catch (ResultNotAvailableException e) {
0665:                    FaultUtils.setFault(respMsg, e);
0666:
0667:                    return;
0668:                }
0669:            }
0670:
0671:            /**
0672:             * Extracts the process data from the given context data.
0673:             * @param contextData the context data.
0674:             * @return process data to set in the the process.
0675:             * @throws RemoteException 
0676:             * @throws SOAPException 
0677:             * @throws ParseException 
0678:             */
0679:            private ProcessData getProcessData(ProcessDefinition procdef,
0680:                    SOAPElement contextData) throws RemoteException,
0681:                    SOAPException, ParseException {
0682:                ProcessDataInfo info = procdef.contextSignature();
0683:                ProcessData procData = new DefaultProcessData();
0684:
0685:                for (Iterator pdi = contextData.getChildElements(); pdi
0686:                        .hasNext();) {
0687:                    SOAPElement current = (SOAPElement) pdi.next();
0688:                    String pdname = current.getLocalName();
0689:                    Object type = info.get(pdname);
0690:                    if (type == null) {
0691:                        throw new SOAPException(
0692:                                "process does not contain a variable "
0693:                                        + "with name " + pdname);
0694:                    }
0695:                    String pdvalue = XMLUtil.getFirstLevelTextContent(current);
0696:
0697:                    Object value;
0698:
0699:                    if (type.equals(String.class)) {
0700:                        value = pdvalue;
0701:                    } else if (type.equals(Long.class)) {
0702:                        value = new Long(pdvalue);
0703:                    } else if (type.equals(Double.class)) {
0704:                        value = new Double(XMLUtil.parseXsdDouble(pdvalue));
0705:                    } else if (type.equals(Boolean.class)) {
0706:                        value = new Boolean(XMLUtil.parseXsdBoolean(pdvalue));
0707:                    } else if (type.equals(Date.class)) {
0708:                        value = XMLUtil.parseXsdDateTime(pdvalue);
0709:                    } else if (type.equals(org.w3c.dom.Element.class)) {
0710:                        // TODO: Check other values for schema types.
0711:                        value = current.getFirstChild();
0712:                    } else {
0713:                        // cannot resolve the type. leave it as a string and pray.
0714:                        value = pdvalue;
0715:                    }
0716:
0717:                    procData.put(pdname, value);
0718:                }
0719:
0720:                return procData;
0721:            }
0722:
0723:            /**
0724:             * Subscribes to a process instance.
0725:             * @param instanceref the resource reference of the instance
0726:             * @param action the action element.
0727:             * @param reqMsg the request message.
0728:             * @param respMsg the response message
0729:             * @throws SOAPException
0730:             *         error evaluating the request or constructing the response.
0731:             * @throws RemoteException
0732:             *         error accessing the workflow engine.
0733:             */
0734:            private void subscribe(SOAPElement action, SOAPMessage reqMsg,
0735:                    SOAPMessage respMsg) throws SOAPException, RemoteException {
0736:                String receiverKey = getHeaderValue(reqMsg, Consts.RECEIVER_KEY);
0737:
0738:                Process proc = null;
0739:                try {
0740:                    proc = (Process) getProcess(receiverKey);
0741:                } catch (InvalidKeyException e) {
0742:                    FaultUtils.setFault(respMsg,
0743:                            ASAPException.ASAP_INVALID_INSTANCE_KEY, e
0744:                                    .getMessage());
0745:
0746:                    return;
0747:                } catch (NoSuchElementException e) {
0748:                    FaultUtils.setFault(respMsg,
0749:                            ASAPException.ASAP_INVALID_INSTANCE_KEY, e
0750:                                    .getMessage());
0751:
0752:                    return;
0753:                }
0754:
0755:                String observer = getChildsTextContent(action, "ObserverKey");
0756:                if (observer == null) {
0757:                    FaultUtils.setFault(respMsg,
0758:                            ASAPException.ASAP_ELEMENT_MISSING,
0759:                            "Missing observer key!");
0760:                    return;
0761:                }
0762:
0763:                ProcessDefinition procdef = proc.processDefinition();
0764:                try {
0765:                    ObserverRegistry obs = getObserverRegistry();
0766:                    obs.subscribe(observer, procdef.packageId(), procdef
0767:                            .processId(), proc.key(), getResourceReference()
0768:                            .getBaseUrl());
0769:                } catch (SQLException e) {
0770:                    FaultUtils.setFault(respMsg, e);
0771:
0772:                    return;
0773:                }
0774:
0775:                createAsapResponseNode(respMsg, Consts.SUBSCRIBE_RESPONSE);
0776:            }
0777:
0778:            /**
0779:             * Unsubscribes from a process instance.
0780:             * @param action the action element.
0781:             * @param reqMsg the request message.
0782:             * @param respMsg the response message
0783:             * @throws SOAPException
0784:             *         error evaluating the request or constructing the response.
0785:             * @throws RemoteException
0786:             *         error accessing the workflow engine.
0787:             */
0788:            private void unsubscribe(SOAPElement action, SOAPMessage reqMsg,
0789:                    SOAPMessage respMsg) throws SOAPException, RemoteException {
0790:                String receiverKey = getHeaderValue(reqMsg, Consts.RECEIVER_KEY);
0791:
0792:                Process proc = null;
0793:                try {
0794:                    proc = (Process) getProcess(receiverKey);
0795:                } catch (InvalidKeyException e) {
0796:                    FaultUtils.setFault(respMsg,
0797:                            ASAPException.ASAP_INVALID_INSTANCE_KEY, e
0798:                                    .getMessage());
0799:
0800:                    return;
0801:                } catch (NoSuchElementException e) {
0802:                    FaultUtils.setFault(respMsg,
0803:                            ASAPException.ASAP_INVALID_INSTANCE_KEY, e
0804:                                    .getMessage());
0805:
0806:                    return;
0807:                }
0808:
0809:                String observer = getChildsTextContent(action, "ObserverKey");
0810:                if (observer == null) {
0811:                    FaultUtils.setFault(respMsg,
0812:                            ASAPException.ASAP_ELEMENT_MISSING,
0813:                            "Missing observer key!");
0814:
0815:                    return;
0816:                }
0817:
0818:                ProcessDefinition procdef = proc.processDefinition();
0819:                try {
0820:                    ObserverRegistry obs = getObserverRegistry();
0821:                    obs.unsubscribe(observer, procdef.packageId(), procdef
0822:                            .processId(), proc.key());
0823:                } catch (SQLException e) {
0824:                    FaultUtils.setFault(respMsg, e);
0825:
0826:                    return;
0827:                }
0828:
0829:                createAsapResponseNode(respMsg, Consts.UNSUBSCRIBE_RESPONSE);
0830:            }
0831:
0832:            /**
0833:             * Returns a list of currently active activities.
0834:             * @param reqMsg the request message.
0835:             * @param respMsg the response message
0836:             * @throws SOAPException
0837:             *         error evaluating the request or constructing the response.
0838:             * @throws RemoteException
0839:             *         error accessing the workflow engine.
0840:             */
0841:            private void listActivities(SOAPMessage reqMsg, SOAPMessage respMsg)
0842:                    throws SOAPException, RemoteException {
0843:                String receiverKey = getHeaderValue(reqMsg, Consts.RECEIVER_KEY);
0844:
0845:                WfProcess proc = null;
0846:                try {
0847:                    proc = getProcess(receiverKey);
0848:                } catch (InvalidKeyException e) {
0849:                    FaultUtils.setFault(respMsg,
0850:                            ASAPException.ASAP_INVALID_INSTANCE_KEY, e
0851:                                    .getMessage());
0852:
0853:                    return;
0854:                } catch (NoSuchElementException e) {
0855:                    FaultUtils.setFault(respMsg,
0856:                            ASAPException.ASAP_INVALID_INSTANCE_KEY, e
0857:                                    .getMessage());
0858:
0859:                    return;
0860:                }
0861:
0862:                Collection activities;
0863:                try {
0864:                    activities = proc.activitiesInState("open.running");
0865:                } catch (InvalidStateException e) {
0866:                    FaultUtils
0867:                            .setFault(respMsg,
0868:                                    ASAPException.ASAP_OPERATION_FAILED, e
0869:                                            .getMessage());
0870:
0871:                    return;
0872:                }
0873:
0874:                SOAPBodyElement activitiesNode = createWfxmlResponseNode(
0875:                        respMsg, Consts.LIST_ACTIVITIES_RESPONSE);
0876:                activitiesNode.addNamespaceDeclaration(Consts.ASAP_PREFIX,
0877:                        Consts.ASAP_NS);
0878:
0879:                Iterator iterator = activities.iterator();
0880:                while (iterator.hasNext()) {
0881:                    Activity activity = (Activity) iterator.next();
0882:                    SOAPElement activityNode = activitiesNode.addChildElement(
0883:                            "ActivityInfo", Consts.WFXML_PREFIX);
0884:                    SOAPElement activityKey = activityNode.addChildElement(
0885:                            "ActivityKey", Consts.WFXML_PREFIX);
0886:                    ResourceReference actResRef = new ResourceReference(
0887:                            getResourceReference().getBaseUrl(), activity);
0888:                    activityKey.addTextNode(actResRef.getResourceKey());
0889:                    SOAPElement name = activityNode.addChildElement("Name",
0890:                            Consts.ASAP_PREFIX);
0891:                    String val = activity.name();
0892:                    maybeAddTextNode(name, val);
0893:                    SOAPElement description = activityNode.addChildElement(
0894:                            "Description", Consts.ASAP_PREFIX);
0895:                    val = activity.description();
0896:                    maybeAddTextNode(description, val);
0897:                    Collection assignments = activity.assignments();
0898:                    Iterator assignmentIterator = assignments.iterator();
0899:                    while (assignmentIterator.hasNext()) {
0900:                        Assignment assignment = (Assignment) iterator.next();
0901:                        WfResource resource = assignment.assignee();
0902:                        SOAPElement assignee = activityNode.addChildElement(
0903:                                "Assignee", Consts.WFXML_PREFIX);
0904:                        val = resource.resourceName();
0905:                        if (val == null) {
0906:                            assignee.addTextNode(resource.resourceKey());
0907:                        } else {
0908:                            assignee.addTextNode(val);
0909:                        }
0910:                    }
0911:                }
0912:            }
0913:
0914:            /**
0915:             * Changes the state of this process.
0916:             * @param action the element containing the request.
0917:             * @param reqMsg the request message.
0918:             * @param respMsg the response message
0919:             * @throws SOAPException
0920:             *         error evaluating the request or constructing the response.
0921:             * @throws RemoteException
0922:             *         error accessing the workflow engine.
0923:             */
0924:            private void changeState(SOAPElement action, SOAPMessage reqMsg,
0925:                    SOAPMessage respMsg) throws SOAPException, RemoteException {
0926:                String receiverKey = getHeaderValue(reqMsg, Consts.RECEIVER_KEY);
0927:
0928:                WfProcess proc = null;
0929:                try {
0930:                    proc = getProcess(receiverKey);
0931:                } catch (InvalidKeyException e) {
0932:                    FaultUtils.setFault(respMsg,
0933:                            ASAPException.ASAP_INVALID_INSTANCE_KEY, e
0934:                                    .getMessage());
0935:
0936:                    return;
0937:                } catch (NoSuchElementException e) {
0938:                    FaultUtils.setFault(respMsg,
0939:                            ASAPException.ASAP_INVALID_INSTANCE_KEY, e
0940:                                    .getMessage());
0941:
0942:                    return;
0943:                }
0944:
0945:                String requestedAsapState = getChildsTextContent(action,
0946:                        "State");
0947:                String newAsapState;
0948:                try {
0949:                    if (logger.isDebugEnabled()) {
0950:                        logger.debug("changing state of " + proc.name() + "/"
0951:                                + proc.key() + " to '" + requestedAsapState
0952:                                + "'...");
0953:                    }
0954:
0955:                    String requestedOmgState = StateMapper
0956:                            .asap2omgState(requestedAsapState);
0957:
0958:                    proc.changeState(requestedOmgState);
0959:
0960:                    String newOmgState = proc.state();
0961:                    newAsapState = StateMapper.omg2asapState(newOmgState);
0962:                } catch (InvalidStateException e) {
0963:                    FaultUtils.setFault(respMsg,
0964:                            ASAPException.ASAP_INVALID_CONTEXT_DATA, e
0965:                                    .getMessage());
0966:                    return;
0967:                } catch (TransitionNotAllowedException e) {
0968:                    FaultUtils.setFault(respMsg,
0969:                            ASAPException.ASAP_INVALID_STATE_TRANSITION, e
0970:                                    .getMessage());
0971:                    return;
0972:                }
0973:
0974:                SOAPBodyElement stateNode = createAsapResponseNode(respMsg,
0975:                        Consts.CHANGE_STATE_RESPONSE);
0976:                stateNode.addNamespaceDeclaration(Consts.ASAP_PREFIX,
0977:                        Consts.ASAP_NS);
0978:
0979:                SOAPElement newStateElement = stateNode.addChildElement(
0980:                        "State", Consts.ASAP_PREFIX);
0981:                newStateElement.addTextNode(newAsapState);
0982:
0983:                if (logger.isDebugEnabled()) {
0984:                    logger.debug("changed state of " + proc.name() + "/"
0985:                            + proc.key() + " from " + requestedAsapState
0986:                            + " to " + newAsapState);
0987:                }
0988:            }
0989:
0990:            /**
0991:             * Terminates the process instance.
0992:             * 
0993:             * <p>
0994:             * The specification is inconsistent at this point. The WfXML 20 
0995:             * specification redirects to the ASAP specification where terminate should
0996:             * be defined. This specification in the ASAP documentation is missing
0997:             * (in the xsd as well). So we leave it unimplemented at this point.
0998:             * If the implementation is more clear, this is the point where the 
0999:             * implementation must go. 
1000:             * </p>
1001:             * 
1002:             * @param reqMsg the request message.
1003:             * @param respMsg the response message
1004:             * @throws SOAPException
1005:             *         error evaluating the request or constructing the response.
1006:             * @throws RemoteException
1007:             *         error accessing the workflow engine.
1008:             */
1009:            private void terminate(SOAPMessage reqMsg, SOAPMessage respMsg)
1010:                    throws SOAPException, RemoteException {
1011:                FaultUtils
1012:                        .setFault(
1013:                                respMsg,
1014:                                ASAPException.ASAP_OPERATION_FAILED,
1015:                                Consts.TERMINATE_REQUEST
1016:                                        + " is not implemented due to a missing specification!");
1017:            }
1018:
1019:            /**
1020:             * Gets the process manager that that can handle the package id, the
1021:             * process id, and the process key that are encoded in the given uri.
1022:             * @param uri the uri with package id, process id and process key.
1023:             * @return process.
1024:             * @throws RemoteException
1025:             *         error accessing the workflow engine
1026:             * @throws InvalidKeyException
1027:             *         process manager or process does not exist
1028:             */
1029:            private WfProcess getProcess(String uri) throws RemoteException,
1030:                    InvalidKeyException {
1031:                String packageId = getResourceReference().getPackageId();
1032:                String processId = getResourceReference().getProcessId();
1033:                String processKey = getResourceReference().getProcessKey();
1034:
1035:                if (logger.isDebugEnabled()) {
1036:                    logger.debug("finding process definition'" + packageId
1037:                            + "/" + processId + "/" + processKey + "'...");
1038:                }
1039:
1040:                ProcessDirectory pd = getWorkflowService().processDirectory();
1041:
1042:                WfProcess proc = pd.lookupProcess(packageId + "/" + processId,
1043:                        processKey);
1044:
1045:                return proc;
1046:            }
1047:
1048:            /**
1049:             * Creates a state changed notification message for the given observer.
1050:             * @param observer the observer
1051:             * @param newState the new state of the process
1052:             * @param oldState  the old state of the process
1053:             * @return notification message.
1054:             * @throws SOAPException
1055:             *         error creating the message.
1056:             */
1057:            public SOAPMessage createStateChangedMessage(String observer,
1058:                    String newState, String oldState) throws SOAPException {
1059:                MessageFactory messageFactory = MessageFactory.newInstance();
1060:                SOAPMessage message = messageFactory.createMessage();
1061:
1062:                SOAPEnvelope env = message.getSOAPPart().getEnvelope();
1063:                SOAPHeader header = env.getHeader();
1064:                SOAPHeaderElement req = header.addHeaderElement(env.createName(
1065:                        "Request", "as", Consts.ASAP_NS));
1066:                SOAPElement receiverkey = req.addChildElement("ReceiverKey",
1067:                        Consts.ASAP_PREFIX);
1068:                receiverkey.addTextNode(observer);
1069:                SOAPElement senderkey = req.addChildElement("SenderKey",
1070:                        Consts.ASAP_PREFIX);
1071:                senderkey.addTextNode(getResourceReference().getResourceKey());
1072:                SOAPElement responseRequired = req.addChildElement(
1073:                        "ResponseRequired", Consts.ASAP_PREFIX);
1074:                responseRequired.addTextNode("No");
1075:
1076:                SOAPBody body = env.getBody();
1077:                Name respName = env.createName(Consts.STATE_CHANGE_REQUEST,
1078:                        Consts.ASAP_PREFIX, Consts.ASAP_NS);
1079:
1080:                SOAPBodyElement action = body.addBodyElement(respName);
1081:                SOAPElement newStateNode = action.addChildElement("State",
1082:                        Consts.ASAP_PREFIX);
1083:                newStateNode.addTextNode(newState);
1084:                SOAPElement oldStateNode = action.addChildElement(
1085:                        "PreviousState", Consts.ASAP_PREFIX);
1086:                oldStateNode.addTextNode(oldState);
1087:
1088:                return message;
1089:            }
1090:
1091:            /**
1092:             * Creates a completed notification message for a given observer.
1093:             * @param observer the observer
1094:             * @return notification message.
1095:             * @throws SOAPException
1096:             *         error creating the message.
1097:             * @throws SAXException 
1098:             * @throws TransformerException 
1099:             * @throws ResultNotAvailableException 
1100:             * @throws RemoteException 
1101:             */
1102:            public SOAPMessage createCompletedMessage(String observer,
1103:                    ProcessData result) throws SOAPException, RemoteException {
1104:                MessageFactory messageFactory = MessageFactory.newInstance();
1105:                SOAPMessage message = messageFactory.createMessage();
1106:
1107:                SOAPEnvelope env = message.getSOAPPart().getEnvelope();
1108:                SOAPHeader header = env.getHeader();
1109:                SOAPHeaderElement req = header.addHeaderElement(env.createName(
1110:                        "Request", "as", Consts.ASAP_NS));
1111:                SOAPElement receiverKey = req.addChildElement("ReceiverKey",
1112:                        Consts.ASAP_PREFIX);
1113:                receiverKey.addTextNode(observer);
1114:                SOAPElement senderKey = req.addChildElement("SenderKey",
1115:                        Consts.ASAP_PREFIX);
1116:                senderKey.addTextNode(getResourceReference().getResourceKey());
1117:                SOAPElement responseRequired = req.addChildElement(
1118:                        "ResponseRequired", Consts.ASAP_PREFIX);
1119:                responseRequired.addTextNode("No");
1120:
1121:                SOAPBody body = env.getBody();
1122:                Name respName = env.createName(Consts.COMPLETED_REQUEST,
1123:                        Consts.ASAP_PREFIX, Consts.ASAP_NS);
1124:
1125:                SOAPBodyElement action = body.addBodyElement(respName);
1126:                appendResultData(message, result, action);
1127:
1128:                return message;
1129:            }
1130:
1131:            /**
1132:             * Appends the result data to the given node in a properties request. 
1133:             * @param respMsg the message to send
1134:             * @param result result of the process.
1135:             * @param parent the parent node
1136:             * @throws RemoteException
1137:             *         Error accessing the workflow engine
1138:             * @throws SOAPException
1139:             *         Error creating the message
1140:             * @throws ResultNotAvailableException 
1141:             * @throws SAXException 
1142:             * @throws TransformerException 
1143:             */
1144:            private void appendResultData(SOAPMessage respMsg,
1145:                    ProcessData result, SOAPBodyElement parent)
1146:                    throws RemoteException, SOAPException {
1147:                SOAPElement resultData = parent.addChildElement("ResultData",
1148:                        Consts.ASAP_PREFIX);
1149:
1150:                if (result == null) {
1151:                    return;
1152:                }
1153:
1154:                Iterator iterator = result.keySet().iterator();
1155:                while (iterator.hasNext()) {
1156:                    String name = (String) iterator.next();
1157:                    Object value = result.get(name);
1158:                    SOAPElement dataNode = resultData.addChildElement(name,
1159:                            Consts.RS_PREFIX);
1160:                    maybeAddObjectAsTextNode(respMsg, value, dataNode);
1161:                }
1162:            }
1163:
1164:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.