001: /*
002: * <copyright>
003: *
004: * Copyright 1997-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.micro.http;
028:
029: import java.io.IOException;
030: import java.net.BindException;
031: import java.net.ServerSocket;
032: import java.util.Map;
033: import javax.servlet.Servlet;
034: import javax.servlet.ServletException;
035:
036: import org.cougaar.core.service.ThreadService;
037: import org.cougaar.core.thread.Schedulable;
038: import org.cougaar.lib.web.engine.AbstractServletEngine;
039: import org.cougaar.lib.web.micro.base.Connection;
040: import org.cougaar.lib.web.micro.base.ServerFactory;
041: import org.cougaar.lib.web.micro.base.ServletEngine;
042: import org.cougaar.lib.web.micro.base.ServletEngineImpl;
043: import org.cougaar.lib.web.micro.base.SocketServerFactory;
044:
045: /**
046: * This component creates a minimal servlet engine based on the trimmed-down
047: * {@link ServletEngineImpl} implementation.
048: * <p>
049: * This implementation is intended as a drop-in replacement for the
050: * heavier-weight, Tomcat-based "webtomcat" servlet engine.
051: */
052: public class HttpServletEngine extends AbstractServletEngine {
053:
054: private boolean made_engine = false;
055: private ThreadService threadService;
056: private ServletEngine engine;
057:
058: public void unload() {
059: releaseEngine();
060: super .unload();
061: }
062:
063: // forward all calls to our engine
064: protected void configure(int httpPort, int httpsPort, Map options) {
065: findOrMakeEngine().configure(httpPort, httpsPort, options);
066: }
067:
068: protected void startServer() throws BindException, IOException {
069: findOrMakeEngine().start();
070: }
071:
072: protected void setGateway(Servlet s) throws ServletException {
073: findOrMakeEngine().setGateway(s);
074: }
075:
076: protected void stopServer() {
077: findOrMakeEngine().stop();
078: }
079:
080: // create the engine on first request
081: private ServletEngine findOrMakeEngine() {
082: if (made_engine) {
083: return engine;
084: }
085: made_engine = true;
086:
087: // get thread service
088: threadService = (ThreadService) sb.getService(this ,
089: ThreadService.class, null);
090: if (threadService == null) {
091: throw new RuntimeException(
092: "Unable to obtains ThreadService");
093: }
094:
095: // subclass factory to use threading service
096: ServerFactory server_factory = new SocketServerFactory() {
097: protected void listen_bg(final ServerSocket serverSock,
098: final Map settings, final AcceptCallback callback) {
099: Runnable r = new Runnable() {
100: public void run() {
101: if (log.isDebugEnabled()) {
102: log.debug("listen");
103: }
104: listen(serverSock, settings, callback);
105: }
106: };
107: // we'll block forever, but it's still better to use a pooled thread
108: // than to spawn a raw Java thread
109: Schedulable thread = threadService.getThread(this , r,
110: "HttpServletEngine listener " + serverSock,
111: ThreadService.WILL_BLOCK_LANE);
112: thread.start();
113: }
114:
115: protected void accept_bg(final AcceptCallback callback,
116: final Connection con) {
117: Runnable r = new Runnable() {
118: public void run() {
119: if (log.isDebugEnabled()) {
120: log.debug("accept " + con);
121: }
122: accept(callback, con);
123: }
124: };
125: // this will block if the servlet keeps the stream open
126: Schedulable thread = threadService.getThread(this , r,
127: "HttpServletEngine accept " + con,
128: ThreadService.WILL_BLOCK_LANE);
129: thread.start();
130: }
131: };
132:
133: // create base engine
134: engine = new ServletEngineImpl(server_factory);
135:
136: return engine;
137: }
138:
139: private void releaseEngine() {
140: if (!made_engine) {
141: return;
142: }
143: made_engine = false;
144:
145: // release engine
146: if (engine != null) {
147: if (engine.isRunning()) {
148: engine.stop();
149: }
150: engine = null;
151: }
152:
153: // release services
154: if (threadService != null) {
155: sb.releaseService(this , ThreadService.class, threadService);
156: threadService = null;
157: }
158: }
159: }
|