1 17 18 package org.apache.geronimo.classloaderserver.http; 19 20 import java.io.ByteArrayOutputStream ; 21 import java.io.IOException ; 22 import java.io.InputStream ; 23 import java.io.OutputStream ; 24 import java.net.MalformedURLException ; 25 import java.net.URL ; 26 import java.util.HashMap ; 27 import java.util.Map ; 28 29 import org.apache.commons.logging.Log; 30 import org.apache.commons.logging.LogFactory; 31 import org.apache.geronimo.classloaderserver.ClassLoaderInfo; 32 import org.apache.geronimo.classloaderserver.ClassLoaderServer; 33 import org.apache.geronimo.classloaderserver.ClassLoaderServerException; 34 import org.apache.geronimo.gbean.GBeanInfo; 35 import org.apache.geronimo.gbean.GBeanInfoBuilder; 36 import org.apache.geronimo.gbean.GBeanLifecycle; 37 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; 38 import org.apache.geronimo.jetty.JettyContainer; 39 import org.apache.geronimo.jetty.connector.JettyConnector; 40 import org.mortbay.http.HttpContext; 41 import org.mortbay.http.HttpException; 42 import org.mortbay.http.HttpHandler; 43 import org.mortbay.http.HttpRequest; 44 import org.mortbay.http.HttpResponse; 45 46 47 51 public class HTTPClassLoaderServer implements ClassLoaderServer, GBeanLifecycle { 52 private final Log log = LogFactory.getLog(HTTPClassLoaderServer.class); 53 54 private final JettyContainer jettyContainer; 55 private final JettyConnector jettyConnector; 56 private final Map infos = new HashMap (); 57 private String protocol; 58 private String host; 59 private int port; 60 61 public HTTPClassLoaderServer(JettyContainer jettyContainer, JettyConnector jettyConnector) { 62 this.jettyContainer = jettyContainer; 63 this.jettyConnector = jettyConnector; 64 } 65 66 public void export(ClassLoaderInfo info) throws ClassLoaderServerException { 67 String id = getID(info); 68 ClassLoaderContext context = new ClassLoaderContext(id, info.getClassLoader()); 69 synchronized(infos) { 70 if (infos.containsKey(id)) { 71 throw new ClassLoaderServerException("ClassLoader with ID " + id + " already defined"); 72 } 73 infos.put(id, context); 74 } 75 jettyContainer.addContext(context); 76 try { 77 context.start(); 78 } catch (Exception e) { 79 throw new ClassLoaderServerException("Cannot start ClassLoaderContext", e); 80 } 81 82 URL url; 83 try { 84 url = new URL (protocol, host, port, id); 85 } catch (MalformedURLException e) { 86 throw new ClassLoaderServerException("Cannot build baseURL", e); 87 } 88 info.setClassLoaderServerURLs(new URL [] {url}); 89 } 90 91 public void unexport(ClassLoaderInfo info) throws ClassLoaderServerException { 92 String id = getID(info); 93 ClassLoaderContext context; 94 synchronized(infos) { 95 context = (ClassLoaderContext) infos.remove(id); 96 } 97 if (null == context) { 98 throw new ClassLoaderServerException("ClassLoader with ID " + id + " is undefined"); 99 } 100 try { 101 context.stop(); 102 } catch (InterruptedException e) { 103 log.error("Error while stopping ClassLoaderContext", e); 104 } 105 jettyContainer.removeContext(context); 106 info.setClassLoaderServerURLs(null); 107 } 108 109 public void doStart() throws Exception { 110 protocol = jettyConnector.getDefaultScheme(); 111 host = jettyConnector.getHost(); 112 port = jettyConnector.getPort(); 113 } 114 115 public void doStop() throws Exception { 116 } 117 118 public void doFail() { 119 } 120 121 private String getID(ClassLoaderInfo info) { 122 String id = info.getID().toString().replace('/', '.'); 123 return "/HTTPClassLoaderServer[" + id + "]/"; 124 } 125 126 private static class ClassLoaderContext extends HttpContext { 127 private ClassLoaderContext(String contextPath, ClassLoader cl) { 128 setContextPath(contextPath); 129 addHandler(new ClassLoaderHandler(cl)); 130 } 131 } 132 133 private static class ClassLoaderHandler implements HttpHandler { 134 private final ClassLoader cl; 135 private HttpContext httpContext; 136 private boolean started; 137 138 private ClassLoaderHandler(ClassLoader cl) { 139 this.cl = cl; 140 } 141 142 public String getName() { 143 return "ClassLoaderHandler"; 144 } 145 146 public HttpContext getHttpContext() { 147 return httpContext; 148 } 149 150 public void initialize(HttpContext httpContext) { 151 this.httpContext = httpContext; 152 } 153 154 public void handle(String pathInContext, String pathParams, HttpRequest request, HttpResponse response) throws HttpException, IOException { 155 String method=request.getMethod(); 156 if (false == method.equals(HttpRequest.__GET)) { 157 response.sendError(HttpResponse.__405_Method_Not_Allowed); 158 return; 159 } 160 161 String resource = pathInContext.substring(1); 162 163 InputStream in = cl.getResourceAsStream(resource); 164 if (null == in) { 165 response.sendError(HttpResponse.__404_Not_Found); 166 return; 167 } 168 169 ByteArrayOutputStream out = new ByteArrayOutputStream (); 170 byte[] buffer = new byte[1024]; 171 try { 172 int read = 0; 173 while (0 < (read = in.read(buffer))) { 174 out.write(buffer, 0, read); 175 } 176 } catch (IOException e) { 177 response.sendError(HttpResponse.__500_Internal_Server_Error); 178 return; 179 } 180 181 response.setContentLength(out.size()); 182 OutputStream respOut = response.getOutputStream(); 183 out.writeTo(respOut); 184 } 185 186 public void start() throws Exception { 187 started = true; 188 } 189 190 public void stop() throws InterruptedException { 191 started = false; 192 } 193 194 public boolean isStarted() { 195 return started; 196 } 197 } 198 199 public static final GBeanInfo GBEAN_INFO; 200 201 static { 202 GBeanInfoBuilder infoBuilder = new GBeanInfoBuilder("HTTP ClassLoader Server", HTTPClassLoaderServer.class); 203 204 infoBuilder.addOperation("export", new Class [] {ClassLoaderInfo.class}); 205 infoBuilder.addOperation("unexport", new Class [] {ClassLoaderInfo.class}); 206 207 infoBuilder.addReference("JettyContainer", JettyContainer.class, NameFactory.GERONIMO_SERVICE); 208 infoBuilder.addReference("JettyConnector", JettyConnector.class, NameFactory.GERONIMO_SERVICE); 209 210 infoBuilder.setConstructor(new String [] {"JettyContainer", "JettyConnector"}); 211 212 GBEAN_INFO = infoBuilder.getBeanInfo(); 213 } 214 215 public static GBeanInfo getGBeanInfo() { 216 return GBEAN_INFO; 217 } 218 } 219 220 | Popular Tags |