Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse McConnell2012-08-21 21:56:35 +0000
committerJesse McConnell2012-08-21 21:56:35 +0000
commit0ad217f39a4350f48d26d7d68eabc22d98d045d1 (patch)
tree1533866a251223518c3f2c455ef44680c07f6eb6 /jetty-ant/src/main
parent71dd5322c732d9c6eea3e1ae0bc084610833ea5e (diff)
downloadorg.eclipse.jetty.project-0ad217f39a4350f48d26d7d68eabc22d98d045d1.tar.gz
org.eclipse.jetty.project-0ad217f39a4350f48d26d7d68eabc22d98d045d1.tar.xz
org.eclipse.jetty.project-0ad217f39a4350f48d26d7d68eabc22d98d045d1.zip
add jetty-ant module from codehaus via CQ6712
Diffstat (limited to 'jetty-ant/src/main')
-rw-r--r--jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebInfConfiguration.java146
-rw-r--r--jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebXmlConfiguration.java136
-rw-r--r--jetty-ant/src/main/java/org/eclipse/jetty/ant/JettyRunTask.java328
-rw-r--r--jetty-ant/src/main/java/org/eclipse/jetty/ant/ServerProxyImpl.java255
-rw-r--r--jetty-ant/src/main/java/org/eclipse/jetty/ant/WebApplicationProxyImpl.java542
-rw-r--r--jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Attribute.java47
-rw-r--r--jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Attributes.java38
-rw-r--r--jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Connectors.java116
-rw-r--r--jetty-ant/src/main/java/org/eclipse/jetty/ant/types/ContextHandlers.java46
-rw-r--r--jetty-ant/src/main/java/org/eclipse/jetty/ant/types/FileMatchingConfiguration.java99
-rw-r--r--jetty-ant/src/main/java/org/eclipse/jetty/ant/types/LoginServices.java46
-rwxr-xr-xjetty-ant/src/main/java/org/eclipse/jetty/ant/types/SystemProperties.java66
-rwxr-xr-xjetty-ant/src/main/java/org/eclipse/jetty/ant/types/WebApp.java296
-rw-r--r--jetty-ant/src/main/java/org/eclipse/jetty/ant/utils/ServerProxy.java40
-rw-r--r--jetty-ant/src/main/java/org/eclipse/jetty/ant/utils/TaskLog.java54
-rw-r--r--jetty-ant/src/main/java/org/eclipse/jetty/ant/utils/WebApplicationProxy.java47
-rwxr-xr-xjetty-ant/src/main/resources/tasks.properties1
17 files changed, 2303 insertions, 0 deletions
diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebInfConfiguration.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebInfConfiguration.java
new file mode 100644
index 0000000000..831a494447
--- /dev/null
+++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebInfConfiguration.java
@@ -0,0 +1,146 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2012 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.ant;
+
+import java.io.File;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.eclipse.jetty.util.PatternMatcher;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.webapp.WebInfConfiguration;
+
+public class AntWebInfConfiguration extends WebInfConfiguration
+{
+
+
+ @Override
+ public void preConfigure(final WebAppContext context) throws Exception
+ {
+ // Look for a work directory
+ File work = findWorkDirectory(context);
+ if (work != null)
+ makeTempDirectory(work, context, false);
+
+ //Make a temp directory for the webapp if one is not already set
+ resolveTempDirectory(context);
+
+ //Extract webapp if necessary
+ unpack (context);
+
+
+ //Apply an initial ordering to the jars which governs which will be scanned for META-INF
+ //info and annotations. The ordering is based on inclusion patterns.
+ String tmp = (String)context.getAttribute(WEBINF_JAR_PATTERN);
+ Pattern webInfPattern = (tmp==null?null:Pattern.compile(tmp));
+ tmp = (String)context.getAttribute(CONTAINER_JAR_PATTERN);
+ Pattern containerPattern = (tmp==null?null:Pattern.compile(tmp));
+
+ //Apply ordering to container jars - if no pattern is specified, we won't
+ //match any of the container jars
+ PatternMatcher containerJarNameMatcher = new PatternMatcher ()
+ {
+ public void matched(URI uri) throws Exception
+ {
+ context.getMetaData().addContainerJar(Resource.newResource(uri));
+ }
+ };
+ ClassLoader loader = context.getClassLoader();
+ if (loader != null)
+ {
+ loader = loader.getParent();
+ if (loader != null)
+ {
+ URI[] containerUris = null;
+
+ if (loader instanceof URLClassLoader)
+ {
+ URL[] urls = ((URLClassLoader)loader).getURLs();
+ if (urls != null)
+ {
+ containerUris = new URI[urls.length];
+ int i=0;
+ for (URL u : urls)
+ {
+ try
+ {
+ containerUris[i] = u.toURI();
+ }
+ catch (URISyntaxException e)
+ {
+ containerUris[i] = new URI(u.toString().replaceAll(" ", "%20"));
+ }
+ i++;
+ }
+ }
+ }
+ else if (loader instanceof AntClassLoader)
+ {
+ AntClassLoader antLoader = (AntClassLoader)loader;
+ String[] paths = antLoader.getClasspath().split(new String(new char[]{File.pathSeparatorChar}));
+ if (paths != null)
+ {
+ containerUris = new URI[paths.length];
+ int i=0;
+ for (String p:paths)
+ {
+ File f = new File(p);
+ containerUris[i] = f.toURI();
+ i++;
+ }
+ }
+ }
+
+ containerJarNameMatcher.match(containerPattern, containerUris, false);
+ }
+ }
+
+ //Apply ordering to WEB-INF/lib jars
+ PatternMatcher webInfJarNameMatcher = new PatternMatcher ()
+ {
+ @Override
+ public void matched(URI uri) throws Exception
+ {
+ context.getMetaData().addWebInfJar(Resource.newResource(uri));
+ }
+ };
+ List<Resource> jars = findJars(context);
+
+ //Convert to uris for matching
+ URI[] uris = null;
+ if (jars != null)
+ {
+ uris = new URI[jars.size()];
+ int i=0;
+ for (Resource r: jars)
+ {
+ uris[i++] = r.getURI();
+ }
+ }
+ webInfJarNameMatcher.match(webInfPattern, uris, true); //null is inclusive, no pattern == all jars match
+ }
+
+
+}
diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebXmlConfiguration.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebXmlConfiguration.java
new file mode 100644
index 0000000000..9fb209f49f
--- /dev/null
+++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebXmlConfiguration.java
@@ -0,0 +1,136 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2012 Sabre Holdings.
+// ------------------------------------------------------------------------
+// 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.ant;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.eclipse.jetty.ant.utils.TaskLog;
+import org.eclipse.jetty.plus.webapp.PlusConfiguration;
+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.Descriptor;
+import org.eclipse.jetty.webapp.StandardDescriptorProcessor;
+import org.eclipse.jetty.webapp.WebAppClassLoader;
+import org.eclipse.jetty.webapp.WebXmlConfiguration;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.xml.XmlParser.Node;
+
+
+/**
+ * This configuration object provides additional way to inject application
+ * properties into the configured web application. The list of classpath files,
+ * the application base directory and web.xml file could be specified in this
+ * way.
+ *
+ * @author Jakub Pawlowicz
+ * @author Athena Yao
+ */
+public class AntWebXmlConfiguration extends WebXmlConfiguration
+{
+ private static final Logger LOG = Log.getLogger(WebXmlConfiguration.class);
+
+
+
+ /** List of classpath files. */
+ private List classPathFiles;
+
+ /** Web application root directory. */
+ private File webAppBaseDir;
+
+ /** Web application web.xml file. */
+ private File webXmlFile;
+
+ private File webDefaultXmlFile;
+
+ public AntWebXmlConfiguration() throws ClassNotFoundException
+ {
+ }
+
+ public File getWebDefaultXmlFile()
+ {
+ return this.webDefaultXmlFile;
+ }
+
+ public void setWebDefaultXmlFile(File webDefaultXmlfile)
+ {
+ this.webDefaultXmlFile = webDefaultXmlfile;
+ }
+
+ public void setClassPathFiles(List classPathFiles)
+ {
+ this.classPathFiles = classPathFiles;
+ }
+
+ public void setWebAppBaseDir(File webAppBaseDir)
+ {
+ this.webAppBaseDir = webAppBaseDir;
+ }
+
+ public void setWebXmlFile(File webXmlFile)
+ {
+ this.webXmlFile = webXmlFile;
+
+ if (webXmlFile.exists())
+ {
+ TaskLog.log("web.xml file = " + webXmlFile);
+ }
+ }
+
+ /**
+ * Adds classpath files into web application classloader, and
+ * sets web.xml and base directory for the configured web application.
+ *
+ * @see WebXmlConfiguration#configure(WebAppContext)
+ */
+ public void configure(WebAppContext context) throws Exception
+ {
+ if (context.isStarted())
+ {
+ TaskLog.log("Cannot configure webapp after it is started");
+ return;
+ }
+
+
+ if (webXmlFile.exists())
+ {
+ context.setDescriptor(webXmlFile.getCanonicalPath());
+ }
+
+ super.configure(context);
+
+ Iterator filesIterator = classPathFiles.iterator();
+
+ while (filesIterator.hasNext())
+ {
+ File classPathFile = (File) filesIterator.next();
+ if (classPathFile.exists())
+ {
+ ((WebAppClassLoader) context.getClassLoader())
+ .addClassPath(classPathFile.getCanonicalPath());
+ }
+ }
+ }
+}
diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/JettyRunTask.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/JettyRunTask.java
new file mode 100644
index 0000000000..20b615322b
--- /dev/null
+++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/JettyRunTask.java
@@ -0,0 +1,328 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2012 Sabre Holdings.
+// ------------------------------------------------------------------------
+// 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.ant;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Property;
+import org.eclipse.jetty.ant.types.Connectors;
+import org.eclipse.jetty.ant.types.LoginServices;
+import org.eclipse.jetty.ant.types.SystemProperties;
+import org.eclipse.jetty.ant.types.WebApp;
+import org.eclipse.jetty.ant.utils.ServerProxy;
+import org.eclipse.jetty.ant.utils.TaskLog;
+import org.eclipse.jetty.server.RequestLog;
+import org.eclipse.jetty.util.Scanner;
+
+/**
+ * Ant task for running a Jetty server.
+ *
+ * @author Jakub Pawlowicz
+ */
+public class JettyRunTask extends Task
+{
+
+ /** Temporary files directory. */
+ private File tempDirectory;
+
+ /** List of web applications to be deployed. */
+ private List webapps = new ArrayList();
+
+ /** Location of jetty.xml file. */
+ private File jettyXml;
+
+ /** List of server connectors. */
+ private Connectors connectors = null;
+
+ /** Server request logger object. */
+ private RequestLog requestLog;
+
+ /** List of login services. */
+ private LoginServices loginServices;
+
+ /** List of system properties to be set. */
+ private SystemProperties systemProperties;
+
+ /** Port Jetty will use for the default connector */
+ private int jettyPort = 8080;
+
+
+ public JettyRunTask()
+ {
+ TaskLog.setTask(this);
+ }
+
+ /**
+ * Creates a new <code>WebApp</code> Ant object.
+ *
+ */
+ public void addWebApp(WebApp webapp)
+ {
+ webapps.add(webapp);
+ }
+
+ /**
+ * Adds a new Ant's connector tag object if it have not been created yet.
+ */
+ public void addConnectors(Connectors connectors)
+ {
+ if (this.connectors != null)
+ {
+ throw new BuildException("Only one <connectors> tag is allowed!");
+ }
+
+ this.connectors = connectors;
+ }
+
+ /**
+ * @deprecated
+ */
+ public void addUserRealms(Object o)
+ {
+ TaskLog.log("User realms are deprecated.");
+ }
+
+ public void addLoginServices(LoginServices services)
+ {
+ if (this.loginServices != null )
+ {
+ throw new BuildException("Only one <loginServices> tag is allowed!");
+ }
+
+ this.loginServices = services;
+ }
+
+ public void addSystemProperties(SystemProperties systemProperties)
+ {
+ if (this.systemProperties != null)
+ {
+ throw new BuildException("Only one <systemProperties> tag is allowed!");
+ }
+
+ this.systemProperties = systemProperties;
+ }
+
+ public File getTempDirectory()
+ {
+ return tempDirectory;
+ }
+
+ public void setTempDirectory(File tempDirectory)
+ {
+ this.tempDirectory = tempDirectory;
+ }
+
+ public File getJettyXml()
+ {
+ return jettyXml;
+ }
+
+ public void setJettyXml(File jettyXml)
+ {
+ this.jettyXml = jettyXml;
+ }
+
+ public void setRequestLog(String className)
+ {
+ try
+ {
+ this.requestLog = (RequestLog) Class.forName(className).newInstance();
+ }
+ catch (InstantiationException e)
+ {
+ throw new BuildException("Request logger instantiation exception: " + e);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new BuildException("Request logger instantiation exception: " + e);
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw new BuildException("Unknown request logger class: " + className);
+ }
+ }
+
+ public String getRequestLog()
+ {
+ if (requestLog != null)
+ {
+ return requestLog.getClass().getName();
+ }
+
+ return "";
+ }
+
+ /**
+ * Sets the port Jetty uses for the default connector.
+ *
+ * @param jettyPort The port Jetty will use for the default connector
+ */
+ public void setJettyPort(final int jettyPort)
+ {
+ this.jettyPort = jettyPort;
+ }
+
+ /**
+ * Executes this Ant task. The build flow is being stopped until Jetty
+ * server stops.
+ *
+ * @throws BuildException
+ */
+ public void execute() throws BuildException
+ {
+
+ TaskLog.log("Configuring Jetty for project: " + getProject().getName());
+ WebApplicationProxyImpl.setBaseTempDirectory(tempDirectory);
+ setSystemProperties();
+
+ List connectorsList = null;
+
+ if (connectors != null)
+ {
+ connectorsList = connectors.getConnectors();
+ }
+ else
+ {
+ connectorsList = new Connectors(jettyPort,30000).getDefaultConnectors();
+ }
+
+ List loginServicesList = (loginServices != null?loginServices.getLoginServices():new ArrayList());
+ ServerProxy server = new ServerProxyImpl(connectorsList,loginServicesList,requestLog,jettyXml);
+
+ try
+ {
+ Iterator iterator = webapps.iterator();
+ while (iterator.hasNext())
+ {
+ WebApp webAppConfiguration = (WebApp)iterator.next();
+ WebApplicationProxyImpl webApp = new WebApplicationProxyImpl(webAppConfiguration.getName());
+ webApp.setSourceDirectory(webAppConfiguration.getWarFile());
+ webApp.setContextPath(webAppConfiguration.getContextPath());
+ webApp.setWebXml(webAppConfiguration.getWebXmlFile());
+ webApp.setJettyEnvXml(webAppConfiguration.getJettyEnvXml());
+ webApp.setClassPathFiles(webAppConfiguration.getClassPathFiles());
+ webApp.setLibrariesConfiguration(webAppConfiguration.getLibrariesConfiguration());
+ webApp.setExtraScanTargetsConfiguration(webAppConfiguration.getScanTargetsConfiguration());
+ webApp.setContextHandlers(webAppConfiguration.getContextHandlers());
+ webApp.setAttributes(webAppConfiguration.getAttributes());
+ webApp.setWebDefaultXmlFile(webAppConfiguration.getWebDefaultXmlFile());
+
+ server.addWebApplication(webApp,webAppConfiguration.getScanIntervalSeconds());
+ }
+ }
+ catch (Exception e)
+ {
+ throw new BuildException(e);
+ }
+
+ server.start();
+ }
+
+ /**
+ * Starts a new thread which scans project files and automatically reloads a
+ * container on any changes.
+ *
+ * @param scanIntervalSeconds
+ *
+ * @param webapp
+ * @param appContext
+ */
+ static void startScanner(final WebApplicationProxyImpl webApp, int scanIntervalSeconds) throws Exception
+ {
+ List scanList = new ArrayList();
+ scanList.add(webApp.getWebXmlFile());
+ scanList.addAll(webApp.getLibraries());
+ scanList.addAll(webApp.getExtraScanTargets());
+
+ Scanner.Listener changeListener = new Scanner.BulkListener()
+ {
+
+ public void filesChanged(List changedFiles)
+ {
+ if (hasAnyFileChanged(changedFiles))
+ {
+ try
+ {
+ webApp.stop();
+ webApp.applyConfiguration();
+ webApp.start();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Checks if any file in this particular application has changed.
+ * This is not that easy, because some applications may use the same
+ * class'es directory.
+ *
+ * @param changedFiles list of changed files.
+ * @return true if any of passed files has changed, false otherwise.
+ */
+ private boolean hasAnyFileChanged(List changedFiles)
+ {
+ Iterator changes = changedFiles.iterator();
+ while (changes.hasNext())
+ {
+ String className = (String) changes.next();
+ if (webApp.isFileScanned(className))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ };
+
+ TaskLog.log("Web application '" + webApp.getName() + "': starting scanner at interval of "
+ + scanIntervalSeconds + " seconds.");
+
+ Scanner scanner = new Scanner();
+ scanner.setScanInterval(scanIntervalSeconds);
+ scanner.addListener(changeListener);
+ scanner.setScanDirs(scanList);
+ scanner.setReportExistingFilesOnStartup(false);
+ scanner.start();
+ }
+
+ /**
+ * Sets the system properties.
+ */
+ private void setSystemProperties()
+ {
+ if (systemProperties != null)
+ {
+ Iterator propertiesIterator = systemProperties.getSystemProperties().iterator();
+ while (propertiesIterator.hasNext())
+ {
+ Property property = ((Property) propertiesIterator.next());
+ SystemProperties.setIfNotSetAlready(property);
+ }
+ }
+ }
+}
diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/ServerProxyImpl.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/ServerProxyImpl.java
new file mode 100644
index 0000000000..03da6761ae
--- /dev/null
+++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/ServerProxyImpl.java
@@ -0,0 +1,255 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2012 Sabre Holdings.
+// ------------------------------------------------------------------------
+// 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.ant;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jetty.ant.types.Connectors.Connector;
+import org.eclipse.jetty.ant.utils.ServerProxy;
+import org.eclipse.jetty.ant.utils.TaskLog;
+import org.eclipse.jetty.ant.utils.WebApplicationProxy;
+import org.eclipse.jetty.security.LoginService;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.RequestLog;
+import org.eclipse.jetty.server.SelectChannelConnector;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.handler.ContextHandlerCollection;
+import org.eclipse.jetty.server.handler.DefaultHandler;
+import org.eclipse.jetty.server.handler.HandlerCollection;
+import org.eclipse.jetty.server.handler.RequestLogHandler;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.xml.XmlConfiguration;
+import org.xml.sax.SAXException;
+
+/**
+ * A proxy class for interaction with Jetty server object. Used to have some
+ * level of abstraction over standard Jetty classes.
+ *
+ * @author Jakub Pawlowicz
+ */
+public class ServerProxyImpl implements ServerProxy
+{
+
+ /** Proxied Jetty server object. */
+ private Server server;
+
+ /** Collection of context handlers (web application contexts). */
+ private ContextHandlerCollection contexts;
+
+ /** Location of jetty.xml file. */
+ private File jettyXml;
+
+ /** List of connectors. */
+ private List connectors;
+
+ /** Request logger. */
+ private RequestLog requestLog;
+
+ /** User realms. */
+ private List loginServices;
+
+ /** List of added web applications. */
+ private Map webApplications = new HashMap();
+
+ /**
+ * Default constructor. Creates a new Jetty server with a standard connector
+ * listening on a given port.
+ *
+ * @param connectors
+ * @param loginServicesList
+ * @param requestLog
+ * @param jettyXml
+ */
+ public ServerProxyImpl(List connectors, List loginServicesList, RequestLog requestLog,
+ File jettyXml)
+ {
+ server = new Server();
+ server.setStopAtShutdown(true);
+
+ this.connectors = connectors;
+ this.loginServices = loginServicesList;
+ this.requestLog = requestLog;
+ this.jettyXml = jettyXml;
+ configure();
+ }
+
+ /**
+ * @see org.eclipse.jetty.ant.utils.ServerProxy#addWebApplication(WebApplicationProxy,
+ * int)
+ */
+ public void addWebApplication(WebApplicationProxy webApp, int scanIntervalSeconds)
+ {
+ webApp.createApplicationContext(contexts);
+
+ if (scanIntervalSeconds > 0)
+ {
+ webApplications.put(webApp, new Integer(scanIntervalSeconds));
+ }
+ }
+
+ /**
+ * Configures Jetty server before adding any web applications to it.
+ */
+ private void configure()
+ {
+ // Applies external configuration via jetty.xml
+ applyJettyXml();
+
+ // Configures connectors for this server instance.
+ Iterator<Connector> connectorIterator = connectors.iterator();
+ while (connectorIterator.hasNext())
+ {
+ Connector jettyConnector = (Connector) connectorIterator.next();
+ SelectChannelConnector jc = new SelectChannelConnector(server);
+
+ jc.setPort(jettyConnector.getPort());
+ jc.setIdleTimeout(jettyConnector.getMaxIdleTime());
+
+ server.addConnector(jc);
+ }
+
+ // Configures login services
+ Iterator servicesIterator = loginServices.iterator();
+ while (servicesIterator.hasNext())
+ {
+ LoginService service = (LoginService) servicesIterator.next();
+ server.addBean(service);
+ }
+
+ // Does not cache resources, to prevent Windows from locking files
+ Resource.setDefaultUseCaches(false);
+
+ // Set default server handlers
+ configureHandlers();
+ }
+
+ private void configureHandlers()
+ {
+ RequestLogHandler requestLogHandler = new RequestLogHandler();
+ if (requestLog != null)
+ {
+ requestLogHandler.setRequestLog(requestLog);
+ }
+
+ contexts = (ContextHandlerCollection) server
+ .getChildHandlerByClass(ContextHandlerCollection.class);
+ if (contexts == null)
+ {
+ contexts = new ContextHandlerCollection();
+ HandlerCollection handlers = (HandlerCollection) server
+ .getChildHandlerByClass(HandlerCollection.class);
+ if (handlers == null)
+ {
+ handlers = new HandlerCollection();
+ server.setHandler(handlers);
+ handlers.setHandlers(new Handler[] { contexts, new DefaultHandler(),
+ requestLogHandler });
+ }
+ else
+ {
+ handlers.addHandler(contexts);
+ }
+ }
+ }
+
+ /**
+ * Applies jetty.xml configuration to the Jetty server instance.
+ */
+ private void applyJettyXml()
+ {
+ if (jettyXml != null && jettyXml.exists())
+ {
+ TaskLog.log("Configuring jetty from xml configuration file = "
+ + jettyXml.getAbsolutePath());
+ XmlConfiguration configuration;
+ try
+ {
+ configuration = new XmlConfiguration(Resource.toURL(jettyXml));
+ configuration.configure(server);
+ }
+ catch (MalformedURLException e)
+ {
+ throw new RuntimeException(e);
+ }
+ catch (SAXException e)
+ {
+ throw new RuntimeException(e);
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /**
+ * @see org.eclipse.jetty.ant.utils.ServerProxy#start()
+ */
+ public void start()
+ {
+ try
+ {
+ server.start();
+ startScanners();
+ server.join();
+
+ }
+ catch (InterruptedException e)
+ {
+ new RuntimeException(e);
+ }
+ catch (Exception e)
+ {
+ new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Starts web applications' scanners.
+ */
+ private void startScanners() throws Exception
+ {
+ Iterator i = webApplications.keySet().iterator();
+ while (i.hasNext())
+ {
+ WebApplicationProxyImpl webApp = (WebApplicationProxyImpl) i.next();
+ Integer scanIntervalSeconds = (Integer) webApplications.get(webApp);
+ JettyRunTask.startScanner(webApp, scanIntervalSeconds.intValue());
+ }
+ }
+
+ /**
+ * @see org.eclipse.jetty.ant.utils.ServerProxy#getProxiedObject()
+ */
+ public Object getProxiedObject()
+ {
+ return server;
+ }
+}
diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/WebApplicationProxyImpl.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/WebApplicationProxyImpl.java
new file mode 100644
index 0000000000..450dd0e97a
--- /dev/null
+++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/WebApplicationProxyImpl.java
@@ -0,0 +1,542 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2012 Sabre Holdings.
+// ------------------------------------------------------------------------
+// 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.ant;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.servlet.Servlet;
+
+
+import org.apache.tools.ant.AntClassLoader;
+import org.eclipse.jetty.annotations.AnnotationConfiguration;
+import org.eclipse.jetty.ant.types.Attribute;
+import org.eclipse.jetty.ant.types.FileMatchingConfiguration;
+import org.eclipse.jetty.ant.utils.TaskLog;
+import org.eclipse.jetty.ant.utils.WebApplicationProxy;
+import org.eclipse.jetty.plus.webapp.EnvConfiguration;
+import org.eclipse.jetty.plus.webapp.PlusConfiguration;
+import org.eclipse.jetty.security.SecurityHandler;
+import org.eclipse.jetty.server.HandlerContainer;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.server.handler.ContextHandlerCollection;
+import org.eclipse.jetty.server.handler.ErrorHandler;
+import org.eclipse.jetty.server.session.SessionHandler;
+import org.eclipse.jetty.servlet.Holder;
+import org.eclipse.jetty.servlet.ServletHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.webapp.Configuration;
+import org.eclipse.jetty.webapp.FragmentConfiguration;
+import org.eclipse.jetty.webapp.JettyWebXmlConfiguration;
+import org.eclipse.jetty.webapp.MetaInfConfiguration;
+import org.eclipse.jetty.webapp.TagLibConfiguration;
+import org.eclipse.jetty.webapp.WebAppClassLoader;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.webapp.WebInfConfiguration;
+import org.eclipse.jetty.webapp.WebXmlConfiguration;
+
+/**
+ * An abstraction layer over Jetty WebAppContext.
+ *
+ * @author Jakub Pawlowicz
+ */
+public class WebApplicationProxyImpl implements WebApplicationProxy
+{
+
+ /** Common root temp directory for all web applications. */
+ static File baseTempDirectory = new File(".");
+
+ /** Name of this web application. */
+ private String name;
+
+ /** Location of WAR file (either expanded or not). */
+ private File warFile;
+
+ /** Application context path. */
+ private String contextPath;
+
+ /** Location of web.xml file. */
+ private File webXmlFile;
+
+ /** Location of jetty-env.xml file. */
+ private File jettyEnvXml;
+
+ /** List of classpath files. */
+ private List classPathFiles;
+
+ /** Jetty6 Web Application Context. */
+ private WebAppContext webAppContext;
+
+ /** Extra scan targets. */
+ private FileMatchingConfiguration extraScanTargetsConfiguration;
+
+ /** Extra context handlers. */
+ private List contextHandlers;
+
+ private List attributes;
+
+ Configuration[] configurations;
+
+ private FileMatchingConfiguration librariesConfiguration;
+
+ public static void setBaseTempDirectory(File tempDirectory)
+ {
+ baseTempDirectory = tempDirectory;
+ }
+
+
+ public static class AntServletHolder extends ServletHolder
+ {
+
+ public AntServletHolder()
+ {
+ super();
+ }
+
+
+ public AntServletHolder(Class<? extends Servlet> servlet)
+ {
+ super(servlet);
+ }
+
+
+ public AntServletHolder(Servlet servlet)
+ {
+ super(servlet);
+ }
+
+
+ public AntServletHolder(String name, Class<? extends Servlet> servlet)
+ {
+ super(name, servlet);
+ }
+
+
+ public AntServletHolder(String name, Servlet servlet)
+ {
+ super(name, servlet);
+ }
+
+
+ @Override
+ protected void initJspServlet() throws Exception
+ {
+ //super.initJspServlet();
+
+ ContextHandler ch = ((ContextHandler.Context)getServletHandler().getServletContext()).getContextHandler();
+
+ /* Set the webapp's classpath for Jasper */
+ ch.setAttribute("org.apache.catalina.jsp_classpath", ch.getClassPath());
+
+ /* Set the system classpath for Jasper */
+ String sysClassPath = getSystemClassPath(ch.getClassLoader().getParent());
+ setInitParameter("com.sun.appserv.jsp.classpath", sysClassPath);
+
+ /* Set up other classpath attribute */
+ if ("?".equals(getInitParameter("classpath")))
+ {
+ String classpath = ch.getClassPath();
+ if (classpath != null)
+ setInitParameter("classpath", classpath);
+ }
+ }
+
+
+ protected String getSystemClassPath (ClassLoader loader) throws Exception
+ {
+ StringBuilder classpath=new StringBuilder();
+ while (loader != null)
+ {
+ if (loader instanceof URLClassLoader)
+ {
+ URL[] urls = ((URLClassLoader)loader).getURLs();
+ if (urls != null)
+ {
+ for (int i=0;i<urls.length;i++)
+ {
+ Resource resource = Resource.newResource(urls[i]);
+ File file=resource.getFile();
+ if (file!=null && file.exists())
+ {
+ if (classpath.length()>0)
+ classpath.append(File.pathSeparatorChar);
+ classpath.append(file.getAbsolutePath());
+ }
+ }
+ }
+ }
+ else if (loader instanceof AntClassLoader)
+ {
+ classpath.append(((AntClassLoader)loader).getClasspath());
+ }
+
+ loader = loader.getParent();
+ }
+
+ return classpath.toString();
+ }
+
+ }
+
+ public static class AntServletHandler extends ServletHandler
+ {
+
+ @Override
+ public ServletHolder newServletHolder(Holder.Source source)
+ {
+ return new AntServletHolder();
+ }
+
+ }
+
+ public static class AntWebAppContext extends WebAppContext
+ {
+ public AntWebAppContext()
+ {
+ super();
+ }
+
+ public AntWebAppContext(HandlerContainer parent, String webApp, String contextPath)
+ {
+ super(parent, webApp, contextPath);
+ }
+
+ public AntWebAppContext(SessionHandler sessionHandler, SecurityHandler securityHandler, ServletHandler servletHandler, ErrorHandler errorHandler)
+ {
+ super(sessionHandler, securityHandler, servletHandler, errorHandler);
+ }
+
+ public AntWebAppContext(String webApp, String contextPath)
+ {
+ super(webApp, contextPath);
+ }
+
+ @Override
+ protected ServletHandler newServletHandler()
+ {
+ return new AntServletHandler();
+ }
+ }
+
+
+ /**
+ * Default constructor. Takes application name as an argument
+ *
+ * @param name web application name.
+ */
+ public WebApplicationProxyImpl(String name) throws Exception
+ {
+ this.name = name;
+ TaskLog.log("\nConfiguring Jetty for web application: " + name);
+
+ this.configurations = new Configuration[]
+ { new AntWebInfConfiguration(),
+ new AntWebXmlConfiguration(),
+ new MetaInfConfiguration(),
+ new FragmentConfiguration(),
+ new EnvConfiguration(),
+ new PlusConfiguration(),
+ new AnnotationConfiguration(),
+ new JettyWebXmlConfiguration(),
+ new TagLibConfiguration() };
+ }
+
+ public List getClassPathFiles()
+ {
+ return classPathFiles;
+ }
+
+ public String getContextPath()
+ {
+ return contextPath;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public File getSourceDirectory()
+ {
+ return warFile;
+ }
+
+ public File getWebXmlFile()
+ {
+ return webXmlFile;
+ }
+
+ public void setSourceDirectory(File warFile)
+ {
+ this.warFile = warFile;
+ TaskLog.log("Webapp source directory = " + warFile);
+ }
+
+ public void setContextPath(String contextPath)
+ {
+ if (!contextPath.startsWith("/"))
+ {
+ contextPath = "/" + contextPath;
+ }
+ this.contextPath = contextPath;
+ TaskLog.log("Context path = " + contextPath);
+
+ }
+
+ public void setWebXml(File webXmlFile)
+ {
+ this.webXmlFile = webXmlFile;
+ }
+
+ public void setJettyEnvXml(File jettyEnvXml)
+ {
+ this.jettyEnvXml = jettyEnvXml;
+ if (this.jettyEnvXml != null)
+ {
+ TaskLog.log("jetty-env.xml file: = " + jettyEnvXml.getAbsolutePath());
+ }
+ }
+
+ public void setClassPathFiles(List classPathFiles)
+ {
+ this.classPathFiles = classPathFiles;
+ TaskLog.log("Classpath = " + classPathFiles);
+ }
+
+ /**
+ * Checks if a given file is scanned according to the internal
+ * configuration. This may be difficult due to use of 'includes' and
+ * 'excludes' statements.
+ *
+ * @param pathToFile a fully qualified path to file.
+ * @return true if file is being scanned, false otherwise.
+ */
+ public boolean isFileScanned(String pathToFile)
+ {
+ return librariesConfiguration.isIncluded(pathToFile)
+ || extraScanTargetsConfiguration.isIncluded(pathToFile);
+ }
+
+ public void setLibrariesConfiguration(FileMatchingConfiguration classesConfiguration)
+ {
+ TaskLog.log("Default scanned paths = " + classesConfiguration.getBaseDirectories());
+ this.librariesConfiguration = classesConfiguration;
+ }
+
+ public List getLibraries()
+ {
+ return librariesConfiguration.getBaseDirectories();
+ }
+
+ public void setExtraScanTargetsConfiguration(
+ FileMatchingConfiguration extraScanTargetsConfiguration)
+ {
+ this.extraScanTargetsConfiguration = extraScanTargetsConfiguration;
+ TaskLog.log("Extra scan targets = " + extraScanTargetsConfiguration.getBaseDirectories());
+ }
+
+ public void setAttributes(List attributes)
+ {
+ this.attributes = attributes;
+ }
+
+ public List getExtraScanTargets()
+ {
+ return extraScanTargetsConfiguration.getBaseDirectories();
+ }
+
+ public List getContextHandlers()
+ {
+ return contextHandlers;
+ }
+
+ public void setContextHandlers(List contextHandlers)
+ {
+ this.contextHandlers = contextHandlers;
+ }
+
+ /**
+ * @see WebApplicationProxy#getProxiedObject()
+ */
+ public Object getProxiedObject()
+ {
+ return webAppContext;
+ }
+
+ /**
+ * @see WebApplicationProxy#start()
+ */
+ public void start()
+ {
+ try
+ {
+ TaskLog.logWithTimestamp("Starting web application " + name + " ...\n");
+ webAppContext.start();
+ }
+ catch (Exception e)
+ {
+ TaskLog.log(e.toString());
+ }
+ }
+
+ /**
+ * @see WebApplicationProxy#stop()
+ */
+ public void stop()
+ {
+ try
+ {
+ TaskLog.logWithTimestamp("Stopping web application " + name + " ...");
+ Thread.currentThread().sleep(500L);
+ webAppContext.stop();
+ }
+ catch (InterruptedException e)
+ {
+ TaskLog.log(e.toString());
+ }
+ catch (Exception e)
+ {
+ TaskLog.log(e.toString());
+ }
+ }
+
+ /**
+ * @see WebApplicationProxy#createApplicationContext(org.eclipse.jetty.server.handler.ContextHandlerCollection)
+ */
+ public void createApplicationContext(ContextHandlerCollection contexts)
+ {
+ webAppContext = new AntWebAppContext(contexts, warFile.getAbsolutePath(), contextPath);
+ webAppContext.setDisplayName(name);
+
+ configurePaths();
+
+ if ( !attributes.isEmpty() )
+ {
+ for ( Iterator i = attributes.iterator(); i.hasNext(); )
+ {
+ Attribute attr = (Attribute) i.next();
+
+ webAppContext.setAttribute(attr.getName(),attr.getValue());
+ }
+ }
+
+ configureHandlers(contexts);
+
+ applyConfiguration();
+ }
+
+ private void configureHandlers(ContextHandlerCollection contexts)
+ {
+ // adding extra context handlers
+ Iterator handlersIterator = contextHandlers.iterator();
+ while (handlersIterator.hasNext())
+ {
+ ContextHandler contextHandler = (ContextHandler) handlersIterator.next();
+ contexts.addHandler(contextHandler);
+ }
+ }
+
+ private void configurePaths()
+ {
+ // configuring temp directory
+ File tempDir = new File(baseTempDirectory, contextPath);
+ if (!tempDir.exists())
+ {
+ tempDir.mkdirs();
+ }
+ webAppContext.setTempDirectory(tempDir);
+ tempDir.deleteOnExit();
+ TaskLog.log("Temp directory = " + tempDir.getAbsolutePath());
+
+ // configuring WAR directory for packaged web applications
+ if (warFile.isFile())
+ {
+ warFile = new File(tempDir, "webapp");
+ webXmlFile = new File(new File(warFile, "WEB-INF"), "web.xml");
+ }
+ }
+
+ /**
+ * Applies web application configuration at the end of configuration process
+ * or after application restart.
+ */
+ void applyConfiguration()
+ {
+ for (int i = 0; i < configurations.length; i++)
+ {
+ if (configurations[i] instanceof EnvConfiguration)
+ {
+ try
+ {
+ if (jettyEnvXml != null && jettyEnvXml.exists())
+ {
+ ((EnvConfiguration) configurations[i]).setJettyEnvXml(Resource.toURL(jettyEnvXml));
+ }
+ }
+ catch (MalformedURLException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+ else if (configurations[i] instanceof AntWebXmlConfiguration)
+ {
+ ((AntWebXmlConfiguration) configurations[i]).setClassPathFiles(classPathFiles);
+ ((AntWebXmlConfiguration) configurations[i]).setWebAppBaseDir(warFile);
+ ((AntWebXmlConfiguration) configurations[i]).setWebXmlFile(webXmlFile);
+ ((AntWebXmlConfiguration) configurations[i]).setWebDefaultXmlFile(webDefaultXmlFile);
+ }
+ }
+
+ try
+ {
+ ClassLoader loader = new WebAppClassLoader(this.getClass().getClassLoader(),
+ webAppContext);
+ webAppContext.setParentLoaderPriority(true);
+ webAppContext.setClassLoader(loader);
+ if (webDefaultXmlFile != null)
+ webAppContext.setDefaultsDescriptor(webDefaultXmlFile.getCanonicalPath());
+
+ }
+ catch (IOException e)
+ {
+ TaskLog.log(e.toString());
+ }
+
+ webAppContext.setConfigurations(configurations);
+ }
+
+ private File webDefaultXmlFile;
+
+ public File getWebDefaultXmlFile()
+ {
+ return this.webDefaultXmlFile;
+ }
+
+ public void setWebDefaultXmlFile(File webDefaultXmlfile)
+ {
+ this.webDefaultXmlFile = webDefaultXmlfile;
+ }
+}
diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Attribute.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Attribute.java
new file mode 100644
index 0000000000..024bda8cbf
--- /dev/null
+++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Attribute.java
@@ -0,0 +1,47 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2012 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.ant.types;
+
+public class Attribute
+{
+
+ String name;
+
+ String value;
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public void setValue(String value)
+ {
+ this.value = value;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public String getValue()
+ {
+ return value;
+ }
+}
diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Attributes.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Attributes.java
new file mode 100644
index 0000000000..b073279621
--- /dev/null
+++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Attributes.java
@@ -0,0 +1,38 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2012 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.ant.types;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Attributes
+{
+
+ List _attributes = new ArrayList();
+
+ public void addAttribute(Attribute attr )
+ {
+ _attributes.add(attr);
+ }
+
+ public List getAttributes()
+ {
+ return _attributes;
+ }
+}
diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Connectors.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Connectors.java
new file mode 100644
index 0000000000..d140f2dd4c
--- /dev/null
+++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/Connectors.java
@@ -0,0 +1,116 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2012 Sabre Holdings.
+// ------------------------------------------------------------------------
+// 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.ant.types;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.SelectChannelConnector;
+
+/**
+ * Specifies a jetty configuration <connectors/> element for Ant build file.
+ *
+ * @author Jakub Pawlowicz
+ */
+public class Connectors
+{
+ private List<Connector> connectors = new ArrayList<Connector>();
+ private List<Connector> defaultConnectors = new ArrayList<Connector>();
+
+ /**
+ * Default constructor.
+ */
+ public Connectors() {
+ this(8080, 30000);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param port The port that the default connector will listen on
+ * @param maxIdleTime The maximum idle time for the default connector
+ */
+ public Connectors(int port, int maxIdleTime)
+ {
+ defaultConnectors.add(new Connector(port, maxIdleTime));
+ }
+
+ /**
+ * Adds a connector to the list of connectors to deploy.
+ *
+ * @param connector A connector to add to the list
+ */
+ public void add(Connector connector)
+ {
+ connectors.add(connector);
+ }
+
+ /**
+ * Returns the list of known connectors to deploy.
+ *
+ * @return The list of known connectors
+ */
+ public List<Connector> getConnectors()
+ {
+ return connectors;
+ }
+
+ /**
+ * Gets the default list of connectors to deploy when no connectors
+ * were explicitly added to the list.
+ *
+ * @return The list of default connectors
+ */
+ public List<Connector> getDefaultConnectors()
+ {
+ return defaultConnectors;
+ }
+
+ public class Connector
+ {
+ private int port;
+ private int maxIdleTime;
+
+ public Connector(int port, int maxIdleTime)
+ {
+ this.port = port;
+ this.maxIdleTime = maxIdleTime;
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ public int getMaxIdleTime() {
+ return maxIdleTime;
+ }
+
+ public void setMaxIdleTime(int maxIdleTime) {
+ this.maxIdleTime = maxIdleTime;
+ }
+
+ }
+
+}
diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/ContextHandlers.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/ContextHandlers.java
new file mode 100644
index 0000000000..838da3953f
--- /dev/null
+++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/ContextHandlers.java
@@ -0,0 +1,46 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2012 Sabre Holdings.
+// ------------------------------------------------------------------------
+// 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.ant.types;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jetty.server.handler.ContextHandler;
+
+/**
+ * Specifies <contextHandlers/> element in web app configuration.
+ *
+ * @author Jakub Pawlowicz
+ */
+public class ContextHandlers
+{
+
+ private List contextHandlers = new ArrayList();
+
+ public void add(ContextHandler handler)
+ {
+ contextHandlers.add(handler);
+ }
+
+ public List getContextHandlers()
+ {
+ return contextHandlers;
+ }
+}
diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/FileMatchingConfiguration.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/FileMatchingConfiguration.java
new file mode 100644
index 0000000000..f6d1deffd3
--- /dev/null
+++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/FileMatchingConfiguration.java
@@ -0,0 +1,99 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2012 Sabre Holdings.
+// ------------------------------------------------------------------------
+// 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.ant.types;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.tools.ant.DirectoryScanner;
+
+/**
+ * Describes set of files matched by <fileset/> elements in ant configuration
+ * file. It is used to group application classes, libraries, and scannedTargets
+ * elements.
+ *
+ * @author Jakub Pawlowicz
+ */
+public class FileMatchingConfiguration
+{
+
+ private List directoryScanners;
+
+ public FileMatchingConfiguration()
+ {
+ this.directoryScanners = new ArrayList();
+ }
+
+ /**
+ * @param directoryScanner new directory scanner retrieved from the
+ * <fileset/> element.
+ */
+ public void addDirectoryScanner(DirectoryScanner directoryScanner)
+ {
+ this.directoryScanners.add(directoryScanner);
+ }
+
+ /**
+ * @return a list of base directories denoted by a list of directory
+ * scanners.
+ */
+ public List getBaseDirectories()
+ {
+ List baseDirs = new ArrayList();
+ Iterator scanners = directoryScanners.iterator();
+ while (scanners.hasNext())
+ {
+ DirectoryScanner scanner = (DirectoryScanner) scanners.next();
+ baseDirs.add(scanner.getBasedir());
+ }
+
+ return baseDirs;
+ }
+
+ /**
+ * Checks if passed file is scanned by any of the directory scanners.
+ *
+ * @param pathToFile a fully qualified path to tested file.
+ * @return true if so, false otherwise.
+ */
+ public boolean isIncluded(String pathToFile)
+ {
+ Iterator scanners = directoryScanners.iterator();
+ while (scanners.hasNext())
+ {
+ DirectoryScanner scanner = (DirectoryScanner) scanners.next();
+ scanner.scan();
+ String[] includedFiles = scanner.getIncludedFiles();
+
+ for (int i = 0; i < includedFiles.length; i++)
+ {
+ File includedFile = new File(scanner.getBasedir(), includedFiles[i]);
+ if (pathToFile.equalsIgnoreCase(includedFile.getAbsolutePath()))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/LoginServices.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/LoginServices.java
new file mode 100644
index 0000000000..faaebe098e
--- /dev/null
+++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/LoginServices.java
@@ -0,0 +1,46 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2012 Sabre Holdings.
+// ------------------------------------------------------------------------
+// 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.ant.types;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jetty.security.LoginService;
+
+/**
+ * Specifies a jetty configuration <loginServices/> element for Ant build file.
+ *
+ * @author Jakub Pawlowicz
+ */
+public class LoginServices
+{
+
+ private List loginServices = new ArrayList();
+
+ public void add(LoginService service)
+ {
+ loginServices.add(service);
+ }
+
+ public List getLoginServices()
+ {
+ return loginServices;
+ }
+}
diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/SystemProperties.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/SystemProperties.java
new file mode 100755
index 0000000000..69190412eb
--- /dev/null
+++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/SystemProperties.java
@@ -0,0 +1,66 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2012 Sabre Holdings.
+// ------------------------------------------------------------------------
+// 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.ant.types;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tools.ant.taskdefs.Property;
+import org.eclipse.jetty.ant.utils.TaskLog;
+
+/**
+ * Ant <systemProperties/> tag definition.
+ *
+ * @author Jakub Pawlowicz
+ */
+public class SystemProperties
+{
+
+ private List systemProperties = new ArrayList();
+
+ public List getSystemProperties()
+ {
+ return systemProperties;
+ }
+
+ public void addSystemProperty(Property property)
+ {
+ systemProperties.add(property);
+ }
+
+ /**
+ * Set a System.property with this value if it is not already set.
+ *
+ * @returns true if property has been set
+ */
+ public static boolean setIfNotSetAlready(Property property)
+ {
+ if (System.getProperty(property.getName()) == null)
+ {
+ System.setProperty(property.getName(), (property.getValue() == null ? "" : property
+ .getValue()));
+ TaskLog.log("Setting property '" + property.getName() + "' to value '"
+ + property.getValue() + "'");
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/WebApp.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/WebApp.java
new file mode 100755
index 0000000000..de36e1a113
--- /dev/null
+++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/types/WebApp.java
@@ -0,0 +1,296 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2012 Sabre Holdings.
+// ------------------------------------------------------------------------
+// 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.ant.types;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.FileSet;
+
+/**
+ * Ant's WebApp object definition.
+ *
+ * @author Jakub Pawlowicz
+ */
+public class WebApp
+{
+
+ /** List of web application libraries. */
+ private List libraries = new ArrayList();
+
+ /** List of web application class directories. */
+ private List classes = new ArrayList();
+
+ /** Reference to Ant project variable. */
+ private Project project;
+
+ /** Application context path. */
+ private String contextPath;
+
+ /** Application name. */
+ private String name;
+
+ /** Application war file (either exploded or not). */
+ private File warFile;
+
+ /** Location of application web.xml file. */
+ private File webXmlFile;
+
+ /** Location of jetty-env.xml file. */
+ private File jettyEnvXml;
+
+ /** List of extra scan targets for this web application. */
+ private FileSet scanTargets;
+
+ /** List of the attributes to set to webapp context */
+ private Attributes attributes;
+
+ /** List of optional context handlers. */
+ private ContextHandlers contextHandlers;
+
+ private File webDefaultXmlFile;
+
+ /**
+ * Length of interval in which application will be scanned for changes (0
+ * means scanner wouldn't be created).
+ */
+ private int scanIntervalSeconds = 0;
+
+ public WebApp(Project project)
+ {
+ this.project = project;
+ }
+
+ public File getWebDefaultXmlFile()
+ {
+ return this.webDefaultXmlFile;
+ }
+
+ public void setWebDefaultXmlFile(File webDefaultXmlfile)
+ {
+ this.webDefaultXmlFile = webDefaultXmlfile;
+ }
+
+ public void addLib(FileSet lib)
+ {
+ libraries.add(lib);
+ }
+
+ public List getLibraries()
+ {
+ return libraries;
+ }
+
+ public void addClasses(FileSet classes)
+ {
+ this.classes.add(classes);
+ }
+
+ public List getClasses()
+ {
+ return classes;
+ }
+
+ public File getWarFile()
+ {
+ return warFile;
+ }
+
+ public void setWarFile(File warFile)
+ {
+ this.warFile = warFile;
+ }
+
+ public String getContextPath()
+ {
+ return contextPath;
+ }
+
+ public void setContextPath(String contextPath)
+ {
+ this.contextPath = contextPath;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ /**
+ * @return a list of classpath files (libraries and class directories).
+ */
+ public List getClassPathFiles()
+ {
+ List classPathFiles = new ArrayList();
+ Iterator classesIterator = classes.iterator();
+ while (classesIterator.hasNext())
+ {
+ FileSet clazz = (FileSet) classesIterator.next();
+ classPathFiles.add(clazz.getDirectoryScanner(project).getBasedir());
+ }
+
+ Iterator iterator = libraries.iterator();
+ while (iterator.hasNext())
+ {
+ FileSet library = (FileSet) iterator.next();
+ String[] includedFiles = library.getDirectoryScanner(project).getIncludedFiles();
+ File baseDir = library.getDirectoryScanner(project).getBasedir();
+
+ for (int i = 0; i < includedFiles.length; i++)
+ {
+ classPathFiles.add(new File(baseDir, includedFiles[i]));
+ }
+ }
+
+
+ return classPathFiles;
+ }
+
+ /**
+ * @return a <code>FileMatchingConfiguration</code> object describing the
+ * configuration of all libraries added to this particular web app
+ * (both classes and libraries).
+ */
+ public FileMatchingConfiguration getLibrariesConfiguration()
+ {
+ FileMatchingConfiguration config = new FileMatchingConfiguration();
+
+ Iterator classesIterator = classes.iterator();
+ while (classesIterator.hasNext())
+ {
+ FileSet clazz = (FileSet) classesIterator.next();
+ config.addDirectoryScanner(clazz.getDirectoryScanner(project));
+ }
+
+ Iterator librariesIterator = libraries.iterator();
+ while (librariesIterator.hasNext())
+ {
+ FileSet library = (FileSet) librariesIterator.next();
+ config.addDirectoryScanner(library.getDirectoryScanner(project));
+ }
+
+ return config;
+ }
+
+ public FileMatchingConfiguration getScanTargetsConfiguration()
+ {
+ FileMatchingConfiguration configuration = new FileMatchingConfiguration();
+
+ if (scanTargets != null)
+ {
+ configuration.addDirectoryScanner(scanTargets.getDirectoryScanner(project));
+ }
+
+ return configuration;
+ }
+
+ /**
+ * @return location of web.xml file (either inside WAR or on the external
+ * location).
+ */
+ public File getWebXmlFile()
+ {
+ if (webXmlFile == null)
+ {
+ File webInf = new File(warFile, "WEB-INF");
+ return new File(webInf, "web.xml");
+ }
+
+ return webXmlFile;
+ }
+
+ public void setWebXmlFile(File webXmlFile)
+ {
+ this.webXmlFile = webXmlFile;
+ }
+
+ public void addScanTargets(FileSet scanTargets)
+ {
+ if (this.scanTargets != null)
+ {
+ throw new BuildException("Only one <scanTargets> tag is allowed!");
+ }
+
+ this.scanTargets = scanTargets;
+ }
+
+ public void addContextHandlers(ContextHandlers contextHandlers)
+ {
+ if (this.contextHandlers != null)
+ {
+ throw new BuildException("Only one <contextHandlers> tag is allowed!");
+ }
+
+ this.contextHandlers = contextHandlers;
+ }
+
+ public void addAttributes(Attributes attributes)
+ {
+ if (this.attributes != null)
+ {
+ throw new BuildException("Only one <attributes> tag is allowed!");
+ }
+
+ this.attributes = attributes;
+ }
+
+ public int getScanIntervalSeconds()
+ {
+ return scanIntervalSeconds;
+ }
+
+ public void setScanIntervalSeconds(int scanIntervalSeconds)
+ {
+ this.scanIntervalSeconds = scanIntervalSeconds;
+ }
+
+ public File getJettyEnvXml()
+ {
+ return jettyEnvXml;
+ }
+
+ public void setJettyEnvXml(File jettyEnvXml)
+ {
+ this.jettyEnvXml = jettyEnvXml;
+ }
+
+ public List getContextHandlers()
+ {
+ return (contextHandlers != null ? contextHandlers.getContextHandlers() : new ArrayList());
+ }
+
+ public List getAttributes()
+ {
+ return (attributes != null ? attributes.getAttributes() : new ArrayList());
+ }
+}
diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/utils/ServerProxy.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/utils/ServerProxy.java
new file mode 100644
index 0000000000..9ac07b1dbd
--- /dev/null
+++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/utils/ServerProxy.java
@@ -0,0 +1,40 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2012 Sabre Holdings.
+// ------------------------------------------------------------------------
+// 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.ant.utils;
+
+public interface ServerProxy
+{
+
+ /**
+ * Adds a new web application to this server.
+ *
+ * @param webApp a WebApplicationProxy object.
+ * @param scanIntervalSeconds
+ */
+ public void addWebApplication(WebApplicationProxy webApp, int scanIntervalSeconds);
+
+ /**
+ * Starts this server.
+ */
+ public void start();
+
+ public Object getProxiedObject();
+
+} \ No newline at end of file
diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/utils/TaskLog.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/utils/TaskLog.java
new file mode 100644
index 0000000000..cbd2ab6d0b
--- /dev/null
+++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/utils/TaskLog.java
@@ -0,0 +1,54 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2012 Sabre Holdings.
+// ------------------------------------------------------------------------
+// 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.ant.utils;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.tools.ant.Task;
+
+/**
+ * Provides logging functionality for classes without access to the Ant project
+ * variable.
+ *
+ * @author Jakub Pawlowicz
+ */
+public class TaskLog
+{
+
+ private static Task task;
+
+ private static SimpleDateFormat format = new SimpleDateFormat(
+ "yyyy-MM-dd HH:mm:ss.SSS");
+
+ public static void setTask(Task task)
+ {
+ TaskLog.task = task;
+ }
+
+ public static void log(String message)
+ {
+ task.log(message);
+ }
+
+ public static void logWithTimestamp(String message)
+ {
+ task.log(format.format(new Date()) + ": " + message);
+ }
+}
diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/utils/WebApplicationProxy.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/utils/WebApplicationProxy.java
new file mode 100644
index 0000000000..9be016fa2e
--- /dev/null
+++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/utils/WebApplicationProxy.java
@@ -0,0 +1,47 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2012 Sabre Holdings.
+// ------------------------------------------------------------------------
+// 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.ant.utils;
+
+import org.eclipse.jetty.server.handler.ContextHandlerCollection;
+
+public interface WebApplicationProxy
+{
+
+ public Object getProxiedObject();
+
+ /**
+ * Starts this web application context.
+ */
+ public void start();
+
+ /**
+ * Stops this web application context.
+ */
+ public void stop();
+
+ /**
+ * Creates a new Jetty web application context from this object.
+ *
+ * @param contexts collection of context this application should be added
+ * to.
+ */
+ public void createApplicationContext(ContextHandlerCollection contexts);
+
+}
diff --git a/jetty-ant/src/main/resources/tasks.properties b/jetty-ant/src/main/resources/tasks.properties
new file mode 100755
index 0000000000..c7218df929
--- /dev/null
+++ b/jetty-ant/src/main/resources/tasks.properties
@@ -0,0 +1 @@
+jetty=org.eclipse.jetty.ant.JettyRunTask

Back to the top