001: package org.objectweb.celtix.bus.transports.http;
002:
003: import java.io.IOException;
004: import java.net.MalformedURLException;
005: import java.net.URL;
006: import java.util.HashMap;
007: import java.util.Map;
008:
009: import org.mortbay.http.HttpContext;
010: import org.mortbay.http.HttpHandler;
011: import org.mortbay.http.HttpServer;
012: import org.mortbay.http.SocketListener;
013: import org.mortbay.http.SslListener;
014: import org.mortbay.http.handler.AbstractHttpHandler;
015: import org.mortbay.util.InetAddrPort;
016: import org.objectweb.celtix.Bus;
017: import org.objectweb.celtix.bus.configuration.security.SSLServerPolicy;
018: import org.objectweb.celtix.bus.transports.https.JettySslListenerConfigurer;
019: import org.objectweb.celtix.configuration.Configuration;
020: import org.objectweb.celtix.configuration.ConfigurationBuilder;
021: import org.objectweb.celtix.configuration.ConfigurationBuilderFactory;
022: import org.objectweb.celtix.transports.http.configuration.HTTPListenerPolicy;
023:
024: public final class JettyHTTPServerEngine {
025: private static final long serialVersionUID = 1L;
026: private static final String HTTP_LISTENER_CONFIGURATION_URI = "http://celtix.objectweb.org/bus/transports/http/http-listener-config";
027:
028: private static Map<Integer, JettyHTTPServerEngine> portMap = new HashMap<Integer, JettyHTTPServerEngine>();
029:
030: int servantCount;
031: HttpServer server;
032: SocketListener listener;
033: Configuration config;
034: HTTPListenerPolicy policy;
035: SSLServerPolicy sslPolicy;
036: int port;
037:
038: private JettyHTTPServerEngine(Bus bus, String protocol, int p) {
039: port = p;
040: config = createConfiguration(bus, port);
041: policy = config.getObject(HTTPListenerPolicy.class,
042: "httpListener");
043: sslPolicy = config
044: .getObject(SSLServerPolicy.class, "sslServer");
045: if (sslPolicy == null && "https".equals(protocol)) {
046: sslPolicy = new SSLServerPolicy();
047: }
048: }
049:
050: private Configuration createConfiguration(Bus bus, int p) {
051: // REVISIT: listener config should not be child of bus configuration
052: Configuration busCfg = bus.getConfiguration();
053: String id = "http-listener." + p;
054: ConfigurationBuilder cb = ConfigurationBuilderFactory
055: .getBuilder(null);
056: Configuration cfg = cb.getConfiguration(
057: HTTP_LISTENER_CONFIGURATION_URI, id, busCfg);
058: if (null == cfg) {
059: cfg = cb.buildConfiguration(
060: HTTP_LISTENER_CONFIGURATION_URI, id, busCfg);
061: }
062: return cfg;
063: }
064:
065: static synchronized JettyHTTPServerEngine getForPort(Bus bus,
066: String protocol, int p) {
067: JettyHTTPServerEngine ref = portMap.get(p);
068: if (ref == null) {
069: ref = new JettyHTTPServerEngine(bus, protocol, p);
070: portMap.put(p, ref);
071: }
072: return ref;
073: }
074:
075: public static synchronized void destroyForPort(int p) {
076: JettyHTTPServerEngine ref = portMap.remove(p);
077: if (ref != null && ref.server != null) {
078: try {
079: ref.listener.getServerSocket().close();
080: ref.server.stop(true);
081: ref.server.destroy();
082: ref.server = null;
083: ref.listener = null;
084: } catch (InterruptedException ex) {
085: ex.printStackTrace();
086: } catch (IOException ex) {
087: ex.printStackTrace();
088: }
089:
090: }
091: }
092:
093: synchronized void addServant(String url, AbstractHttpHandler handler) {
094:
095: URL nurl = null;
096: try {
097: nurl = new URL(url);
098: } catch (MalformedURLException e1) {
099: // TODO Auto-generated catch block
100: e1.printStackTrace();
101: }
102: String lpath = nurl.getPath();
103:
104: if (server == null) {
105: server = new HttpServer();
106:
107: if (sslPolicy != null) {
108: listener = new SslListener(new InetAddrPort(port));
109: SslListener secureListener = (SslListener) listener;
110:
111: JettySslListenerConfigurer secureListenerConfigurer = new JettySslListenerConfigurer(
112: config, sslPolicy, secureListener);
113: secureListenerConfigurer.configure();
114:
115: } else {
116: listener = new SocketListener(new InetAddrPort(port));
117: }
118:
119: if (policy.isSetMinThreads()) {
120: listener.setMinThreads(policy.getMinThreads());
121: }
122: if (policy.isSetMaxThreads()) {
123: listener.setMaxThreads(policy.getMaxThreads());
124: }
125: if (policy.isSetMaxIdleTimeMs()) {
126: listener.setMaxIdleTimeMs(policy.getMaxIdleTimeMs()
127: .intValue());
128: }
129: if (policy.isSetLowResourcePersistTimeMs()) {
130: listener.setLowResourcePersistTimeMs(policy
131: .getLowResourcePersistTimeMs().intValue());
132: }
133:
134: server.addListener(listener);
135: try {
136: server.start();
137: } catch (Exception e) {
138: // TODO Auto-generated catch block
139: e.printStackTrace();
140: }
141: }
142:
143: String contextName = "";
144: String servletMap = lpath;
145: int idx = lpath.lastIndexOf('/');
146: if (idx > 0) {
147: contextName = lpath.substring(0, idx);
148: servletMap = lpath.substring(idx);
149: }
150: final String smap = servletMap;
151:
152: HttpContext context = server.getContext(contextName);
153: try {
154: context.start();
155: } catch (Exception e1) {
156: // TODO Auto-generated catch block
157: e1.printStackTrace();
158: }
159:
160: if ("".equals(smap) && "".equals(contextName)) {
161: handler.setName("/");
162: } else {
163: handler.setName(smap);
164: }
165: context.addHandler(handler);
166: try {
167: handler.start();
168: } catch (Exception e) {
169: // TODO Auto-generated catch block
170: e.printStackTrace();
171: }
172: ++servantCount;
173: }
174:
175: synchronized void removeServant(String url) throws IOException {
176: URL nurl = new URL(url);
177: String lpath = nurl.getPath();
178:
179: String contextName = "";
180: String servletMap = lpath;
181: int idx = lpath.lastIndexOf('/');
182: if (idx > 0) {
183: contextName = lpath.substring(0, idx);
184: servletMap = lpath.substring(idx);
185: }
186: if ("".equals(servletMap) && "".equals(contextName)) {
187: servletMap = "/";
188: }
189:
190: boolean found = false;
191: // REVISIT: how come server can be null?
192: if (server != null) {
193: HttpContext context = server.getContext(contextName);
194: for (HttpHandler handler : context.getHandlers()) {
195: if (servletMap.equals(handler.getName())) {
196: try {
197: handler.stop();
198: } catch (InterruptedException e) {
199: // TODO Auto-generated catch block
200: e.printStackTrace();
201: }
202: context.removeHandler(handler);
203: found = true;
204: }
205: }
206: }
207: if (!found) {
208: System.err.println("Not able to remove the handler");
209: }
210:
211: --servantCount;
212: /* Bug in Jetty, we cannot do this. If we restart later, data goes off
213: * someplace unknown
214: if (servantCount == 0) {
215: server.removeListener(listener);
216: }
217: */
218: }
219:
220: synchronized HttpHandler getServant(String url) throws IOException {
221: URL nurl = new URL(url);
222: String lpath = nurl.getPath();
223:
224: String contextName = "";
225: String servletMap = lpath;
226: int idx = lpath.lastIndexOf('/');
227: if (idx > 0) {
228: contextName = lpath.substring(0, idx);
229: servletMap = lpath.substring(idx);
230: }
231:
232: HttpHandler ret = null;
233: // REVISIT: how come server can be null?
234: if (server != null) {
235: HttpContext context = server.getContext(contextName);
236: for (HttpHandler handler : context.getHandlers()) {
237: if (servletMap.equals(handler.getName())) {
238: ret = handler;
239: break;
240: }
241: }
242: }
243: return ret;
244: }
245: }
|