diff options
Diffstat (limited to 'jetty-ant/src/main')
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 |