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


001:        /*
002:         * This file is part of the WfMOpen project.
003:         * Copyright (C) 2001-2003 Danet GmbH (www.danet.de), GS-AN.
004:         * All rights reserved.
005:         *
006:         * This program is free software; you can redistribute it and/or modify
007:         * it under the terms of the GNU General Public License as published by
008:         * the Free Software Foundation; either version 2 of the License, or
009:         * (at your option) any later version.
010:         *
011:         * This program is distributed in the hope that it will be useful,
012:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014:         * GNU General Public License for more details.
015:         *
016:         * You should have received a copy of the GNU General Public License
017:         * along with this program; if not, write to the Free Software
018:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
019:         *
020:         * $Id: Servlet.java,v 1.4 2007/03/27 21:59:44 mlipp Exp $
021:         *
022:         * $Log: Servlet.java,v $
023:         * Revision 1.4  2007/03/27 21:59:44  mlipp
024:         * Fixed lots of checkstyle warnings.
025:         *
026:         * Revision 1.3  2007/01/19 22:52:58  mlipp
027:         * Updated.
028:         *
029:         * Revision 1.2  2006/09/29 12:32:09  drmlipp
030:         * Consistently using WfMOpen as projct name now.
031:         *
032:         * Revision 1.1.1.2  2004/08/18 15:17:38  drmlipp
033:         * Update to 1.2
034:         *
035:         * Revision 1.19  2004/04/13 15:24:04  lipp
036:         * Improved content-type and debugging support.
037:         *
038:         * Revision 1.18  2004/04/02 12:41:07  lipp
039:         * Added missing xml decalaration.
040:         *
041:         * Revision 1.17  2004/03/18 10:15:26  schlue
042:         * Session invalidation for closed process added.
043:         *
044:         * Revision 1.16  2004/03/04 08:25:23  schlue
045:         * Stylesheet example added (transformation performed by web browser)
046:         *
047:         * Revision 1.15  2004/03/01 14:58:22  schlue
048:         * Chabacc servlet extensions, part 2 completed.
049:         *
050:         * Revision 1.14  2004/02/27 10:20:17  schlue
051:         * Review comments implemented.
052:         *
053:         * Revision 1.13  2004/02/25 16:15:19  schlue
054:         * Chabacc servlet extensions added.
055:         *
056:         * Revision 1.12  2004/02/24 15:20:05  schlue
057:         * Servlet code (initial version) added.
058:         *
059:         * Revision 1.11  2004/01/30 14:36:30  lipp
060:         * Partial implementation of message receipt.
061:         *
062:         * Revision 1.10  2003/10/08 19:13:38  lipp
063:         * Fixed multi caller problem.
064:         *
065:         * Revision 1.9  2003/10/08 15:15:35  lipp
066:         * Updated channel handling.
067:         *
068:         * Revision 1.8  2003/10/07 21:04:59  lipp
069:         * Made process selectable.
070:         *
071:         * Revision 1.7  2003/10/06 20:43:22  lipp
072:         * Continuing channel communication.
073:         *
074:         * Revision 1.6  2003/10/06 18:28:48  lipp
075:         * Added data submission.
076:         *
077:         * Revision 1.5  2003/10/06 15:21:15  lipp
078:         * Use session create method.
079:         *
080:         * Revision 1.4  2003/10/06 13:57:18  lipp
081:         * Finished restructuring.
082:         *
083:         * Revision 1.3  2003/10/05 19:57:20  lipp
084:         * Prepared reorganization.
085:         *
086:         * Revision 1.2  2003/10/05 15:40:18  lipp
087:         * Continuing chabacc implementation.
088:         *
089:         * Revision 1.1  2003/10/02 20:04:28  lipp
090:         * Started channel based access module.
091:         *
092:         */
093:        package de.danet.an.workflow.tools.chabacc.plain;
094:
095:        import java.io.CharArrayWriter;
096:        import java.io.IOException;
097:        import java.io.PrintWriter;
098:
099:        import java.util.Collection;
100:        import java.util.Enumeration;
101:        import java.util.Map;
102:        import java.util.StringTokenizer;
103:
104:        import java.lang.reflect.InvocationTargetException;
105:        import java.rmi.RemoteException;
106:
107:        import javax.servlet.ServletConfig;
108:        import javax.servlet.ServletException;
109:        import javax.servlet.http.HttpServlet;
110:        import javax.servlet.http.HttpServletRequest;
111:        import javax.servlet.http.HttpServletResponse;
112:        import javax.servlet.http.HttpSession;
113:        import javax.xml.transform.OutputKeys;
114:        import javax.xml.transform.Transformer;
115:        import javax.xml.transform.TransformerConfigurationException;
116:        import javax.xml.transform.TransformerFactory;
117:        import javax.xml.transform.sax.SAXTransformerFactory;
118:        import javax.xml.transform.sax.TransformerHandler;
119:        import javax.xml.transform.stream.StreamResult;
120:
121:        import org.xml.sax.SAXException;
122:
123:        import de.danet.an.workflow.omgcore.AlreadyRunningException;
124:        import de.danet.an.workflow.omgcore.CannotStartException;
125:        import de.danet.an.workflow.omgcore.InvalidDataException;
126:        import de.danet.an.workflow.omgcore.ProcessData;
127:        import de.danet.an.workflow.omgcore.WfProcess;
128:
129:        import de.danet.an.workflow.api.Channel;
130:        import de.danet.an.workflow.api.DefaultProcessData;
131:        import de.danet.an.workflow.api.DefaultRequester;
132:        import de.danet.an.workflow.api.FactoryConfigurationError;
133:        import de.danet.an.workflow.api.InvalidKeyException;
134:        import de.danet.an.workflow.api.MethodInvocationBatch;
135:        import de.danet.an.workflow.api.ProcessDefinitionDirectory;
136:        import de.danet.an.workflow.api.ProcessDirectory;
137:        import de.danet.an.workflow.api.ProcessMgr;
138:        import de.danet.an.workflow.api.SAXEventBuffer;
139:        import de.danet.an.workflow.api.WorkflowService;
140:        import de.danet.an.workflow.api.WorkflowServiceFactory;
141:
142:        /**
143:         * This class provides an interface between the workflow engine (i.e. its
144:         * processes and any HTTP based client (e.g. Web browser application).
145:         *
146:         * @author <a href="mailto:mnl@mnl.de">Michael N. Lipp</a>
147:         * @version $Revision: 1.4 $
148:         */
149:
150:        public class Servlet extends HttpServlet {
151:
152:            private static final org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory
153:                    .getLog(Servlet.class);
154:
155:            /** Configuration parameter "packageId" */
156:            private String defaultPackageId = "boot";
157:            /** Configuration parameter "processId" */
158:            private String defaultProcessId = "chabacc_http_plain";
159:            /** Cachable singleton "workflow service" */
160:            private WorkflowService wfsCache = null;
161:
162:            /** Local exception for handling processing problems. */
163:            private class ProcessingException extends Exception {
164:                private int statusCode = HttpServletResponse.SC_OK;
165:
166:                /** Create exception always with error message and status code.
167:                 * @param message error message
168:                 * @param sc status code for servlet response
169:                 */
170:                public ProcessingException(int sc, String message) {
171:                    super (message);
172:                    statusCode = sc;
173:                }
174:
175:                public int getStatusCode() {
176:                    return statusCode;
177:                }
178:            }
179:
180:            /** Container class for process lookup (retrieval or creation). */
181:            private class ProcessLookup {
182:                WfProcess process = null;
183:                String packageId = null;
184:                String processId = null;
185:                String procKey = null;
186:                boolean created = false;
187:            }
188:
189:            /** Container class for reponse information from channel. */
190:            private class ResponseInfo {
191:                String responseData;
192:                String mimeType;
193:                boolean invalidateSession;
194:            }
195:
196:            /**
197:             * Default init method.
198:             *
199:             * @param servletConfig a <code>ServletConfig</code> value
200:             * @exception ServletException if an error occurs
201:             */
202:            public void init(ServletConfig servletConfig)
203:                    throws ServletException {
204:                // Read configuration values and overwrite default, if set
205:                if (servletConfig != null) {
206:                    String id = servletConfig
207:                            .getInitParameter("packagePathSegmentDefault");
208:                    if (id != null) {
209:                        defaultPackageId = id;
210:                    }
211:                    id = servletConfig
212:                            .getInitParameter("processPathSegmentDefault");
213:                    if (id != null) {
214:                        defaultProcessId = id;
215:                    }
216:                }
217:            }
218:
219:            /**
220:             * Receive HTTP requests for a channel based access to a workflow process.
221:             * See user manual (chapter "tools")  for a detailed description.
222:             * 
223:             * @param request a <code>HttpServletRequest</code> value
224:             * @param response a <code>HttpServletResponse</code> value
225:             * @exception ServletException if an error occurs
226:             * @exception IOException if an error occurs
227:             */
228:            public void doPost(HttpServletRequest request,
229:                    HttpServletResponse response) throws ServletException,
230:                    IOException {
231:                String packageID = null;
232:                String processID = null;
233:                String dataItemName = null;
234:                String dataItemValue = null;
235:                boolean waitForResponse = true;
236:
237:                // Scan request params and store data values in a map for later use
238:                ProcessData sendData = new DefaultProcessData();
239:                for (Enumeration e = request.getParameterNames(); e
240:                        .hasMoreElements();) {
241:                    String pn = (String) e.nextElement();
242:                    if (pn.equals("WFM_packageID")) {
243:                        packageID = request.getParameter(pn);
244:                    } else if (pn.equals("WFM_processID")) {
245:                        processID = request.getParameter(pn);
246:                    } else if (pn.equals("WFM_dataItemName")) {
247:                        dataItemName = request.getParameter(pn);
248:                    } else if (pn.equals("WFM_dataItemValue")) {
249:                        dataItemValue = request.getParameter(pn);
250:                    } else if (pn.equals("WFM_waitForResponse")) {
251:                        waitForResponse = (new Boolean(request.getParameter(pn))
252:                                .booleanValue());
253:                    } else {
254:                        sendData.put(pn, request.getParameter(pn));
255:                    }
256:                }
257:
258:                HttpSession session = request.getSession(true);
259:                if (logger.isDebugEnabled()) {
260:                    logger.debug("Post called for session " + session.getId());
261:                }
262:
263:                WorkflowService wfs = getWorkflowService();
264:                if (wfs == null) {
265:                    response.sendError(
266:                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
267:                            "Unable to retrieve workflow service");
268:                    return;
269:                }
270:                Channel channel = null;
271:                boolean invalidateSession = false;
272:                try {
273:                    // Retrieve (or create) process
274:                    ProcessLookup pl = lookupProcess(session, packageID,
275:                            processID, sendData, dataItemName, dataItemValue);
276:
277:                    // Open channel to process (and start process, or send data)
278:                    if (waitForResponse) {
279:                        channel = openChannel(pl);
280:                    }
281:                    if (pl.created) {
282:                        pl.process.start();
283:                    } else {
284:                        sendData(session, channel, sendData);
285:                    }
286:                    // If no response expected, that's it
287:                    if (!waitForResponse) {
288:                        response.setStatus(HttpServletResponse.SC_OK);
289:                        return;
290:                    }
291:
292:                    // forward answer from process
293:                    Map data = receiveData(session, channel);
294:                    ResponseInfo responseInfo = getResponseInfo(data);
295:                    invalidateSession = responseInfo.invalidateSession;
296:
297:                    response.setStatus(HttpServletResponse.SC_OK);
298:                    String mt = responseInfo.mimeType;
299:                    if (mt.indexOf("charset=") < 0) {
300:                        mt = mt + "; charset=UTF-8";
301:                    }
302:                    if (logger.isDebugEnabled()) {
303:                        logger.debug("Response (of type \"" + mt + "\") is:\n"
304:                                + responseInfo.responseData);
305:                    }
306:                    response.setContentType(mt);
307:                    PrintWriter ow = response.getWriter();
308:                    ow.write(responseInfo.responseData);
309:                    ow.close();
310:                    return;
311:                } catch (CannotStartException e) {
312:                    logger.error(e.getMessage());
313:                    response.sendError(
314:                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e
315:                                    .getMessage());
316:                } catch (AlreadyRunningException e) {
317:                    logger.error(e.getMessage());
318:                    response.sendError(
319:                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e
320:                                    .getMessage());
321:                } catch (ProcessingException e) {
322:                    response.sendError(e.getStatusCode(), e.getMessage());
323:                    return;
324:                } finally {
325:                    if (channel != null) {
326:                        wfs.release(channel);
327:                    }
328:                    if (invalidateSession) {
329:                        session.invalidate();
330:                    }
331:                }
332:            }
333:
334:            /**
335:             * Create a new process and forward initial response (e.g. HTML start page).
336:             * See user manual (chapter "tools")  for a detailed description.
337:             *
338:             * @param request a <code>HttpServletRequest</code> value
339:             * @param response a <code>HttpServletResponse</code> value
340:             * @exception ServletException if an error occurs
341:             * @exception IOException if an error occurs
342:             */
343:            public void doGet(HttpServletRequest request,
344:                    HttpServletResponse response) throws ServletException,
345:                    IOException {
346:                String packageID = defaultPackageId;
347:                String processID = defaultProcessId;
348:                String extraPath = request.getPathInfo();
349:                if (extraPath != null) {
350:                    // Read package ID and process ID from extra path info
351:                    StringTokenizer tok = new StringTokenizer(extraPath, "/");
352:                    if (tok.hasMoreTokens()) {
353:                        packageID = tok.nextToken();
354:                    }
355:                    if (tok.hasMoreTokens()) {
356:                        processID = tok.nextToken();
357:                    }
358:                }
359:
360:                WorkflowService wfs = getWorkflowService();
361:                if (wfs == null) {
362:                    response.sendError(
363:                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
364:                            "Unable to retrieve workflow service");
365:                    return;
366:                }
367:
368:                // Create new process
369:                Channel channel = null;
370:                try {
371:                    ProcessData sendData = new DefaultProcessData();
372:                    // Create new process
373:                    ProcessLookup pl = lookupProcess(null, packageID,
374:                            processID, sendData, null, null);
375:
376:                    // Build connection to process and start process
377:                    channel = openChannel(pl);
378:                    if (pl.created) {
379:                        pl.process.start();
380:                    }
381:
382:                    // Send data to process and forward answer from process
383:                    if (!pl.created) {
384:                        sendData(null, channel, sendData);
385:                    }
386:                    Map data = receiveData(null, channel);
387:                    ResponseInfo responseInfo = getResponseInfo(data);
388:                    response.setStatus(HttpServletResponse.SC_OK);
389:                    String mt = responseInfo.mimeType;
390:                    if (mt.indexOf("charset=") < 0) {
391:                        mt = mt + "; charset=UTF-8";
392:                    }
393:                    if (logger.isDebugEnabled()) {
394:                        logger.debug("Response (of type \"" + mt + "\") is:\n"
395:                                + responseInfo.responseData);
396:                    }
397:                    response.setContentType(mt);
398:                    PrintWriter ow = response.getWriter();
399:                    ow.write(responseInfo.responseData);
400:                    ow.close();
401:                    return;
402:                } catch (CannotStartException e) {
403:                    logger.error(e.getMessage());
404:                    response.sendError(
405:                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e
406:                                    .getMessage());
407:                } catch (AlreadyRunningException e) {
408:                    logger.error(e.getMessage());
409:                    response.sendError(
410:                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e
411:                                    .getMessage());
412:                } catch (ProcessingException e) {
413:                    response.sendError(e.getStatusCode(), e.getMessage());
414:                    return;
415:                } finally {
416:                    if (channel != null) {
417:                        wfs.release(channel);
418:                    }
419:                }
420:            }
421:
422:            /**
423:             * Helper for process lookup (retrieval or creation).
424:             * Saves information about the process in session attributes
425:             * "WfM_mgrName" and "WfM_procKey".
426:             * 
427:             * @param session current HTTP session
428:             * @param packageID package id of process manager
429:             * @param processID id of process
430:             * @param initData processData for process initialization
431:             * @param dataItemName name of additional process data
432:             * @param dataItemValue value of additional process data
433:             * @exception ProcessingException if an error occurs
434:             */
435:            private ProcessLookup lookupProcess(HttpSession session,
436:                    String packageID, String processID, ProcessData initData,
437:                    String dataItemName, String dataItemValue)
438:                    throws ProcessingException {
439:                while (true) {
440:                    try {
441:                        WorkflowService wfs = getWorkflowService();
442:                        if (wfs == null) {
443:                            throw new ProcessingException(
444:                                    HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
445:                                    "Unable to retrieve workflow service");
446:                        }
447:                        ProcessLookup pl = new ProcessLookup();
448:                        ProcessDefinitionDirectory procDefDir = wfs
449:                                .processDefinitionDirectory();
450:                        if (packageID != null && processID != null) {
451:                            ProcessMgr mgr = null;
452:                            try {
453:                                mgr = procDefDir.processMgr(packageID,
454:                                        processID);
455:                            } catch (InvalidKeyException e) {
456:                                throw new ProcessingException(
457:                                        HttpServletResponse.SC_BAD_REQUEST, e
458:                                                .getMessage());
459:                            }
460:                            String mgrName = mgr.name();
461:                            if (dataItemName != null && dataItemValue != null) {
462:                                // Try to connect to existing process
463:                                Collection procs = mgr.findByDataItem(
464:                                        dataItemName, dataItemValue);
465:                                if (procs.size() == 1) {
466:                                    pl.process = (WfProcess) procs.iterator()
467:                                            .next();
468:                                    pl.procKey = pl.process.key();
469:                                    pl.packageId = packageID;
470:                                    pl.processId = processID;
471:                                    if (session != null) {
472:                                        session.setAttribute("WfM_mgrName", mgr
473:                                                .name());
474:                                        session.setAttribute("WfM_procKey",
475:                                                pl.procKey);
476:                                    }
477:                                    return pl;
478:                                }
479:                                if (procs.size() > 1) {
480:                                    logger
481:                                            .error("More than one process found for "
482:                                                    + mgr.name()
483:                                                    + ", data item: "
484:                                                    + dataItemName
485:                                                    + " = "
486:                                                    + dataItemValue);
487:                                    throw new ProcessingException(
488:                                            HttpServletResponse.SC_CONFLICT,
489:                                            "More than one matching process found");
490:                                }
491:                                // add to init data for creation
492:                                initData.put(dataItemName, dataItemValue);
493:                            }
494:                            // Not found, create new process
495:                            MethodInvocationBatch mib = new MethodInvocationBatch();
496:                            mib
497:                                    .addInvocation(
498:                                            mgr,
499:                                            "createProcess",
500:                                            new String[] { "de.danet.an.workflow.omgcore.WfRequester" },
501:                                            new Object[] { new DefaultRequester(
502:                                                    wfs) });
503:                            mib
504:                                    .addInvocation(
505:                                            -1,
506:                                            "setProcessContext",
507:                                            new String[] { "de.danet.an.workflow.omgcore.ProcessData" },
508:                                            new Object[] { initData }, false);
509:                            mib.addInvocation(-2, "key", null, null, false);
510:                            MethodInvocationBatch.Result mir = (MethodInvocationBatch.Result) wfs
511:                                    .executeBatch(mib);
512:                            if (mir.hasExceptions()) {
513:                                Exception e = mir.firstException();
514:                                logger.error("Problem executing batch: "
515:                                        + e.getMessage(), e);
516:                                throw new ProcessingException(
517:                                        HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
518:                                        mir.firstException().getMessage());
519:                            }
520:                            pl.process = (WfProcess) mir.result(0);
521:                            pl.procKey = mir.resultAsString(2);
522:                            pl.packageId = packageID;
523:                            pl.processId = processID;
524:                            pl.created = true;
525:                            if (session != null) {
526:                                session.setAttribute("WfM_mgrName", mgrName);
527:                                session.setAttribute("WfM_procKey", pl.procKey);
528:                            }
529:                            return pl;
530:                        }
531:                        if (session != null) {
532:                            // Retrieve process key from session context
533:                            String mgrName = (String) session
534:                                    .getAttribute("WfM_mgrName");
535:                            String procKey = (String) session
536:                                    .getAttribute("WfM_procKey");
537:                            if (mgrName == null || procKey == null) {
538:                                throw new ProcessingException(
539:                                        HttpServletResponse.SC_BAD_REQUEST,
540:                                        "No process information available");
541:                            }
542:                            ProcessDirectory procDir = wfs.processDirectory();
543:                            try {
544:                                pl.process = procDir.lookupProcess(mgrName,
545:                                        procKey);
546:                                pl.procKey = pl.process.key();
547:                            } catch (InvalidKeyException e) {
548:                                session.invalidate();
549:                                throw new ProcessingException(
550:                                        HttpServletResponse.SC_GONE,
551:                                        "Process has been removed");
552:                            }
553:                            StringTokenizer tok = new StringTokenizer(mgrName,
554:                                    "/");
555:                            if (tok.hasMoreTokens()) {
556:                                pl.packageId = tok.nextToken();
557:                            }
558:                            if (tok.hasMoreTokens()) {
559:                                pl.processId = tok.nextToken();
560:                            }
561:                            return pl;
562:                        }
563:                        return pl;
564:                    } catch (RemoteException e) {
565:                        logger.debug(e.getMessage(), e);
566:                    } catch (FactoryConfigurationError e) {
567:                        logger.error(e.getMessage());
568:                        throw new ProcessingException(
569:                                HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e
570:                                        .getMessage());
571:                    } catch (InvocationTargetException e) {
572:                        String s = "Unexpected exception: "
573:                                + e.getCause().getMessage();
574:                        logger.error(s, e);
575:                        throw new ProcessingException(
576:                                HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e
577:                                        .getCause().getMessage());
578:                    }
579:                }
580:            }
581:
582:            /**
583:             * Helper for opening a channel to the given process.
584:             * If process has been created, it is started after opening the channel.
585:             * 
586:             * @param pl process lookup information
587:             * @exception ProcessingException if an error occurs
588:             */
589:            private Channel openChannel(ProcessLookup pl)
590:                    throws ProcessingException {
591:                while (true) {
592:                    try {
593:                        WorkflowService wfs = getWorkflowService();
594:                        if (wfs == null) {
595:                            throw new ProcessingException(
596:                                    HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
597:                                    "Unable to retrieve workflow service");
598:                        }
599:                        ProcessDefinitionDirectory procDefDir = wfs
600:                                .processDefinitionDirectory();
601:                        ProcessMgr mgr = null;
602:                        try {
603:                            mgr = procDefDir.processMgr(pl.packageId,
604:                                    pl.processId);
605:                        } catch (InvalidKeyException e) {
606:                            throw new ProcessingException(
607:                                    HttpServletResponse.SC_BAD_REQUEST, e
608:                                            .getMessage());
609:                        }
610:                        ProcessDirectory procDir = wfs.processDirectory();
611:                        WfProcess proc = null;
612:                        try {
613:                            proc = procDir
614:                                    .lookupProcess(mgr.name(), pl.procKey);
615:                        } catch (InvalidKeyException e) {
616:                            throw new ProcessingException(
617:                                    HttpServletResponse.SC_GONE,
618:                                    "Process has been removed");
619:                        }
620:                        return wfs.getChannel(proc, "initiator");
621:                    } catch (RemoteException e) {
622:                        logger.debug(e.getMessage(), e);
623:                    }
624:                }
625:            }
626:
627:            /**
628:             * Helper for sending data to a channel.
629:             * 
630:             * @param session current HTTP session
631:             * @param channel channel for sending data
632:             * @param sendData data to be sent on channel
633:             * @exception ProcessingException if an error occurs
634:             */
635:            private void sendData(HttpSession session, Channel channel,
636:                    ProcessData sendData) throws ProcessingException {
637:                while (true) {
638:                    try {
639:                        channel.sendMessage(sendData);
640:                        break;
641:                    } catch (InvalidKeyException e) {
642:                        if (session != null) {
643:                            session.invalidate();
644:                        }
645:                        throw new ProcessingException(
646:                                HttpServletResponse.SC_GONE,
647:                                "Process is no longer accessible: "
648:                                        + e.getMessage());
649:                    } catch (InvalidDataException e) {
650:                        throw new ProcessingException(
651:                                HttpServletResponse.SC_BAD_REQUEST, e
652:                                        .getMessage());
653:                    } catch (RemoteException e) {
654:                        logger.debug(e.getMessage(), e);
655:                    }
656:                }
657:            }
658:
659:            /**
660:             * Receive data from the given channel.
661:             * 
662:             * @param session current HTTP session
663:             * @param channel channel for sending data
664:             * @exception ProcessingException if an error occurs
665:             */
666:            private Map receiveData(HttpSession session, Channel channel)
667:                    throws ProcessingException {
668:                while (true) {
669:                    try {
670:                        Map data = channel.receiveMessage();
671:                        if (data == null) {
672:                            throw new InvalidKeyException(
673:                                    "Process has been closed or removed");
674:                        }
675:                        return data;
676:                    } catch (InvalidKeyException e) {
677:                        if (session != null) {
678:                            session.invalidate();
679:                        }
680:                        throw new ProcessingException(
681:                                HttpServletResponse.SC_GONE,
682:                                "Process is no longer accessible: "
683:                                        + e.getMessage());
684:                    } catch (RemoteException e) {
685:                        logger.debug(e.getMessage(), e);
686:                    }
687:                }
688:            }
689:
690:            /**
691:             * Request workflow service once after authentification.
692:             * Thus it performed be called within the servlet's init method
693:             * which may be called during the deployment process.
694:             */
695:            private synchronized WorkflowService getWorkflowService() {
696:                if (wfsCache == null) {
697:                    try {
698:                        wfsCache = WorkflowServiceFactory.newInstance()
699:                                .newWorkflowService();
700:                    } catch (FactoryConfigurationError e) {
701:                        logger.error(e.getMessage());
702:                    }
703:                }
704:                return wfsCache;
705:            }
706:
707:            /**
708:             * Helper to determine complete reponse info from response data map.
709:             * 
710:             * @param data response data map
711:             * @exception ProcessingException if an error occurs
712:             */
713:            private ResponseInfo getResponseInfo(Map data)
714:                    throws ProcessingException {
715:                // create and initialize result structure
716:                ResponseInfo responseInfo = new ResponseInfo();
717:                String doctypeSystem = (String) data.get("doctype-system");
718:                String doctypePublic = (String) data.get("doctype-public");
719:                responseInfo.mimeType = (String) data.get("mimeType");
720:                responseInfo.invalidateSession = false;
721:                Object responseData = null;
722:                if (data.size() == 1) {
723:                    responseData = data.values().iterator().next();
724:                } else {
725:                    responseData = data.get("data");
726:                    if (responseData == null) {
727:                        throw new ProcessingException(
728:                                HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
729:                                "No data found");
730:                    }
731:                    if (data.containsKey("invalidateSession")) {
732:                        responseInfo.invalidateSession = ((Boolean) data
733:                                .get("invalidateSession")).booleanValue();
734:                    }
735:                }
736:                // transform data into string
737:                if (responseData instanceof  String) {
738:                    responseInfo.responseData = (String) responseData;
739:                    if (responseInfo.mimeType == null) {
740:                        String cmp = (responseInfo.responseData.length() > 50) ? responseInfo.responseData
741:                                .substring(0, 50).toUpperCase()
742:                                : responseInfo.responseData.toUpperCase();
743:                        if (cmp
744:                                .startsWith("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML")
745:                                || cmp
746:                                        .startsWith("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML")) {
747:                            responseInfo.mimeType = "text/html";
748:                        } else {
749:                            responseInfo.mimeType = "application/data";
750:                        }
751:                    }
752:                } else if (responseData instanceof  SAXEventBuffer) {
753:                    CharArrayWriter out = new CharArrayWriter();
754:                    try {
755:                        SAXEventBuffer eventbuf = (SAXEventBuffer) responseData;
756:                        SAXTransformerFactory tf = (SAXTransformerFactory) TransformerFactory
757:                                .newInstance();
758:                        TransformerHandler th = null;
759:                        th = tf.newTransformerHandler();
760:                        Transformer xformer = th.getTransformer();
761:                        if (doctypeSystem != null) {
762:                            xformer.setOutputProperty(
763:                                    OutputKeys.DOCTYPE_SYSTEM, doctypeSystem);
764:                        }
765:                        if (doctypePublic != null) {
766:                            xformer.setOutputProperty(
767:                                    OutputKeys.DOCTYPE_PUBLIC, doctypePublic);
768:                        }
769:                        th.setResult(new StreamResult(out));
770:                        eventbuf.emit(th);
771:                    } catch (SAXException e) {
772:                        String s = "Error generating XML process data: "
773:                                + e.getMessage();
774:                        logger.error(s, e);
775:                        throw new ProcessingException(
776:                                HttpServletResponse.SC_INTERNAL_SERVER_ERROR, s);
777:                    } catch (TransformerConfigurationException e) {
778:                        String s = "Error generating XML process data: "
779:                                + e.getMessage();
780:                        logger.error(s, e);
781:                        throw new ProcessingException(
782:                                HttpServletResponse.SC_INTERNAL_SERVER_ERROR, s);
783:                    }
784:                    responseInfo.responseData = out.toString();
785:                    if (responseInfo.mimeType == null) {
786:                        responseInfo.mimeType = "text/xml";
787:                    }
788:                } else {
789:                    String e = "Illegal data type in channel message: "
790:                            + responseData.getClass().getName();
791:                    logger.error(e);
792:                    throw new ProcessingException(
793:                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);
794:                }
795:                return responseInfo;
796:            }
797:        }
w_ww__.___j__av_a__2_s.c__om___ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.