Source Code Cross Referenced for AbstractServletEngine.java in  » Science » Cougaar12_4 » org » cougaar » lib » web » engine » 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.lib.web.engine 
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.lib.web.engine;
028:
029:        import java.io.File;
030:        import java.io.IOException;
031:        import java.net.BindException;
032:        import java.net.InetAddress;
033:        import java.net.URI;
034:        import java.util.Collections;
035:        import java.util.Enumeration;
036:        import java.util.HashMap;
037:        import java.util.List;
038:        import java.util.Map;
039:        import java.util.Properties;
040:        import javax.servlet.Servlet;
041:        import javax.servlet.ServletConfig;
042:        import javax.servlet.ServletException;
043:
044:        import org.cougaar.bootstrap.SystemProperties;
045:        import org.cougaar.core.component.Component;
046:        import org.cougaar.core.component.ServiceBroker;
047:        import org.cougaar.core.component.ServiceProvider;
048:        import org.cougaar.core.service.LoggingService;
049:        import org.cougaar.util.GenericStateModelAdapter;
050:        import org.cougaar.util.Parameters;
051:
052:        /**
053:         * This component is a base class for {@link ServletEngineService} providers.
054:         * <p>
055:         * This class reads the parameters, scans for available ports, starts the
056:         * server, and advertises our service.
057:         * <p>
058:         * If HTTPS is enabled, the "cougaar.rc" must contain:<pre>
059:         *   org.cougaar.web.keystore=FILENAME
060:         *   org.cougaar.web.keypass=Password
061:         * </pre>
062:         * where the FILENAME is relative to the "$cougaar.install.path".
063:         * See {@link Parameters} for "cougaar.rc" documentation.
064:         * <p>
065:         * All the following parameters are also supported as prefix-free component
066:         * parameters, e.g. "http.port=1234".
067:         *
068:         * <pre>
069:         * @property org.cougaar.lib.web.scanRange
070:         *   The scan range for ports beyond the configured base HTTP
071:         *   and HTTPS ports.  If either port is in use the ports will 
072:         *   be incremented by one until "scanRange" ports have been 
073:         *   tried, at which time a java.net.BindingException will be 
074:         *   thrown.  The default is 100, which (if no other ports are
075:         *   being used, and no change to the below "http[s].port" 
076:         *   parameters) would allow for 100 Nodes on a machine.
077:         *
078:         * @property org.cougaar.lib.web.http.port
079:         *   The base integer port for the HTTP server, which defaults to
080:         *   8800.  The most common value is 8800.  If a negative number 
081:         *   is passed then HTTP listening is disabled.  Also see the 
082:         *    "org.cougaar.lib.web.scanRange" property.
083:         *
084:         * @property org.cougaar.lib.web.http.factory
085:         *   Optional classname for factory used to create HTTP server
086:         *   sockets.  Defaults to a standard socket factory.
087:         *
088:         * @property org.cougaar.lib.web.http.acceptCount
089:         *   HTTP ServerSocket backlog.  Defaults to a server default.
090:         *
091:         * @property org.cougaar.lib.web.https.port
092:         *   The base integer port for the HTTPS server, which defaults to
093:         *   -1.  The most common value is 8400.  If a negative number is 
094:         *   passed then HTTPS listening is disabled.  Also see the 
095:         *   "org.cougaar.lib.web.scanRange" property.
096:         *
097:         * @property org.cougaar.lib.web.https.acceptCount
098:         *   HTTPS ServerSocket backlog.  Defaults to a server default.
099:         *
100:         * @property org.cougaar.lib.web.https.clientAuth
101:         *   Used to enable HTTPS client-authentication.  Defaults to
102:         *   false.
103:         *
104:         * @property org.cougaar.lib.web.https.factory
105:         *   Optional classname for factory used to create HTTPS (SSL) 
106:         *   server sockets.  Defaults to a standard SSL socket factory.
107:         *
108:         * @property org.cougaar.lib.web.https.keystore
109:         *   Optional HTTPS keystore.  Prefer "cougaar.rc" entry
110:         *   for "org.cougaar.web.keystore=FILENAME".
111:         *
112:         * @property org.cougaar.lib.web.https.keypass
113:         *   Optional HTTPS keystore.  Prefer "cougaar.rc" entry
114:         *   for "org.cougaar.web.keypass=PASSWORD".
115:         * </pre>
116:         */
117:        public abstract class AbstractServletEngine extends
118:                GenericStateModelAdapter implements  Component {
119:            private static final String PROPERTY_PREFIX = "org.cougaar.lib.web.";
120:
121:            protected ServiceBroker sb;
122:
123:            protected LoggingService log;
124:
125:            private List paramList;
126:
127:            private boolean running;
128:
129:            private Map namingEntries;
130:
131:            private ServletEngineService ses;
132:            private ServletEngineRegistryService sers;
133:            private ServiceProvider ses_sp;
134:
135:            //
136:            // abstract methods:
137:            //
138:
139:            /**
140:             * Set the HTTP and HTTPS (SSL) configuration -- this is called before
141:             * {@link #startServer()}.
142:             *
143:             * @param httpPort the HTTP port, or -1 if HTTP is disabled
144:             * @param httpsPort the HTTPS port, or -1 if HTTP is disabled
145:             * @param options a Map of String keys to String values that specify
146:             *    additional server options (e.g. "http.acceptCount").
147:             */
148:            protected abstract void configure(int httpPort, int httpsPort,
149:                    Map options);
150:
151:            /**
152:             * Start the server.
153:             *
154:             * @throws BindException if the either the HTTP or HTTPS port is already in
155:             *   use.  The base class will then call "configure" with different port(s)
156:             *   and try to start again.
157:             * @throws IOException some other server exception occurred.
158:             */
159:            protected abstract void startServer() throws BindException,
160:                    IOException;
161:
162:            /**
163:             * Set the single <code>Servlet</code> that will handle <b>all</b> service
164:             * requests for the running server.
165:             * <p>
166:             * Even though this is defined as <tt>setGateway(Servlet)</tt>, all calls
167:             * to:<pre>
168:             *  <tt>Servlet.service(ServletRequest, ServletResponse)</tt>
169:             * must pass in the HTTP subclasses of these request/response interfaces:
170:             *  <tt>Servlet.service(HttpServletRequest, HttpServletResponse)</tt>
171:             * </pre>, since this is an HTTP/HTTPS server engine.
172:             */
173:            protected abstract void setGateway(Servlet s)
174:                    throws ServletException;
175:
176:            /**
177:             * Stop the server.
178:             * <p>
179:             * This is only called if {@link #startServer()} was called and didn't throw
180:             * an exception.
181:             */
182:            protected abstract void stopServer();
183:
184:            //
185:            // implementation:
186:            //
187:
188:            public void setServiceBroker(ServiceBroker sb) {
189:                this .sb = sb;
190:            }
191:
192:            public void setParameter(Object o) {
193:                if (!(o instanceof  List)) {
194:                    throw new IllegalArgumentException(
195:                            "Invalid non-List parameter: "
196:                                    + o.getClass().getName());
197:                }
198:                this .paramList = (List) o;
199:            }
200:
201:            protected Map parseParameters(List args) {
202:                // Map<String, String>
203:                Map m = new HashMap(13);
204:
205:                // set defaults
206:                m.put("debug", Boolean.toString(log.isDebugEnabled()));
207:                m.put("redirect.timeout", "0");
208:                m.put("scanRange", "100");
209:                m.put("https.keyname", "tomcat");
210:                m.put("http.port", "8800");
211:                m.put("https.port", "-1");
212:
213:                // override with init parameters
214:                for (int i = 0; i < args.size(); i++) {
215:                    String s = (String) args.get(i);
216:                    if (s == null)
217:                        continue;
218:                    int sep = s.indexOf('=');
219:                    String key;
220:                    String value;
221:                    if (sep >= 0) {
222:                        key = s.substring(0, sep);
223:                        value = s.substring(sep + 1);
224:                    } else {
225:                        key = s;
226:                        value = null;
227:                    }
228:                    m.put(key, value);
229:                }
230:
231:                // override with system properties
232:                Properties sysProps = SystemProperties
233:                        .getSystemPropertiesWithPrefix(PROPERTY_PREFIX);
234:                if (sysProps != null) {
235:                    for (Enumeration en = sysProps.propertyNames(); en
236:                            .hasMoreElements();) {
237:                        String key = (String) en.nextElement();
238:                        String value = sysProps.getProperty(key);
239:                        key = key.substring(PROPERTY_PREFIX.length());
240:                        m.put(key, value);
241:                    }
242:                }
243:
244:                // override with "cougaar.rc"
245:                String serverKeystore = Parameters
246:                        .findParameter("org.cougaar.web.keystore");
247:                if (serverKeystore != null) {
248:                    // look for keystore in RUNTIME, SOCIETY, then INSTALL
249:                    for (int i = 0; i < 2; i++) {
250:                        String s = (i == 0 ? "runtime" : i == 1 ? "society"
251:                                : "install");
252:                        String base = SystemProperties
253:                                .getProperty("org.cougaar." + s + ".path");
254:                        if (base != null) {
255:                            String file = base + File.separator
256:                                    + serverKeystore;
257:                            if ((new File(file)).isFile()) {
258:                                serverKeystore = file;
259:                                break;
260:                            }
261:                        }
262:                    }
263:                    if (serverKeystore != null) {
264:                        m.put("https.keystore", serverKeystore);
265:                    }
266:                }
267:                String serverKeypass = Parameters
268:                        .findParameter("org.cougaar.web.keypass");
269:                if (serverKeypass != null) {
270:                    m.put("https.keypass", serverKeypass);
271:                }
272:
273:                if (!m.containsKey("https.trustKeystore")
274:                        && serverKeystore != null) {
275:                    // default trustKeystore is the keystore
276:                    m.put("https.trustKeystore", serverKeystore);
277:                }
278:
279:                if (log.isDebugEnabled()) {
280:                    log.debug("Config: " + m);
281:                }
282:
283:                // save the server options
284:                return Collections.unmodifiableMap(m);
285:            }
286:
287:            public void load() {
288:                super .load();
289:
290:                // get services
291:                log = (LoggingService) sb.getService(this ,
292:                        LoggingService.class, null);
293:
294:                // read config map
295:                List l = (paramList == null ? Collections.EMPTY_LIST
296:                        : paramList);
297:                paramList = null;
298:                Map config = parseParameters(l);
299:                if (config == null) {
300:                    config = Collections.EMPTY_MAP;
301:                }
302:
303:                // configure and start the server
304:                final UsedPorts usedPorts;
305:                try {
306:                    usedPorts = startServer(config);
307:                } catch (Exception e) {
308:                    throw new RuntimeException(
309:                            "Unable to start servlet server", e);
310:                }
311:                running = true;
312:
313:                // create and advertise our service
314:                ses = new ServletEngineService() {
315:                    private Servlet gateway;
316:
317:                    public void setGateway(Servlet s) throws ServletException {
318:                        this .gateway = s;
319:                        AbstractServletEngine.this .setGateway(s);
320:                    }
321:
322:                    public Map getNamingEntries() {
323:                        return findOrMakeNamingEntries(usedPorts, gateway);
324:                    }
325:
326:                    public String toString() {
327:                        return AbstractServletEngine.this .toString();
328:                    }
329:                };
330:                sers = (ServletEngineRegistryService) sb.getService(this ,
331:                        ServletEngineRegistryService.class, null);
332:                if (sers != null) {
333:                    // share registry
334:                    sers.add(ses);
335:                } else {
336:                    // just us
337:                    final Class cl = ServletEngineService.class;
338:                    ses_sp = new ServiceProvider() {
339:                        public Object getService(ServiceBroker sb, Object req,
340:                                Class scl) {
341:                            return (cl.isAssignableFrom(scl) ? ses : null);
342:                        }
343:
344:                        public void releaseService(ServiceBroker sb,
345:                                Object req, Class scl, Object svc) {
346:                        }
347:                    };
348:                    sb.addService(cl, ses_sp);
349:                }
350:            }
351:
352:            public void unload() {
353:                // remove/revoke our service
354:                if (ses != null) {
355:                    if (sers != null) {
356:                        sers.remove(ses);
357:                        sers = null;
358:                    } else if (ses_sp != null) {
359:                        sb.revokeService(ServletEngineService.class, ses_sp);
360:                        ses_sp = null;
361:                    }
362:                    ses = null;
363:                }
364:
365:                // stop server
366:                if (running) {
367:                    running = false;
368:                    try {
369:                        stopServer();
370:                    } catch (Exception e) {
371:                        throw new RuntimeException("Unable to stop server", e);
372:                    }
373:                }
374:
375:                // release the logger
376:                if (log != null) {
377:                    sb.releaseService(this , LoggingService.class, log);
378:                    log = null;
379:                }
380:
381:                super .unload();
382:            }
383:
384:            /**
385:             * Start the server, scan the port range based upon the
386:             * "org.cougaar.lib.web.scanRange" property.
387:             * <p>
388:             * See the "@property" javadocs at the top of this file.
389:             *
390:             * @return used ports
391:             */
392:            protected UsedPorts startServer(Map config) throws Exception {
393:
394:                // extract our parameters
395:                int scanRange = Integer.parseInt((String) config
396:                        .get("scanRange"));
397:                int initHttpPort = Integer.parseInt((String) config
398:                        .get("http.port"));
399:                int initHttpsPort = Integer.parseInt((String) config
400:                        .get("https.port"));
401:
402:                if (initHttpPort < 0 && initHttpsPort < 0) {
403:                    return null;
404:                }
405:
406:                // validate our parameters
407:                if (scanRange < 1) {
408:                    throw new IllegalArgumentException(
409:                            "Port scan range must be at least 1, not \""
410:                                    + scanRange + "\"");
411:                }
412:                if ((initHttpPort > 0) && (initHttpsPort > 0)
413:                        && (initHttpPort == initHttpsPort)) {
414:                    throw new IllegalArgumentException("HTTP port ("
415:                            + initHttpPort + ") and HTTPS port ("
416:                            + initHttpsPort + ") must be different!");
417:                }
418:
419:                // set the scan range
420:                int maxI = scanRange;
421:
422:                // FIXME notice |httpsPort-httpPort|, adjust maxI
423:                //
424:                // would make scanning more efficient...
425:
426:                int httpPort = initHttpPort;
427:                int httpsPort = initHttpsPort;
428:
429:                // scan the ports, try to launch the server
430:                for (int i = 0;; i++) {
431:
432:                    if (i >= maxI) {
433:                        // failure; tried too many ports
434:                        String msg = "Unable to launch server"
435:                                + ((httpPort > 0) ? (", attempted " + maxI
436:                                        + " HTTP  ports (" + httpPort + "-"
437:                                        + (httpPort + (maxI - 1)) + ")") : (""))
438:                                + ((httpPort > 0) ? (", attempted " + maxI
439:                                        + " HTTPS ports (" + httpsPort + "-"
440:                                        + (httpsPort + (maxI - 1)) + ")")
441:                                        : (""));
442:                        if (log.isErrorEnabled()) {
443:                            log.error(msg);
444:                        }
445:                        throw new BindException(msg);
446:                    }
447:
448:                    if (log.isDebugEnabled()) {
449:                        log
450:                                .debug("Server launch attempt["
451:                                        + i
452:                                        + " / "
453:                                        + maxI
454:                                        + "]:"
455:                                        + ((httpPort > 0) ? (" HTTP  port ("
456:                                                + httpPort + ")") : (""))
457:                                        + ((httpPort > 0) ? (" HTTPS port ("
458:                                                + httpsPort + ")") : ("")));
459:                    }
460:
461:                    configure(httpPort, httpsPort, config);
462:
463:                    try {
464:                        startServer();
465:                        break;
466:                    } catch (BindException be) {
467:                        // port(s) in use, try again
468:                    }
469:
470:                    if (httpPort > 0) {
471:                        ++httpPort;
472:                    }
473:                    if (httpsPort > 0) {
474:                        ++httpsPort;
475:                    }
476:                }
477:
478:                // success
479:                if (log.isInfoEnabled()) {
480:                    log
481:                            .info("\nServer launched with: "
482:                                    + ((httpPort > 0) ? ("\nHTTP : " + httpPort)
483:                                            : (""))
484:                                    + ((httpPort > 0) ? ("\nHTTPS: " + httpsPort)
485:                                            : ("")));
486:                }
487:                return new UsedPorts(httpPort, httpsPort);
488:            }
489:
490:            protected Map findOrMakeNamingEntries(UsedPorts usedPorts,
491:                    Servlet gateway) {
492:                if (namingEntries == null) {
493:                    namingEntries = Collections.EMPTY_MAP;
494:                    Map m = makeNamingEntries(usedPorts, gateway);
495:                    if (m != null && !m.isEmpty()) {
496:                        namingEntries = Collections.unmodifiableMap(m);
497:                    }
498:                }
499:                return namingEntries;
500:            }
501:
502:            protected Map makeNamingEntries(UsedPorts usedPorts, Servlet gateway) {
503:                // get host:port info
504:                if (usedPorts == null) {
505:                    return null;
506:                }
507:                int httpPort = usedPorts.getHttpPort();
508:                int httpsPort = usedPorts.getHttpsPort();
509:                if (httpPort < 0 && httpsPort < 0) {
510:                    return null;
511:                }
512:                String localhost = null;
513:                try {
514:                    localhost = InetAddress.getLocalHost().getHostName();
515:                } catch (Exception e) {
516:                    throw new RuntimeException(
517:                            "Unable to get localhost address", e);
518:                }
519:
520:                // get the optional base path from our gateway.
521:                //
522:                // This should match our servlet request "getContextPath()", but that
523:                // method is only available during a servlet call.  As a work-around,
524:                // we'll check for a custom "path" context parameter.
525:                String contextPath = "";
526:                if (gateway != null) {
527:                    ServletConfig sc = gateway.getServletConfig();
528:                    if (sc != null) {
529:                        String s = sc.getInitParameter("path");
530:                        if (s != null && s.length() > 0 && s.charAt(0) == '/') {
531:                            contextPath = s;
532:                        }
533:                    }
534:                }
535:
536:                // create our entries
537:                Map m = new HashMap();
538:                if (httpPort >= 0) {
539:                    m.put("http", URI.create("http://" + localhost
540:                            + (httpPort == 80 ? "" : (":" + httpPort))
541:                            + contextPath));
542:                }
543:                if (httpsPort >= 0) {
544:                    m.put("https", URI.create("https://" + localhost
545:                            + (httpsPort == 443 ? "" : (":" + httpsPort))
546:                            + contextPath));
547:                }
548:                return m;
549:            }
550:
551:            protected static final class UsedPorts {
552:                private final int httpPort;
553:                private final int httpsPort;
554:
555:                public UsedPorts(int httpPort, int httpsPort) {
556:                    this .httpPort = httpPort;
557:                    this .httpsPort = httpsPort;
558:                }
559:
560:                public int getHttpPort() {
561:                    return httpPort;
562:                }
563:
564:                public int getHttpsPort() {
565:                    return httpsPort;
566:                }
567:
568:                public String toString() {
569:                    return "(used-ports http=" + httpPort + " https="
570:                            + httpsPort + ")";
571:                }
572:            }
573:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.