001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.microservice.jetty;
018
019import static org.apache.juneau.commons.utils.FileUtils.*;
020import static org.apache.juneau.commons.utils.IoUtils.*;
021
022import java.io.*;
023import java.util.*;
024
025import org.eclipse.jetty.server.*;
026import org.eclipse.jetty.util.resource.*;
027import org.eclipse.jetty.xml.*;
028
029/**
030 * Basic implementation of a Jetty server factory.
031 *
032 * <h2 class='section'>See Also:</h2><ul>
033 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauMicroserviceJetty">juneau-microservice-jetty</a>
034 * </ul>
035 */
036public class BasicJettyServerFactory implements JettyServerFactory {
037
038   private static final String VALIDATING_PROPERTY = "org.eclipse.jetty.xml.XmlParser.Validating";
039
040   /**
041    * Jetty turns on DTD/schema validation of <c>jetty.xml</c> whenever the JDK's built-in Xerces parser is in use, which
042    * requires fetching the DTD over the network.  Newer JDKs (28+) block that fetch, so the configuration fails to load.
043    * Validation adds nothing for our shipped files, so default it off, unless the user has set the property explicitly.
044    * Jetty reads this property when its (pooled) parser is created, so it must be set before the first
045    * {@link XmlConfiguration} is constructed.
046    */
047   private static void disableXmlValidationByDefault() {
048      if (System.getProperty(VALIDATING_PROPERTY) == null)
049         System.setProperty(VALIDATING_PROPERTY, "false");
050   }
051
052   @Override
053   public Server create(String jettyXml) throws Exception {
054      Objects.requireNonNull(jettyXml,
055         "jetty.xml file location was not specified in the configuration file (Jetty/config) or manifest file (Jetty-Config) or found on the file system or classpath.");
056      var f = createTempFile("jetty.xml");
057      try (var r = new StringReader(jettyXml); Writer w = new FileWriter(f)) {
058         pipe(r, w);
059         w.flush();
060      }
061      disableXmlValidationByDefault();
062      var xmlConfiguration = new XmlConfiguration(new PathResourceFactory().newResource(f.toPath()));
063      return (Server)xmlConfiguration.configure();
064   }
065}