package net.unit8.waitt.server.jetty9; import net.unit8.waitt.api.ClassLoaderFactory; import net.unit8.waitt.api.EmbeddedServer; import net.unit8.waitt.api.ServerStatus; import net.unit8.waitt.api.WebappDecorator; import net.unit8.waitt.api.configuration.FilterConfiguration; import org.codehaus.plexus.classworlds.realm.ClassRealm; import org.eclipse.jetty.annotations.ServletContainerInitializersStarter; import org.eclipse.jetty.apache.jsp.JettyJasperInitializer; import org.eclipse.jetty.plus.annotation.ContainerInitializer; import org.eclipse.jetty.server.NetworkTrafficServerConnector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.webapp.WebAppClassLoader; import org.eclipse.jetty.webapp.WebAppContext; import java.io.File; import java.net.URL; import java.util.ArrayList; import java.util.List; /** * Jetty9 embedded server. * * @author kawasima */ public class Jetty9EmbeddedServer implements EmbeddedServer { final Server server; final WaittHandlerList handlers; WebAppContext mainWebapp; List<WebappDecorator> decorators; public Jetty9EmbeddedServer() { server = new Server(); handlers = new WaittHandlerList(); server.setHandler(handlers); } @Override public String getName() { return "jetty9"; } @Override public void setPort(int port) { NetworkTrafficServerConnector connector = new NetworkTrafficServerConnector(server); connector.setPort(port); server.addConnector(connector); } @Override public void setBaseDir(String baseDir) { } @Override public void setMainContext(String contextPath, String baseDir, ClassLoader loader) { mainWebapp = addWebapp(contextPath, baseDir, loader, true); } @Override public void addContext(String contextPath, String baseDir, ClassLoader loader) { addWebapp(contextPath, baseDir, loader, false); } @Override public void setClassLoaderFactory(ClassLoaderFactory factory) { ClassLoaderFactoryHolder.setClassLoaderFactory(factory); } @Override public void start() { try { server.start(); } catch (Exception e) { throw new RuntimeException(e); } } @Override public void reload() { try { mainWebapp.stop(); mainWebapp.start(); } catch (Exception e) { throw new RuntimeException(e); } } @Override public ServerStatus getStatus() { if (server.isRunning()) { return ServerStatus.RUNNING; } else if (server.isStopped()){ return ServerStatus.STOPPED; } else { return ServerStatus.UNKNOWN; } } @Override public void await() { try { server.join(); } catch (InterruptedException e) { throw new RuntimeException(e); } } @Override public void stop() { try { server.stop(); } catch (Exception e) { throw new RuntimeException(e); } } @Override public void setWebappDecorators(List<WebappDecorator> decorators) { this.decorators = decorators; } private WebAppContext addWebapp(String contextPath, String baseDir, ClassLoader loader, boolean mainContext) { WebAppContext webapp = new WebAppContext(); webapp.setContextPath(contextPath); File warFile = new File(baseDir); webapp.setWar(warFile.getAbsolutePath()); for (URL url : ((ClassRealm) loader).getURLs()) { webapp.getMetaData().addContainerResource(Resource.newResource(url)); } webapp.setExtractWAR(true); webapp.setAttribute("org.eclipse.jetty.containerInitializers", jspInitializers()); webapp.addBean(new ServletContainerInitializersStarter(webapp), true); webapp.setAllowNullPathInfo(false); if (mainContext) { for (WebappDecorator decorator : decorators) { for (FilterConfiguration filterConfig : decorator.getFilterConfigs()) { FilterHolder filterHolder = new FilterHolder(); filterHolder.setClassName(filterConfig.getClassName()); filterHolder.setName(filterConfig.getName()); webapp.addFilter(filterHolder, filterConfig.getUrlPattern()[0], null); for (URL url : ((ClassRealm) decorator.getClass().getClassLoader()).getURLs()) { ((ClassRealm) loader).addURL(url); } } } } try { if (mainContext && ClassLoaderFactoryHolder.getClassLoaderFactory() != null) { webapp.setClassLoader(new WebAppClassLoader(ClassLoaderFactoryHolder.getClassLoaderFactory().create(loader), webapp)); } else { webapp.setClassLoader(new WebAppClassLoader(loader, webapp)); } handlers.prependHandler(webapp); webapp.start(); return webapp; } catch (Exception e) { throw new RuntimeException(e); } } private List<ContainerInitializer> jspInitializers() { JettyJasperInitializer sci = new JettyJasperInitializer(); ContainerInitializer initializer = new ContainerInitializer(sci, null); List<ContainerInitializer> initializers = new ArrayList<ContainerInitializer>(); initializers.add(initializer); return initializers; } }