Source Code Cross Referenced for ServletPlugin.java in  » Science » Cougaar12_4 » org » cougaar » core » plugin » 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 » Science » Cougaar12_4 » org.cougaar.core.plugin 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * <copyright>
003:         *
004:         *  Copyright 2000-2007 BBNT Solutions, LLC
005:         *  under sponsorship of the Defense Advanced Research Projects
006:         *  Agency (DARPA).
007:         *
008:         *  You can redistribute this software and/or modify it under the
009:         *  terms of the Cougaar Open Source License as published on the
010:         *  Cougaar Open Source Website (www.cougaar.org).
011:         *
012:         *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013:         *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014:         *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015:         *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016:         *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017:         *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018:         *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019:         *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020:         *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021:         *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022:         *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023:         *
024:         * </copyright>
025:         */
026:
027:        package org.cougaar.core.plugin;
028:
029:        import java.io.IOException;
030:        import java.io.UnsupportedEncodingException;
031:        import java.lang.reflect.InvocationTargetException;
032:        import java.net.URLEncoder;
033:        import java.net.URLDecoder;
034:        import java.util.Collection;
035:        import java.util.Iterator;
036:        import javax.servlet.ServletException;
037:        import javax.servlet.http.HttpServlet;
038:        import javax.servlet.http.HttpServletRequest;
039:        import javax.servlet.http.HttpServletResponse;
040:
041:        import org.cougaar.bootstrap.SystemProperties;
042:        import org.cougaar.core.blackboard.Subscription;
043:        import org.cougaar.core.blackboard.TodoSubscription;
044:        import org.cougaar.core.service.ServletService;
045:        import org.cougaar.util.Arguments;
046:        import org.cougaar.util.FutureResult;
047:        import org.cougaar.util.UnaryPredicate;
048:
049:        /**
050:         * This plugin is a base class for servlets that either modify or subscribe
051:         * to the blackboard.
052:         * <p>
053:         * If a servlet only requires blackboard queries and no subscriptions or
054:         * add/change/remove modifications, then {@link ComponentServlet} is
055:         * recommended.
056:         * <p>
057:         * If {@link #isTransactional} is true then all servlet processing work is
058:         * done single-threaded in the "execute()" method, where it can access
059:         * subscriptions and modify the blackboard using the standard
060:         * "blackboard.publish*" methods.
061:         *
062:         * @param org.cougaar.core.servlet.ServletPlugin.timeout=60000
063:         * Default timeout for ServletPlugin requests, which are processed
064:         * in the plugin's "execute()" thread.
065:         */
066:        public abstract class ServletPlugin extends ComponentPlugin {
067:
068:            private static final long DEFAULT_TIMEOUT = SystemProperties
069:                    .getLong("org.cougaar.core.servlet.ServletPlugin.timeout",
070:                            60000);
071:
072:            private String path;
073:            private boolean isTrans;
074:            private long timeout;
075:            private String encAgentName;
076:
077:            private ServletService servletService;
078:
079:            private TodoSubscription todo;
080:
081:            public ServletPlugin() {
082:                super ();
083:            }
084:
085:            /**
086:             * Return true (the default) if all servlet requests should run
087:             * single-threaded in the "execute()" method, otherwise false if they should
088:             * run in the servlet engine's threads (and possibly in parallel with other
089:             * servlet requests and the "execute()" thread).
090:             * <p>
091:             * If a servlet requires a cross-transaction result, e.g.:<ol>
092:             *   <li>publishAdd object X</li>
093:             *   <li>wait another plugin to react to object X, e.g. via a
094:             *       "notify()" callback or published response</li>
095:             *   <li>finish the servlet call</li>
096:             * </ol>
097:             * then "isTransactional()" must return false.
098:             * <p>
099:             * Also, if a servlet has no subscriptions or private state, then it's
100:             * slightly more efficient to have this method return false.  This will allow
101:             * requests to run in parallel.
102:             * <p>
103:             * In all other cases, this method should return true.  This allows the
104:             * "doGet(...)" method to access subscriptions and other internal state
105:             * without a synchronization lock, since the "execute()" method is always
106:             * single-threaded and runs in a blackboard transaction.
107:             */
108:            protected boolean isTransactional() {
109:                return true;
110:            }
111:
112:            /**
113:             * Get the path for the Servlet's registration.
114:             * <p>
115:             * Typically the path is supplied by a "path=" plugin argument, but a
116:             * subclass can hard-code the path by overriding this method.
117:             */
118:            protected String getPath() {
119:                return path;
120:            }
121:
122:            public void load() {
123:                super .load();
124:
125:                Collection params = getParameters();
126:                Arguments args = new Arguments(params);
127:
128:                // set threading
129:                isTrans = isTransactional();
130:
131:                // set path
132:                path = getPath();
133:                if (path == null) {
134:                    path = args.getString("path");
135:                    if (path == null && !params.isEmpty()) {
136:                        String s = (String) params.iterator().next();
137:                        if (s.indexOf('=') < 0) {
138:                            path = s;
139:                        }
140:                    }
141:                    if (path == null) {
142:                        throw new IllegalArgumentException(
143:                                "Missing path parameter");
144:                    }
145:                }
146:
147:                // set timeout
148:                timeout = args.getLong("timeout", DEFAULT_TIMEOUT);
149:
150:                // get encoded agent name
151:                String agentName = (agentId == null ? null : agentId
152:                        .getAddress());
153:                encAgentName = (agentName == null ? null : encode(agentName));
154:
155:                // get our servlet service
156:                servletService = (ServletService) getServiceBroker()
157:                        .getService(this , ServletService.class, null);
158:                if (servletService == null) {
159:                    throw new RuntimeException(
160:                            "Unable to obtain ServletService");
161:                }
162:
163:                // register our servlet
164:                try {
165:                    HttpServlet servlet = createServlet();
166:                    servletService.register(path, servlet);
167:                } catch (Exception e) {
168:                    throw new RuntimeException("Unable to register " + path, e);
169:                }
170:            }
171:
172:            public void unload() {
173:                if (servletService != null) {
174:                    // this will automatically unregister our servlet
175:                    getServiceBroker().releaseService(this ,
176:                            ServletService.class, servletService);
177:                    servletService = null;
178:                }
179:
180:                super .unload();
181:            }
182:
183:            /** Get the URL-encoded name of the local agent */
184:            protected String getEncodedAgentName() {
185:                return encAgentName;
186:            }
187:
188:            protected void setupSubscriptions() {
189:                if (isTrans) {
190:                    todo = (TodoSubscription) blackboard
191:                            .subscribe(new TodoSubscription("x"));
192:                }
193:            }
194:
195:            protected void execute() {
196:                if (!isTrans)
197:                    return;
198:                ensureTodo();
199:                if (!todo.hasChanged())
200:                    return;
201:                for (Iterator iter = todo.getAddedCollection().iterator(); iter
202:                        .hasNext();) {
203:                    HttpJob job = (HttpJob) iter.next();
204:                    try {
205:                        service(job.getHttpServletRequest(), job
206:                                .getHttpServletResponse());
207:                        job.notifySuccess();
208:                    } catch (Exception e) {
209:                        job.notifyFailure(e);
210:                    }
211:                }
212:            }
213:
214:            private void ensureTodo() {
215:                if (todo == null) {
216:                    throw new RuntimeException(
217:                            "The \"todo\" subscription is null.  Is \"setupSubscriptions()\""
218:                                    + " missing a call to \"super.setupSubscriptions()\"?");
219:                }
220:            }
221:
222:            protected Subscription subscribe(UnaryPredicate pred) {
223:                if (!isTrans || !blackboard.isTransactionOpen()) {
224:                    throw new IllegalStateException(
225:                            "Can only subscribe if \"isTransactional()\" is true");
226:                }
227:                return blackboard.subscribe(pred);
228:            }
229:
230:            protected Collection query(UnaryPredicate pred) {
231:                if (isTrans || blackboard.isTransactionOpen()) {
232:                    return blackboard.query(pred);
233:                } else {
234:                    blackboard.openTransaction();
235:                    Collection c = blackboard.query(pred);
236:                    blackboard.closeTransactionDontReset();
237:                    return c;
238:                }
239:            }
240:
241:            protected void publishAdd(Object o) {
242:                if (isTrans || blackboard.isTransactionOpen()) {
243:                    blackboard.publishAdd(o);
244:                } else {
245:                    blackboard.openTransaction();
246:                    blackboard.publishAdd(o);
247:                    blackboard.closeTransactionDontReset();
248:                }
249:            }
250:
251:            protected void publishChange(Object o) {
252:                publishChange(o, null);
253:            }
254:
255:            protected void publishChange(Object o, Collection changes) {
256:                if (isTrans || blackboard.isTransactionOpen()) {
257:                    blackboard.publishChange(o, changes);
258:                } else {
259:                    blackboard.openTransaction();
260:                    blackboard.publishChange(o, changes);
261:                    blackboard.closeTransactionDontReset();
262:                }
263:            }
264:
265:            protected void publishRemove(Object o) {
266:                if (isTrans || blackboard.isTransactionOpen()) {
267:                    blackboard.publishRemove(o);
268:                } else {
269:                    blackboard.openTransaction();
270:                    blackboard.publishRemove(o);
271:                    blackboard.closeTransactionDontReset();
272:                }
273:            }
274:
275:            protected void serviceLater(HttpServletRequest req,
276:                    HttpServletResponse resp) throws ServletException,
277:                    IOException {
278:                if (!isTrans) {
279:                    throw new IllegalStateException(
280:                            "Can only call \"serviceLater(...)\" if \"isTransactional()\" is"
281:                                    + " true.");
282:                }
283:                ensureTodo();
284:
285:                // put on our "todo" queue
286:                HttpJob job = new HttpJob(req, resp);
287:                todo.add(job);
288:
289:                // wait for the result, which will rethrow any "notifyFailure" exception
290:                job.waitForNotify(timeout);
291:            }
292:
293:            /**
294:             * Create our servlet, which by default calls our doGet/doPost/doPost
295:             * methods.
296:             * <p>
297:             * A subclass can override this method if it's designed to create a separate
298:             * servlet.  However, if {@link #isTransactional} is true then it should use
299:             * {@link #serviceLater} to do all blackboard work in the "execute()" method
300:             * instead of the servlet callback thread.
301:             * <p>
302:             * Even though we switch to the "execute()" thread, we must still block
303:             * the servlet callback until we finish the work, otherwise the servlet engine
304:             * will close our response stream.
305:             */
306:            protected HttpServlet createServlet() {
307:                return new HttpServlet() {
308:                    protected void service(HttpServletRequest req,
309:                            HttpServletResponse resp) throws ServletException,
310:                            IOException {
311:                        if (isTrans) {
312:                            serviceLater(req, resp);
313:                        } else {
314:                            ServletPlugin.this .service(req, resp);
315:                        }
316:                    }
317:                };
318:            }
319:
320:            /** Basic servlet methods */
321:            protected void service(HttpServletRequest req,
322:                    HttpServletResponse resp) throws ServletException,
323:                    IOException {
324:                String method = req.getMethod();
325:                if ("GET".equals(method)) {
326:                    doGet(req, resp);
327:                } else if ("POST".equals(method)) {
328:                    doPost(req, resp);
329:                } else if ("PUT".equals(method)) {
330:                    doPut(req, resp);
331:                } else if ("OPTIONS".equals(method)) {
332:                    // RFE do same thing as in HttpServlet
333:                    resp.setHeader("Allow", "GET, HEAD, POST, PUT, OPTIONS");
334:                } else {
335:                    notSupported(req, resp);
336:                }
337:            }
338:
339:            protected void doGet(HttpServletRequest req,
340:                    HttpServletResponse resp) throws ServletException,
341:                    IOException {
342:                notSupported(req, resp);
343:            }
344:
345:            protected void doPost(HttpServletRequest req,
346:                    HttpServletResponse resp) throws ServletException,
347:                    IOException {
348:                notSupported(req, resp);
349:            }
350:
351:            protected void doPut(HttpServletRequest req,
352:                    HttpServletResponse resp) throws ServletException,
353:                    IOException {
354:                notSupported(req, resp);
355:            }
356:
357:            protected void notSupported(HttpServletRequest req,
358:                    HttpServletResponse resp) throws IOException {
359:                String method = req.getMethod();
360:                String msg = "HTTP method " + method
361:                        + " is not supported by this URL";
362:                String protocol = req.getProtocol();
363:                int sc = (protocol != null && protocol.endsWith("1.1") ? HttpServletResponse.SC_METHOD_NOT_ALLOWED
364:                        : HttpServletResponse.SC_BAD_REQUEST);
365:                resp.sendError(sc, msg);
366:            }
367:
368:            /** @return the UTF-8 encoded string */
369:            protected String encode(String s) {
370:                try {
371:                    return (s == null ? null : URLEncoder.encode(s, "UTF-8"));
372:                } catch (UnsupportedEncodingException e) {
373:                    // should never happen
374:                    throw new RuntimeException("Unable to encode to UTF-8?");
375:                }
376:            }
377:
378:            /** @return the UTF-8 decoded string */
379:            protected String decode(String s) {
380:                try {
381:                    return (s == null ? null : URLDecoder.decode(s, "UTF-8"));
382:                } catch (UnsupportedEncodingException e) {
383:                    // should never happen
384:                    throw new RuntimeException("Unable to decode to UTF-8?");
385:                }
386:            }
387:
388:            protected static final class HttpJob {
389:
390:                private final HttpServletRequest req;
391:                private final HttpServletResponse resp;
392:                private final FutureResult future = new FutureResult();
393:
394:                public HttpJob(HttpServletRequest req, HttpServletResponse resp) {
395:                    this .req = req;
396:                    this .resp = resp;
397:                }
398:
399:                public HttpServletRequest getHttpServletRequest() {
400:                    return req;
401:                }
402:
403:                public HttpServletResponse getHttpServletResponse() {
404:                    return resp;
405:                }
406:
407:                public void notifySuccess() {
408:                    future.set(Boolean.TRUE);
409:                }
410:
411:                public void notifyFailure(Throwable t) {
412:                    future.setException(t);
413:                }
414:
415:                public void waitForNotify(long timeout)
416:                        throws ServletException, IOException {
417:                    // wait for the result
418:                    Throwable t;
419:                    try {
420:                        Object o = future.timedGet(timeout);
421:                        if (o == Boolean.TRUE) {
422:                            // success
423:                            return;
424:                        }
425:                        t = new InternalError("Unexpected submit result: " + o);
426:                    } catch (InvocationTargetException ite) {
427:                        t = ite.getCause();
428:                    } catch (InterruptedException ie) {
429:                        t = ie;
430:                    }
431:
432:                    // rethrow the exception
433:                    if (t instanceof  RuntimeException) {
434:                        throw (RuntimeException) t;
435:                    } else if (t instanceof  ServletException) {
436:                        throw (ServletException) t;
437:                    } else if (t instanceof  IOException) {
438:                        throw (IOException) t;
439:                    } else if (t instanceof  InterruptedException) {
440:                        throw new RuntimeException("Request timeout");
441:                    } else if (t instanceof  Error) {
442:                        throw (Error) t;
443:                    } else {
444:                        throw new RuntimeException("Wrapped exception", t);
445:                    }
446:                }
447:            }
448:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.