content: 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("<web-app>", Charset.defaultCharset()),
                          precompiledJspWebXml),
                  IOUtils.toInputStream("</web-app>", 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);
          }
      }
  
  }
  