Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Wilkins2014-03-17 07:22:36 +0000
committerGreg Wilkins2014-03-18 22:56:19 +0000
commit119718d86fb773ae9c5839639107de4be126999e (patch)
tree1788a20ec32bd5e4e5f59143c7ac5b8af42496d2 /jetty-quickstart
parent1ffd308bbef7c9cad816631131c1029fe7ac88db (diff)
downloadorg.eclipse.jetty.project-119718d86fb773ae9c5839639107de4be126999e.tar.gz
org.eclipse.jetty.project-119718d86fb773ae9c5839639107de4be126999e.tar.xz
org.eclipse.jetty.project-119718d86fb773ae9c5839639107de4be126999e.zip
added jetty-quickstart module
Diffstat (limited to 'jetty-quickstart')
-rw-r--r--jetty-quickstart/README.txt6
-rw-r--r--jetty-quickstart/pom.xml170
-rw-r--r--jetty-quickstart/src/main/config/etc/example-quickstart.xml21
-rw-r--r--jetty-quickstart/src/main/config/modules/quickstart.mod12
-rw-r--r--jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/PreconfigureDescriptorProcessor.java88
-rw-r--r--jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/PreconfigureQuickStartWar.java129
-rw-r--r--jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartConfiguration.java139
-rw-r--r--jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartDescriptorProcessor.java218
-rw-r--r--jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartWebApp.java720
-rw-r--r--jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureJNDIWar.java49
-rw-r--r--jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureSpecWar.java58
-rw-r--r--jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureStandardTestWar.java62
-rw-r--r--jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartJNDIWar.java31
-rw-r--r--jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartSpecWar.java30
-rw-r--r--jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartStandardTestWar.java30
-rw-r--r--jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/Quickstart.java73
-rw-r--r--jetty-quickstart/src/test/resources/realm.properties21
-rw-r--r--jetty-quickstart/src/test/resources/test-jndi.xml60
-rw-r--r--jetty-quickstart/src/test/resources/test-spec.xml39
-rw-r--r--jetty-quickstart/src/test/resources/test.xml45
20 files changed, 2001 insertions, 0 deletions
diff --git a/jetty-quickstart/README.txt b/jetty-quickstart/README.txt
new file mode 100644
index 0000000000..43ad7f3e9f
--- /dev/null
+++ b/jetty-quickstart/README.txt
@@ -0,0 +1,6 @@
+mvn exec:java -Dexec.classpathScope=test -Dexec.mainClass="org.eclipse.jetty.quickstart.StartBenchmarkWar"
+
+OR
+
+mvn exec:java -Dexec.classpathScope=test -Dexec.mainClass="org.eclipse.jetty.quickstart.PreconfigureBenchmarkWar"
+mvn exec:java -Dexec.classpathScope=test -Dexec.mainClass="org.eclipse.jetty.quickstart.QuickStartBenchmarkWar"
diff --git a/jetty-quickstart/pom.xml b/jetty-quickstart/pom.xml
new file mode 100644
index 0000000000..5f9f03cf97
--- /dev/null
+++ b/jetty-quickstart/pom.xml
@@ -0,0 +1,170 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-project</artifactId>
+ <version>9.1.4-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-quickstart</artifactId>
+ <name>Example :: Jetty Quick Start</name>
+ <description>Jetty Quick Start</description>
+ <url>http://www.eclipse.org/jetty</url>
+ <dependencies>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-webapp</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-jmx</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-plus</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-annotations</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.transaction</groupId>
+ <artifactId>javax.transaction-api</artifactId>
+ <version>1.2</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty.tests</groupId>
+ <artifactId>test-mock-resources</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty.orbit</groupId>
+ <artifactId>javax.mail.glassfish</artifactId>
+ <version>1.4.1.v201005082020</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-servlets</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty.websocket</groupId>
+ <artifactId>javax-websocket-server-impl</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty.websocket</groupId>
+ <artifactId>websocket-server</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>apache-jsp</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>apache-jstl</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>appassembler-maven-plugin</artifactId>
+ <version>1.7</version>
+ <configuration>
+ <platforms>
+ <platform>unix</platform>
+ </platforms>
+ <programs>
+ <program>
+ <id>preconfigure</id>
+ <mainClass>org.eclipse.jetty.quickstart.PreconfigureQuickStartWar</mainClass>
+ </program>
+ <program>
+ <mainClass>org.eclipse.jetty.quickstart.QuickStartWar</mainClass>
+ <id>quickstart</id>
+ </program>
+ </programs>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>org.eclipse.jetty.tests</groupId>
+ <artifactId>test-jndi-webapp</artifactId>
+ <version>${project.version}</version>
+ <type>war</type>
+ <overWrite>true</overWrite>
+ <includes>**</includes>
+ <outputDirectory>${basedir}/target</outputDirectory>
+ <destFileName>test-jndi.war</destFileName>
+ </artifactItem>
+ <artifactItem>
+ <groupId>org.eclipse.jetty.tests</groupId>
+ <artifactId>test-spec-webapp</artifactId>
+ <version>${project.version}</version>
+ <type>war</type>
+ <overWrite>true</overWrite>
+ <includes>**</includes>
+ <outputDirectory>${basedir}/target</outputDirectory>
+ <destFileName>test-spec.war</destFileName>
+ </artifactItem>
+ <artifactItem>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>test-jetty-webapp</artifactId>
+ <version>${project.version}</version>
+ <type>war</type>
+ <overWrite>true</overWrite>
+ <includes>**</includes>
+ <outputDirectory>${basedir}/target</outputDirectory>
+ <destFileName>test-standard.war</destFileName>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <descriptorRefs>
+ <descriptorRef>config</descriptorRef>
+ </descriptorRefs>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/jetty-quickstart/src/main/config/etc/example-quickstart.xml b/jetty-quickstart/src/main/config/etc/example-quickstart.xml
new file mode 100644
index 0000000000..9a012c701a
--- /dev/null
+++ b/jetty-quickstart/src/main/config/etc/example-quickstart.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
+
+<!-- An example context XML for a quickstart webapp
+A quick started webapp has all the jar scanning and fragment resolution done in a
+Preconfigure phase, with all the discovered configuration encoded into a
+WEB-INF/quickstart-web.xml file.
+
+This allows very rapid and precise starting of a webapp, without the risk of accidental
+deployment of other discovered resources. This is above and beyond what is available
+with web.xml meta-data-complete, as it also prevents scanning for ServletContainer
+initialisers and any annotations/classes they require.
+
+If autoPreconfigure is set to true, then the webapp will be preconfigured the first
+time it is run.
+ -->
+<Configure class="org.eclipse.jetty.quickstart.QuickStartWebApp">
+ <Set name="autoPreconfigure">true</Set>
+ <Set name="contextPath">/</Set>
+ <Set name="war"><Property name="jetty.webapps" default="."/>/application.war</Set>
+</Configure>
diff --git a/jetty-quickstart/src/main/config/modules/quickstart.mod b/jetty-quickstart/src/main/config/modules/quickstart.mod
new file mode 100644
index 0000000000..89db9fd4fe
--- /dev/null
+++ b/jetty-quickstart/src/main/config/modules/quickstart.mod
@@ -0,0 +1,12 @@
+#
+# Jetty Quickstart module
+#
+
+[depend]
+server
+plus
+annotations
+
+
+[lib]
+lib/jetty-quickstart-${jetty.version}.jar
diff --git a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/PreconfigureDescriptorProcessor.java b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/PreconfigureDescriptorProcessor.java
new file mode 100644
index 0000000000..627277e2eb
--- /dev/null
+++ b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/PreconfigureDescriptorProcessor.java
@@ -0,0 +1,88 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.quickstart;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.webapp.Descriptor;
+import org.eclipse.jetty.webapp.IterativeDescriptorProcessor;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.xml.XmlParser;
+
+/**
+ * Preconfigure DescriptorProcessor
+ *
+ * Saves literal XML snippets
+ *
+ */
+
+public class PreconfigureDescriptorProcessor extends IterativeDescriptorProcessor
+{
+ private static final Logger LOG = Log.getLogger(PreconfigureDescriptorProcessor.class);
+
+ private final StringBuilder _buffer = new StringBuilder();
+ private final boolean _showOrigin;
+ private String _origin;
+
+ public PreconfigureDescriptorProcessor ()
+ {
+ _showOrigin=LOG.isDebugEnabled();
+ try
+ {
+ registerVisitor("env-entry", getClass().getDeclaredMethod("saveSnippet", __signature));
+ registerVisitor("resource-ref", getClass().getDeclaredMethod("saveSnippet", __signature));
+ registerVisitor("resource-env-ref", getClass().getDeclaredMethod("saveSnippet", __signature));
+ registerVisitor("message-destination-ref", getClass().getDeclaredMethod("saveSnippet", __signature));
+ registerVisitor("data-source", getClass().getDeclaredMethod("saveSnippet", __signature));
+ }
+ catch (Exception e)
+ {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Override
+ public void start(WebAppContext context, Descriptor descriptor)
+ {
+ LOG.debug("process {}",descriptor);
+ _origin=(" <!-- "+descriptor+" -->\n");
+ }
+
+
+ @Override
+ public void end(WebAppContext context,Descriptor descriptor)
+ {
+ }
+
+
+ public void saveSnippet (WebAppContext context, Descriptor descriptor, XmlParser.Node node)
+ throws Exception
+ {
+ LOG.debug("save {}",node.getTag());
+ if (_showOrigin)
+ _buffer.append(_origin);
+ _buffer.append(" ").append(node.toString()).append("\n");
+ }
+
+ public String getXML()
+ {
+ return _buffer.toString();
+ }
+
+}
diff --git a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/PreconfigureQuickStartWar.java b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/PreconfigureQuickStartWar.java
new file mode 100644
index 0000000000..204ad2ecd1
--- /dev/null
+++ b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/PreconfigureQuickStartWar.java
@@ -0,0 +1,129 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.quickstart;
+
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.JarResource;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.xml.XmlConfiguration;
+
+public class PreconfigureQuickStartWar
+{
+ private static final Logger LOG = Log.getLogger(PreconfigureQuickStartWar.class);
+ static final boolean ORIGIN=LOG.isDebugEnabled();
+
+
+ public static void main(String... args) throws Exception
+ {
+ Resource war = null;
+ Resource dir = null;
+ Resource xml = null;
+
+ switch (args.length)
+ {
+ case 0:
+ error("No WAR file or directory given");
+ break;
+
+ case 1:
+ dir = Resource.newResource(args[0]);
+
+ case 2:
+ war = Resource.newResource(args[0]);
+ if (war.isDirectory())
+ {
+ dir = war;
+ war = null;
+ xml = Resource.newResource(args[1]);
+ }
+ else
+ {
+ dir = Resource.newResource(args[1]);
+ }
+
+ break;
+
+ case 3:
+ war = Resource.newResource(args[0]);
+ dir = Resource.newResource(args[1]);
+ xml = Resource.newResource(args[2]);
+ break;
+
+ default:
+ error("Too many args");
+ break;
+ }
+
+
+ preconfigure(war,dir,xml);
+ }
+
+ /**
+ * @param war The war (or directory) to preconfigure
+ * @param dir The directory to expand the war into (or null if war is a directory)
+ * @param xml A context XML to apply (or null if none)
+ * @throws Exception
+ */
+ public static void preconfigure(Resource war, Resource dir, Resource xml) throws Exception
+ {
+ // Do we need to unpack a war?
+ if (war != null)
+ {
+ if (war.isDirectory())
+ error("war file is directory");
+
+ if (!dir.exists())
+ dir.getFile().mkdirs();
+ JarResource.newJarResource(war).copyTo(dir.getFile());
+ }
+
+ final Server server = new Server();
+
+ QuickStartWebApp webapp = new QuickStartWebApp();
+
+ if (xml != null)
+ {
+ if (xml.isDirectory() || !xml.toString().toLowerCase().endsWith(".xml"))
+ error("Bad context.xml: "+xml);
+ XmlConfiguration xmlConfiguration = new XmlConfiguration(xml.getURL());
+ xmlConfiguration.configure(webapp);
+ }
+ webapp.setResourceBase(dir.getFile().getAbsolutePath());
+ webapp.setPreconfigure(true);
+ server.setHandler(webapp);
+ server.start();
+ server.stop();
+ }
+
+
+
+
+ private static void error(String message)
+ {
+ System.err.println("ERROR: " + message);
+ System.err.println("Usage: java -jar PreconfigureQuickStartWar.jar <war-directory>");
+ System.err.println(" java -jar PreconfigureQuickStartWar.jar <war-directory> <context-xml-file>");
+ System.err.println(" java -jar PreconfigureQuickStartWar.jar <war-file> <target-war-directory>");
+ System.err.println(" java -jar PreconfigureQuickStartWar.jar <war-file> <target-war-directory> <context-xml-file>");
+ System.exit(1);
+ }
+
+}
diff --git a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartConfiguration.java b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartConfiguration.java
new file mode 100644
index 0000000000..313c5c03c8
--- /dev/null
+++ b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartConfiguration.java
@@ -0,0 +1,139 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.quickstart;
+
+import org.eclipse.jetty.annotations.AnnotationConfiguration;
+import org.eclipse.jetty.annotations.AnnotationDecorator;
+import org.eclipse.jetty.annotations.ServletContainerInitializersStarter;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.webapp.StandardDescriptorProcessor;
+import org.eclipse.jetty.webapp.WebAppClassLoader;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.webapp.WebInfConfiguration;
+
+/**
+ * QuickStartConfiguration
+ *
+ * Re-inflate a deployable webapp from a saved effective-web.xml
+ * which combines all pre-parsed web xml descriptors and annotations.
+ *
+ */
+public class QuickStartConfiguration extends WebInfConfiguration
+{
+ private static final Logger LOG = Log.getLogger(QuickStartConfiguration.class);
+
+ /**
+ * @see org.eclipse.jetty.webapp.AbstractConfiguration#preConfigure(org.eclipse.jetty.webapp.WebAppContext)
+ */
+ @Override
+ public void preConfigure(WebAppContext context) throws Exception
+ {
+ //check that webapp is suitable for quick start - it is not a packed war
+ String war = context.getWar();
+ if (war == null || war.length()<=0)
+ throw new IllegalStateException ("No location for webapp");
+
+ //Make a temp directory for the webapp if one is not already set
+ resolveTempDirectory(context);
+
+ Resource webApp = context.newResource(war);
+
+ // Accept aliases for WAR files
+ if (webApp.getAlias() != null)
+ {
+ LOG.debug(webApp + " anti-aliased to " + webApp.getAlias());
+ webApp = context.newResource(webApp.getAlias());
+ }
+
+ // Is the WAR usable directly?
+ if (!webApp.exists() || !webApp.isDirectory() || webApp.toString().startsWith("jar:"))
+ throw new IllegalStateException("Webapp does not exist or is not unpacked");
+
+ context.setBaseResource(webApp);
+
+ LOG.debug("webapp={}",webApp);
+
+
+ //look for effective-web.xml in WEB-INF of webapp
+ Resource webInf = context.getWebInf();
+ if (webInf == null || !webInf.exists())
+ throw new IllegalStateException("No WEB-INF");
+ LOG.debug("webinf={}",webInf);
+
+ Resource quickStartWebXml = webInf.addPath("quickstart-web.xml");
+ if (!quickStartWebXml.exists())
+ throw new IllegalStateException ("No WEB-INF/quickstart-web.xml");
+ LOG.debug("quickStartWebXml={}",quickStartWebXml);
+
+ context.getMetaData().setWebXml(quickStartWebXml);
+ }
+
+
+ /**
+ * @see org.eclipse.jetty.webapp.AbstractConfiguration#configure(org.eclipse.jetty.webapp.WebAppContext)
+ */
+ @Override
+ public void configure(WebAppContext context) throws Exception
+ {
+ LOG.debug("configure {}",this);
+ if (context.isStarted())
+ {
+ LOG.warn("Cannot configure webapp after it is started");
+ return;
+ }
+
+ //Temporary: set up the classpath here. This should be handled by the QuickStartDescriptorProcessor
+ Resource webInf = context.getWebInf();
+
+ if (webInf != null && webInf.isDirectory() && context.getClassLoader() instanceof WebAppClassLoader)
+ {
+ // Look for classes directory
+ Resource classes= webInf.addPath("classes/");
+ if (classes.exists())
+ ((WebAppClassLoader)context.getClassLoader()).addClassPath(classes);
+
+ // Look for jars
+ Resource lib= webInf.addPath("lib/");
+ if (lib.exists() || lib.isDirectory())
+ ((WebAppClassLoader)context.getClassLoader()).addJars(lib);
+ }
+
+ //add the processor to handle normal web.xml content
+ context.getMetaData().addDescriptorProcessor(new StandardDescriptorProcessor());
+
+ //add a processor to handle extended web.xml format
+ context.getMetaData().addDescriptorProcessor(new QuickStartDescriptorProcessor());
+
+ //add a decorator that will find introspectable annotations
+ context.addDecorator(new AnnotationDecorator(context)); //this must be the last Decorator because they are run in reverse order!
+
+ //add a context bean that will run ServletContainerInitializers as the context starts
+ ServletContainerInitializersStarter starter = (ServletContainerInitializersStarter)context.getAttribute(AnnotationConfiguration.CONTAINER_INITIALIZER_STARTER);
+ if (starter != null)
+ throw new IllegalStateException("ServletContainerInitializersStarter already exists");
+ starter = new ServletContainerInitializersStarter(context);
+ context.setAttribute(AnnotationConfiguration.CONTAINER_INITIALIZER_STARTER, starter);
+ context.addBean(starter, true);
+
+ LOG.debug("configured {}",this);
+ }
+
+}
diff --git a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartDescriptorProcessor.java b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartDescriptorProcessor.java
new file mode 100644
index 0000000000..7e5a6c849b
--- /dev/null
+++ b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartDescriptorProcessor.java
@@ -0,0 +1,218 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.quickstart;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+
+import javax.servlet.ServletContext;
+
+import org.eclipse.jetty.annotations.AnnotationConfiguration;
+import org.eclipse.jetty.annotations.ServletContainerInitializersStarter;
+import org.eclipse.jetty.plus.annotation.ContainerInitializer;
+import org.eclipse.jetty.util.QuotedStringTokenizer;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.util.resource.ResourceCollection;
+import org.eclipse.jetty.webapp.Descriptor;
+import org.eclipse.jetty.webapp.IterativeDescriptorProcessor;
+import org.eclipse.jetty.webapp.MetaInfConfiguration;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.xml.XmlParser;
+
+/**
+ * QuickStartDescriptorProcessor
+ *
+ * Handle extended elements for quickstart-web.xml
+ */
+public class QuickStartDescriptorProcessor extends IterativeDescriptorProcessor
+{
+ /**
+ *
+ */
+ public QuickStartDescriptorProcessor()
+ {
+ try
+ {
+ registerVisitor("context-param", this.getClass().getDeclaredMethod("visitContextParam", __signature));
+ }
+ catch (Exception e)
+ {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ /**
+ * @see org.eclipse.jetty.webapp.IterativeDescriptorProcessor#start(org.eclipse.jetty.webapp.WebAppContext, org.eclipse.jetty.webapp.Descriptor)
+ */
+ @Override
+ public void start(WebAppContext context, Descriptor descriptor)
+ {
+ }
+
+ /**
+ * @see org.eclipse.jetty.webapp.IterativeDescriptorProcessor#end(org.eclipse.jetty.webapp.WebAppContext, org.eclipse.jetty.webapp.Descriptor)
+ */
+ @Override
+ public void end(WebAppContext context, Descriptor descriptor)
+ {
+ }
+
+
+ /**
+ * @param context
+ * @param descriptor
+ * @param node
+ */
+ public void visitContextParam (WebAppContext context, Descriptor descriptor, XmlParser.Node node)
+ throws Exception
+ {
+ String name = node.getString("param-name", false, true);
+ String value = node.getString("param-value", false, true);
+ List<String> values = new ArrayList<>();
+
+ // extract values
+ switch(name)
+ {
+ case ServletContext.ORDERED_LIBS:
+ case AnnotationConfiguration.CONTAINER_INITIALIZERS:
+ case MetaInfConfiguration.METAINF_TLDS:
+ case MetaInfConfiguration.METAINF_RESOURCES:
+
+ context.removeAttribute(name);
+
+ QuotedStringTokenizer tok = new QuotedStringTokenizer(value,",");
+ while(tok.hasMoreElements())
+ values.add(tok.nextToken().trim());
+
+ break;
+
+ default:
+ values.add(value);
+ }
+
+ // handle values
+ switch(name)
+ {
+ case ServletContext.ORDERED_LIBS:
+ {
+ List<Object> libs = new ArrayList<>();
+ Object o=context.getAttribute(ServletContext.ORDERED_LIBS);
+ if (o instanceof Collection<?>)
+ libs.addAll((Collection<?>)o);
+ libs.addAll(values);
+ if (libs.size()>0)
+ context.setAttribute(ServletContext.ORDERED_LIBS,libs);
+
+ break;
+ }
+
+ case AnnotationConfiguration.CONTAINER_INITIALIZERS:
+ {
+ for (String i : values)
+ visitContainerInitializer(context, new ContainerInitializer(Thread.currentThread().getContextClassLoader(), i));
+ break;
+ }
+
+ case MetaInfConfiguration.METAINF_TLDS:
+ {
+ List<Object> tlds = new ArrayList<>();
+ String war=context.getBaseResource().getURI().toString();
+ Object o=context.getAttribute(MetaInfConfiguration.METAINF_TLDS);
+ if (o instanceof Collection<?>)
+ tlds.addAll((Collection<?>)o);
+ for (String i : values)
+ {
+ Resource r = Resource.newResource(i.replace("${WAR}/",war));
+ if (r.exists())
+ tlds.add(r.getURL());
+ else
+ throw new IllegalArgumentException("TLD not found: "+r);
+ }
+
+ if (tlds.size()>0)
+ context.setAttribute(MetaInfConfiguration.METAINF_TLDS,tlds);
+ break;
+ }
+
+ case MetaInfConfiguration.METAINF_RESOURCES:
+ {
+ String war=context.getBaseResource().getURI().toString();
+ for (String i : values)
+ {
+ Resource r = Resource.newResource(i.replace("${WAR}/",war));
+ if (r.exists())
+ visitMetaInfResource(context,r);
+ else
+ throw new IllegalArgumentException("Resource not found: "+r);
+ }
+ break;
+ }
+
+ default:
+
+ }
+ }
+
+
+ public void visitContainerInitializer (WebAppContext context, ContainerInitializer containerInitializer)
+ {
+ if (containerInitializer == null)
+ return;
+
+ //add the ContainerInitializer to the list of container initializers
+ List<ContainerInitializer> containerInitializers = (List<ContainerInitializer>)context.getAttribute(AnnotationConfiguration.CONTAINER_INITIALIZERS);
+ if (containerInitializers == null)
+ {
+ containerInitializers = new ArrayList<ContainerInitializer>();
+ context.setAttribute(AnnotationConfiguration.CONTAINER_INITIALIZERS, containerInitializers);
+ }
+
+ containerInitializers.add(containerInitializer);
+
+ //Ensure a bean is set up on the context that will invoke the ContainerInitializers as the context starts
+ ServletContainerInitializersStarter starter = (ServletContainerInitializersStarter)context.getAttribute(AnnotationConfiguration.CONTAINER_INITIALIZER_STARTER);
+ if (starter == null)
+ {
+ starter = new ServletContainerInitializersStarter(context);
+ context.setAttribute(AnnotationConfiguration.CONTAINER_INITIALIZER_STARTER, starter);
+ context.addBean(starter, true);
+ }
+ }
+
+
+ public void visitMetaInfResource (WebAppContext context, Resource dir)
+ {
+ Collection<Resource> metaInfResources = (Collection<Resource>)context.getAttribute(MetaInfConfiguration.METAINF_RESOURCES);
+ if (metaInfResources == null)
+ {
+ metaInfResources = new HashSet<Resource>();
+ context.setAttribute(MetaInfConfiguration.METAINF_RESOURCES, metaInfResources);
+ }
+ metaInfResources.add(dir);
+ //also add to base resource of webapp
+ Resource[] collection=new Resource[metaInfResources.size()+1];
+ int i=0;
+ collection[i++]=context.getBaseResource();
+ for (Resource resource : metaInfResources)
+ collection[i++]=resource;
+ context.setBaseResource(new ResourceCollection(collection));
+ }
+}
diff --git a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartWebApp.java b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartWebApp.java
new file mode 100644
index 0000000000..bcbcab8080
--- /dev/null
+++ b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartWebApp.java
@@ -0,0 +1,720 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.quickstart;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EventListener;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.DispatcherType;
+import javax.servlet.MultipartConfigElement;
+import javax.servlet.ServletContext;
+import javax.servlet.SessionCookieConfig;
+import javax.servlet.SessionTrackingMode;
+import javax.servlet.descriptor.JspPropertyGroupDescriptor;
+import javax.servlet.descriptor.TaglibDescriptor;
+
+import org.eclipse.jetty.annotations.AnnotationConfiguration;
+import org.eclipse.jetty.http.MimeTypes;
+import org.eclipse.jetty.plus.annotation.LifeCycleCallback;
+import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
+import org.eclipse.jetty.security.ConstraintAware;
+import org.eclipse.jetty.security.ConstraintMapping;
+import org.eclipse.jetty.security.SecurityHandler;
+import org.eclipse.jetty.security.authentication.FormAuthenticator;
+import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.servlet.FilterMapping;
+import org.eclipse.jetty.servlet.Holder;
+import org.eclipse.jetty.servlet.ServletHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.servlet.ServletMapping;
+import org.eclipse.jetty.util.QuotedStringTokenizer;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.JarResource;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.util.security.Constraint;
+import org.eclipse.jetty.webapp.MetaData;
+import org.eclipse.jetty.webapp.MetaData.OriginInfo;
+import org.eclipse.jetty.webapp.MetaInfConfiguration;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.xml.XmlAppendable;
+
+/**
+ * QuickStartWar
+ *
+ */
+public class QuickStartWebApp extends WebAppContext
+{
+ private static final Logger LOG = Log.getLogger(QuickStartWebApp.class);
+
+ public static final String[] __configurationClasses = new String[]
+ {
+ org.eclipse.jetty.quickstart.QuickStartConfiguration.class.getCanonicalName(),
+ org.eclipse.jetty.plus.webapp.EnvConfiguration.class.getCanonicalName(),
+ org.eclipse.jetty.plus.webapp.PlusConfiguration.class.getCanonicalName(),
+ org.eclipse.jetty.webapp.JettyWebXmlConfiguration.class.getCanonicalName()
+ };
+
+
+ private boolean _preconfigure=false;
+ private boolean _autoPreconfigure=false;
+ private boolean _startWebapp=false;
+ private PreconfigureDescriptorProcessor _preconfigProcessor;
+
+
+ public static final String[] __preconfigurationClasses = new String[]
+ {
+ org.eclipse.jetty.webapp.WebInfConfiguration.class.getCanonicalName(),
+ org.eclipse.jetty.webapp.WebXmlConfiguration.class.getCanonicalName(),
+ org.eclipse.jetty.webapp.MetaInfConfiguration.class.getCanonicalName(),
+ org.eclipse.jetty.webapp.FragmentConfiguration.class.getCanonicalName(),
+ org.eclipse.jetty.plus.webapp.EnvConfiguration.class.getCanonicalName(),
+ org.eclipse.jetty.plus.webapp.PlusConfiguration.class.getCanonicalName(),
+ org.eclipse.jetty.annotations.AnnotationConfiguration.class.getCanonicalName(),
+ };
+
+ public QuickStartWebApp()
+ {
+ super();
+ setConfigurationClasses(__preconfigurationClasses);
+ setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",".*\\.jar");
+ }
+
+ public boolean isPreconfigure()
+ {
+ return _preconfigure;
+ }
+
+ /* ------------------------------------------------------------ */
+ /** Preconfigure webapp
+ * @param preconfigure If true, then starting the webapp will generate
+ * the WEB-INF/quickstart-web.xml rather than start the webapp.
+ */
+ public void setPreconfigure(boolean preconfigure)
+ {
+ _preconfigure = preconfigure;
+ }
+
+ public boolean isAutoPreconfigure()
+ {
+ return _autoPreconfigure;
+ }
+
+ public void setAutoPreconfigure(boolean autoPrecompile)
+ {
+ _autoPreconfigure = autoPrecompile;
+ }
+
+ @Override
+ protected void startWebapp() throws Exception
+ {
+ if (isPreconfigure())
+ generateQuickstartWebXml(_preconfigProcessor.getXML());
+
+ if (_startWebapp)
+ super.startWebapp();
+ }
+
+ @Override
+ protected void doStart() throws Exception
+ {
+ // unpack and Adjust paths.
+ Resource war = null;
+ Resource dir = null;
+
+ Resource base = getBaseResource();
+ if (base==null)
+ base=Resource.newResource(getWar());
+
+ if (base.isDirectory())
+ dir=base;
+ else if (base.toString().toLowerCase().endsWith(".war"))
+ {
+ war=base;
+ String w=war.toString();
+ dir=Resource.newResource(w.substring(0,w.length()-4));
+
+ if (!dir.exists())
+ {
+ LOG.info("Quickstart Extract " + war + " to " + dir);
+ dir.getFile().mkdirs();
+ JarResource.newJarResource(war).copyTo(dir.getFile());
+ }
+
+ setWar(null);
+ setBaseResource(dir);
+ }
+ else
+ throw new IllegalArgumentException();
+
+
+ Resource qswebxml=dir.addPath("/WEB-INF/quickstart-web.xml");
+
+ if (isPreconfigure())
+ {
+ _preconfigProcessor = new PreconfigureDescriptorProcessor();
+ getMetaData().addDescriptorProcessor(_preconfigProcessor);
+ _startWebapp=false;
+ }
+ else if (qswebxml.exists())
+ {
+ setConfigurationClasses(__configurationClasses);
+ _startWebapp=true;
+ }
+ else if (_autoPreconfigure)
+ {
+ LOG.info("Quickstart preconfigure: {}(war={},dir={})",this,war,dir);
+
+ _preconfigProcessor = new PreconfigureDescriptorProcessor();
+
+ getMetaData().addDescriptorProcessor(_preconfigProcessor);
+ setPreconfigure(true);
+ _startWebapp=true;
+ }
+ else
+ _startWebapp=true;
+
+ super.doStart();
+ }
+
+
+ public void generateQuickstartWebXml(String extraXML) throws IOException
+ {
+ getMetaData().getOrigins();
+ // dumpStdErr();
+
+ if (getBaseResource()==null)
+ throw new IllegalArgumentException("No base resource for "+this);
+
+ File webxml = new File(getWebInf().getFile(),"quickstart-web.xml");
+
+ LOG.info("Quickstart generate {}",webxml);
+
+ XmlAppendable out = new XmlAppendable(new FileOutputStream(webxml),"UTF-8");
+ MetaData md = getMetaData();
+
+ Map<String, String> webappAttr = new HashMap<>();
+ webappAttr.put("xmlns","http://xmlns.jcp.org/xml/ns/javaee");
+ webappAttr.put("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance");
+ webappAttr.put("xsi:schemaLocation","http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd");
+ webappAttr.put("metadata-complete","true");
+ webappAttr.put("version","3.1");
+
+ out.open("web-app",webappAttr);
+
+ if (getDisplayName() != null)
+ out.tag("display-name",getDisplayName());
+
+ // Set some special context parameters
+
+ // The location of the war file on disk
+ String resourceBase=getBaseResource().getFile().getCanonicalFile().getAbsoluteFile().toURI().toString();
+
+ // The library order
+ addContextParamFromAttribute(out,ServletContext.ORDERED_LIBS);
+ //the servlet container initializers
+ addContextParamFromAttribute(out,AnnotationConfiguration.CONTAINER_INITIALIZERS);
+ //the tlds discovered
+ addContextParamFromAttribute(out,MetaInfConfiguration.METAINF_TLDS,resourceBase);
+ //the META-INF/resources discovered
+ addContextParamFromAttribute(out,MetaInfConfiguration.METAINF_RESOURCES,resourceBase);
+
+
+ // init params
+ for (String p : getInitParams().keySet())
+ out.open("context-param",origin(md,"context-param." + p))
+ .tag("param-name",p)
+ .tag("param-value",getInitParameter(p))
+ .close();
+
+ if (getEventListeners() != null)
+ for (EventListener e : getEventListeners())
+ out.open("listener",origin(md,e.getClass().getCanonicalName() + ".listener"))
+ .tag("listener-class",e.getClass().getCanonicalName())
+ .close();
+
+ ServletHandler servlets = getServletHandler();
+
+ if (servlets.getFilters() != null)
+ {
+ for (FilterHolder holder : servlets.getFilters())
+ outholder(out,md,"filter",holder);
+ }
+
+ if (servlets.getFilterMappings() != null)
+ {
+ for (FilterMapping mapping : servlets.getFilterMappings())
+ {
+ out.open("filter-mapping");
+ out.tag("filter-name",mapping.getFilterName());
+ if (mapping.getPathSpecs() != null)
+ for (String s : mapping.getPathSpecs())
+ out.tag("url-pattern",s);
+ if (mapping.getServletNames() != null)
+ for (String n : mapping.getServletNames())
+ out.tag("servlet-name",n);
+
+ if (!mapping.isDefaultDispatches())
+ {
+ if (mapping.appliesTo(DispatcherType.REQUEST))
+ out.tag("dispatcher","REQUEST");
+ if (mapping.appliesTo(DispatcherType.ASYNC))
+ out.tag("dispatcher","ASYNC");
+ if (mapping.appliesTo(DispatcherType.ERROR))
+ out.tag("dispatcher","ERROR");
+ if (mapping.appliesTo(DispatcherType.FORWARD))
+ out.tag("dispatcher","FORWARD");
+ if (mapping.appliesTo(DispatcherType.INCLUDE))
+ out.tag("dispatcher","INCLUDE");
+ }
+ out.close();
+ }
+ }
+
+ if (servlets.getServlets() != null)
+ {
+ for (ServletHolder holder : servlets.getServlets())
+ outholder(out,md,"servlet",holder);
+ }
+
+ if (servlets.getServletMappings() != null)
+ {
+ for (ServletMapping mapping : servlets.getServletMappings())
+ {
+ out.open("servlet-mapping",origin(md,mapping.getServletName() + ".servlet.mappings"));
+ out.tag("servlet-name",mapping.getServletName());
+ if (mapping.getPathSpecs() != null)
+ for (String s : mapping.getPathSpecs())
+ out.tag("url-pattern",s);
+ out.close();
+ }
+ }
+
+ // Security elements
+ SecurityHandler security = getSecurityHandler();
+
+ if (security!=null && (security.getRealmName()!=null || security.getAuthMethod()!=null))
+ {
+ out.open("login-config");
+ if (security.getAuthMethod()!=null)
+ out.tag("auth-method",origin(md,"auth-method"),security.getAuthMethod());
+ if (security.getRealmName()!=null)
+ out.tag("realm-name",origin(md,"realm-name"),security.getRealmName());
+
+
+ if (Constraint.__FORM_AUTH.equalsIgnoreCase(security.getAuthMethod()))
+ {
+ out.open("form-login-config");
+ out.tag("form-login-page",origin(md,"form-login-page"),security.getInitParameter(FormAuthenticator.__FORM_LOGIN_PAGE));
+ out.tag("form-error-page",origin(md,"form-error-page"),security.getInitParameter(FormAuthenticator.__FORM_ERROR_PAGE));
+ out.close();
+ }
+
+ out.close();
+ }
+
+ if (security instanceof ConstraintAware)
+ {
+ ConstraintAware ca = (ConstraintAware)security;
+ for (String r:ca.getRoles())
+ out.open("security-role")
+ .tag("role-name",r)
+ .close();
+
+ for (ConstraintMapping m : ca.getConstraintMappings())
+ {
+ out.open("security-constraint");
+
+ if (m.getConstraint().getAuthenticate())
+ {
+ out.open("auth-constraint");
+ if (m.getConstraint().getRoles()!=null)
+ for (String r : m.getConstraint().getRoles())
+ out.tag("role-name",r);
+
+ out.close();
+ }
+
+ switch (m.getConstraint().getDataConstraint())
+ {
+ case Constraint.DC_NONE:
+ out.open("user-data-constraint").tag("transport-guarantee","NONE").close();
+ break;
+
+ case Constraint.DC_INTEGRAL:
+ out.open("user-data-constraint").tag("transport-guarantee","INTEGRAL").close();
+ break;
+
+ case Constraint.DC_CONFIDENTIAL:
+ out.open("user-data-constraint").tag("transport-guarantee","CONFIDENTIAL").close();
+ break;
+
+ default:
+ break;
+
+ }
+
+ out.open("web-resource-collection");
+ {
+ if (m.getConstraint().getName()!=null)
+ out.tag("web-resource-name",m.getConstraint().getName());
+ if (m.getPathSpec()!=null)
+ out.tag("url-pattern",origin(md,"constraint.url."+m.getPathSpec()),m.getPathSpec());
+ if (m.getMethod()!=null)
+ out.tag("http-method",m.getMethod());
+
+ if (m.getMethodOmissions()!=null)
+ for (String o:m.getMethodOmissions())
+ out.tag("http-method-omission",o);
+
+ out.close();
+ }
+
+ out.close();
+
+ }
+ }
+
+ if (getWelcomeFiles() != null)
+ {
+ out.open("welcome-file-list");
+ for (String welcomeFile:getWelcomeFiles())
+ {
+ out.tag("welcome-file", welcomeFile);
+ }
+ out.close();
+ }
+
+ Map<String,String> localeEncodings = getLocaleEncodings();
+ if (localeEncodings != null && !localeEncodings.isEmpty())
+ {
+ out.open("locale-encoding-mapping-list");
+ for (Map.Entry<String, String> entry:localeEncodings.entrySet())
+ {
+ out.open("locale-encoding-mapping", origin(md,"locale-encoding."+entry.getKey()));
+ out.tag("locale", entry.getKey());
+ out.tag("encoding", entry.getValue());
+ out.close();
+ }
+ out.close();
+ }
+
+ //session-config
+ if (getSessionHandler().getSessionManager() != null)
+ {
+ out.open("session-config");
+ int maxInactiveSec = getSessionHandler().getSessionManager().getMaxInactiveInterval();
+ out.tag("session-timeout", (maxInactiveSec==0?"0":Integer.toString(maxInactiveSec/60)));
+
+ Set<SessionTrackingMode> modes = getSessionHandler().getSessionManager().getEffectiveSessionTrackingModes();
+ if (modes != null)
+ {
+ for (SessionTrackingMode mode:modes)
+ out.tag("tracking-mode", mode.toString());
+ }
+
+ //cookie-config
+ SessionCookieConfig cookieConfig = getSessionHandler().getSessionManager().getSessionCookieConfig();
+ if (cookieConfig != null)
+ {
+ out.open("cookie-config");
+ if (cookieConfig.getName() != null)
+ out.tag("name", origin(md,"cookie-config.name"), cookieConfig.getName());
+
+ if (cookieConfig.getDomain() != null)
+ out.tag("domain", origin(md, "cookie-config.domain"), cookieConfig.getDomain());
+
+ if (cookieConfig.getPath() != null)
+ out.tag("path", origin(md, "cookie-config.path"), cookieConfig.getPath());
+
+ if (cookieConfig.getComment() != null)
+ out.tag("comment", origin(md, "cookie-config.comment"), cookieConfig.getComment());
+
+ out.tag("http-only", origin(md, "cookie-config.http-only"), Boolean.toString(cookieConfig.isHttpOnly()));
+ out.tag("secure", origin(md, "cookie-config.secure"), Boolean.toString(cookieConfig.isSecure()));
+ out.tag("max-age", origin(md, "cookie-config.max-age"), Integer.toString(cookieConfig.getMaxAge()));
+ out.close();
+ }
+ out.close();
+ }
+
+ //error-pages
+ Map<String,String> errorPages = ((ErrorPageErrorHandler)getErrorHandler()).getErrorPages();
+ if (errorPages != null)
+ {
+ for (Map.Entry<String, String> entry:errorPages.entrySet())
+ {
+ out.open("error-page", origin(md, "error."+entry.getKey()));
+ //a global or default error page has no code or exception
+ if (!ErrorPageErrorHandler.GLOBAL_ERROR_PAGE.equals(entry.getKey()))
+ {
+ if (entry.getKey().matches("\\d{3}"))
+ out.tag("error-code", entry.getKey());
+ else
+ out.tag("exception-type", entry.getKey());
+ }
+ out.tag("location", entry.getValue());
+ out.close();
+ }
+ }
+
+ //mime-types
+ MimeTypes mimeTypes = getMimeTypes();
+ if (mimeTypes != null)
+ {
+ for (Map.Entry<String, String> entry:mimeTypes.getMimeMap().entrySet())
+ {
+ out.open("mime-mapping");
+ out.tag("extension", origin(md, "extension."+entry.getKey()), entry.getKey());
+ out.tag("mime-type", entry.getValue());
+ out.close();
+ }
+ }
+
+ //jsp-config
+ JspConfig jspConfig = (JspConfig)getServletContext().getJspConfigDescriptor();
+ if (jspConfig != null)
+ {
+ out.open("jsp-config");
+ Collection<TaglibDescriptor> tlds = jspConfig.getTaglibs();
+ if (tlds != null && !tlds.isEmpty())
+ {
+ for (TaglibDescriptor tld:tlds)
+ {
+ out.open("taglib");
+ out.tag("taglib-uri", tld.getTaglibURI());
+ out.tag("taglib-location", tld.getTaglibLocation());
+ out.close();
+ }
+ }
+
+ Collection<JspPropertyGroupDescriptor> jspPropertyGroups = jspConfig.getJspPropertyGroups();
+ if (jspPropertyGroups != null && !jspPropertyGroups.isEmpty())
+ {
+ for (JspPropertyGroupDescriptor jspPropertyGroup:jspPropertyGroups)
+ {
+ out.open("jsp-property-group");
+ Collection<String> strings = jspPropertyGroup.getUrlPatterns();
+ if (strings != null && !strings.isEmpty())
+ {
+ for (String urlPattern:strings)
+ out.tag("url-pattern", urlPattern);
+ }
+
+ if (jspPropertyGroup.getElIgnored() != null)
+ out.tag("el-ignored", jspPropertyGroup.getElIgnored());
+
+ if (jspPropertyGroup.getPageEncoding() != null)
+ out.tag("page-encoding", jspPropertyGroup.getPageEncoding());
+
+ if (jspPropertyGroup.getScriptingInvalid() != null)
+ out.tag("scripting-invalid", jspPropertyGroup.getScriptingInvalid());
+
+ if (jspPropertyGroup.getIsXml() != null)
+ out.tag("is-xml", jspPropertyGroup.getIsXml());
+
+ if (jspPropertyGroup.getDeferredSyntaxAllowedAsLiteral() != null)
+ out.tag("deferred-syntax-allowed-as-literal", jspPropertyGroup.getDeferredSyntaxAllowedAsLiteral());
+
+ if (jspPropertyGroup.getTrimDirectiveWhitespaces() != null)
+ out.tag("trim-directive-whitespaces", jspPropertyGroup.getTrimDirectiveWhitespaces());
+
+ if (jspPropertyGroup.getDefaultContentType() != null)
+ out.tag("default-content-type", jspPropertyGroup.getDefaultContentType());
+
+ if (jspPropertyGroup.getBuffer() != null)
+ out.tag("buffer", jspPropertyGroup.getBuffer());
+
+ if (jspPropertyGroup.getErrorOnUndeclaredNamespace() != null)
+ out.tag("error-on-undeclared-namespace", jspPropertyGroup.getErrorOnUndeclaredNamespace());
+
+ strings = jspPropertyGroup.getIncludePreludes();
+ if (strings != null && !strings.isEmpty())
+ {
+ for (String prelude:strings)
+ out.tag("include-prelude", prelude);
+ }
+
+ strings = jspPropertyGroup.getIncludeCodas();
+ if (strings != null && !strings.isEmpty())
+ {
+ for (String coda:strings)
+ out.tag("include-coda", coda);
+ }
+
+ out.close();
+ }
+ }
+
+ out.close();
+ }
+
+ //lifecycle: post-construct, pre-destroy
+ LifeCycleCallbackCollection lifecycles = ((LifeCycleCallbackCollection)getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION));
+ if (lifecycles != null)
+ {
+ Collection<LifeCycleCallback> tmp = lifecycles.getPostConstructCallbacks();
+
+ for (LifeCycleCallback c:tmp)
+ {
+ out.open("post-construct");
+ out.tag("lifecycle-callback-class", c.getTargetClassName());
+ out.tag("lifecycle-callback-method", c.getMethodName());
+ out.close();
+ }
+
+ tmp = lifecycles.getPreDestroyCallbacks();
+ for (LifeCycleCallback c:tmp)
+ {
+ out.open("pre-destroy");
+ out.tag("lifecycle-callback-class", c.getTargetClassName());
+ out.tag("lifecycle-callback-method", c.getMethodName());
+ out.close();
+ }
+ }
+
+ out.literal(extraXML);
+
+ out.close();
+ }
+
+ private void addContextParamFromAttribute(XmlAppendable out, String attribute) throws IOException
+ {
+ addContextParamFromAttribute(out,attribute,null);
+ }
+
+ private void addContextParamFromAttribute(XmlAppendable out, String attribute, String resourceBase) throws IOException
+ {
+ Object o=getAttribute(attribute);
+ if (o==null)
+ return;
+
+ Collection<?> c = (o instanceof Collection)? (Collection<?>)o:Collections.singletonList(o);
+ StringBuilder v=new StringBuilder();
+ for (Object i:c)
+ {
+ if (i!=null)
+ {
+ if (v.length()>0)
+ v.append(",\n ");
+ else
+ v.append("\n ");
+ if (resourceBase==null)
+ QuotedStringTokenizer.quote(v,i.toString());
+ else
+ QuotedStringTokenizer.quote(v,i.toString().replace(resourceBase,"${WAR}/"));
+ }
+ }
+ out.open("context-param")
+ .tag("param-name",attribute)
+ .tagCDATA("param-value",v.toString())
+ .close();
+ }
+
+ private static void outholder(XmlAppendable out, MetaData md, String tag, Holder<?> holder) throws IOException
+ {
+ out.open(tag,Collections.singletonMap("source",holder.getSource().toString()));
+ String n = holder.getName();
+ out.tag(tag + "-name",n);
+
+ String ot = n + "." + tag + ".";
+
+ out.tag(tag + "-class",origin(md,ot + tag + "-class"),holder.getClassName());
+
+ for (String p : holder.getInitParameters().keySet())
+ {
+ if ("scratchdir".equalsIgnoreCase(p)) //don't preconfigure the temp dir for jsp output
+ continue;
+ out.open("init-param",origin(md,ot + "init-param." + p))
+ .tag("param-name",p)
+ .tag("param-value",holder.getInitParameter(p))
+ .close();
+ }
+
+ if (holder instanceof ServletHolder)
+ {
+ ServletHolder s = (ServletHolder)holder;
+ if (s.getForcedPath() != null)
+ out.tag("jsp-file",s.getForcedPath());
+
+ if (s.getInitOrder() != 0)
+ out.tag("load-on-startup",Integer.toString(s.getInitOrder()));
+
+ if (s.getRunAsRole() != null)
+ out.open("run-as",origin(md,ot + "run-as"))
+ .tag("role-name",s.getRunAsRole())
+ .close();
+
+ Map<String,String> roles = s.getRoleRefMap();
+ if (roles!=null)
+ {
+ for (Map.Entry<String, String> e : roles.entrySet())
+ {
+ out.open("security-role-ref",origin(md,ot+"role-name."+e.getKey()))
+ .tag("role-name",e.getKey())
+ .tag("role-link",e.getValue())
+ .close();
+ }
+ }
+
+ if (!s.isEnabled())
+ out.tag("enabled",origin(md,ot + "enabled"),"false");
+
+ //multipart-config
+ MultipartConfigElement multipartConfig = ((ServletHolder.Registration)s.getRegistration()).getMultipartConfig();
+ if (multipartConfig != null)
+ {
+ out.open("multipart-config", origin(md, s.getName()+".servlet.multipart-config"));
+ if (multipartConfig.getLocation() != null)
+ out.tag("location", multipartConfig.getLocation());
+ out.tag("max-file-size", Long.toString(multipartConfig.getMaxFileSize()));
+ out.tag("max-request-size", Long.toString(multipartConfig.getMaxRequestSize()));
+ out.tag("file-size-threshold", Long.toString(multipartConfig.getFileSizeThreshold()));
+ out.close();
+ }
+ }
+
+ out.tag("async-supported",origin(md,ot + "async-supported"),holder.isAsyncSupported()?"true":"false");
+ out.close();
+ }
+
+ public static Map<String, String> origin(MetaData md, String name)
+ {
+ if (!LOG.isDebugEnabled())
+ return Collections.emptyMap();
+ if (name == null)
+ return Collections.emptyMap();
+ OriginInfo origin = md.getOriginInfo(name);
+ // System.err.println("origin of "+name+" is "+origin);
+ if (origin == null)
+ return Collections.emptyMap();
+ return Collections.singletonMap("origin",origin.toString());
+
+ }
+
+}
diff --git a/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureJNDIWar.java b/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureJNDIWar.java
new file mode 100644
index 0000000000..570b724cae
--- /dev/null
+++ b/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureJNDIWar.java
@@ -0,0 +1,49 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.quickstart;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+public class PreconfigureJNDIWar
+{
+ private static final long __start=System.nanoTime();
+ private static final Logger LOG = Log.getLogger(Server.class);
+
+ public static void main(String[] args) throws Exception
+ {
+ String target="target/test-jndi-preconfigured";
+ File file = new File(target);
+ if (file.exists())
+ IO.delete(file);
+
+ PreconfigureQuickStartWar.main("target/test-jndi.war",target, "src/test/resources/test-jndi.xml");
+
+ LOG.info("Preconfigured in {}ms",TimeUnit.NANOSECONDS.toMillis(System.nanoTime()-__start));
+
+ IO.copy(new FileInputStream("target/test-jndi-preconfigured/WEB-INF/quickstart-web.xml"),System.out);
+ }
+
+}
diff --git a/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureSpecWar.java b/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureSpecWar.java
new file mode 100644
index 0000000000..f8b49c77c2
--- /dev/null
+++ b/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureSpecWar.java
@@ -0,0 +1,58 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.quickstart;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+
+public class PreconfigureSpecWar
+{
+ private static final long __start=System.nanoTime();
+ private static final Logger LOG = Log.getLogger(Server.class);
+
+ public static void main(String[] args) throws Exception
+ {
+ String target="target/test-spec-preconfigured";
+ File file = new File(target);
+ if (file.exists())
+ IO.delete(file);
+
+ File realmPropertiesDest = new File ("target/test-spec-realm.properties");
+ if (realmPropertiesDest.exists())
+ IO.delete(realmPropertiesDest);
+
+ Resource realmPropertiesSrc = Resource.newResource("src/test/resources/realm.properties");
+ realmPropertiesSrc.copyTo(realmPropertiesDest);
+ System.setProperty("jetty.home", "target");
+
+ PreconfigureQuickStartWar.main("target/test-spec.war",target, "src/test/resources/test-spec.xml");
+
+ LOG.info("Preconfigured in {}ms",TimeUnit.NANOSECONDS.toMillis(System.nanoTime()-__start));
+
+ IO.copy(new FileInputStream("target/test-spec-preconfigured/WEB-INF/quickstart-web.xml"),System.out);
+ }
+
+}
diff --git a/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureStandardTestWar.java b/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureStandardTestWar.java
new file mode 100644
index 0000000000..91e424165e
--- /dev/null
+++ b/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureStandardTestWar.java
@@ -0,0 +1,62 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.quickstart;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+
+/**
+ * PreconfigureStandardTestWar
+ *
+ */
+public class PreconfigureStandardTestWar
+{
+
+ private static final long __start=System.nanoTime();
+ private static final Logger LOG = Log.getLogger(Server.class);
+
+ public static void main(String[] args) throws Exception
+ {
+ String target="target/test-standard-preconfigured";
+ File file = new File(target);
+ if (file.exists())
+ IO.delete(file);
+
+ File realmPropertiesDest = new File ("target/test-standard-realm.properties");
+ if (realmPropertiesDest.exists())
+ IO.delete(realmPropertiesDest);
+
+ Resource realmPropertiesSrc = Resource.newResource("src/test/resources/realm.properties");
+ realmPropertiesSrc.copyTo(realmPropertiesDest);
+ System.setProperty("jetty.home", "target");
+
+ PreconfigureQuickStartWar.main("target/test-standard.war",target, "src/test/resources/test.xml");
+
+ LOG.info("Preconfigured in {}ms",TimeUnit.NANOSECONDS.toMillis(System.nanoTime()-__start));
+
+ IO.copy(new FileInputStream("target/test-standard-preconfigured/WEB-INF/quickstart-web.xml"),System.out);
+ }
+}
diff --git a/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartJNDIWar.java b/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartJNDIWar.java
new file mode 100644
index 0000000000..07bc1b6648
--- /dev/null
+++ b/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartJNDIWar.java
@@ -0,0 +1,31 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.quickstart;
+
+public class QuickStartJNDIWar
+{
+
+ public static void main(String... args) throws Exception
+ {
+ // Log.getRootLogger().setDebugEnabled(true);
+ Quickstart.main("target/test-jndi-preconfigured", "src/test/resources/test-jndi.xml");
+ }
+
+
+}
diff --git a/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartSpecWar.java b/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartSpecWar.java
new file mode 100644
index 0000000000..b84a12f298
--- /dev/null
+++ b/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartSpecWar.java
@@ -0,0 +1,30 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.quickstart;
+
+
+public class QuickStartSpecWar
+{
+ public static void main(String... args) throws Exception
+ {
+ // Log.getRootLogger().setDebugEnabled(true);
+ System.setProperty("jetty.home", "target");
+ Quickstart.main("target/test-spec-preconfigured", "src/test/resources/test-spec.xml");
+ }
+}
diff --git a/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartStandardTestWar.java b/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartStandardTestWar.java
new file mode 100644
index 0000000000..7da8b23465
--- /dev/null
+++ b/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartStandardTestWar.java
@@ -0,0 +1,30 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.quickstart;
+
+public class QuickStartStandardTestWar
+{
+
+ public static void main(String... args) throws Exception
+ {
+ // Log.getRootLogger().setDebugEnabled(true);
+ System.setProperty("jetty.home", "target");
+ Quickstart.main("target/test-standard-preconfigured", "src/test/resources/test.xml");
+ }
+}
diff --git a/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/Quickstart.java b/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/Quickstart.java
new file mode 100644
index 0000000000..75dc114e10
--- /dev/null
+++ b/jetty-quickstart/src/test/java/org/eclipse/jetty/quickstart/Quickstart.java
@@ -0,0 +1,73 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.quickstart;
+
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.xml.XmlConfiguration;
+
+public class Quickstart
+{
+
+ public static void main(String... args) throws Exception
+ {
+ if (args.length<1)
+ error("No WAR file or directory given");
+
+ //war file or dir to start
+ String war = args[0];
+
+ //optional jetty context xml file to configure the webapp
+ Resource contextXml = null;
+ if (args.length > 1)
+ contextXml = Resource.newResource(args[1]);
+
+ Server server = new Server(8080);
+
+ QuickStartWebApp webapp = new QuickStartWebApp();
+ webapp.setAutoPreconfigure(true);
+ webapp.setWar(war);
+ webapp.setContextPath("/");
+
+ //apply context xml file
+ if (contextXml != null)
+ {
+ // System.err.println("Applying "+contextXml);
+ XmlConfiguration xmlConfiguration = new XmlConfiguration(contextXml.getURL());
+ xmlConfiguration.configure(webapp);
+ }
+
+ server.setHandler(webapp);
+
+ server.start();
+
+
+
+ server.join();
+ }
+
+
+ private static void error(String message)
+ {
+ System.err.println("ERROR: "+message);
+ System.err.println("Usage: java -jar QuickStartWar.jar <war-directory> <context-xml>");
+ System.err.println(" java -jar QuickStartWar.jar <war-file> <context-xml>");
+ System.exit(1);
+ }
+}
diff --git a/jetty-quickstart/src/test/resources/realm.properties b/jetty-quickstart/src/test/resources/realm.properties
new file mode 100644
index 0000000000..9d88b852b7
--- /dev/null
+++ b/jetty-quickstart/src/test/resources/realm.properties
@@ -0,0 +1,21 @@
+#
+# This file defines users passwords and roles for a HashUserRealm
+#
+# The format is
+# <username>: <password>[,<rolename> ...]
+#
+# Passwords may be clear text, obfuscated or checksummed. The class
+# org.eclipse.util.Password should be used to generate obfuscated
+# passwords or password checksums
+#
+# If DIGEST Authentication is used, the password must be in a recoverable
+# format, either plain text or OBF:.
+#
+jetty: MD5:164c88b302622e17050af52c89945d44,user
+admin: CRYPT:adpexzg3FUZAk,server-administrator,content-administrator,admin,user
+other: OBF:1xmk1w261u9r1w1c1xmq,user
+plain: plain,user
+user: password,user
+
+# This entry is for digest auth. The credential is a MD5 hash of username:realmname:password
+digest: MD5:6e120743ad67abfbc385bc2bb754e297,user
diff --git a/jetty-quickstart/src/test/resources/test-jndi.xml b/jetty-quickstart/src/test/resources/test-jndi.xml
new file mode 100644
index 0000000000..14c0934845
--- /dev/null
+++ b/jetty-quickstart/src/test/resources/test-jndi.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
+
+<!-- =============================================================== -->
+<!-- Configure the test-jndi webapp -->
+<!-- =============================================================== -->
+<Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext">
+
+ <New id="tx" class="org.eclipse.jetty.plus.jndi.Transaction">
+ <Arg>
+ <New class="com.acme.MockUserTransaction"/>
+ </Arg>
+ </New>
+
+ <!-- Define an env entry with Server scope for java:comp/env -->
+ <New id="woggle" class="org.eclipse.jetty.plus.jndi.EnvEntry">
+ <Arg><Property name='server'/></Arg>
+ <Arg>woggle</Arg>
+ <Arg type="java.lang.Integer">4000</Arg>
+ <Arg type="boolean">false</Arg>
+ </New>
+
+ <!-- Define an env entry with webapp scope for java:comp/env -->
+ <New id="wiggle" class="org.eclipse.jetty.plus.jndi.EnvEntry">
+ <Arg><Ref refid='wac'/></Arg>
+ <Arg>wiggle</Arg>
+ <Arg type="java.lang.Double">100</Arg>
+ <Arg type="boolean">true</Arg>
+ </New>
+
+ <!-- Mail Session setup -->
+ <New id="xxxmail" class="org.eclipse.jetty.plus.jndi.Resource">
+ <Arg><Ref refid='wac'/></Arg>
+ <Arg>mail/Session</Arg>
+ <Arg>
+ <New class="org.eclipse.jetty.jndi.factories.MailSessionReference">
+ <Set name="user">CHANGE-ME</Set>
+ <Set name="password">CHANGE-ME</Set>
+ <Set name="properties">
+ <New class="java.util.Properties">
+ <Put name="mail.smtp.auth">false</Put> <!-- change to true if you want to authenticate -->
+ <Put name="mail.smtp.host">CHANGE-ME</Put>
+ <Put name="mail.from">CHANGE-ME</Put>
+ <Put name="mail.debug">false</Put>
+ </New>
+ </Set>
+ </New>
+ </Arg>
+ </New>
+
+ <!-- A mock DataSource -->
+ <New id="mydatasource" class="org.eclipse.jetty.plus.jndi.Resource">
+ <Arg><Ref refid='wac'/></Arg>
+ <Arg>jdbc/mydatasource</Arg>
+ <Arg>
+ <New class="com.acme.MockDataSource"/>
+ </Arg>
+ </New>
+
+</Configure>
diff --git a/jetty-quickstart/src/test/resources/test-spec.xml b/jetty-quickstart/src/test/resources/test-spec.xml
new file mode 100644
index 0000000000..99fc577205
--- /dev/null
+++ b/jetty-quickstart/src/test/resources/test-spec.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
+
+<Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext">
+
+ <New id="tx" class="org.eclipse.jetty.plus.jndi.Transaction">
+ <Arg>
+ <New class="com.acme.MockUserTransaction"/>
+ </Arg>
+ </New>
+
+ <Get name="securityHandler">
+ <Set name="loginService">
+ <New class="org.eclipse.jetty.security.HashLoginService">
+ <Set name="name">Test Realm</Set>
+ <Set name="config"><SystemProperty name="jetty.home" default="."/>/test-spec-realm.properties</Set>
+ </New>
+ </Set>
+ </Get>
+
+
+ <New id="maxAmount" class="org.eclipse.jetty.plus.jndi.EnvEntry">
+ <Arg><Ref refid='wac'/></Arg>
+ <Arg>maxAmount</Arg>
+ <Arg type="java.lang.Double">100</Arg>
+ <Arg type="boolean">true</Arg>
+ </New>
+
+
+ <New id="mydatasource" class="org.eclipse.jetty.plus.jndi.Resource">
+ <Arg><Ref refid='wac'/></Arg>
+ <Arg>jdbc/mydatasource</Arg>
+ <Arg>
+ <New class="com.acme.MockDataSource">
+ </New>
+ </Arg>
+ </New>
+
+</Configure>
diff --git a/jetty-quickstart/src/test/resources/test.xml b/jetty-quickstart/src/test/resources/test.xml
new file mode 100644
index 0000000000..bbdf08a23a
--- /dev/null
+++ b/jetty-quickstart/src/test/resources/test.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
+
+<!-- ==================================================================
+Configure and deploy the test web application in $(jetty.home)/webapps/test
+
+Note. If this file did not exist or used a context path other that /test
+then the default configuration of jetty.xml would discover the test
+webapplication with a WebAppDeployer. By specifying a context in this
+directory, additional configuration may be specified and hot deployments
+detected.
+===================================================================== -->
+
+<Configure class="org.eclipse.jetty.webapp.WebAppContext">
+
+ <Set name="contextPath">/test</Set>
+
+ <Get name="securityHandler">
+ <Set name="loginService">
+ <New class="org.eclipse.jetty.security.HashLoginService">
+ <Set name="name">Test Realm</Set>
+ <Set name="config"><SystemProperty name="jetty.home" default="."/>/test-standard-realm.properties</Set>
+ </New>
+ </Set>
+ <Set name="authenticator">
+ <New class="org.eclipse.jetty.security.authentication.FormAuthenticator">
+ <Set name="alwaysSaveUri">true</Set>
+ </New>
+ </Set>
+ <Set name="checkWelcomeFiles">true</Set>
+ </Get>
+
+ <!-- Non standard error page mapping -->
+ <!--
+ <Get name="errorHandler">
+ <Call name="addErrorPage">
+ <Arg type="int">500</Arg>
+ <Arg type="int">599</Arg>
+ <Arg type="String">/dump/errorCodeRangeMapping</Arg>
+ </Call>
+ </Get>
+ -->
+
+
+</Configure>

Back to the top