package com.xoom.oss.feathercon;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletHolder;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.Servlet;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ServletConfiguration {
private final Logger logger = LoggerFactory.getLogger(ServletConfiguration.class);
public final ServletHolder servletHolder;
public final Class<? extends Servlet> servletClass;
public final String servletName;
public final Integer initOrder;
public final List<String> pathSpecs;
public final Map<String, String> initParameters;
private ServletConfiguration(ServletHolder servletHolder, Class<? extends Servlet> servletClass, List<String> pathSpecs, String servletName, Integer initOrder, Map<String, String> initParameters) {
this.servletHolder = servletHolder;
this.servletClass = servletClass;
this.servletName = servletName;
this.initOrder = initOrder;
this.initParameters = Collections.unmodifiableMap(initParameters);
this.pathSpecs = Collections.unmodifiableList(pathSpecs);
if (pathSpecs.isEmpty()) {
logger.warn("Servlet {}:{} has no path specs, therefore no query will route here.", servletClass, servletName == null ? "<no servlet name>" : servletName);
}
}
public static class Builder {
private final Logger logger = LoggerFactory.getLogger(Builder.class);
Class<? extends Servlet> servletClass;
Servlet servlet;
Integer initOrder = 1;
String servletName;
List<String> pathSpecs = new ArrayList<String>();
Map<String, String> initParameters = new HashMap<String, String>();
Boolean built = false;
public Builder withServletClass(@NotNull Class<? extends Servlet> servletClass) {
if (servlet != null) {
throw new IllegalStateException(String.format("This builder already has been configured with Servlet %s", servlet));
}
if (!Servlet.class.isAssignableFrom(servletClass)) {
throw new IllegalArgumentException(String.format("Provided class %s is not a servlet", servletClass));
}
this.servletClass = servletClass;
return this;
}
@SuppressWarnings("unchecked")
public Builder withServletClassName(@NotNull String servletClassName) {
if (servlet != null) {
throw new IllegalStateException(String.format("This builder already has been configured with Servlet %s", servlet));
}
try {
Class<?> aClass = getClass().getClassLoader().loadClass(servletClassName);
if (!Servlet.class.isAssignableFrom(aClass)) {
throw new IllegalArgumentException(String.format("Provided class %s is not a servlet", servletClassName));
}
this.servletClass = (Class<? extends Servlet>) aClass;
return this;
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException(e);
}
}
public Builder withInitOrder(@NotNull Integer initOrder) {
this.initOrder = initOrder;
return this;
}
public Builder withServletName(String servletName) {
this.servletName = servletName;
return this;
}
public Builder withServlet(Servlet servlet) {
if (servletClass != null) {
throw new IllegalStateException(String.format("This builder already has been configured with Servlet class %s", servletClass));
}
this.servlet = servlet;
return this;
}
public Builder withPathSpec(@NotNull String pathSpec) {
pathSpecs.add(pathSpec);
return this;
}
public Builder withInitParameter(String key, String value) {
initParameters.put(key, value);
return this;
}
public Builder withInitParameters(Map<String, String> initParameters) {
this.initParameters.putAll(initParameters);
return this;
}
public ServletConfiguration build() {
if (built) {
throw new IllegalStateException("This builder has already built a ServletConfiguration. Please create a new builder and start over");
}
if (servletClass == null) {
servletClass = DefaultServlet.class;
}
ServletHolder servletHolder = servlet != null ? new ServletHolder(servlet) : new ServletHolder(servletClass);
if (initOrder != null) {
servletHolder.setInitOrder(initOrder);
}
if (servletName != null) {
servletHolder.setName(servletName);
}
servletHolder.setInitParameters(initParameters);
ServletConfiguration servletConfiguration = new ServletConfiguration(servletHolder, servletClass, pathSpecs, servletName, initOrder, initParameters);
built = true;
logger.info("Built {}", this);
return servletConfiguration;
}
@Override
public String toString() {
return "ServletConfigurationBuilder{" +
"servletClass=" + servletClass +
", initOrder=" + initOrder +
", servletName='" + servletName + '\'' +
", pathSpecs='" + pathSpecs + '\'' +
", initParameters=" + initParameters +
", built=" + built +
'}';
}
}
@Override
public String toString() {
return "ServletConfiguration{" +
"servletHolder=" + servletHolder +
", servletClass=" + servletClass +
", pathSpecs='" + pathSpecs + '\'' +
", servletName='" + servletName + '\'' +
", initOrder=" + initOrder +
", initParameters=" + initParameters +
'}';
}
}