package org.airsonic.player.spring; import org.airsonic.player.service.SettingsService; import org.airsonic.player.spring.webxmldomain.ServletDef; import org.airsonic.player.spring.webxmldomain.ServletMappingDef; import org.airsonic.player.spring.webxmldomain.WebApp; import org.apache.commons.io.IOUtils; import org.apache.cxf.jaxb.JAXBDataBinding; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.web.servlet.ServletContextInitializer; import org.springframework.stereotype.Component; import javax.servlet.ServletContext; import javax.servlet.ServletRegistration; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import java.io.InputStream; import java.io.SequenceInputStream; import java.nio.charset.Charset; @Component public class RegisterPrecompiledJSPInitializer implements ServletContextInitializer { private static final Logger LOG = LoggerFactory.getLogger(RegisterPrecompiledJSPInitializer.class); @Override public void onStartup(ServletContext servletContext) { if (SettingsService.isDevelopmentMode()) { LOG.debug("Not registering precompiled jsps"); } else { LOG.debug("Registering precompiled jsps"); registerPrecompiledJSPs(servletContext); } } private static void registerPrecompiledJSPs(ServletContext servletContext) { WebApp webApp = parseXmlFragment(); for (ServletDef def : webApp.getServletDefs()) { LOG.trace("Registering precompiled JSP: {} -> {}", def.getName(), def.getSclass()); ServletRegistration.Dynamic reg = servletContext.addServlet(def.getName(), def.getSclass()); // Need to set loadOnStartup somewhere between 0 and 128. 0 is highest priority. 99 should be fine reg.setLoadOnStartup(99); } for (ServletMappingDef mapping : webApp.getServletMappingDefs()) { LOG.trace("Mapping servlet: {} -> {}", mapping.getName(), mapping.getUrlPattern()); servletContext.getServletRegistration(mapping.getName()).addMapping(mapping.getUrlPattern()); } } private static WebApp parseXmlFragment() { InputStream precompiledJspWebXml = RegisterPrecompiledJSPInitializer.class.getResourceAsStream("/precompiled-jsp-web.xml"); InputStream webXmlIS = new SequenceInputStream( new SequenceInputStream( IOUtils.toInputStream("", Charset.defaultCharset()), precompiledJspWebXml), IOUtils.toInputStream("", Charset.defaultCharset())); try { JAXBContext jaxbContext = new JAXBDataBinding(WebApp.class).getContext(); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); WebApp webapp = (WebApp) unmarshaller.unmarshal(webXmlIS); try { webXmlIS.close(); } catch (java.io.IOException ignored) {} return webapp; } catch (JAXBException e) { throw new RuntimeException("Could not parse precompiled-jsp-web.xml", e); } } }