001/* 002 * The contents of this file are subject to the license and copyright 003 * detailed in the LICENSE and NOTICE files at the root of the source 004 * tree. 005 */ 006package org.fcrepo.http.commons.test.util; 007 008import static org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory.createHttpServer; 009import static org.slf4j.LoggerFactory.getLogger; 010 011import java.net.URI; 012import java.util.Collection; 013 014import javax.annotation.PostConstruct; 015import javax.annotation.PreDestroy; 016import javax.xml.bind.JAXBContext; 017import javax.xml.bind.Unmarshaller; 018 019import com.google.common.base.Strings; 020import org.fcrepo.http.commons.webxml.WebAppConfig; 021import org.fcrepo.http.commons.webxml.bind.ContextParam; 022import org.fcrepo.http.commons.webxml.bind.Filter; 023import org.fcrepo.http.commons.webxml.bind.FilterMapping; 024import org.fcrepo.http.commons.webxml.bind.InitParam; 025import org.fcrepo.http.commons.webxml.bind.Listener; 026import org.fcrepo.http.commons.webxml.bind.Servlet; 027import org.fcrepo.http.commons.webxml.bind.ServletMapping; 028import org.glassfish.grizzly.http.server.HttpServer; 029import org.glassfish.grizzly.servlet.FilterRegistration; 030import org.glassfish.grizzly.servlet.ServletRegistration; 031import org.glassfish.grizzly.servlet.WebappContext; 032import org.slf4j.Logger; 033import org.springframework.beans.BeansException; 034import org.springframework.beans.factory.annotation.Value; 035import org.springframework.context.ApplicationContext; 036import org.springframework.context.ApplicationContextAware; 037import org.springframework.web.context.support.WebApplicationContextUtils; 038 039/** 040 * <p>ContainerWrapper class.</p> 041 * 042 * @author awoods 043 */ 044public class ContainerWrapper implements ApplicationContextAware { 045 046 private static final Logger logger = getLogger(ContainerWrapper.class); 047 048 private static final int DEFAULT_PORT = 8080; 049 050 @Value("${fcrepo.dynamic.test.port:" + DEFAULT_PORT + "}") 051 private String port; 052 053 private HttpServer server; 054 055 private WebappContext appContext; 056 057 private String configLocation; 058 059 public void setConfigLocation(final String configLocation) { 060 this.configLocation = configLocation.replaceFirst("^classpath:", "/"); 061 } 062 063 public void setPort(final int port) { 064 this.port = Integer.toString(port); 065 } 066 067 private int resolvePort() { 068 /* 069 This nonsense is necessary, rather than using @Value(${fcrepo.dynamic.test.port:8080}) because Intellij is 070 smart enough to attempt to set fcrepo.dynamic.test.port based on the pom but too dumb to run the 071 build-helper-maven-plugin plugin that actually determines its value. As a result, it's populated with an empty 072 value rather than null, and Spring will only default null property values. 073 */ 074 if (Strings.isNullOrEmpty(port)) { 075 return DEFAULT_PORT; 076 } 077 return Integer.parseInt(port); 078 } 079 080 @PostConstruct 081 public void start() throws Exception { 082 083 final JAXBContext context = JAXBContext.newInstance(WebAppConfig.class); 084 final Unmarshaller u = context.createUnmarshaller(); 085 final WebAppConfig o = 086 (WebAppConfig) u.unmarshal(getClass().getResource( 087 this.configLocation)); 088 089 final URI uri = URI.create("http://localhost:" + resolvePort()); 090 091 server = createHttpServer(uri); 092 093 // create a "root" web application 094 appContext = new WebappContext(o.displayName(), "/"); 095 096 for (final ContextParam p : o.contextParams()) { 097 appContext.addContextInitParameter(p.name(), p.value()); 098 } 099 100 for (final Listener l : o.listeners()) { 101 appContext.addListener(l.className()); 102 } 103 104 for (final Servlet s : o.servlets()) { 105 final ServletRegistration servlet = 106 appContext.addServlet(s.servletName(), s.servletClass()); 107 108 final Collection<ServletMapping> mappings = 109 o.servletMappings(s.servletName()); 110 for (final ServletMapping sm : mappings) { 111 servlet.addMapping(sm.urlPattern()); 112 } 113 for (final InitParam p : s.initParams()) { 114 servlet.setInitParameter(p.name(), p.value()); 115 } 116 } 117 118 for (final Filter f : o.filters()) { 119 final FilterRegistration filter = 120 appContext.addFilter(f.filterName(), f.filterClass()); 121 122 final Collection<FilterMapping> mappings = 123 o.filterMappings(f.filterName()); 124 for (final FilterMapping sm : mappings) { 125 final String urlPattern = sm.urlPattern(); 126 final String servletName = sm.servletName(); 127 if (urlPattern != null) { 128 filter.addMappingForUrlPatterns(null, urlPattern); 129 } else { 130 filter.addMappingForServletNames(null, servletName); 131 } 132 133 } 134 for (final InitParam p : f.initParams()) { 135 filter.setInitParameter(p.name(), p.value()); 136 } 137 } 138 139 appContext.deploy(server); 140 141 logger.debug("started grizzly webserver endpoint at " + 142 server.getHttpHandler().getName()); 143 } 144 145 @PreDestroy 146 public void stop() { 147 try { 148 appContext.undeploy(); 149 } catch (final Exception e) { 150 logger.warn(e.getMessage(), e); 151 } finally { 152 server.shutdownNow(); 153 } 154 } 155 156 public ApplicationContext getSpringAppContext() { 157 return WebApplicationContextUtils.findWebApplicationContext(appContext); 158 } 159 160 @Override 161 public void setApplicationContext(final ApplicationContext springAppContext) 162 throws BeansException { 163 } 164 165}