Source Code Cross Referenced for Servlet.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 WfXML servlet.
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: Servlet.java,v 1.25 2007/07/15 22:01:11 mlipp Exp $
0021:         *
0022:         * $Log: Servlet.java,v $
0023:         * Revision 1.25  2007/07/15 22:01:11  mlipp
0024:         * Fixed thread not running problem.
0025:         *
0026:         * Revision 1.24  2007/04/03 14:47:54  schnelle
0027:         * Some code cleanup.
0028:         *
0029:         * Revision 1.23  2007/03/29 11:46:54  schnelle
0030:         * Reactivated ASAPException to propagate ASAP error messages in cases of an invalid key, a missing resource or an invalid factory.
0031:         *
0032:         * Revision 1.22  2007/03/27 21:59:42  mlipp
0033:         * Fixed lots of checkstyle warnings.
0034:         *
0035:         * Revision 1.21  2007/03/01 12:32:57  schnelle
0036:         * Enhanced Instance.SetProperties to process ContextData.
0037:         *
0038:         * Revision 1.20  2007/02/21 21:32:29  mlipp
0039:         * Using pooled JMS connections when in EJB now.
0040:         *
0041:         * Revision 1.19  2007/02/17 21:19:48  mlipp
0042:         * Workflow service caching redone.
0043:         *
0044:         * Revision 1.18  2007/02/06 08:35:34  schnelle
0045:         * Started automatic generation of wsdl description.
0046:         *
0047:         * Revision 1.17  2007/02/01 10:08:36  drmlipp
0048:         * Removed no longer used observer resource.
0049:         *
0050:         * Revision 1.16  2007/01/31 22:55:36  mlipp
0051:         * Some more refactoring and fixes of problems introduced by refactoring.
0052:         *
0053:         * Revision 1.15  2007/01/31 14:53:06  schnelle
0054:         * Small corrections wvaluating the resource reference.
0055:         *
0056:         * Revision 1.14  2007/01/31 12:24:06  drmlipp
0057:         * Design revisited.
0058:         *
0059:         * Revision 1.13  2007/01/30 11:56:14  drmlipp
0060:         * Merged Wf-XML branch.
0061:         *
0062:         * Revision 1.12.6.24  2007/01/29 15:04:19  schnelle
0063:         * Renaming of Observer to ObserverRegistry and URIDecoder to ResourceReference.
0064:         *
0065:         * Revision 1.12.6.23  2007/01/29 13:40:31  schnelle
0066:         * Storing of the sender base in the servlet context.
0067:         *
0068:         * Revision 1.12.6.22  2007/01/29 10:48:28  schnelle
0069:         * Using a key-value encoding of the parameters instead of the directory approach.
0070:         *
0071:         * Revision 1.12.6.21  2007/01/26 15:50:28  schnelle
0072:         * Added encoding for process id and package id.
0073:         *
0074:         * Revision 1.12.6.20  2007/01/24 14:22:38  schnelle
0075:         * Observer handler starts on servlet startup.
0076:         *
0077:         * Revision 1.12.6.19  2007/01/24 10:56:50  schnelle
0078:         * Prepared return of a result for aobservers.
0079:         *
0080:         * Revision 1.12.6.18  2007/01/19 12:34:56  schnelle
0081:         * Moved generation and decoding of the URI that is used as the receiver key to new class URIDecoder.
0082:         *
0083:         * Revision 1.12.6.17  2007/01/19 07:59:35  schnelle
0084:         * Corrected return value for factory list instances.
0085:         *
0086:         * Revision 1.12.6.16  2007/01/16 11:05:42  schnelle
0087:         * Refactoring: Moved subscription handling methods to own class.
0088:         *
0089:         * Revision 1.12.6.15  2007/01/11 10:23:52  schnelle
0090:         * Creation of StateChanged notifications.
0091:         *
0092:         * Revision 1.12.6.14  2007/01/10 13:41:27  schnelle
0093:         * Implemented subscribe.
0094:         *
0095:         * Revision 1.12.6.13  2007/01/09 12:06:14  schnelle
0096:         * Implemented methods to receive xsd and wsdl files.
0097:         *
0098:         * Revision 1.12.6.12  2006/12/20 13:32:24  schnelle
0099:         * Basic implementato of GetProperties for Instance and Activity.
0100:         *
0101:         * Revision 1.12.6.11  2006/12/18 14:41:02  schnelle
0102:         * Preparatation for individual schema definition for each getproperties request.
0103:         *
0104:         * Revision 1.12.6.10  2006/12/13 11:23:48  schnelle
0105:         * Implemented instance ListActivities.
0106:         *
0107:         * Revision 1.12.6.9  2006/12/12 13:24:38  schnelle
0108:         * Introduction of ASAPException to provide a detailed mesage.
0109:         *
0110:         * Revision 1.12.6.8  2006/12/12 09:34:35  schnelle
0111:         * Implemented ChangeState for Instance.
0112:         *
0113:         * Revision 1.12.6.7  2006/12/11 11:05:34  schnelle
0114:         * Added template methods for all requests.
0115:         *
0116:         * Revision 1.12.6.6  2006/12/01 12:49:54  schnelle
0117:         * Basic import of context data for process creation.
0118:         *
0119:         * Revision 1.12.6.5  2006/11/29 14:12:37  schnelle
0120:         * Take respect to namespaces of asap requests and responses.
0121:         *
0122:         * Revision 1.12.6.4  2006/11/28 15:31:51  schnelle
0123:         * Proper selection of the response generator.
0124:         *
0125:         * Revision 1.12.6.3  2006/11/28 12:20:09  schnelle
0126:         * Creation of a separate class to handle the issues for a specific resource.
0127:         *
0128:         * Revision 1.12.6.2  2006/11/27 15:41:55  schnelle
0129:         * Introducing some constants for request and response identification.
0130:         *
0131:         * Revision 1.12.6.1  2006/11/24 12:19:13  schnelle
0132:         * Separtion of response generation into ResponseGenerator class.
0133:         *
0134:         * Revision 1.12  2006/09/29 12:32:11  drmlipp
0135:         * Consistently using WfMOpen as projct name now.
0136:         *
0137:         * Revision 1.11  2005/11/17 21:30:25  mlipp
0138:         * Finished re-organization of jetspeed module creation.
0139:         *
0140:         * Revision 1.10  2005/06/18 19:43:12  mlipp
0141:         * Improved.
0142:         *
0143:         * Revision 1.9  2005/06/01 20:46:16  mlipp
0144:         * Started getProperties.
0145:         *
0146:         * Revision 1.8  2005/04/24 18:55:34  mlipp
0147:         * Fixed bug with scalar result.
0148:         *
0149:         * Revision 1.7  2005/04/11 20:22:18  mlipp
0150:         * Implemented enabled process definition list.
0151:         *
0152:         * Revision 1.6  2005/04/10 20:59:30  mlipp
0153:         * Improved exception handling.
0154:         *
0155:         * Revision 1.5  2005/04/10 19:53:54  mlipp
0156:         * Valid response and JaWE workaround.
0157:         *
0158:         * Revision 1.4  2005/04/06 21:08:05  mlipp
0159:         * Getting on...
0160:         *
0161:         * Revision 1.3  2005/04/06 20:03:26  mlipp
0162:         * Generating web.xml now.
0163:         *
0164:         * Revision 1.2  2005/01/24 20:25:56  mlipp
0165:         * Reverted saaj back to 1.1 to fit Axis version.
0166:         *
0167:         * Revision 1.1  2005/01/23 15:23:11  mlipp
0168:         * Getting started with WfXML.
0169:         *
0170:         */
0171:        package de.danet.an.workflow.clients.wfxml;
0172:
0173:        import java.io.File;
0174:        import java.io.FileInputStream;
0175:        import java.io.FileNotFoundException;
0176:        import java.io.IOException;
0177:        import java.io.OutputStream;
0178:        import java.rmi.RemoteException;
0179:        import java.util.Enumeration;
0180:        import java.util.Iterator;
0181:        import java.util.List;
0182:        import java.util.Map;
0183:        import java.util.StringTokenizer;
0184:
0185:        import javax.naming.NamingException;
0186:        import javax.naming.directory.InvalidSearchFilterException;
0187:        import javax.security.auth.callback.Callback;
0188:        import javax.security.auth.callback.CallbackHandler;
0189:        import javax.security.auth.callback.NameCallback;
0190:        import javax.security.auth.callback.PasswordCallback;
0191:        import javax.security.auth.callback.TextOutputCallback;
0192:        import javax.security.auth.callback.UnsupportedCallbackException;
0193:        import javax.security.auth.login.LoginContext;
0194:        import javax.security.auth.login.LoginException;
0195:        import javax.servlet.ServletConfig;
0196:        import javax.servlet.ServletContext;
0197:        import javax.servlet.ServletException;
0198:        import javax.servlet.ServletOutputStream;
0199:        import javax.servlet.http.HttpServlet;
0200:        import javax.servlet.http.HttpServletRequest;
0201:        import javax.servlet.http.HttpServletResponse;
0202:        import javax.servlet.http.HttpSession;
0203:        import javax.wsdl.Binding;
0204:        import javax.wsdl.Definition;
0205:        import javax.wsdl.Import;
0206:        import javax.wsdl.Port;
0207:        import javax.wsdl.Service;
0208:        import javax.wsdl.Types;
0209:        import javax.wsdl.WSDLException;
0210:        import javax.wsdl.extensions.schema.Schema;
0211:        import javax.wsdl.extensions.schema.SchemaImport;
0212:        import javax.wsdl.extensions.soap.SOAPAddress;
0213:        import javax.wsdl.factory.WSDLFactory;
0214:        import javax.wsdl.xml.WSDLReader;
0215:        import javax.wsdl.xml.WSDLWriter;
0216:        import javax.xml.namespace.QName;
0217:        import javax.xml.soap.MessageFactory;
0218:        import javax.xml.soap.MimeHeaders;
0219:        import javax.xml.soap.Name;
0220:        import javax.xml.soap.Node;
0221:        import javax.xml.soap.SOAPElement;
0222:        import javax.xml.soap.SOAPException;
0223:        import javax.xml.soap.SOAPFault;
0224:        import javax.xml.soap.SOAPHeader;
0225:        import javax.xml.soap.SOAPHeaderElement;
0226:        import javax.xml.soap.SOAPMessage;
0227:        import javax.xml.transform.Transformer;
0228:        import javax.xml.transform.TransformerConfigurationException;
0229:        import javax.xml.transform.TransformerException;
0230:        import javax.xml.transform.TransformerFactory;
0231:        import javax.xml.transform.dom.DOMSource;
0232:        import javax.xml.transform.stream.StreamResult;
0233:
0234:        import com.ibm.wsdl.extensions.soap.SOAPAddressImpl;
0235:        import com.ibm.wsdl.factory.WSDLFactoryImpl;
0236:
0237:        import de.danet.an.util.XMLUtil;
0238:        import de.danet.an.workflow.api.EventSubscriber;
0239:        import de.danet.an.workflow.api.FactoryConfigurationError;
0240:        import de.danet.an.workflow.api.WorkflowService;
0241:        import de.danet.an.workflow.api.WorkflowServiceFactory;
0242:        import de.danet.an.workflow.omgcore.WfAuditEvent;
0243:
0244:        /**
0245:         * This class provides an interface between the workflow engine (i.e. its
0246:         * processes and any HTTP based client (e.g. Web browser application).
0247:         * 
0248:         * <p>
0249:         * The servlet works as a mediator for services of the different roles, 
0250:         * excluding the observer, as they are defined by the Wf-XML 2.0 standard.
0251:         * </p>
0252:         * 
0253:         * @author Michael Lipp
0254:         * @author Dirk Schnelle
0255:         * @version $Revision: 1.25 $
0256:         * @web.servlet name="WfXML Servlet" display-name="WfXML Servlet"
0257:         *              description="WfXML interface servlet" load-on-startup="1"
0258:         * @web.servlet-mapping url-pattern="/*"
0259:         * @web.servlet-init-param name="SenderBase" value="@@@_WfXML_service_url_@@@"
0260:         * @web.servlet-init-param name="ApplicationPolicy" 
0261:         *                         value="@@@_WfXML_servlet_application_policy_@@@"
0262:         * @web.servlet-init-param name="UserName" 
0263:         *                         value="@@@_WfXML_servlet_username_@@@"
0264:         * @web.servlet-init-param name="Password" 
0265:         *                         value="@@@_WfXML_servlet_password_@@@"
0266:         * @web.resource-ref name="jdbc/WfEngine" type="javax.sql.DataSource"
0267:         *                   auth="Container"
0268:         * @jboss.resource-ref res-ref-name="jdbc/WfEngine" jndi-name="java:/WfMOpenDS"
0269:         */
0270:        public class Servlet extends HttpServlet {
0271:            /** Logger instance. */
0272:            private static final org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory
0273:                    .getLog(Servlet.class);
0274:
0275:            /** Attribute sender base in the servlet context. */
0276:            private static final String SENDER_BASE = "SenderBase";
0277:
0278:            /** Attribute observer registry in the servlet context. */
0279:            static final String OBSERVER_REGISTRY = "ObserverRegistry";
0280:
0281:            /** The servlet context. */
0282:            private ServletContext ctx = null;
0283:
0284:            /** Audit handler thread. */
0285:            private AuditHandlerThread auditHandlerThread = null;
0286:
0287:            /** Cache of the last workflow service lookup. */
0288:            private WorkflowService wfsCache = null;
0289:
0290:            /** Base URL that is used as a prefix in the sender key. */
0291:            private String senderBase;
0292:
0293:            /** The observer registry. */
0294:            private ObserverRegistry observerRegistry = null;
0295:
0296:            /** The event subscriber */
0297:            private EventSubscriber eventSubscriber = null;
0298:
0299:            /**
0300:             * Request workflow service.
0301:             */
0302:            private synchronized WorkflowService getWorkflowService() {
0303:                synchronized (this ) {
0304:                    if (wfsCache == null) {
0305:                        WorkflowServiceFactory factory = WorkflowServiceFactory
0306:                                .newInstance();
0307:                        wfsCache = factory.newWorkflowService();
0308:                    }
0309:                    return wfsCache;
0310:                }
0311:            }
0312:
0313:            /**
0314:             * Default initialization method.
0315:             * 
0316:             * @param servletConfig
0317:             *            a <code>ServletConfig</code> value
0318:             * @exception ServletException
0319:             *                if an error occurs
0320:             */
0321:            public void init(ServletConfig servletConfig)
0322:                    throws ServletException {
0323:                ctx = servletConfig.getServletContext();
0324:
0325:                try {
0326:                    observerRegistry = new ObserverRegistry();
0327:                    ctx.setAttribute(OBSERVER_REGISTRY, observerRegistry);
0328:                } catch (NamingException e) {
0329:                    throw new ServletException(e);
0330:                }
0331:
0332:                // Read configuration values and overwrite default, if set
0333:                if (servletConfig != null) {
0334:                    senderBase = servletConfig.getInitParameter(SENDER_BASE);
0335:                    String applicationPolicy = servletConfig
0336:                            .getInitParameter("ApplicationPolicy");
0337:                    String userName = servletConfig
0338:                            .getInitParameter("UserName");
0339:                    String password = servletConfig
0340:                            .getInitParameter("Password");
0341:                    // The workflow engine may not yet be available, when the servlet
0342:                    // is started. Repeat trying to subscribe until we are successful.
0343:                    auditHandlerThread = new AuditHandlerThread(
0344:                            applicationPolicy, userName, password);
0345:                    auditHandlerThread.start();
0346:                }
0347:            }
0348:
0349:            /*
0350:             * (non-Javadoc)
0351:             * 
0352:             * @see javax.servlet.GenericServlet#destroy()
0353:             */
0354:            public void destroy() {
0355:                if (auditHandlerThread != null) {
0356:                    auditHandlerThread.terminate();
0357:                    try {
0358:                        auditHandlerThread.join();
0359:                    } catch (InterruptedException e) {
0360:                        // deliberately ignored
0361:                    }
0362:                    auditHandlerThread = null;
0363:                }
0364:                if (eventSubscriber != null) {
0365:                    wfsCache.release(eventSubscriber);
0366:                    eventSubscriber = null;
0367:                }
0368:                if (wfsCache != null) {
0369:                    wfsCache.release(wfsCache);
0370:                    wfsCache = null;
0371:                }
0372:                super .destroy();
0373:            }
0374:
0375:            /**
0376:             * Retrieves the sender base.
0377:             * 
0378:             * <p>
0379:             * The sender base is derived from the request. The this value may be
0380:             * overridden via the <code>SenderBase</code> parameter in the
0381:             * <code>web.xml</code>.
0382:             * </p>
0383:             * @param request the servlet request.
0384:             * @return the sender base.
0385:             */
0386:            String getSenderBase(HttpServletRequest request) {
0387:                if (senderBase != null && senderBase.length() > 0) {
0388:                    return senderBase;
0389:                }
0390:                return getRequestBasePath(request);
0391:            }
0392:
0393:            /**
0394:             * Create a new process and forward initial response (e.g. HTML start page).
0395:             * See user manual (chapter "tools") for a detailed description.
0396:             * 
0397:             * @param request
0398:             *            a <code>HttpServletRequest</code> value
0399:             * @param response
0400:             *            a <code>HttpServletResponse</code> value
0401:             * @exception ServletException
0402:             *                if an error occurs
0403:             * @exception IOException
0404:             *                if an error occurs
0405:             */
0406:            public void doGet(HttpServletRequest request,
0407:                    HttpServletResponse response) throws ServletException,
0408:                    IOException {
0409:
0410:                String requestUrl = request.getRequestURL().toString();
0411:                String query = request.getQueryString();
0412:                if ((query != null) && query.equalsIgnoreCase("wsdl")) {
0413:                    getWsdl(request, response);
0414:                } else if (requestUrl.endsWith(".xsd")
0415:                        || requestUrl.endsWith(".wsdl")) {
0416:                    getFile(request, response);
0417:                } else {
0418:                    doPost(request, response);
0419:                }
0420:            }
0421:
0422:            /**
0423:             * Returns the contents of the requested file encoded as
0424:             * <code>text/plain</code>.
0425:             * 
0426:             * @param request
0427:             * @param response
0428:             * @throws IOException
0429:             *             Error accessing the file.
0430:             */
0431:            private void getWsdl(HttpServletRequest request,
0432:                    HttpServletResponse response) throws IOException {
0433:                WSDLFactory factory = new WSDLFactoryImpl();
0434:                WSDLReader reader = factory.newWSDLReader();
0435:                WSDLWriter writer = factory.newWSDLWriter();
0436:
0437:                String wsdllocation = ctx.getRealPath("/wfxml.wsdl");
0438:                File file = new File(wsdllocation);
0439:
0440:                try {
0441:                    Definition definition = reader.readWSDL(file.toURI()
0442:                            .getPath());
0443:
0444:                    String requestBasePath = getRequestBasePath(request);
0445:                    if (requestBasePath.endsWith("/")) {
0446:                        requestBasePath = requestBasePath.substring(0,
0447:                                requestBasePath.length() - 1);
0448:                    }
0449:
0450:                    definition.setDocumentBaseURI(requestBasePath);
0451:                    adjustReferencedElements(definition, requestBasePath);
0452:
0453:                    addWsdlService(request, definition, "WfXmlServiceRegistry",
0454:                            "WfMOpenServiceRegistry",
0455:                            "WfMOpenServiceRegistryService");
0456:
0457:                    addWsdlService(request, definition, "WfXmlFactory",
0458:                            "WfMOpenFactory", "WfMOpenFactoryService");
0459:
0460:                    addWsdlService(request, definition, "WfXmlInstance",
0461:                            "WfMOpenInstance", "WfMOpenInstanceService");
0462:
0463:                    addWsdlService(request, definition, "WfXmlActivity",
0464:                            "WfMOpenActivity", "WfMOpenActivityService");
0465:
0466:                    writer.writeWSDL(definition, response.getOutputStream());
0467:                } catch (WSDLException e) {
0468:                    throw new IOException(e.getMessage());
0469:                }
0470:            }
0471:
0472:            /**
0473:             * Adjust the import definitions to the path under which we were called.
0474:             * This is necessary, since the referenced resources will be retrieved
0475:             * from a package above the servlet directory, if the servlet
0476:             * is called with <code>http://.../wfxml?wsdl</code>.
0477:             * @param definition the WSDL definition.
0478:             * @param requestBasePath the base path.
0479:             */
0480:            private void adjustReferencedElements(Definition definition,
0481:                    String requestBasePath) {
0482:                List imports = definition
0483:                        .getImports("http://www.oasis-open.org/asap/0.9/asap.wsdl");
0484:                Import asapImport = (Import) imports.get(0);
0485:                asapImport.setLocationURI(requestBasePath + "/asap.wsdl");
0486:
0487:                // TODO: The types are not properly written to the definition.
0488:                Types types = definition.getTypes();
0489:                List typeList = types.getExtensibilityElements();
0490:                Iterator iterator = typeList.iterator();
0491:                while (iterator.hasNext()) {
0492:                    Object o = iterator.next();
0493:                    if (o instanceof  Schema) {
0494:                        Schema schema = (Schema) o;
0495:                        Map map = schema.getImports();
0496:
0497:                        List schemaImports = (List) map
0498:                                .get("http://www.wfmc.org/wfxml/2.0/wfxml20.xsd");
0499:                        SchemaImport schemaImport = (SchemaImport) schemaImports
0500:                                .get(0);
0501:                        Schema ref = schemaImport.getReferencedSchema();
0502:
0503:                        schemaImport.setSchemaLocationURI(requestBasePath
0504:                                + "/wfxml20.xsd");
0505:                    }
0506:                }
0507:            }
0508:
0509:            /**
0510:             * Adds a service description to the WSDL definition.
0511:             * @param request
0512:             * @param definition
0513:             */
0514:            private void addWsdlService(HttpServletRequest request,
0515:                    Definition definition, String bindingName, String portName,
0516:                    String serviceName) {
0517:                Service service = definition.createService();
0518:                Port port = definition.createPort();
0519:                QName name = new QName(
0520:                        "http://wfmopen.sourceforge.net/wfxml20.wsdl",
0521:                        bindingName, "");
0522:                Binding binding = definition.getBinding(name);
0523:                port.setName(portName);
0524:                port.setBinding(binding);
0525:
0526:                service.setQName(new QName(
0527:                        "http://wfmopen.sourceforge.net/wfxml20.wsdl",
0528:                        serviceName, "tns"));
0529:                service.addPort(port);
0530:                SOAPAddress address = new SOAPAddressImpl();
0531:                address.setLocationURI(getRequestBasePath(request));
0532:
0533:                port.addExtensibilityElement(address);
0534:
0535:                definition.addService(service);
0536:            }
0537:
0538:            /**
0539:             * Returns the contents of the requested file encoded as
0540:             * <code>text/plain</code>.
0541:             * 
0542:             * @param request
0543:             * @param response
0544:             * @throws IOException
0545:             *             Error accessing the file.
0546:             */
0547:            private void getFile(HttpServletRequest request,
0548:                    HttpServletResponse response) throws IOException {
0549:                ServletOutputStream out = response.getOutputStream();
0550:                // Get the file to view
0551:                String file = request.getPathTranslated();
0552:
0553:                // No file, nothing to view
0554:                if (file == null) {
0555:                    out.println("No file to view");
0556:                    return;
0557:                }
0558:
0559:                // Get and set the type of the file
0560:                response.setContentType("text/plain");
0561:
0562:                // Return the file
0563:                try {
0564:                    FileInputStream fis = null;
0565:                    try {
0566:                        fis = new FileInputStream(file);
0567:                        byte[] buf = new byte[4 * 1024]; // 4K buffer
0568:                        int bytesRead;
0569:                        while ((bytesRead = fis.read(buf)) != -1) {
0570:                            out.write(buf, 0, bytesRead);
0571:                        }
0572:                    } finally {
0573:                        if (fis != null) {
0574:                            fis.close();
0575:                        }
0576:                    }
0577:                } catch (FileNotFoundException e) {
0578:                    out.println("File not found");
0579:                }
0580:            }
0581:
0582:            /**
0583:             * Receive HTTP requests for a channel based access to a workflow process.
0584:             * See user manual (chapter "tools") for a detailed description.
0585:             * 
0586:             * @param request
0587:             *            a <code>HttpServletRequest</code> value
0588:             * @param response
0589:             *            a <code>HttpServletResponse</code> value
0590:             * @exception ServletException
0591:             *                if an error occurs
0592:             * @exception IOException
0593:             *                if an error occurs
0594:             */
0595:            public void doPost(HttpServletRequest request,
0596:                    HttpServletResponse response) throws ServletException,
0597:                    IOException {
0598:                HttpSession session = request.getSession(true);
0599:
0600:                MessageFactory messageFactory = null;
0601:                try {
0602:                    messageFactory = MessageFactory.newInstance();
0603:                } catch (SOAPException e) {
0604:                    response.sendError(
0605:                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
0606:                            "Unable to access SOAP subsystem: "
0607:                                    + e.getMessage());
0608:                    return;
0609:                }
0610:
0611:                SOAPMessage respMsg = null;
0612:                WorkflowService wfs = null;
0613:                // workaround JaWE bug
0614:                boolean agentIsJaWE = false;
0615:                Throwable fatalProblem = null;
0616:
0617:                try {
0618:                    // get mime request headers for building request structure
0619:                    MimeHeaders mimeHeaders = new MimeHeaders();
0620:                    for (Enumeration en = request.getHeaderNames(); en
0621:                            .hasMoreElements();) {
0622:                        String headerName = (String) en.nextElement();
0623:                        String headerVal = request.getHeader(headerName);
0624:                        if (headerName.equalsIgnoreCase("user-agent")
0625:                                && headerVal.startsWith("JaWE")) {
0626:                            agentIsJaWE = true;
0627:                        }
0628:                        StringTokenizer tk = new StringTokenizer(headerVal, ",");
0629:                        while (tk.hasMoreTokens()) {
0630:                            mimeHeaders.addHeader(headerName, tk.nextToken()
0631:                                    .trim());
0632:                        }
0633:                    }
0634:
0635:                    // build request message from headers and stream
0636:                    SOAPMessage reqMsg = messageFactory.createMessage(
0637:                            mimeHeaders, request.getInputStream());
0638:
0639:                    while (true) {
0640:                        try {
0641:                            respMsg = messageFactory.createMessage();
0642:                            wfs = getWorkflowService();
0643:                            if (wfs == null) {
0644:                                SOAPFault fault = respMsg.getSOAPPart()
0645:                                        .getEnvelope().getBody().addFault();
0646:                                fault
0647:                                        .setFaultString("Unable to access workflow service");
0648:                                return;
0649:                            }
0650:
0651:                            AbstractResponseGenerator respgen = getResponseGenerator(
0652:                                    getSenderBase(request), reqMsg, wfs);
0653:                            respgen.fillResponseHeader(reqMsg, respMsg);
0654:                            respgen.evaluate(reqMsg, respMsg);
0655:
0656:                            break;
0657:                        } catch (RemoteException e) {
0658:                            logger.debug(
0659:                                    "Problem while trying to create response "
0660:                                            + "(retrying): " + e.getMessage(),
0661:                                    e);
0662:                        }
0663:                    }
0664:                } catch (SOAPException e) {
0665:                    fatalProblem = e;
0666:                } catch (FactoryConfigurationError e) {
0667:                    fatalProblem = e;
0668:                } catch (ASAPException e) {
0669:                    fatalProblem = e;
0670:                } catch (InvalidSearchFilterException e) {
0671:                    fatalProblem = e;
0672:                } finally {
0673:                    if (fatalProblem != null) {
0674:                        if (logger.isDebugEnabled()) {
0675:                            logger.debug("error executing the client request",
0676:                                    fatalProblem);
0677:                        }
0678:
0679:                        try {
0680:                            respMsg = messageFactory.createMessage();
0681:                            if (fatalProblem instanceof  ASAPException) {
0682:                                ASAPException cause = (ASAPException) fatalProblem;
0683:                                FaultUtils.setFault(respMsg, cause
0684:                                        .getErrorCode(), cause.getMessage());
0685:                            } else {
0686:                                FaultUtils.setFault(respMsg, fatalProblem);
0687:                            }
0688:                        } catch (SOAPException ee) {
0689:                            response
0690:                                    .sendError(
0691:                                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
0692:                                            "Unable to use SOAP subsystem: "
0693:                                                    + ee.getMessage());
0694:                            return;
0695:                        }
0696:                    }
0697:                }
0698:
0699:                sendResponse(response, respMsg, agentIsJaWE);
0700:            }
0701:
0702:            /**
0703:             * Retrieves an {@link AbstractResponseGenerator} instance that is capable
0704:             * to handle the current request.
0705:             * 
0706:             * <p>
0707:             * The response generator is determined through evaluation of the
0708:             * <code>&lt;as:RecieverKey&gt;</code> in the header of the request
0709:             * message
0710:             * </p>
0711:             * 
0712:             * @param senderBase the base for constructing the sender key
0713:             * @param reqMsg
0714:             *            the SOAP request.
0715:             * @param wfs
0716:             *            reference to the workflow engine.
0717:             * 
0718:             * @return Response generator to handle the current request.
0719:             * @throws SOAPException
0720:             *             error evaluating the SOAP header.
0721:             * @throws FileNotFoundException 
0722:             *             error obtaining the sender base.
0723:             */
0724:            private AbstractResponseGenerator getResponseGenerator(
0725:                    String senderBase, SOAPMessage reqMsg, WorkflowService wfs)
0726:                    throws SOAPException, ASAPException,
0727:                    InvalidSearchFilterException {
0728:                // Determine the base request URL as a basis for referenced
0729:                // resources.
0730:                String receiverKey = null;
0731:                receiverKey = getReceiverKey(reqMsg);
0732:
0733:                ResourceReference resRef = new ResourceReference(senderBase,
0734:                        receiverKey);
0735:
0736:                ObserverRegistry observerRegistry = (ObserverRegistry) ctx
0737:                        .getAttribute(OBSERVER_REGISTRY);
0738:                String resource = resRef.getResource();
0739:                if (resource
0740:                        .equals(AbstractResponseGenerator.RESOURCE_SERVICE_REGISTRY)) {
0741:                    return new ServiceRegistryResponseGenerator(
0742:                            observerRegistry, wfs, resRef);
0743:                }
0744:                if (resource.equals(AbstractResponseGenerator.RESOURCE_FACTORY)) {
0745:                    return new FactoryResponseGenerator(observerRegistry, wfs,
0746:                            resRef);
0747:                }
0748:                if (resource
0749:                        .equals(AbstractResponseGenerator.RESOURCE_INSTANCE)) {
0750:                    return new InstanceResponseGenerator(observerRegistry, wfs,
0751:                            resRef);
0752:                }
0753:                if (resource
0754:                        .equals(AbstractResponseGenerator.RESOURCE_ACTIVITY)) {
0755:                    return new ActivityResponseGenerator(observerRegistry, wfs,
0756:                            resRef);
0757:                }
0758:
0759:                // This should not happen, since we trap into an exception, trying
0760:                // to obtain the resource string.
0761:                throw new ASAPException(ASAPException.ASAP_INVALID_FACTORY,
0762:                        receiverKey + " cannot be mapped to a known resource.");
0763:            }
0764:
0765:            /**
0766:             * Retrieves the base path that was used to call this servlet. Since this
0767:             * servlet may be called with the same URL as it is specified in the 
0768:             * <code>SenderKey</code> of the ASAP header, we  have to determine the
0769:             * base path without any extra path info to create the responses.
0770:             * @param request the request.
0771:             * @return base path.
0772:             */
0773:            private String getRequestBasePath(HttpServletRequest request) {
0774:                String requestUrl = request.getRequestURL().toString();
0775:                String servletPath = request.getPathInfo();
0776:
0777:                // Some implementations may return "/" if there is no extra path info
0778:                // available, although they should return null in that case.
0779:                if ((servletPath == null) || (servletPath.length() <= 1)) {
0780:                    return requestUrl;
0781:                }
0782:
0783:                return requestUrl.substring(0, requestUrl.length()
0784:                        - servletPath.length());
0785:            }
0786:
0787:            /**
0788:             * Reads the <code>ReceiverKey</code> from the request header of the given
0789:             * message.
0790:             * 
0791:             * @param message
0792:             *            the message to inspect.
0793:             * @return value of the <code>ReceiverKey</code>.
0794:             * @throws SOAPException
0795:             *             error evaluating the message.
0796:             */
0797:            private String getReceiverKey(SOAPMessage message)
0798:                    throws SOAPException, ASAPException {
0799:                SOAPHeaderElement headerElement = null;
0800:
0801:                SOAPHeader header = message.getSOAPHeader();
0802:                for (Iterator i = header.getChildElements(); i.hasNext();) {
0803:                    Node node = (Node) i.next();
0804:                    if (node instanceof  SOAPHeaderElement) {
0805:                        headerElement = (SOAPHeaderElement) node;
0806:
0807:                        Name headerElementName = headerElement.getElementName();
0808:                        String localName = headerElementName.getLocalName();
0809:                        if (localName.equals(Consts.REQUEST_HEADER)) {
0810:                            String headerUri = headerElementName.getURI();
0811:                            if (headerUri.equals(Consts.ASAP_NS)
0812:                                    || headerUri.equals(Consts.WFXML_NS)) {
0813:                                break;
0814:                            }
0815:                        }
0816:                    }
0817:                }
0818:
0819:                if (headerElement == null) {
0820:                    throw new ASAPException(ASAPException.ASAP_ELEMENT_MISSING,
0821:                            "ASAP request header not found.");
0822:                }
0823:
0824:                for (Iterator i = headerElement.getChildElements(); i.hasNext();) {
0825:                    Node node = (Node) i.next();
0826:                    if (node instanceof  SOAPElement) {
0827:                        SOAPElement element = (SOAPElement) node;
0828:                        String name = element.getElementName().getLocalName();
0829:                        if (name.equals(Consts.RECEIVER_KEY)) {
0830:                            return XMLUtil.getFirstLevelTextContent(element);
0831:                        }
0832:                    }
0833:                }
0834:
0835:                throw new ASAPException(ASAPException.ASAP_ELEMENT_MISSING,
0836:                        Consts.SENDER_KEY + " must be specified in the header");
0837:            }
0838:
0839:            /**
0840:             * Sends the response.
0841:             * 
0842:             * @param response
0843:             *            the servlet's response.
0844:             * @param respMsg
0845:             *            the SOAP response message.
0846:             * @param agentIsJaWE
0847:             *            <code>true</code> if this servlet was called by JaWE.
0848:             * @throws IOException
0849:             *             Error accessing the output stream.
0850:             */
0851:            private void sendResponse(HttpServletResponse response,
0852:                    SOAPMessage respMsg, boolean agentIsJaWE)
0853:                    throws IOException {
0854:                response.setHeader("Content-Type", "text/xml");
0855:                OutputStream os = response.getOutputStream();
0856:
0857:                try {
0858:                    if (!agentIsJaWE) {
0859:                        respMsg.writeTo(os);
0860:                    } else {
0861:                        // workaround JaWE bug. JaWE cannot handle pretty
0862:                        // printed XML
0863:                        try {
0864:                            TransformerFactory tf = TransformerFactory
0865:                                    .newInstance();
0866:                            Transformer t = tf.newTransformer();
0867:                            t.transform(new DOMSource(respMsg.getSOAPPart()
0868:                                    .getEnvelope()), new StreamResult(os));
0869:                        } catch (TransformerConfigurationException ee) {
0870:                            response
0871:                                    .sendError(
0872:                                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
0873:                                            "Cannot get transformer: "
0874:                                                    + ee.getMessage());
0875:                            return;
0876:                        } catch (TransformerException ee) {
0877:                            response
0878:                                    .sendError(
0879:                                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
0880:                                            "Cannot transform: "
0881:                                                    + ee.getMessage());
0882:                            return;
0883:                        }
0884:                    }
0885:                } catch (SOAPException ee) {
0886:                    response
0887:                            .sendError(
0888:                                    HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
0889:                                    "Unable to write SOAP response: "
0890:                                            + ee.getMessage());
0891:                    return;
0892:                }
0893:
0894:                os.flush();
0895:            }
0896:
0897:            /**
0898:             * This class creates a workflow engine reference, and, when available
0899:             * receives events and forwards them to the WfXmlAuditHandler.
0900:             *
0901:             * @author Dirk Schnelle
0902:             * @author Michael Lipp
0903:             */
0904:            private class AuditHandlerThread extends Thread {
0905:                private String applicationPolicy;
0906:                private String userName;
0907:                private String password;
0908:                private boolean running = true;
0909:
0910:                /**
0911:                 * Constructs a new object.
0912:                 */
0913:                public AuditHandlerThread(String applicationPolicy,
0914:                        String userName, String password) {
0915:                    setDaemon(true);
0916:
0917:                    this .applicationPolicy = applicationPolicy;
0918:                    this .userName = userName;
0919:                    this .password = password;
0920:
0921:                }
0922:
0923:                /* (non-Javadoc)
0924:                 * @see java.lang.Thread#run()
0925:                 */
0926:                public void run() {
0927:                    try {
0928:                        LoginContext loginContext = new AuditHandlerLoginContext(
0929:                                applicationPolicy, userName, password);
0930:                        loginContext.login();
0931:                    } catch (LoginException e) {
0932:                        logger.error("login error", e);
0933:                        return;
0934:                    }
0935:
0936:                    WorkflowService wfs = null;
0937:                    while (running && wfs == null) {
0938:                        try {
0939:                            wfs = getWorkflowService();
0940:                        } catch (FactoryConfigurationError fce) {
0941:                            try {
0942:                                sleep(500);
0943:                            } catch (InterruptedException e) {
0944:                                return;
0945:                            }
0946:                        }
0947:                    }
0948:
0949:                    try {
0950:                        eventSubscriber = wfs.createEventSubscriber();
0951:                    } catch (IOException e) {
0952:                        logger.error("Cannot create event subscriber: "
0953:                                + e.getMessage(), e);
0954:                        return;
0955:                    }
0956:
0957:                    // Now handle events
0958:                    WfXmlAuditHandler handler = new WfXmlAuditHandler(wfs,
0959:                            observerRegistry);
0960:                    while (running) {
0961:                        try {
0962:                            WfAuditEvent event = eventSubscriber.receive();
0963:                            handler.receiveEvent(event);
0964:                        } catch (Exception e) {
0965:                            logger.warn("Cannot handle event (ignored): "
0966:                                    + e.getMessage());
0967:                        }
0968:                    }
0969:                }
0970:
0971:                /**
0972:                 * Preliminarily terminate the running thread.
0973:                 */
0974:                public void terminate() {
0975:                    running = false;
0976:                    interrupt();
0977:                }
0978:
0979:            }
0980:
0981:            /**
0982:             * Simple login context for authentication.
0983:             * @author Dirk Schnelle
0984:             */
0985:            private static class AuditHandlerLoginContext extends LoginContext {
0986:
0987:                private static class CBH implements  CallbackHandler {
0988:                    private String userName = null;
0989:                    private String password = null;
0990:
0991:                    public CBH(String userName, String password) {
0992:                        this .userName = userName;
0993:                        this .password = password;
0994:                    }
0995:
0996:                    public void handle(Callback[] callbacks)
0997:                            throws UnsupportedCallbackException, IOException {
0998:                        for (int i = 0; i < callbacks.length; i++) {
0999:                            if (callbacks[i] instanceof  TextOutputCallback) {
1000:                                // display the message according to the specified type
1001:                                TextOutputCallback toc = (TextOutputCallback) callbacks[i];
1002:                                switch (toc.getMessageType()) {
1003:                                case TextOutputCallback.INFORMATION:
1004:                                    if (logger.isInfoEnabled()) {
1005:                                        logger.info(toc.getMessage());
1006:                                    }
1007:                                    break;
1008:                                case TextOutputCallback.ERROR:
1009:                                    logger.error("ERROR: " + toc.getMessage());
1010:                                    break;
1011:                                case TextOutputCallback.WARNING:
1012:                                    logger.warn("WARNING: " + toc.getMessage());
1013:                                    break;
1014:                                default:
1015:                                    throw new IOException(
1016:                                            "Unsupported message type: "
1017:                                                    + toc.getMessageType());
1018:                                }
1019:                            } else if (callbacks[i] instanceof  NameCallback) {
1020:                                // prompt the user for a username
1021:                                NameCallback nc = (NameCallback) callbacks[i];
1022:                                nc.setName(userName);
1023:                            } else if (callbacks[i] instanceof  PasswordCallback) {
1024:                                // prompt the user for sensitive information
1025:                                PasswordCallback pc = (PasswordCallback) callbacks[i];
1026:                                pc.setPassword(password.toCharArray());
1027:                            } else if (callbacks[i]
1028:                                    .getClass()
1029:                                    .getName()
1030:                                    .equals(
1031:                                            "weblogic.security.auth.callback.URLCallback")) {
1032:                                // deliberately ignored.
1033:                            } else {
1034:                                throw new UnsupportedCallbackException(
1035:                                        callbacks[i],
1036:                                        "Unrecognized Callback \""
1037:                                                + callbacks[i].getClass()
1038:                                                        .getName() + "\"");
1039:                            }
1040:                        }
1041:                    }
1042:                }
1043:
1044:                public AuditHandlerLoginContext(String applicationPolicy,
1045:                        String userName, String password) throws LoginException {
1046:                    super (applicationPolicy, new CBH(userName, password));
1047:                }
1048:            }
1049:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.