dev@grizzly.java.net

Re: RFC Deployer refactoring

From: Jeanfrancois Arcand <Jeanfrancois.Arcand_at_Sun.COM>
Date: Wed, 16 Sep 2009 15:51:34 -0400

Salut,

Hubert Iwaniuk wrote:
> Hi *,
>
> Refactoring is nearly finished.
> I've attached a patch. There should be no regression compared to trunk.
> Please comment on this patch.

for other peoples, can you summarize what you did exactly? I see than
WebAppAdapter.service() is empty now, as a place holder for welcome page
processing. I think this behavior needs to happens inside the
GrizzlyAdapterChain where we properly populate the Mapper with the
information we are getting from web.xml/default web.xml.

You should commit on the trunk if there is no regression so dev folks
can makes changes directly.

Like I said, Great Work!

-- Jeanfrancois



>
> Index: modules/utils/src/main/java/com/sun/grizzly/util/ClassLoaderUtil.java
> ===================================================================
> --- modules/utils/src/main/java/com/sun/grizzly/util/ClassLoaderUtil.java (.../trunk/code) (revision 3643)
> +++ modules/utils/src/main/java/com/sun/grizzly/util/ClassLoaderUtil.java (.../branches/deployer-refactoring) (revision 3643)
> @@ -40,7 +40,6 @@
> import java.io.File;
> import java.io.FilenameFilter;
> import java.io.IOException;
> -import java.net.MalformedURLException;
> import java.net.URL;
> import java.net.URLClassLoader;
> import java.util.logging.Level;
> @@ -56,31 +55,27 @@
> * Create a class loader that can load classes from the specified
> * file directory. The file directory must contains .jar ot .zip
> *
> - * @param file a directory
> - * @param ClassLoader the parent classloader, or null if none.
> + * @param libDir a directory
> + * @param cl the parent classloader, or null if none.
> * @return A Classloader that can load classes from a directory that
> * contains jar and zip files.
> + * @throws java.io.IOException I/O fail
> + * @deprecated removal candidate, never used
> */
> - public final static ClassLoader createClassloader(File libDir, ClassLoader cl)
> + public static ClassLoader createClassloader(File libDir, ClassLoader cl)
> throws IOException{
> URLClassLoader urlClassloader = null;
> if (libDir.exists()){
> if (libDir.isDirectory()){
> String[] jars = libDir.list(new FilenameFilter() {
> public boolean accept(File dir, String name) {
> - if (name.endsWith(".jar") || name.endsWith(".zip")){
> - return true;
> - } else {
> - return false;
> - }
> -
> + return name.endsWith(".jar") || name.endsWith(".zip");
> }
> });
> URL[] urls = new URL[jars.length];
> for (int i=0; i < jars.length; i++){
> String path = new File(libDir.getName()
> - + File.separator + jars[i]).getCanonicalFile().toURL()
> - .toString();
> + + File.separator + jars[i]).getCanonicalFile().toURI().toURL().toString();
> urls[i] = new URL(path);
> }
> urlClassloader = new URLClassLoader(urls,cl);
> @@ -90,17 +85,18 @@
> }
>
> /**
> - * Construct a {_at_link URLClassloader} based on a canonial file location.
> + * Construct a {_at_link URLClassLoader} based on a canonial file location.
> * @param dirPath a canonial path location
> * @return a {_at_link URLClassLoader}
> + * @throws java.io.IOException I/O
> + * @throws java.net.MalformedURLException Invalid URL
> */
> - public static URLClassLoader createURLClassLoader(String dirPath) throws MalformedURLException
> - , IOException{
> + public static URLClassLoader createURLClassLoader(String dirPath) throws IOException{
>
> String path;
> - File file = null;
> - URL appRoot = null;
> - URL classesURL = null;
> + File file;
> + URL appRoot;
> + URL classesURL;
>
> if (!dirPath.endsWith(File.separator)){
> dirPath += File.separator;
> @@ -120,10 +116,10 @@
> appRoot = new URL("file://" + path);
> }
>
> - String absolutePath = new File(path).getAbsolutePath();
> - URL[] urls = null;
> + String absolutePath = new File(path).getAbsolutePath();
> + URL[] urls;
> File libFiles = new File(absolutePath + File.separator + "WEB-INF"+ File.separator + "lib");
> - int arraySize = (appRoot == null ? 1:2);
> + int arraySize = 2;
>
> //Must be a better way because that sucks!
> String separator = (System.getProperty("os.name")
> @@ -140,9 +136,7 @@
>
> urls[urls.length -1] = classesURL;
> urls[urls.length -2] = appRoot;
> - URLClassLoader urlClassloader = new URLClassLoader(urls,
> - Thread.currentThread().getContextClassLoader());
> - return urlClassloader;
> + return new URLClassLoader(urls, Thread.currentThread().getContextClassLoader());
> }
>
> /**
> @@ -155,13 +149,13 @@
> }
>
> /**
> - * Load a class using the provided {_at_link Classloader}
> + * Load a class using the provided {_at_link ClassLoader}
> * @param clazzName The name of the class you want to load.
> * @param classLoader A classloader to use for loading a class.
> * @return an instance of clazzname
> */
> public static Object load(String clazzName, ClassLoader classLoader) {
> - Class className = null;
> + Class className;
> try {
> className = Class.forName(clazzName, true, classLoader);
> return className.newInstance();
> Index: modules/http-servlet-deployer/src/main/java/com/sun/grizzly/http/servlet/deployer/WebAppAdapter.java
> ===================================================================
> --- modules/http-servlet-deployer/src/main/java/com/sun/grizzly/http/servlet/deployer/WebAppAdapter.java (.../trunk/code) (revision 0)
> +++ modules/http-servlet-deployer/src/main/java/com/sun/grizzly/http/servlet/deployer/WebAppAdapter.java (.../branches/deployer-refactoring) (revision 3643)
> @@ -0,0 +1,453 @@
> +/**
> + *
> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. *
> + * Copyright 2007-2008 Sun Microsystems, Inc. All rights reserved. *
> + * The contents of this file are subject to the terms of either the GNU
> + * General Public License Version 2 only ("GPL") or the Common Development
> + * and Distribution License("CDDL") (collectively, the "License"). You
> + * may not use this file except in compliance with the License. You can obtain
> + * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
> + * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
> + * language governing permissions and limitations under the License.
> + *
> + * When distributing the software, include this License Header Notice in each
> + * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
> + * Sun designates this particular file as subject to the "Classpath" exception
> + * as provided by Sun in the GPL Version 2 section of the License file that
> + * accompanied this code. If applicable, add the following below the License
> + * Header, with the fields enclosed by brackets [] replaced by your own
> + * identifying information: "Portions Copyrighted [year]
> + * [name of copyright owner]"
> + *
> + * Contributor(s):
> + *
> + * If you wish your version of this file to be governed by only the CDDL or
> + * only the GPL Version 2, indicate your decision by adding "[Contributor]
> + * elects to include this software in this distribution under the [CDDL or GPL
> + * Version 2] license." If you don't indicate a single choice of license, a
> + * recipient has the option to distribute your version of this file under
> + * either the CDDL, the GPL Version 2 or to extend the choice of license to
> + * its licensees as provided above. However, if you add GPL Version 2 code
> + * and therefore, elected the GPL Version 2 license, then the option applies
> + * only if the new code is made subject to such option by the copyright
> + * holder.
> + *
> + */
> +package com.sun.grizzly.http.servlet.deployer;
> +
> +import com.sun.grizzly.http.servlet.ServletAdapter;
> +import com.sun.grizzly.http.webxml.schema.*;
> +import com.sun.grizzly.http.embed.GrizzlyWebServer;
> +import com.sun.grizzly.tcp.http11.GrizzlyRequest;
> +import com.sun.grizzly.tcp.http11.GrizzlyResponse;
> +import com.sun.grizzly.util.ClassLoaderUtil;
> +
> +import javax.servlet.Servlet;
> +import javax.servlet.Filter;
> +import java.net.URLClassLoader;
> +import java.util.*;
> +import java.util.logging.Level;
> +import java.util.logging.Logger;
> +
> +/**
> + * {_at_link com.sun.grizzly.http.webxml.schema.WebApp} Adapter.
> + *
> + * @author Hubert Iwaniuk
> + * @since Aug 25, 2009
> + */
> +public class WebAppAdapter extends ServletAdapter {
> + private static Logger logger = Logger.getLogger("WebAppAdapter");
> + private static final String EMPTY_SERVLET_PATH = "";
> +
> + private static final String ROOT = "/";
> +
> + private WebApp webApp;
> + private ClassLoader webAppCL;
> + private GrizzlyWebServer gws;
> + private String root;
> + private String context;
> +
> + /**
> + * Default constructor, takes care of setting up adapter.
> + *
> + * @param gws Grizzly Web Server to register {_at_link ServletAdapter}s.
> + * @param root Root folder, for serving static resources?
> + * @param context Context to be deployed to.
> + * @param webApp Web application to be run by this adapter.
> + * @param webAppCL Web application class loader.
> + * @param webdefault Default web application.
> + */
> + public WebAppAdapter(GrizzlyWebServer gws, String root, String context, final WebApp webApp, URLClassLoader webAppCL, WebApp webdefault) {
> + this.gws = gws;
> + this.root = root;
> + this.context = context;
> + if (webdefault != null) {
> + this.webApp = webApp.mergeWith(webdefault);
> + } else {
> + this.webApp = webApp;
> + }
> + this.webAppCL = webAppCL;
> + ClassLoader prevCL = Thread.currentThread().getContextClassLoader();
> + Thread.currentThread().setContextClassLoader(webAppCL);
> + try {
> + initialize();
> + } finally {
> + Thread.currentThread().setContextClassLoader(prevCL);
> + }
> + }
> +
> + private void initialize() {
> +
> + boolean blankContextServletPathFound = false;
> + boolean defaultContextServletPathFound = false;
> +
> + List<String> aliasesUsed = new ArrayList<String>();
> +
> + for (Map.Entry<ServletAdapter, List<String>> adapterAliases :
> + getServletAdaptersToAlises(webApp, context).entrySet()) {
> + ServletAdapter sa = adapterAliases.getKey();
> + sa.setClassLoader(webAppCL);
> +
> + // set Filters for this context if there are some
> + setFilters(webApp, sa);
> +
> + // set Listeners
> + setListeners(webApp, sa);
> +
> + //set root Folder
> + sa.setRootFolder(root);
> +
> + // create the alias array from the list of urlPattern
> + String alias[] = getAlias(sa, adapterAliases.getValue());
> +
> + // need to be disabled for JSP
> + sa.setHandleStaticResources(false);
> +
> + // enabled it if not / or /*
> + for (String item : alias) {
> + if (item.endsWith(ROOT) || item.endsWith("/*")) {
> + sa.setHandleStaticResources(true);
> + }
> + }
> +
> + if (logger.isLoggable(Level.FINEST)) {
> + logServletAdapterConfigurationWithAliases(sa, alias);
> + }
> +
> + // keep trace of mapping
> + aliasesUsed.addAll(Arrays.asList(alias));
> +
> + gws.addGrizzlyAdapter(sa, alias);
> +
> + if (ROOT.equals(sa.getServletPath())) {
> + defaultContextServletPathFound = true;
> + }
> +
> + if (EMPTY_SERVLET_PATH.equals(sa.getServletPath())) {
> + blankContextServletPathFound = true;
> + }
> + }
> +
> + // we need one servlet that will handle "/"
> + if (!defaultContextServletPathFound) {
> + logger.log(Level.FINEST, "Adding a ServletAdapter to handle / path");
> + createAndInstallServletAdapter(root, context, ROOT);
> + }
> +
> + // pour les jsp dans le root du context
> + if (!blankContextServletPathFound && !aliasesUsed.contains(context + ROOT)) {
> + logger.log(Level.FINEST, "Adding a ServletAdapter to handle root path");
> + createAndInstallServletAdapter(root, context, EMPTY_SERVLET_PATH);
> + }
> + }
> +
> + private void createAndInstallServletAdapter(
> + final String rootFolder, final String context, final String tmpPath) {
> + ServletAdapter sa = new ServletAdapter();
> +
> + sa.setContextPath(context);
> + sa.setServletPath(tmpPath);
> + sa.setHandleStaticResources(true);
> + sa.setRootFolder(rootFolder);
> +
> + logServletAdapterConfiguration(context, sa);
> +
> + gws.addGrizzlyAdapter(sa, new String[]{context + ROOT});
> + }
> +
> + private static void logServletAdapterConfiguration(final String ctx, final ServletAdapter sa) {
> + if (logger.isLoggable(Level.FINEST)) {
> + WebAppAdapter.debugServletAdapterConfiguration(sa, ctx + ROOT);
> + }
> + }
> +
> + public void service(final GrizzlyRequest request, final GrizzlyResponse response) {
> + ClassLoader prevCL = Thread.currentThread().getContextClassLoader();
> + Thread.currentThread().setContextClassLoader(webAppCL);
> + try {
> + // TODO here we should take care of welcome-file
> + } finally {
> + Thread.currentThread().setContextClassLoader(prevCL);
> + }
> + }
> +
> + /**
> + * @param webApp Contains the info about the web.xml
> + * @param context context of the application
> + * @return a list of ServletAdapter with the UrlPattern for each Servlet.
> + */
> + static Map<ServletAdapter, List<String>> getServletAdaptersToAlises(WebApp webApp, String context) {
> +
> + Map<ServletAdapter, List<String>> servletAdapterMap;
> +
> + if (webApp == null || webApp.getServletMapping() == null || webApp.getServletMapping().isEmpty()) {
> + ServletAdapter sa = new ServletAdapter();
> +
> + sa.setContextPath(context);
> + sa.setServletPath(EMPTY_SERVLET_PATH);
> +
> + servletAdapterMap = new HashMap<ServletAdapter, List<String>>(1);
> + servletAdapterMap.put(sa, Arrays.asList(ROOT));
> + } else {
> + // if we have servletMapping
> +
> + final List<ServletMapping> mappings = webApp.getServletMapping();
> + servletAdapterMap = new HashMap<ServletAdapter, List<String>>(mappings.size());
> + for (ServletMapping servletMapping : mappings) {
> +
> + List<String> urlPatternList = servletMapping.getUrlPattern();
> +
> + //TODO support multiple urlPattern ??? for that the SA need to have multiple servletpath ?
> + // ex : urlPattern = /xxx/1.y
> + // urlPattern = /xxx/yyy/1.z
> + // the servlet path will not be the same.. do we create 2 SA ?
> +
> + // WE WILL GET ONLY THE FIRST urlPattern
> + String urlPattern;
> + //if empty, assume "/" as context
> + if (urlPatternList == null || urlPatternList.isEmpty()) {
> + urlPattern = ROOT;
> + } else {
> + urlPattern = urlPatternList.get(0);
> + }
> +
> + // get the context path. The urlPattern could be "", "/",
> + // "/bla/xyz/..."
> + // just to be sure we don't obtain two slash "//"
> +
> + if (!urlPattern.startsWith(ROOT)) {
> + urlPattern = String.format("%s%s", ROOT, urlPattern);
> + }
> + String servletUrlPattern = urlPattern;
> +
> + if (servletUrlPattern.indexOf("//") > -1) {
> + servletUrlPattern = servletUrlPattern.replaceAll("//", ROOT);
> + }
> +
> + ServletAdapter sa = createServletAdapter(context, servletUrlPattern);
> +
> + // Set the Servlet
> + setServlet(webApp, sa, servletMapping);
> +
> + servletAdapterMap.put(sa, Arrays.asList(urlPattern));
> + }
> + }
> +
> + return servletAdapterMap;
> + }
> +
> + protected static void setServlet(WebApp webApp, ServletAdapter sa, ServletMapping servletMapping) {
> + //we need to get the servlet according to the servletMapping
> + for (com.sun.grizzly.http.webxml.schema.Servlet servletItem : webApp.getServlet()) {
> +
> + if (servletItem.getServletName().equalsIgnoreCase(servletMapping.getServletName())) {
> + sa.setServletInstance((Servlet) ClassLoaderUtil.load(servletItem.getServletClass()));
> +
> + List<InitParam> initParamsList = servletItem.getInitParam();
> +
> + if (initParamsList != null && !initParamsList.isEmpty()) {
> + for (InitParam element : initParamsList) {
> + sa.addInitParameter(element.getParamName(), element.getParamValue());
> + }
> + }
> + break;
> + }
> + }
> + }
> +
> + /**
> + * @param path Path to convert.
> + * @return Converted path.
> + */
> + public static String getServletPath(String path) {
> +
> + String result;
> + if (path == null) {
> + result = ROOT;
> + } else {
> +
> + // need to replace "\" and "\\" by "/"
> + result = path.replaceAll("\\\\", ROOT);
> +
> + // the path need to start by "/"
> + if (!result.startsWith(ROOT)) {
> + result = ROOT + result;
> + }
> +
> + // we could have multiples options
> + // /servlet
> + // /servlet/
> + // /servlet/subpath
> + // /servlet/subpath/
> + // /servlet/* or /servlet/*.x
> + // all theses must return /servlet
> +
> + // remove the trailing "/"
> + if (result.endsWith(ROOT) && result.length() > 1) {
> + result = result.substring(0, result.length() - 1);
> + } else if (!result.endsWith(ROOT)) {
> +
> + // find the last "/"
> + int index = result.lastIndexOf(ROOT);
> +
> + // find if we have a wildcard "*" or a extension "."
> + if (result.lastIndexOf('*') > index || result.lastIndexOf('.') > index) {
> +
> + // do we have something like : /a.cdcdcd or /* or /*.abc
> + if (index == 0) {
> + result = ROOT;
> + } else if (index > 0) {
> + //remove the urlpattern
> + if (index < result.length()) {
> + result = result.substring(0, index);
> + }
> + }
> + }
> + }
> + }
> + return result;
> + }
> +
> + static ServletAdapter createServletAdapter(
> + final String context, final String servletUrlPattern) {
> + ServletAdapter sa = new ServletAdapter();
> + sa.setContextPath(context);
> +
> + // be sure not the get the extension mapping
> + // like /blabla/*.jsp
> + sa.setServletPath(getServletPath(servletUrlPattern));
> + return sa;
> + }
> +
> + protected static void setFilters(WebApp webApp, ServletAdapter sa) {
> +
> + if (webApp == null || sa == null) {
> + return;
> + }
> +
> + // Add the Filters
> + List<com.sun.grizzly.http.webxml.schema.Filter> filterList = webApp.getFilter();
> +
> + List<FilterMapping> filterMappingList = webApp.getFilterMapping();
> +
> + if (filterList != null && !filterList.isEmpty()) {
> + for (com.sun.grizzly.http.webxml.schema.Filter filterItem : filterList) {
> +
> + // we had the filter if the url-pattern is for this context
> + // we need to get the right filter-mapping form the name
> + for (FilterMapping filterMapping : filterMappingList) {
> +
> + //we need to find in the filterMapping is for this filter
> + if (filterItem.getFilterName().equalsIgnoreCase(filterMapping.getFilterName())) {
> + Filter filter = (Filter) ClassLoaderUtil.load(filterItem.getFilterClass());
> +
> + // initParams
> + List<InitParam> initParamList = filterItem.getInitParam();
> +
> + Map<String, String> initParamsMap = new HashMap<String, String>();
> + if (initParamList != null) {
> + for (InitParam param : initParamList) {
> + initParamsMap.put(param.getParamName(), param.getParamValue());
> + }
> + }
> +
> + sa.addFilter(filter, filterItem.getFilterName(), initParamsMap);
> +
> + }
> + }
> +
> + }
> + }
> +
> +
> + }
> +
> + protected static void setListeners(WebApp webApp, ServletAdapter sa) {
> + if (webApp == null || sa == null) {
> + return;
> + }
> +
> + // Add the Listener
> + List<Listener> listeners = webApp.getListener();
> +
> + if (listeners != null) {
> + for (Listener element : listeners) {
> + sa.addServletListener(element.getListenerClass());
> + }
> + }
> + }
> +
> + /**
> + * @param sa ServletAdapter
> + * @param aliases contains the list of UrlPattern for this ServletAdapter
> + * @return the alias list for this ServletAdapter
> + */
> + public static String[] getAlias(ServletAdapter sa, Collection<String> aliases) {
> +
> + List<String> aliasList;
> + if (sa == null || aliases == null) {
> + // Default context
> + aliasList = Arrays.asList(ROOT);
> + } else {
> +
> + aliasList = new ArrayList<String>(aliases.size());
> + for (String urlPattern : aliases) {
> +
> + String mapping = EMPTY_SERVLET_PATH;
> +
> + if (!sa.getServletPath().equals(urlPattern) && urlPattern.indexOf(sa.getServletPath()) > -1) {
> + mapping = urlPattern.substring(urlPattern.indexOf(sa.getServletPath()) + sa.getServletPath().length());
> + }
> +
> + // the alias is the context + servletPath + mapping
> + String aliasTmp = String.format("%s%s%s", sa.getContextPath(), sa.getServletPath(), mapping);
> +
> + if (aliasTmp.indexOf("//") > -1) {
> + aliasTmp = aliasTmp.replaceAll("//", ROOT);
> + }
> + aliasList.add(aliasTmp);
> + }
> + }
> + return aliasList.toArray(new String[aliasList.size()]);
> + }
> +
> + static void logServletAdapterConfigurationWithAliases(
> + final ServletAdapter sa, final String[] aliases) {
> + StringBuilder sb = new StringBuilder(64);
> + sb.append('[');
> + for (String item : aliases) {
> + sb.append(item).append(',');
> + }
> + sb.deleteCharAt(sb.length() - 1);
> + sb.append(']');
> + debugServletAdapterConfiguration(sa, sb.toString());
> + }
> +
> + static void debugServletAdapterConfiguration(
> + final ServletAdapter sa, final String alias) {
> + logger.log(Level.FINEST, "sa context=" + sa.getContextPath());
> + logger.log(Level.FINEST, "sa servletPath=" + sa.getServletPath());
> + logger.log(Level.FINEST, "sa alias=" + alias);
> + logger.log(Level.FINEST, "sa rootFolder=" + sa.getRootFolder());
> + }
> +}
> Index: modules/http-servlet-deployer/src/main/java/com/sun/grizzly/http/webxml/schema/WebApp.java
> ===================================================================
> --- modules/http-servlet-deployer/src/main/java/com/sun/grizzly/http/webxml/schema/WebApp.java (.../trunk/code) (revision 3643)
> +++ modules/http-servlet-deployer/src/main/java/com/sun/grizzly/http/webxml/schema/WebApp.java (.../branches/deployer-refactoring) (revision 3643)
> @@ -36,6 +36,7 @@
> package com.sun.grizzly.http.webxml.schema;
>
> import java.util.List;
> +import java.util.ArrayList;
>
> /**
> * This class represent a web.xml.
> @@ -66,38 +67,38 @@
> */
> public class WebApp {
>
> - public List<Icon> icon;
> - public List<String> displayName;
> - public List<String> description;
> + public List<Icon> icon = new ArrayList<Icon>(0);
> + public List<String> displayName = new ArrayList<String>(0);
> + public List<String> description = new ArrayList<String>(0);
> public boolean distributable;
> - public List<ContextParam> contextParam;
> - public List<Filter> filter;
> - public List<FilterMapping> filterMapping;
> - public List<Listener> listener;
> - public List<Servlet> servlet;
> - public List<ServletMapping> servletMapping;
> - public List<SessionConfig> sessionConfig;
> - public List<MimeMapping> mimeMapping;
> - public List<WelcomeFileList> welcomeFileList;
> - public List<ErrorPage> errorPage;
> - public List<Taglib> taglib;
> - public List<ResourceEnvRef> resourceEnvRef;
> - public List<ResourceRef> resourceRef;
> - public List<SecurityConstraint> securityConstraint;
> - public List<LoginConfig> loginConfig;
> - public List<SecurityRole> securityRole;
> - public List<EnvEntry> envEntry;
> - public List<EjbRef> ejbRef;
> - public List<EjbLocalRef> ejbLocalRef;
> - public List<JspConfig> jspConfig;
> - public List<ServiceRef> serviceRef;
> - public List<MessageDestination> messageDestination;
> - public List<MessageDestinationRef> messageDestinationRef;
> - public List<PersistenceContextRef> persistenceContextRef;
> - public List<PersistenceUnitRef> persistenceUnitRef;
> - public List<LifecycleCallback> postConstruct;
> - public List<LifecycleCallback> preDestroy;
> - public List<LocaleEncodingMappingList> localeEncodingMappingList;
> + public List<ContextParam> contextParam = new ArrayList<ContextParam>(0);
> + public List<Filter> filter = new ArrayList<Filter>(0);
> + public List<FilterMapping> filterMapping = new ArrayList<FilterMapping>(0);
> + public List<Listener> listener = new ArrayList<Listener>(0);
> + public List<Servlet> servlet = new ArrayList<Servlet>(0);
> + public List<ServletMapping> servletMapping = new ArrayList<ServletMapping>(0);
> + public List<SessionConfig> sessionConfig = new ArrayList<SessionConfig>(0);
> + public List<MimeMapping> mimeMapping = new ArrayList<MimeMapping>(0);
> + public List<WelcomeFileList> welcomeFileList = new ArrayList<WelcomeFileList>(0);
> + public List<ErrorPage> errorPage = new ArrayList<ErrorPage>(0);
> + public List<Taglib> taglib = new ArrayList<Taglib>(0);
> + public List<ResourceEnvRef> resourceEnvRef = new ArrayList<ResourceEnvRef>(0);
> + public List<ResourceRef> resourceRef = new ArrayList<ResourceRef>(0);
> + public List<SecurityConstraint> securityConstraint = new ArrayList<SecurityConstraint>(0);
> + public List<LoginConfig> loginConfig = new ArrayList<LoginConfig>(0);
> + public List<SecurityRole> securityRole = new ArrayList<SecurityRole>(0);
> + public List<EnvEntry> envEntry = new ArrayList<EnvEntry>(0);
> + public List<EjbRef> ejbRef = new ArrayList<EjbRef>(0);
> + public List<EjbLocalRef> ejbLocalRef = new ArrayList<EjbLocalRef>(0);
> + public List<JspConfig> jspConfig = new ArrayList<JspConfig>(0);
> + public List<ServiceRef> serviceRef = new ArrayList<ServiceRef>(0);
> + public List<MessageDestination> messageDestination = new ArrayList<MessageDestination>(0);
> + public List<MessageDestinationRef> messageDestinationRef = new ArrayList<MessageDestinationRef>(0);
> + public List<PersistenceContextRef> persistenceContextRef = new ArrayList<PersistenceContextRef>(0);
> + public List<PersistenceUnitRef> persistenceUnitRef = new ArrayList<PersistenceUnitRef>(0);
> + public List<LifecycleCallback> postConstruct = new ArrayList<LifecycleCallback>(0);
> + public List<LifecycleCallback> preDestroy = new ArrayList<LifecycleCallback>(0);
> + public List<LocaleEncodingMappingList> localeEncodingMappingList = new ArrayList<LocaleEncodingMappingList>(0);
>
> /**
> * <icon>
> @@ -110,7 +111,9 @@
> }
>
> public void setIcon(List<Icon> icon) {
> - this.icon = icon;
> + if (icon != null) {
> + this.icon = icon;
> + }
> }
>
> /**
> @@ -121,7 +124,9 @@
> }
>
> public void setDisplayName(List<String> displayName) {
> - this.displayName = displayName;
> + if (displayName != null) {
> + this.displayName = displayName;
> + }
> }
>
> /**
> @@ -132,7 +137,9 @@
> }
>
> public void setDescription(List<String> description) {
> - this.description = description;
> + if (description != null) {
> + this.description = description;
> + }
> }
>
> /**
> @@ -158,7 +165,9 @@
> }
>
> public void setServlet(List<Servlet> servlet) {
> - this.servlet = servlet;
> + if (servlet != null) {
> + this.servlet = servlet;
> + }
> }
>
> /**
> @@ -176,7 +185,9 @@
> }
>
> public void setFilter(List<Filter> filter) {
> - this.filter = filter;
> + if (filter != null) {
> + this.filter = filter;
> + }
> }
>
> /**
> @@ -191,7 +202,9 @@
> }
>
> public void setContextParam(List<ContextParam> contextParam) {
> - this.contextParam = contextParam;
> + if (contextParam != null) {
> + this.contextParam = contextParam;
> + }
> }
>
> /**
> @@ -214,7 +227,9 @@
> }
>
> public void setEjbLocalRef(List<EjbLocalRef> ejbLocalRef) {
> - this.ejbLocalRef = ejbLocalRef;
> + if (ejbLocalRef != null) {
> + this.ejbLocalRef = ejbLocalRef;
> + }
> }
>
> /**
> @@ -237,7 +252,9 @@
> }
>
> public void setEjbRef(List<EjbRef> ejbRef) {
> - this.ejbRef = ejbRef;
> + if (ejbRef != null) {
> + this.ejbRef = ejbRef;
> + }
> }
>
> /**
> @@ -258,7 +275,9 @@
> }
>
> public void setEnvEntry(List<EnvEntry> envEntry) {
> - this.envEntry = envEntry;
> + if (envEntry != null) {
> + this.envEntry = envEntry;
> + }
> }
>
> /**
> @@ -273,7 +292,9 @@
> }
>
> public void setErrorPage(List<ErrorPage> errorPage) {
> - this.errorPage = errorPage;
> + if (errorPage != null) {
> + this.errorPage = errorPage;
> + }
> }
>
> /**
> @@ -293,7 +314,9 @@
> }
>
> public void setFilterMapping(List<FilterMapping> filterMapping) {
> - this.filterMapping = filterMapping;
> + if (filterMapping != null) {
> + this.filterMapping = filterMapping;
> + }
> }
>
> /**
> @@ -312,7 +335,9 @@
> }
>
> public void setListener(List<Listener> listener) {
> - this.listener = listener;
> + if (listener != null) {
> + this.listener = listener;
> + }
> }
>
> /**
> @@ -330,7 +355,9 @@
> }
>
> public void setLoginConfig(List<LoginConfig> loginConfig) {
> - this.loginConfig = loginConfig;
> + if (loginConfig != null) {
> + this.loginConfig = loginConfig;
> + }
> }
>
> /**
> @@ -344,7 +371,9 @@
> }
>
> public void setMimeMapping(List<MimeMapping> mimeMapping) {
> - this.mimeMapping = mimeMapping;
> + if (mimeMapping != null) {
> + this.mimeMapping = mimeMapping;
> + }
> }
>
> /**
> @@ -364,7 +393,9 @@
> }
>
> public void setResourceEnvRef(List<ResourceEnvRef> resourceEnvRef) {
> - this.resourceEnvRef = resourceEnvRef;
> + if (resourceEnvRef != null) {
> + this.resourceEnvRef = resourceEnvRef;
> + }
> }
>
> /**
> @@ -387,7 +418,9 @@
> }
>
> public void setSecurityConstraint(List<SecurityConstraint> securityConstraint) {
> - this.securityConstraint = securityConstraint;
> + if (securityConstraint != null) {
> + this.securityConstraint = securityConstraint;
> + }
> }
>
> /**
> @@ -401,7 +434,9 @@
> }
>
> public void setServletMapping(List<ServletMapping> servletMapping) {
> - this.servletMapping = servletMapping;
> + if (servletMapping != null) {
> + this.servletMapping = servletMapping;
> + }
> }
>
> /**
> @@ -423,7 +458,9 @@
> }
>
> public void setSessionConfig(List<SessionConfig> sessionConfig) {
> - this.sessionConfig = sessionConfig;
> + if (sessionConfig != null) {
> + this.sessionConfig = sessionConfig;
> + }
> }
>
> /**
> @@ -437,7 +474,9 @@
> }
>
> public void setTaglib(List<Taglib> taglib) {
> - this.taglib = taglib;
> + if (taglib != null) {
> + this.taglib = taglib;
> + }
> }
>
> /**
> @@ -451,7 +490,9 @@
> }
>
> public void setSecurityRole(List<SecurityRole> securityRole) {
> - this.securityRole = securityRole;
> + if (securityRole != null) {
> + this.securityRole = securityRole;
> + }
> }
>
> /**
> @@ -473,7 +514,9 @@
> }
>
> public void setResourceRef(List<ResourceRef> resourceRef) {
> - this.resourceRef = resourceRef;
> + if (resourceRef != null) {
> + this.resourceRef = resourceRef;
> + }
> }
>
> /**
> @@ -487,7 +530,9 @@
> }
>
> public void setWelcomeFileList(List<WelcomeFileList> welcomeFileList) {
> - this.welcomeFileList = welcomeFileList;
> + if (welcomeFileList != null) {
> + this.welcomeFileList = welcomeFileList;
> + }
> }
>
> /**
> @@ -523,7 +568,9 @@
> }
>
> public void setJspConfig(List<JspConfig> jspConfig) {
> - this.jspConfig = jspConfig;
> + if (jspConfig != null) {
> + this.jspConfig = jspConfig;
> + }
> }
>
> /**
> @@ -600,7 +647,9 @@
> }
>
> public void setServiceRef(List<ServiceRef> serviceRef) {
> - this.serviceRef = serviceRef;
> + if (serviceRef != null) {
> + this.serviceRef = serviceRef;
> + }
> }
>
> /**
> @@ -620,7 +669,9 @@
> }
>
> public void setMessageDestination(List<MessageDestination> messageDestination) {
> - this.messageDestination = messageDestination;
> + if (messageDestination != null) {
> + this.messageDestination = messageDestination;
> + }
> }
>
> /**
> @@ -642,7 +693,9 @@
> }
>
> public void setMessageDestinationRef(List<MessageDestinationRef> messageDestinationRef) {
> - this.messageDestinationRef = messageDestinationRef;
> + if (messageDestinationRef != null) {
> + this.messageDestinationRef = messageDestinationRef;
> + }
> }
>
> /**
> @@ -667,7 +720,9 @@
> }
>
> public void setPersistenceContextRef(List<PersistenceContextRef> persistenceContextRef) {
> - this.persistenceContextRef = persistenceContextRef;
> + if (persistenceContextRef != null) {
> + this.persistenceContextRef = persistenceContextRef;
> + }
> }
>
> /**
> @@ -687,7 +742,9 @@
> }
>
> public void setPersistenceUnitRef(List<PersistenceUnitRef> persistenceUnitRef) {
> - this.persistenceUnitRef = persistenceUnitRef;
> + if (persistenceUnitRef != null) {
> + this.persistenceUnitRef = persistenceUnitRef;
> + }
> }
>
> /**
> @@ -701,7 +758,9 @@
> }
>
> public void setPostConstruct(List<LifecycleCallback> postConstruct) {
> - this.postConstruct = postConstruct;
> + if (postConstruct != null) {
> + this.postConstruct = postConstruct;
> + }
> }
>
> /**
> @@ -715,7 +774,9 @@
> }
>
> public void setPreDestroy(List<LifecycleCallback> preDestroy) {
> - this.preDestroy = preDestroy;
> + if (preDestroy != null) {
> + this.preDestroy = preDestroy;
> + }
> }
>
> /**
> @@ -731,7 +792,9 @@
> }
>
> public void setLocaleEncodingMappingList(List<LocaleEncodingMappingList> localeEncodingMappingList) {
> - this.localeEncodingMappingList = localeEncodingMappingList;
> + if (localeEncodingMappingList != null) {
> + this.localeEncodingMappingList = localeEncodingMappingList;
> + }
> }
>
> public String toString() {
> @@ -994,4 +1057,38 @@
> return buffer.toString();
> }
>
> + public WebApp mergeWith(WebApp with) {
> + this.contextParam.addAll(with.contextParam);
> + this.description.addAll(with.description);
> + this.displayName.addAll(with.displayName);
> + this.ejbLocalRef.addAll(with.ejbLocalRef);
> + this.ejbRef.addAll(with.ejbRef);
> + this.envEntry.addAll(with.envEntry);
> + this.errorPage.addAll(with.errorPage);
> + this.filter.addAll(with.filter);
> + this.filterMapping.addAll(with.filterMapping);
> + this.icon.addAll(with.icon);
> + this.jspConfig.addAll(with.jspConfig);
> + this.listener.addAll(with.listener);
> + this.localeEncodingMappingList.addAll(with.localeEncodingMappingList);
> + this.loginConfig.addAll(with.loginConfig);
> + this.messageDestination.addAll(with.messageDestination);
> + this.messageDestinationRef.addAll(with.messageDestinationRef);
> + this.mimeMapping.addAll(with.mimeMapping);
> + this.persistenceContextRef.addAll(with.persistenceContextRef);
> + this.persistenceUnitRef.addAll(with.persistenceUnitRef);
> + this.postConstruct.addAll(with.postConstruct);
> + this.preDestroy.addAll(with.preDestroy);
> + this.resourceEnvRef.addAll(with.resourceEnvRef);
> + this.resourceRef.addAll(with.resourceRef);
> + this.securityConstraint.addAll(with.securityConstraint);
> + this.securityRole.addAll(with.securityRole);
> + this.serviceRef.addAll(with.serviceRef);
> + this.servlet.addAll(with.servlet);
> + this.servletMapping.addAll(with.servletMapping);
> + this.sessionConfig.addAll(with.sessionConfig);
> + this.taglib.addAll(with.taglib);
> + this.welcomeFileList.addAll(with.welcomeFileList);
> + return this;
> + }
> }
> Index: modules/http-servlet-deployer/src/main/java/com/sun/grizzly/http/webxml/WebappLoader.java
> ===================================================================
> --- modules/http-servlet-deployer/src/main/java/com/sun/grizzly/http/webxml/WebappLoader.java (.../trunk/code) (revision 3643)
> +++ modules/http-servlet-deployer/src/main/java/com/sun/grizzly/http/webxml/WebappLoader.java (.../branches/deployer-refactoring) (revision 3643)
> @@ -126,7 +126,7 @@
> * @return the WebApp loaded
> * @throws Exception any exceptions will be thrown here if there is a problem parsing the file
> */
> - public WebApp load(String webxml) throws Exception {
> + public static WebApp load(String webxml) throws Exception {
>
> // load the xml file to get it's schema version
> WebXmlHelper helper = new WebXmlHelper();
> @@ -143,10 +143,8 @@
> if(logger.isLoggable(Level.FINEST)){
> logger.log(Level.FINEST, "Version found=" + schemaVersion);
> }
> -
> - WebApp webapp = extractWebXmlInfo(schemaVersion, webxml);
> -
> - return webapp;
> +
> + return extractWebXmlInfo(schemaVersion, webxml);
> }
>
> /**
> @@ -157,14 +155,12 @@
> * @throws Exception
> */
> @SuppressWarnings("unchecked")
> - protected WebApp extractWebXmlInfo(String schemaVersion, String webxml) throws Exception {
> -
> - Class clazz = Class.forName(webAppMap.get(schemaVersion));
> - IJAXBWebXmlParser parser = (IJAXBWebXmlParser)clazz.newInstance();
> -
> - WebApp webapp = parser.parse(webxml);
> -
> - return webapp;
> + protected static WebApp extractWebXmlInfo(String schemaVersion, String webxml) throws Exception {
> +
> + IJAXBWebXmlParser parser = (IJAXBWebXmlParser)
> + ((Class) Class.forName(webAppMap.get(schemaVersion))).newInstance();
> +
> + return parser.parse(webxml);
>
> }
>
> Index: modules/bundles/http-servlet-deployer/src/test/java/com/sun/grizzly/http/servlet/deployer/DeployerTest.java
> ===================================================================
> --- modules/bundles/http-servlet-deployer/src/test/java/com/sun/grizzly/http/servlet/deployer/DeployerTest.java (.../trunk/code) (revision 3643)
> +++ modules/bundles/http-servlet-deployer/src/test/java/com/sun/grizzly/http/servlet/deployer/DeployerTest.java (.../branches/deployer-refactoring) (revision 3643)
> @@ -4,8 +4,8 @@
>
> public class DeployerTest extends TestCase {
>
> - protected GrizzlyWebServerDeployer deployer = null;
> -
> + private GrizzlyWebServerDeployer deployer = null;
> +
> protected void setUp() throws Exception {
> deployer = new GrizzlyWebServerDeployer();
> }
> @@ -13,55 +13,55 @@
> /**
> * Extract the servlet path from a URL
> *
> - * @throws Exception
> + * @throws Exception Duh!
> */
> public void testGetServletPath() throws Exception {
>
> // no context and no servlet
> - assertEquals("/", deployer.getServletPath(""));
> + assertEquals("/", WebAppAdapter.getServletPath(""));
>
> // no context and root servlet
> - assertEquals("/", deployer.getServletPath("/"));
> + assertEquals("/", WebAppAdapter.getServletPath("/"));
>
> // no context and root servlet with wildcard mapping
> - assertEquals("/", deployer.getServletPath("/*"));
> + assertEquals("/", WebAppAdapter.getServletPath("/*"));
>
> // with context
> - assertEquals("/servlet1", deployer.getServletPath("/servlet1/"));
> + assertEquals("/servlet1", WebAppAdapter.getServletPath("/servlet1/"));
>
> // with context and urlPattern
> - assertEquals("/servlet1", deployer.getServletPath("/servlet1/*.jsp"));
> + assertEquals("/servlet1", WebAppAdapter.getServletPath("/servlet1/*.jsp"));
>
> // with context and urlPattern
> - assertEquals("/servlet1", deployer.getServletPath("/servlet1/a.jsp"));
> + assertEquals("/servlet1", WebAppAdapter.getServletPath("/servlet1/a.jsp"));
>
> // with context and urlPattern
> - assertEquals("/servlet1", deployer.getServletPath("/servlet1/.jsp"));
> + assertEquals("/servlet1", WebAppAdapter.getServletPath("/servlet1/.jsp"));
>
> // with context and urlPattern
> - assertEquals("/servlet1", deployer.getServletPath("/servlet1/*"));
> + assertEquals("/servlet1", WebAppAdapter.getServletPath("/servlet1/*"));
>
> //with context and multiple paths
> - assertEquals("/servlet1/subpath", deployer.getServletPath("/servlet1/subpath/"));
> + assertEquals("/servlet1/subpath", WebAppAdapter.getServletPath("/servlet1/subpath/"));
>
> //with context and multiple paths
> - assertEquals("/servlet1/subpath", deployer.getServletPath("/servlet1/subpath"));
> + assertEquals("/servlet1/subpath", WebAppAdapter.getServletPath("/servlet1/subpath"));
>
> //with context and multiple paths and wildcard
> - assertEquals("/servlet1/subpath", deployer.getServletPath("/servlet1/subpath/*"));
> + assertEquals("/servlet1/subpath", WebAppAdapter.getServletPath("/servlet1/subpath/*"));
>
> //with context and multiple paths and wildcard
> - assertEquals("/servlet1/subpath/*/abc", deployer.getServletPath("/servlet1/subpath/*/abc"));
> + assertEquals("/servlet1/subpath/*/abc", WebAppAdapter.getServletPath("/servlet1/subpath/*/abc"));
>
> //with context and multiple paths and wildcard
> - assertEquals("/servlet1/subpath/*/abc", deployer.getServletPath("/servlet1/subpath/*/abc/1.zxy"));
> + assertEquals("/servlet1/subpath/*/abc", WebAppAdapter.getServletPath("/servlet1/subpath/*/abc/1.zxy"));
>
> }
>
> /**
> * Extract the servlet path from a URL
> *
> - * @throws Exception
> + * @throws Exception Duh!
> */
> public void testGetContextPath() throws Exception {
> // no context
> Index: modules/bundles/http-servlet-deployer/src/main/java/com/sun/grizzly/http/servlet/deployer/GrizzlyWebServerDeployer.java
> ===================================================================
> --- modules/bundles/http-servlet-deployer/src/main/java/com/sun/grizzly/http/servlet/deployer/GrizzlyWebServerDeployer.java (.../trunk/code) (revision 3643)
> +++ modules/bundles/http-servlet-deployer/src/main/java/com/sun/grizzly/http/servlet/deployer/GrizzlyWebServerDeployer.java (.../branches/deployer-refactoring) (revision 3643)
> @@ -35,44 +35,28 @@
> */
> package com.sun.grizzly.http.servlet.deployer;
>
> -import java.io.File;
> -import java.io.FilenameFilter;
> -import java.io.IOException;
> -import java.net.MalformedURLException;
> -import java.net.URL;
> -import java.net.URLClassLoader;
> -import java.util.ArrayList;
> -import java.util.Arrays;
> -import java.util.Collection;
> -import java.util.HashMap;
> -import java.util.Iterator;
> -import java.util.List;
> -import java.util.Map;
> -import java.util.concurrent.ConcurrentHashMap;
> -import java.util.concurrent.ConcurrentMap;
> -import java.util.logging.Level;
> -import java.util.logging.Logger;
> -
> -import javax.servlet.Filter;
> -import javax.servlet.Servlet;
> -
> import com.sun.grizzly.arp.AsyncHandler;
> import com.sun.grizzly.arp.DefaultAsyncHandler;
> import com.sun.grizzly.comet.CometAsyncFilter;
> import com.sun.grizzly.http.SelectorThread;
> import com.sun.grizzly.http.embed.GrizzlyWebServer;
> import com.sun.grizzly.http.embed.GrizzlyWebServer.PROTOCOL;
> -import com.sun.grizzly.http.servlet.ServletAdapter;
> import com.sun.grizzly.http.servlet.deployer.comparator.WarFileComparator;
> +import com.sun.grizzly.http.servlet.deployer.conf.ConfigurationParser;
> +import com.sun.grizzly.http.servlet.deployer.conf.DeployerConfiguration;
> import com.sun.grizzly.http.webxml.WebappLoader;
> -import com.sun.grizzly.http.webxml.schema.FilterMapping;
> -import com.sun.grizzly.http.webxml.schema.InitParam;
> -import com.sun.grizzly.http.webxml.schema.Listener;
> -import com.sun.grizzly.http.webxml.schema.ServletMapping;
> -import com.sun.grizzly.http.webxml.schema.WebApp;
> -import com.sun.grizzly.util.ClassLoaderUtil;
> +import com.sun.grizzly.http.webxml.schema.*;
> import com.sun.grizzly.util.ExpandJar;
>
> +import java.io.File;
> +import java.io.FilenameFilter;
> +import java.io.IOException;
> +import java.net.URL;
> +import java.net.URLClassLoader;
> +import java.util.*;
> +import java.util.logging.Level;
> +import java.util.logging.Logger;
> +
> /*
> * We have 4 cases :
> *
> @@ -85,917 +69,346 @@
> */
> public class GrizzlyWebServerDeployer {
>
> - protected static Logger logger = Logger.getLogger("GrizzlyWebServerDeployerLogger");
> - public static final String DEFAULT_CONTEXT = "/";
> - public static final String WEB_XML_PATH = "WEB-INF" + File.separator + "web.xml";
> - private GrizzlyWebServer ws = null;
> - private String autodeployFolder;
> - private String locations;
> - private String webxmlPath;
> - private String libraryPath;
> - private String forcedContext;
> - private boolean waitToStart = false;
> - private boolean cometEnabled = false;
> - private boolean forceWarDeployment = false;
> - private boolean ajpEnabled = false;
> - private List<String> deployedApplicationList = null;
> - private int port = 8080;
> + private static Logger logger = Logger.getLogger("GrizzlyWebServerDeployerLogger");
>
> - public void init(String args[]) throws MalformedURLException, IOException, Exception {
> - if (args.length == 0) {
> - printHelpAndExit();
> - }
> + private static final String ROOT = "/";
>
> - // parse options
> - parseOptions(args);
> + public static final String WEB_XML_PATH = "WEB-INF" + File.separator + "web.xml";
>
> - deployedApplicationList = new ArrayList<String>();
> + private GrizzlyWebServer ws = null;
>
> - }
> + private String webxmlPath;
>
> - private void deployWar(String location, String context) throws Exception {
> - webxmlPath = appendWarContentToClassPath(location);
> -
> - if (context == null) {
> - context = getContext(webxmlPath);
> - }
> -
> - deploy(webxmlPath, context, webxmlPath + WEB_XML_PATH);
> + /**
> + * @param args Command line parameters.
> + */
> + public static void main(String[] args) {
> + new GrizzlyWebServerDeployer().launch(init(args));
> }
>
> - private void deployServlet(String location) throws Exception {
> - deployServlet(location, null);
> - }
> -
> - private void deployServlet(String location, String context) throws Exception {
> - if (context == null) {
> - context = getContext("/");
> + public static DeployerConfiguration init(String args[]) {
> + DeployerConfiguration cfg = ConfigurationParser.parseOptions(args, GrizzlyWebServerDeployer.class.getCanonicalName());
> + if (logger.isLoggable(Level.INFO)) {
> + logger.log(Level.INFO, cfg.toString());
> }
> - webxmlPath = appendWarContentToClassPath(null);
> - deploy(null, context, location);
> + return cfg;
> }
>
> - private void deployExpandedWar(String location) throws Exception {
> - webxmlPath = appendWarContentToClassPath(location);
> - deploy(webxmlPath, getContext(webxmlPath), webxmlPath + WEB_XML_PATH);
> - }
> -
> - private Map<String, File> getFile(String location) {
> - // remove ending slash if any
> - // we need to check if the location is not "/"
> - if (location.endsWith("/") && location.length() > 1) {
> - location = location.substring(0, location.length() - 1);
> - }
> -
> - // we try to look of the file's list
> -
> - File folder = new File(location);
> -
> - if (!folder.exists() || !folder.isDirectory()) {
> - return null;
> - }
> -
> - // we only want folders that contains WEB-INF or war files
> - File files[] = folder.listFiles(new FilenameFilter() {
> -
> - public boolean accept(File dir, String name) {
> -
> - if (name.endsWith(".war")) {
> - return true;
> - } else {
> -
> - // check if it's a expanded folder
> - // and it doesn't need to contains a web.xml
> - // a php application could be deployed
> - File file = new File(dir + File.separator + name);
> -
> - if ((file.exists() && file.isDirectory())) {
> - return true;
> - } else {
> - return false;
> - }
> -
> - }
> -
> + public void launch(DeployerConfiguration conf) {
> + try {
> + ws = new GrizzlyWebServer(conf.port);
> + URLClassLoader serverLibLoader = createServerLibClassLoader(conf.libraryPath);
> + configureApplications(conf, serverLibLoader);
> + configureServer(conf);
> + // don't start the server is true: useful for unittest
> + if (!conf.waitToStart) {
> + ws.start();
> }
> - });
> -
> - // do we have something to deploy
> - if (files == null || files.length == 0) {
> - return null;
> + } catch (Exception e) {
> + logger.log(Level.SEVERE, "Error while launching deployer.", e);
> }
> + }
>
> - // sort list. We want expanded folder first followed by war file.
> - Arrays.sort(files, new WarFileComparator());
> -
> -
> - // filter the list.
> - Map<String, File> fileList = new HashMap<String, File>();
> - for (File file : files) {
> -
> - // add folders
> - if (file.isDirectory()) {
> - fileList.put(file.getName(), file);
> - } else if (file.getName().endsWith(".war") && !forceWarDeployment) {
> - String name = file.getName().substring(0, file.getName().length() - ".war".length());
> - if (fileList.containsKey(name)) {
> - logger.log(Level.INFO, "War file skipped");
> - } else {
> - fileList.put(name, file);
> - }
> -
> - } else if (file.getName().endsWith(".war") && forceWarDeployment) {
> -
> - String name = file.getName().substring(0, file.getName().length() - ".war".length());
> -
> - // we must remove the folder from the list if found
> - if (fileList.containsKey(name)) {
> - fileList.remove(name);
> - }
> - fileList.put(name, file);
> - } else {
> - fileList.put(file.getName(), file);
> + private void configureApplications(DeployerConfiguration conf, URLClassLoader serverLibLoader) throws Exception {
> + String locations = conf.locations;
> + if (locations != null) {
> + if (logger.isLoggable(Level.FINEST)) {
> + logger.log(Level.FINEST, "Application(s) Found = " + locations);
> }
> -
> + deployApplications(conf, serverLibLoader);
> }
> -
> - return fileList;
> }
>
> - public void deployApplications(String locations) throws Exception {
> -
> - if (locations != null && locations.length() > 0) {
> - String[] location = locations.split(File.pathSeparator);
> -
> - for (int i = 0; i < location.length; i++) {
> - deployApplication(location[i]);
> + public void deployApplications(final DeployerConfiguration conf, URLClassLoader serverLibLoader) throws Exception {
> + if (conf.locations != null && conf.locations.length() > 0) {
> + final WebApp webDefault = getDefaultSupportWebApp(conf.webdefault);
> + for (String loc : conf.locations.split(File.pathSeparator)) {
> + deployApplication(conf, loc, serverLibLoader, webDefault);
> }
> }
> -
> }
>
> - private void deployApplication(String location) throws Exception {
> - // #1
> - if (location.endsWith(".war")) {
> - deployWar(location, getForcedContext());
> - return;
> - }
> -
> - // #2
> - if (location.endsWith(".xml")) {
> + private void deployApplication(final DeployerConfiguration conf, String location, URLClassLoader serverLibLoader, WebApp webDefault) throws Exception {
> + if (location.endsWith(".war")) {// #1
> + deployWar(location, conf.forcedContext, serverLibLoader, webDefault);
> + } else if (location.endsWith(".xml")) {// #2
> // use the forcedContext if set
> - deployServlet(location, getForcedContext());
> - return;
> - }
> + deployServlet(location, conf.forcedContext, serverLibLoader, webDefault);
> + } else {
>
> - // #3-#4
> - //obtain the list of potential war to deploy
> - Map<String, File> fileList = getFile(location);
> + // #3-#4
> + //obtain the list of potential war to deploy
> + Collection<File> files = getFiles(location, conf.forceWarDeployment);
>
> - if (fileList != null) {
> - for (File file : fileList.values()) {
> + if (files != null) {
> + for (File file : files) {
>
> - if (file.getName().endsWith(".war")) {
> - deployWar(file.getPath(), null);
> - } else {
> - /*
> - * we could have these cases
> - *
> - * folder contains multiple expanded war or servlet
> - *
> - * classes/
> - * jmaki-comet/
> - * jmaki-comet2.war
> - * web.xml
> - *
> - * In this case, we have 1 web.xml (servlet), 1 expanded war and 1 war file
> - *
> - * The 3 of them will be loaded.
> - */
> -
> - // #4 : this folder in a expanded war
> - File webxmlFile = new File(location + File.separator + WEB_XML_PATH);
> -
> - if (webxmlFile.exists()) {
> - deployExpandedWar(location + File.separator);
> + if (file.getName().endsWith(".war")) {
> + deployWar(file.getPath(), null, serverLibLoader, webDefault);
> } else {
> + /*
> + * we could have these cases
> + *
> + * folder contains multiple expanded war or servlet
> + *
> + * classes/
> + * jmaki-comet/
> + * jmaki-comet2.war
> + * web.xml
> + *
> + * In this case, we have 1 web.xml (servlet), 1 expanded war and 1 war file
> + *
> + * The 3 of them will be loaded.
> + */
>
> - // #2 : this folder contains a servlet
> - File webxmlFile2 = new File(location + File.separator + "web.xml");
> -
> - if (webxmlFile2.exists()) {
> - // this one..see #2
> - deployServlet(webxmlFile2.getPath());
> + // #4 : this folder in a expanded war
> + if (isWebXmlInWebInf(location)) {
> + deployExpandedWar(String.format("%s%s", location, File.separator), serverLibLoader, webDefault);
> } else {
>
> - // this folder contains multiple war or webapps
> - File webapp = new File(file.getPath() + File.separator + WEB_XML_PATH);
> + // #2 : this folder contains a servlet
> + File webxmlFile2 = new File(
> + String.format("%s%sweb.xml", location, File.separator));
>
> - if (webapp.exists()) {
> - deployExpandedWar(file.getPath() + File.separator);
> + if (webxmlFile2.exists()) {
> + // this one..see #2
> + deployServlet(webxmlFile2.getPath(), serverLibLoader, webDefault);
> } else {
> - // not a webapp with web.xml, maybe a php application
> - deployCustom(file.getPath() + File.separator);
> - }
>
> + // this folder contains multiple war or webapps
> + File webapp = new File(
> + String.format(
> + "%s%s%s", file.getPath(), File.separator, WEB_XML_PATH));
> +
> + if (webapp.exists()) {
> + deployExpandedWar(
> + String.format("%s%s", file.getPath(), File.separator), serverLibLoader, webDefault);
> + } else {
> + // not a webapp with web.xml, maybe a php application
> + deployCustom(String.format("%s%s", file.getPath(), File.separator), serverLibLoader, webDefault);
> + }
> + }
> }
> }
> }
> -
> }
> }
> }
>
> - /**
> - * Return the context that will be used to deploy the application
> - * @param path : file path where the application is
> - * @return the context
> - */
> - public String getContext(String path) {
> + private static boolean isWebXmlInWebInf(final String location) {
> + return new File(String.format("%s%s%s", location, File.separator, WEB_XML_PATH)).exists();
> + }
>
> - if (path == null || path.trim().length() == 0) {
> - return DEFAULT_CONTEXT;
> - }
> + private void deployWar(
> + String location, String context, URLClassLoader serverLibLoader, WebApp defaultWebApp) throws Exception {
>
> - // need to replace "/" and "\\" par File.separator
> - // that will fix the case on Windows when user enter c:/... instead of
> - // c:\\
> -
> - path = path.replaceAll("[/\\\\]+", "\\" + "/");
> - path = path.replaceAll("\\\\", "\\" + "/");
> -
> - // remove the trailing File.separator
> - if (path.endsWith("/") && path.length() > 1) {
> - path = path.substring(0, path.length() - 1);
> + final Map.Entry<String, URLClassLoader> loaderEntry =
> + explodeAndCraeteWebAppClassLoader(location, serverLibLoader);
> + webxmlPath = loaderEntry.getKey();
> + String ctx = context;
> + if (ctx == null) {
> + ctx = getContext(webxmlPath);
> }
> -
> - int lastIndex = path.lastIndexOf("/");
> -
> - if (lastIndex > 0) {
> - path = DEFAULT_CONTEXT + path.substring(lastIndex + 1);
> - } else if (lastIndex == -1) {
> - // need to add the default_context
> - path = DEFAULT_CONTEXT + path;
> - }
> -
> - return path;
> + deploy(webxmlPath, ctx, webxmlPath + WEB_XML_PATH, loaderEntry.getValue(), defaultWebApp);
> }
>
> - /**
> - *
> - * @param path
> - * @return
> - */
> - public String getServletPath(String path) {
> + private URLClassLoader createServerLibClassLoader(String libraryPath) throws IOException {
> + // Must be a better way because that sucks!
> + String separator = (System.getProperty("os.name").toLowerCase().startsWith("win") ? ROOT : "//");
>
> - if (path == null) {
> - return DEFAULT_CONTEXT;
> - }
> + List<URL> urls = new ArrayList<URL>();
>
> - // need to replace "\" and "\\" by "/"
> - path = path.replaceAll("\\\\", "/");
> + if (libraryPath != null) {
>
> - // the path need to start by "/"
> - if (!path.startsWith("/")) {
> - path = DEFAULT_CONTEXT + path;
> - }
> + // look if we have multiple folder
> + String[] libPaths = libraryPath.split(File.pathSeparator);
>
> - // we could have multiples options
> - // /servlet
> - // /servlet/
> - // /servlet/subpath
> - // /servlet/subpath/
> - // /servlet/* or /servlet/*.x
> - // all theses must return /servlet
> + if (libPaths != null && libPaths.length > 0) {
>
> - // remove the trailing "/"
> - if (path.endsWith("/") && path.length() > 1) {
> - path = path.substring(0, path.length() - 1);
> - } else if (!path.endsWith("/")) {
> + for (String libPath : libPaths) {
> + File libFolder = new File(libPath);
>
> - // find the last "/"
> - int index = path.lastIndexOf("/");
> -
> - // find if we have a wildcard "*" or a extension "."
> - if (path.lastIndexOf("*") > index || path.lastIndexOf(".") > index) {
> -
> - // do we have something like : /a.cdcdcd or /* or /*.abc
> - if (index == 0) {
> - return "/";
> - } else if (index > 0) {
> - //remove the urlpattern
> - if (index < path.length()) {
> - path = path.substring(0, index);
> + if (libFolder.exists() && libFolder.isDirectory()) {
> + for (File file : libFolder.listFiles(new ExtensionFileNameFilter(Arrays.asList(".jar")))) {
> + urls.add(new URL(
> + String.format(
> + "jar:file:%s%s!/", separator,
> + file.getCanonicalPath().replace('\\', '/'))));
> + }
> }
> }
> }
> + }
>
> + if (logger.isLoggable(Level.FINEST)) {
> + logger.log(Level.FINEST, String.format("Server library path contains=%s", urls));
> }
>
> - return path;
> + return new URLClassLoader(urls.toArray(new URL[urls.size()]));
> }
>
> - /**
> - *
> - * @param webApp Contains the info about the web.xml
> - * @param context context of the application
> - * @return a list of ServletAdapter with the UrlPattern for each Servlet.
> - */
> - private ConcurrentMap<ServletAdapter, List<String>> getServletAdapterList(WebApp webApp, String context) {
> -
> - ConcurrentMap<ServletAdapter, List<String>> servletAdapterMap = new ConcurrentHashMap<ServletAdapter, List<String>>();
> -
> - // validate if we have servletMapping
> - if (webApp == null || webApp.getServletMapping() == null || webApp.getServletMapping().isEmpty()) {
> - ServletAdapter sa = new ServletAdapter();
> -
> - sa.setContextPath(context);
> - sa.setServletPath("");
> -
> - List<String> aliasList = new ArrayList<String>();
> - aliasList.add(DEFAULT_CONTEXT);
> - servletAdapterMap.put(sa, aliasList);
> - } else {
> -
> - for (ServletMapping servletMapping : webApp.getServletMapping()) {
> - ServletAdapter sa = new ServletAdapter();
> -
> - List<String> urlPatternList = servletMapping.getUrlPattern();
> -
> - //TODO support multiple urlPattern ??? for that the SA need to have multiple servletpath ?
> - // ex : urlPattern = /xxx/1.y
> - // urlPattern = /xxx/yyy/1.z
> - // the servlet path will not be the same.. do we create 2 SA ?
> -
> - // WE WILL GET ONLY THE FIRST urlPattern
> - String urlPattern = null;
> - //if empty, assume "/" as context
> - if (urlPatternList == null || urlPatternList.size() == 0) {
> - urlPattern = DEFAULT_CONTEXT;
> - } else {
> - urlPattern = urlPatternList.get(0);
> - }
> -
> - // get the context path. The urlPattern could be "", "/",
> - // "/bla/xyz/..."
> - // just to be sure we don't obtain two slash "//"
> - String servletUrlPattern = null;
> -
> - if (!urlPattern.startsWith("/")) {
> - urlPattern = "/" + urlPattern;
> - }
> -
> - servletUrlPattern = urlPattern;
> -
> - if (servletUrlPattern.indexOf("//") > -1) {
> - servletUrlPattern = servletUrlPattern.replaceAll("//", "/");
> - }
> -
> - sa.setContextPath(context);
> -
> - // be sure not the get the extension mapping
> - // like /blabla/*.jsp
> - sa.setServletPath(getServletPath(servletUrlPattern));
> -
> - // Set the Servlet
> - setServlet(webApp, sa, servletMapping);
> -
> - List<String> aliasList = new ArrayList<String>();
> - aliasList.add(urlPattern);
> - servletAdapterMap.put(sa, aliasList);
> - }
> - }
> -
> - return servletAdapterMap;
> + private void deployServlet(String location, URLClassLoader serverLibLoader, WebApp defaultWebApp) throws Exception {
> + deployServlet(location, null, serverLibLoader, defaultWebApp);
> }
>
> - /**
> - *
> - * @param context
> - * @return the root folder
> - */
> - private String getRootFolder(String location, String context) {
> - if (location == null || context == null) {
> - return location;
> + private void deployServlet(String location, String context, URLClassLoader serverLibLoader, WebApp defaultWebApp)
> + throws Exception {
> + String ctx = context;
> + if (ctx == null) {
> + ctx = getContext(ROOT);
> }
> -
> - location = location.replaceAll("[/\\\\]+", "\\" + "/");
> - location = location.replaceAll("\\\\", "\\" + "/");
> -
> - int index = location.lastIndexOf(context);
> -
> - if (index > -1) {
> - location = location.substring(0, index);
> - }
> -
> - return location;
> + final Map.Entry<String, URLClassLoader> loaderEntry = explodeAndCraeteWebAppClassLoader(null, serverLibLoader);
> + webxmlPath = loaderEntry.getKey();
> + deploy(null, ctx, location, loaderEntry.getValue(), defaultWebApp);
> }
>
> - protected void deployCustom(String location) throws Exception {
> - webxmlPath = appendWarContentToClassPath(location);
> -
> - String context = getContext(webxmlPath);
> - String root = getRootFolder(location, context);
> -
> - deploy(root, context, root + context);
> + private void deployExpandedWar(String location, URLClassLoader serverLibLoader, WebApp defaultWebApp) throws Exception {
> + final Map.Entry<String, URLClassLoader> loaderEntry = explodeAndCraeteWebAppClassLoader(location, serverLibLoader);
> + webxmlPath = loaderEntry.getKey();
> + deploy(webxmlPath, getContext(webxmlPath), webxmlPath + WEB_XML_PATH, loaderEntry.getValue(), defaultWebApp);
> }
>
> - public void deploy(String rootFolder, String context, String path) throws Exception {
> + private static Collection<File> getFiles(String location, boolean forceWarDeployment) {
> + Map<String, File> result = null;
> + File folder = getFileNotTrailingSlash(location);
> + if (folder.exists() && folder.isDirectory()) {
>
> - if (logger.isLoggable(Level.INFO)) {
> - logger.log(Level.INFO, "Will deploy application path=" + path);
> - }
> + // we only want folders that contains WEB-INF or war files
> + File files[] = folder.listFiles(new DeployableFilter());
>
> - // deploy default
> - List<WebApp> webAppList = getDefaultSupportWebApp();
> + // do we have something to deploy
> + if (files != null && files.length != 0) {
>
> - if (webAppList == null) {
> - webAppList = new ArrayList<WebApp>();
> - }
> + // sort list. We want expanded folder first followed by war file.
> + Arrays.sort(files, new WarFileComparator());
>
> - WebApp webApp = null;
>
> - if (path != null && path.toLowerCase().endsWith(".xml")) {
> - try {
> - webApp = extractWebxmlInfo(path);
> - webAppList.add(webApp);
> - } catch (Exception e) {
> - logger.log(Level.INFO, "Not a valid WebApp, will be ignored : path=" + path);
> - }
> - }
> + // filter the list.
> + result = new HashMap<String, File>(files.length);
> + for (File file : files) {
>
> -
> - boolean blankContextServletPathFound = false;
> - boolean defaultContextServletPathFound = false;
> -
> - List<String> aliasesUsed = new ArrayList<String>();
> -
> - for (WebApp webApp2 : webAppList) {
> - // obtain a servletAdapter list
> - ConcurrentMap<ServletAdapter, List<String>> servletAdapterList = getServletAdapterList(webApp2, context);
> -
> -
> - for (ServletAdapter sa : servletAdapterList.keySet()) {
> -
> - // set Filters for this context if there are some
> - setFilters(webApp2, sa);
> -
> - // set Listeners
> - setListeners(webApp2, sa);
> -
> - //set root Folder
> - if (rootFolder != null) {
> - rootFolder = rootFolder.replaceAll("[/\\\\]+", "\\" + "/");
> - rootFolder = rootFolder.replaceAll("\\\\", "\\" + "/");
> - sa.setRootFolder(rootFolder);
> - }
> -
> - // create the alias array from the list of urlPattern
> - String alias[] = getAlias(sa, servletAdapterList.get(sa));
> -
> - if (alias == null) {
> - alias = new String[]{DEFAULT_CONTEXT};
> - }
> -
> - // need to be disabled for JSP
> - sa.setHandleStaticResources(false);
> -
> - // enabled it if not / or /*
> - for (String item : alias) {
> - if(item.endsWith(DEFAULT_CONTEXT) || item.endsWith("/*")){
> - sa.setHandleStaticResources(true);
> + // add folders
> + final String filename = file.getName();
> + if (file.isDirectory()) {
> + result.put(filename, file);
> + } else if (filename.endsWith(".war") && !forceWarDeployment) {
> + String name = filename.substring(0, filename.length() - ".war".length());
> + if (result.containsKey(name)) {
> + logger.log(Level.INFO, "War file skipped");
> + } else {
> + result.put(name, file);
> + }
> + } else if (filename.endsWith(".war") && forceWarDeployment) {
> + String name = filename.substring(0, filename.length() - ".war".length());
> + // we must remove the folder from the list if found
> + if (result.containsKey(name)) {
> + result.remove(name);
> + }
> + result.put(name, file);
> + } else {
> + result.put(filename, file);
> }
> }
> -
> -
> - if (logger.isLoggable(Level.FINEST)) {
> - logger.log(Level.FINEST, "sa context=" + sa.getContextPath());
> - logger.log(Level.FINEST, "sa servletPath=" + sa.getServletPath());
> -
> - StringBuffer sb = new StringBuffer();
> - sb.append("[");
> - for (String item : alias) {
> - sb.append(item).append(",");
> - }
> - sb.deleteCharAt(sb.length() - 1);
> - sb.append("]");
> - logger.log(Level.FINEST, "sa alias=" + sb.toString());
> - logger.log(Level.FINEST, "sa rootFolder=" + sa.getRootFolder());
> - }
> -
> - // keep trace of deployed application
> - deployedApplicationList.add(context);
> -
> - // keep trace of mapping
> - aliasesUsed.addAll(Arrays.asList(alias));
> -
> - ws.addGrizzlyAdapter(sa, alias);
> -
> - if (DEFAULT_CONTEXT.equals(sa.getServletPath())) {
> - defaultContextServletPathFound = true;
> - }
> -
> - if ("".equals(sa.getServletPath())) {
> - blankContextServletPathFound = true;
> - }
> -
> -
> -
> }
> }
> + return result == null ? null : result.values();
> + }
>
> - // we need one servlet that will handle "/"
> - if (!defaultContextServletPathFound) {
> - logger.log(Level.FINEST, "Adding a ServletAdapter to handle / path");
> -
> - ServletAdapter sa2 = new ServletAdapter();
> -
> - sa2.setContextPath(context);
> - sa2.setServletPath("/");
> - sa2.setHandleStaticResources(true);
> - sa2.setRootFolder(rootFolder);
> -
> - if (logger.isLoggable(Level.FINEST)) {
> - logger.log(Level.FINEST, "sa context=" + sa2.getContextPath());
> - logger.log(Level.FINEST, "sa servletPath=" + sa2.getServletPath());
> -
> - logger.log(Level.FINEST, "sa alias=" + context + DEFAULT_CONTEXT);
> - logger.log(Level.FINEST, "sa rootFolder=" + sa2.getRootFolder());
> - }
> -
> - ws.addGrizzlyAdapter(sa2, new String[]{context + DEFAULT_CONTEXT});
> - }
> -
> - // pour les jsp dans le root du context
> - if (!blankContextServletPathFound && !aliasesUsed.contains(context + DEFAULT_CONTEXT)) {
> - logger.log(Level.FINEST, "Adding a ServletAdapter to handle root path");
> -
> - ServletAdapter sa2 = new ServletAdapter();
> -
> - sa2.setContextPath(context);
> - sa2.setServletPath("");
> - sa2.setHandleStaticResources(true);
> - sa2.setRootFolder(rootFolder);
> -
> - if (logger.isLoggable(Level.FINEST)) {
> - logger.log(Level.FINEST, "sa context=" + sa2.getContextPath());
> - logger.log(Level.FINEST, "sa servletPath=" + sa2.getServletPath());
> -
> - logger.log(Level.FINEST, "sa alias=" + context + DEFAULT_CONTEXT);
> - logger.log(Level.FINEST, "sa rootFolder=" + sa2.getRootFolder());
> - }
> -
> - ws.addGrizzlyAdapter(sa2, new String[]{context + DEFAULT_CONTEXT});
> -
> - }
> -
> - if (logger.isLoggable(Level.INFO)) {
> - logger.log(Level.INFO, "deployed application path=" + path);
> - }
> -
> -
> + private static File getFileNotTrailingSlash(String name) {
> + return new File(removeTrailingPathSeparator(name));
> }
>
> /**
> - *
> - * @param sa ServletAdapter
> - * @param aliases contains the list of UrlPattern for this ServletAdapter
> - * @return the alias list for this ServletAdapter
> + * Return the context that will be used to deploy the application
> + *
> + * @param path : file path where the application is
> + * @return the context
> */
> - public String[] getAlias(ServletAdapter sa, Collection<String> aliases) {
> + public static String getContext(String path) {
> + String result;
>
> - if (sa == null || aliases == null) {
> - return null;
> - }
> + if (path == null || path.trim().length() == 0) {
> + result = ROOT;
> + } else {
> + result = removeTrailingPathSeparator(fixPath(path));
> + int lastIndex = result.lastIndexOf(ROOT);
>
> - List<String> aliasList = new ArrayList<String>();
> -
> - for (String urlPattern : aliases) {
> -
> - String mapping = "";
> -
> - if (!sa.getServletPath().equals(urlPattern) && urlPattern.indexOf(sa.getServletPath()) > -1) {
> - mapping = urlPattern.substring(urlPattern.indexOf(sa.getServletPath()) + sa.getServletPath().length());
> + if (lastIndex > 0) {
> + result = ROOT + result.substring(lastIndex + 1);
> + } else if (lastIndex == -1) {
> + // need to add the ROOT
> + result = ROOT + result;
> }
> -
> - // the alias is the context + servletPath + mapping
> - String aliasTmp = sa.getContextPath() + sa.getServletPath() + mapping;
> -
> - if (aliasTmp.indexOf("//") > -1) {
> - aliasTmp = aliasTmp.replaceAll("//", "/");
> - }
> -
> - aliasList.add(aliasTmp);
> -
> }
> -
> - String[] array = new String[aliasList.size()];
> -
> - return aliasList.toArray(array);
> + return result;
> }
>
> - public void setLocations(String filename) {
> - locations = filename;
> + private static String fixPath(String path) {
> + return path
> + .replaceAll("[/\\\\]+", '\\' + ROOT)
> + .replaceAll("\\\\", '\\' + ROOT);
> }
>
> - public String getLocations() {
> - return locations;
> - }
> -
> - public void setPort(int port) {
> - this.port = port;
> - }
> -
> - public int getPort() {
> - return port;
> - }
> -
> - public String getLibraryPath() {
> - return libraryPath;
> - }
> -
> - public void setLibraryPath(String path) {
> - this.libraryPath = path;
> - }
> -
> - public String getAutoDeployFolder() {
> - return autodeployFolder;
> - }
> -
> - public void setAutoDeployFolder(String path) {
> - this.autodeployFolder = path;
> - }
> -
> - public boolean getCometEnabled() {
> - return cometEnabled;
> - }
> -
> - public void setCometEnabled(boolean enabled) {
> - this.cometEnabled = enabled;
> - }
> -
> - public boolean getAjpEnabled() {
> - return ajpEnabled;
> - }
> -
> - public void setAjpEnabled(boolean enabled) {
> - this.ajpEnabled = enabled;
> - }
> -
> - public boolean getForceWarDeployment() {
> - return forceWarDeployment;
> - }
> -
> - public void setForceWarDeployment(boolean forceWarDeployment) {
> - this.forceWarDeployment = forceWarDeployment;
> - }
> -
> - public List<String> getDeployedApplicationList() {
> - return deployedApplicationList;
> - }
> -
> - public void setDeployedApplicationList(List<String> deployedApplicationList) {
> - this.deployedApplicationList = deployedApplicationList;
> - }
> -
> - public void printHelpAndExit() {
> - System.err.println();
> - System.err.println("Usage: " + GrizzlyWebServerDeployer.class.getCanonicalName());
> - System.err.println();
> - System.err.println(" --application=[path]* Application(s) path(s).");
> - System.err.println(" --port=[port] Runs Servlet on the specified port.");
> - System.err.println(" --context=[context] Force the context for a servlet.");
> - System.err.println(" --dontstart=[true/false] Won't start the server.");
> - System.err.println(" --libraryPath=[path] Add a libraries folder to the classpath.");
> - System.err.println(" --autodeploy=[path] AutoDeploy to each applications");
> - System.err.println(" --cometEnabled Starts the AsyncFilter for Comet");
> - System.err.println(" --forceWar Force war's deployment over a expanded folder.");
> - System.err.println(" --ajpEnabled Enable mod_jk.");
> - System.err.println(" --help Show this help message.");
> - System.err.println(" --longhelp Show detailled help message.");
> - System.err.println();
> - System.err.println(" * are mandatory");
> - System.exit(1);
> - }
> -
> - public void printLongHelpAndExit() {
> - System.err.println();
> - System.err.println("Usage: " + GrizzlyWebServerDeployer.class.getCanonicalName());
> - System.err.println();
> - System.err.println(" -a, --application=[path]* Application(s) path(s).");
> - System.err.println();
> - System.err.println(" Application(s) deployed can be :");
> - System.err.println(" Servlet(s), war(s) and expanded war folder(s).");
> - System.err.println(" To deploy multiple applications");
> - System.err.println(" use File.pathSeparator");
> - System.err.println();
> - System.err.println(" Example : -a /app.war:/servlet/web.xml:/warfolder/");
> - System.err.println();
> - System.err.println(" -p, --port=[port] Runs Servlet on the specified port.");
> - System.err.println(" Default: 8080");
> - System.err.println();
> - System.err.println(" -c, --context=[context] Force the context for a servlet.");
> - System.err.println(" Only valid for servlet deployed using");
> - System.err.println(" -a [path]/[filename].xml");
> - System.err.println();
> - System.err.println(" --dontstart=[true/false] Won't start the server.");
> - System.err.println(" You will need to call the start method.");
> - System.err.println(" Useful for Unit testing.");
> - System.err.println(" Default : false");
> - System.err.println();
> - System.err.println(" --libraryPath=[path] Add a libraries folder to the classpath.");
> - System.err.println(" You can append multiple folders using");
> - System.err.println(" File.pathSeparator");
> - System.err.println();
> - System.err.println(" Example : --libraryPath=/libs:/common_libs");
> - System.err.println();
> - System.err.println(" --autodeploy=[path] AutoDeploy to each applications.");
> - System.err.println(" You could add JSP support.");
> - System.err.println(" Just add a web.xml that contains Jasper");
> - System.err.println();
> - System.err.println(" Example : --autodeploy=/autodeploy");
> - System.err.println();
> - System.err.println(" --cometEnabled=[true/false] Starts the AsyncFilter for Comet.");
> - System.err.println(" You need to active this for comet applications.");
> - System.err.println(" Default : false");
> - System.err.println();
> - System.err.println(" --forceWar=[true/false] Force war's deployment over a expanded folder.");
> - System.err.println(" Will deploy the war instead of the folder.");
> - System.err.println(" Default : false");
> - System.err.println();
> - System.err.println(" --ajpEnabled=[true/false] Enable mod_jk.");
> - System.err.println(" Default : false");
> - System.err.println();
> - System.err.println(" Default values will be applied if invalid values are passed.");
> - System.err.println();
> - System.err.println(" * are mandatory");
> - System.exit(1);
> - }
> -
> - public boolean parseOptions(String[] args) {
> - // parse options
> - for (int i = 0; i < args.length; i++) {
> - String arg = args[i];
> -
> - if ("-h".equals(arg) || "--help".equals(arg)) {
> - printHelpAndExit();
> - } else if ("--longhelp".equals(arg)) {
> - printLongHelpAndExit();
> - } else if ("-a".equals(arg)) {
> - i++;
> - if (i < args.length) {
> - setLocations(args[i]);
> - }
> - } else if (arg.startsWith("--application=")) {
> - setLocations(arg.substring("--application=".length(), arg.length()));
> - } else if ("-p".equals(arg)) {
> - i++;
> - if (i < args.length) {
> - setPort(Integer.parseInt(args[i]));
> - }
> - } else if (arg.startsWith("--port=")) {
> - String num = arg.substring("--port=".length(), arg.length());
> - setPort(Integer.parseInt(num));
> - } else if ("-c".equals(arg)) {
> - i++;
> - if (i < args.length) {
> - setForcedContext(args[i]);
> - }
> - } else if (arg.startsWith("--context=")) {
> - setForcedContext(arg.substring("--context=".length(), arg.length()));
> - } else if (arg.startsWith("--dontstart=")) {
> - setWaitToStart(Boolean.parseBoolean(arg.substring("--dontstart=".length(), arg.length())));
> - } else if (arg.startsWith("--libraryPath=")) {
> - String value = arg.substring("--libraryPath=".length(), arg.length());
> - setLibraryPath(value);
> - } else if (arg.startsWith("--autodeploy=")) {
> - String value = arg.substring("--autodeploy=".length(), arg.length());
> - setAutoDeployFolder(value);
> - } else if (arg.startsWith("--cometEnabled=")) {
> - setCometEnabled(Boolean.parseBoolean(arg.substring("--cometEnabled=".length(), arg.length())));
> - } else if (arg.startsWith("--forceWar")) {
> - setForceWarDeployment(Boolean.parseBoolean(arg.substring("--forceWar=".length(), arg.length())));
> - } else if (arg.startsWith("--ajpEnabled")) {
> - setAjpEnabled(Boolean.parseBoolean(arg.substring("--ajpEnabled=".length(), arg.length())));
> - }
> -
> -
> + private static String removeTrailingPathSeparator(String path) {
> + String result = path;
> + if (result.endsWith(ROOT) && result.length() > 1) {
> + result = result.substring(0, result.length() - 1);
> }
> -
> - if (getLocations() == null) {
> - System.err.println("Illegal War|Jar file or folder location.");
> - printHelpAndExit();
> - }
> - return true;
> + return result;
> }
>
> - protected void setServlet(WebApp webApp, ServletAdapter sa, ServletMapping servletMapping) {
> - // Set the Servlet
> - List<com.sun.grizzly.http.webxml.schema.Servlet> servletList = webApp.getServlet();
> -
> - //we need to get the servlet according to the servletMapping
> - for (com.sun.grizzly.http.webxml.schema.Servlet servletItem : servletList) {
> -
> - if (servletItem.getServletName().equalsIgnoreCase(servletMapping.getServletName())) {
> - Servlet servlet = (Servlet) ClassLoaderUtil.load(servletItem.getServletClass());
> - sa.setServletInstance(servlet);
> -
> - List<InitParam> initParamsList = servletItem.getInitParam();
> -
> - if (initParamsList != null && initParamsList.size() > 0) {
> - for (InitParam element : initParamsList) {
> - sa.addInitParameter(element.getParamName(), element.getParamValue());
> - }
> - }
> - break;
> + private static String getRootFolder(String location, String context) {
> + String result;
> + if (location == null || context == null) {
> + result = location;
> + } else {
> + result = fixPath(location);
> + int index = result.lastIndexOf(context);
> + if (index > -1) {
> + result = result.substring(0, index);
> }
> -
> }
> -
> + return result;
> }
>
> - protected void setListeners(WebApp webApp, ServletAdapter sa) {
> - if (webApp == null || sa == null) {
> - return;
> - }
> + protected void deployCustom(String location, URLClassLoader serverLibLoader, WebApp defaultSupportWebApp) throws Exception {
> + final Map.Entry<String, URLClassLoader> loaderEntry = explodeAndCraeteWebAppClassLoader(location, serverLibLoader);
> + webxmlPath = loaderEntry.getKey();
>
> - // Add the Listener
> - List<Listener> listeners = webApp.getListener();
> + String context = getContext(webxmlPath);
> + String root = getRootFolder(location, context);
>
> - if (listeners != null) {
> - for (Listener element : listeners) {
> - sa.addServletListener(element.getListenerClass());
> - }
> - }
> + deploy(root, context, root + context, loaderEntry.getValue(), defaultSupportWebApp);
> }
>
> - protected void setFilters(WebApp webApp, ServletAdapter sa) {
> + public void deploy(
> + String rootFolder, String context, String path, URLClassLoader webAppCL, WebApp superApp) throws Exception {
>
> - if (webApp == null || sa == null) {
> - return;
> + String root = rootFolder;
> + if (rootFolder != null) {
> + root = fixPath(rootFolder);
> }
>
> - // Add the Filters
> - List<com.sun.grizzly.http.webxml.schema.Filter> filterList = webApp.getFilter();
> -
> - List<FilterMapping> filterMappingList = webApp.getFilterMapping();
> -
> - if (filterList != null && filterList.size() > 0) {
> - for (com.sun.grizzly.http.webxml.schema.Filter filterItem : filterList) {
> -
> - // we had the filter if the url-pattern is for this context
> - // we need to get the right filter-mapping form the name
> - for (FilterMapping filterMapping : filterMappingList) {
> -
> - //we need to find in the filterMapping is for this filter
> - if (filterItem.getFilterName().equalsIgnoreCase(filterMapping.getFilterName())) {
> - Filter filter = (Filter) ClassLoaderUtil.load(filterItem.getFilterClass());
> -
> - // initParams
> - List<InitParam> initParamList = filterItem.getInitParam();
> -
> - Map<String, String> initParamsMap = new HashMap<String, String>();
> - if (initParamList != null) {
> - for (InitParam param : initParamList) {
> - initParamsMap.put(param.getParamName(), param.getParamValue());
> - }
> - }
> -
> - sa.addFilter(filter, filterItem.getFilterName(), initParamsMap);
> -
> - }
> - }
> -
> - }
> + if (logger.isLoggable(Level.INFO)) {
> + logger.log(Level.INFO, "Will deploy application path=" + path);
> }
>
> -
> - }
> -
> - protected Map<String, List<Object>> getItemMap(List<Object> itemList) throws Exception {
> - // need to find something nicer
> - Map<String, List<Object>> itemMap = null;
> -
> - if (itemList != null) {
> - itemMap = new HashMap<String, List<Object>>();
> - // convert it to a Map, will be easier to retrieve values
> - for (Object object : itemList) {
> - List<Object> list = null;
> - String key = object.getClass().getSimpleName();
> - if (itemMap.containsKey(key)) {
> - list = itemMap.get(key);
> - } else {
> - list = new ArrayList<Object>();
> - itemMap.put(key, list);
> - }
> - list.add(object);
> + if (path != null) {
> + WebApp webApp;
> + if (path.toLowerCase().endsWith(".xml")) {
> + webApp = extractWebXmlInfo(path);
> + } else {
> + webApp = new WebApp(); // empty web app - we might be dealing here with PHP
> }
> - } else {
> - // error handling when list is null ...
> - throw new Exception("invalid");
> + try {
> + final WebAppAdapter webAppAdapter =
> + new WebAppAdapter(ws, root, context, webApp, webAppCL, superApp);
> + ws.addGrizzlyAdapter(webAppAdapter, new String[]{context});
> + } catch (Exception e) {
> + logger.log(Level.INFO, "Not a valid WebApp, will be ignored : path=" + path);
> + logger.log(Level.INFO, "Error follows.", e);
> + }
> }
> -
> - return itemMap;
> }
>
> /**
> @@ -1003,29 +416,29 @@
> * ClassLoader. This function as to be executed before the start() because
> * the new classpath won't take effect.
> *
> - * @return the exploded war file location.
> - *
> + * TODO This potentially can be replaced by {_at_link com.sun.grizzly.util.ClassLoaderUtil#createClassloader(java.io.File, ClassLoader)}
> + * @param appliPath
> + * @param serverLibLoader
> + * @return the exploded war file location and web app CL.
> + * @throws java.io.IOException
> */
> - public String appendWarContentToClassPath(String appliPath) throws MalformedURLException, IOException {
> + public static Map.Entry<String, URLClassLoader> explodeAndCraeteWebAppClassLoader(
> + String appliPath, URLClassLoader serverLibLoader) throws IOException {
>
> - String path = null;
> - File file = null;
> - URL appRoot = null;
> - URL classesURL = null;
> -
> -
> if (appliPath != null && appliPath.endsWith(File.pathSeparator)) {
> - appliPath = appliPath + File.pathSeparator;
> + appliPath += File.pathSeparator;
> }
>
> -
> // Must be a better way because that sucks!
> - String separator = (System.getProperty("os.name").toLowerCase().startsWith("win") ? "/" : "//");
> + String separator = (System.getProperty("os.name").toLowerCase().startsWith("win") ? ROOT : "//");
>
> List<URL> classpathList = new ArrayList<URL>();
>
> + String path = null;
> + URL appRoot = null;
> + URL classesURL = null;
> if (appliPath != null && (appliPath.endsWith(".war") || appliPath.endsWith(".jar"))) {
> - file = new File(appliPath);
> + File file = new File(appliPath);
> appRoot = new URL("jar:file:" + file.getCanonicalPath() + "!/");
> classesURL = new URL("jar:file:" + file.getCanonicalPath() + "!/WEB-INF/classes/");
> path = ExpandJar.expand(appRoot);
> @@ -1036,123 +449,55 @@
> }
>
> if (appliPath != null) {
> - String absolutePath = new File(path).getAbsolutePath();
> - File libFiles = new File(absolutePath + File.separator + "WEB-INF" + File.separator + "lib");
> + File libFiles = new File(new File(path).getAbsolutePath() + File.separator + "WEB-INF" + File.separator + "lib");
>
> if (libFiles.exists() && libFiles.isDirectory()) {
> - for (int i = 0; i < libFiles.listFiles().length; i++) {
> - classpathList.add(new URL("jar:file:" + separator + libFiles.listFiles()[i].toString().replace('\\', '/') + "!/"));
> + for (File file : libFiles.listFiles()) {
> + classpathList.add(
> + new URL(String.format(
> + "jar:file:%s%s!/", separator,
> + file.toString().replace('\\', '/'))));
> }
> }
> }
>
> - if (libraryPath != null) {
> -
> - // look if we have multiple folder
> - String[] array = libraryPath.split(File.pathSeparator);
> -
> - if (array != null && array.length > 0) {
> -
> - for (int i = 0; i < array.length; i++) {
> - File libFolder = new File(array[i]);
> -
> - if (libFolder.exists() && libFolder.isDirectory()) {
> - for (int k = 0; k < libFolder.listFiles().length; k++) {
> - classpathList.add(new URL("jar:file:" + separator + libFolder.listFiles()[k].getCanonicalPath().toString().replace('\\', '/') + "!/"));
> - }
> - }
> - }
> -
> - }
> -
> - }
> -
> if (appliPath != null) {
> classpathList.add(appRoot);
> classpathList.add(classesURL);
> }
>
> if (logger.isLoggable(Level.FINEST)) {
> - for (Iterator<URL> iterator = classpathList.iterator(); iterator.hasNext();) {
> - URL url = iterator.next();
> - logger.log(Level.FINEST, "Classpath contains=" + url);
> - }
> + logger.log(Level.FINEST, String.format("Classpath contains=%s", classpathList));
> }
>
> - URL urls[] = new URL[classpathList.size()];
> -
> - ClassLoader urlClassloader = new URLClassLoader(classpathList.toArray(urls), Thread.currentThread().getContextClassLoader());
> - Thread.currentThread().setContextClassLoader(urlClassloader);
> -
> //be sure to that the path ends by File.separator
> if (path != null && !path.endsWith(File.separator)) {
> - path = path + File.separator;
> + path += File.separator;
> }
>
> - return path;
> + // Linking with serverLibCL
> + return new AbstractMap.SimpleImmutableEntry<String, URLClassLoader>(
> + path, new URLClassLoader(classpathList.toArray(new URL[classpathList.size()]), serverLibLoader));
> }
>
> - public WebApp extractWebxmlInfo(String webxml) throws Exception {
> -
> - if (webxml == null) {
> - return null;
> - }
> -
> - WebappLoader webappLoader = new WebappLoader();
> - WebApp webApp = webappLoader.load(webxml);
> -
> - return webApp;
> + private static WebApp extractWebXmlInfo(String webxml) throws Exception {
> + return webxml == null ? null : WebappLoader.load(webxml);
> }
>
> - public void launch() {
> + private void configureServer(DeployerConfiguration conf) {
> + // comet
> + if (conf.cometEnabled) {
> + SelectorThread st = ws.getSelectorThread();
>
> - try {
> + AsyncHandler asyncHandler = new DefaultAsyncHandler();
> + asyncHandler.addAsyncFilter(new CometAsyncFilter());
> + st.setAsyncHandler(asyncHandler);
>
> - ws = new GrizzlyWebServer(port);
> + st.setEnableAsyncExecution(true);
> + }
>
> - // need to find which case is it : 1-4.
> -
> - /*
> - * #1 - /temp/hudson.war #2 - /temp/web.xml or any .xml
> - * web-sample.xml #3 - /temp or /temp/ #4 - /temp/hudson or
> - * /temp/hudson/
> - *
> - * if #3 find war, it will deployed it, if not, will try #4 if it
> - * found nothing, try web.xml
> - */
> -
> - if (locations != null) {
> -
> - if (logger.isLoggable(Level.FINEST)) {
> - logger.log(Level.FINEST, "Application(s) Found = " + locations);
> - }
> -
> - deployApplications(locations);
> -
> - }
> -
> - // comet
> - if (cometEnabled) {
> - SelectorThread st = ws.getSelectorThread();
> -
> - AsyncHandler asyncHandler = new DefaultAsyncHandler();
> - asyncHandler.addAsyncFilter(new CometAsyncFilter());
> - st.setAsyncHandler(asyncHandler);
> -
> - st.setEnableAsyncExecution(true);
> - }
> -
> - if (ajpEnabled) {
> - ws.enableProtocol(PROTOCOL.AJP);
> - }
> -
> - // don't start the server is true: useful for unittest
> - if (!waitToStart) {
> - ws.start();
> - }
> -
> - } catch (Exception e) {
> - e.printStackTrace();
> + if (conf.ajpEnabled) {
> + ws.enableProtocol(PROTOCOL.AJP);
> }
> }
>
> @@ -1172,96 +517,89 @@
>
> }
>
> - public void setWaitToStart(boolean dontStart) {
> - waitToStart = dontStart;
> - }
> + /**
> + * @param webdefault location of webdefault (directory or file).
> + * @return {_at_link WebApp} with merged webdefaults if many.
> + * @throws IllegalArgumentException If provided webdefault doesn't exist or is empty directory.
> + * @throws Exception If failed to parse web.xml.
> + */
> + private static WebApp getDefaultSupportWebApp(String webdefault) throws Exception {
> + WebApp result = new WebApp();
> + // TODO fields of WebApp are not getting initialized when constructed
>
> - public String getForcedContext() {
> - return forcedContext;
> - }
> + if (webdefault != null) {
>
> - public void setForcedContext(String forcedContext) {
> - this.forcedContext = forcedContext;
> - }
> + File webdefaultFile = getFileNotTrailingSlash(webdefault);
>
> - public List<WebApp> getDefaultSupportWebApp() throws Exception {
> + if (webdefaultFile.exists()) {
> + if (webdefaultFile.isDirectory()) {
> + File xmlFiles[] = webdefaultFile.listFiles(new ExtensionFileNameFilter(Arrays.asList(".xml")));
> + if (xmlFiles != null && xmlFiles.length != 0) {
> + for (File xmlFile : xmlFiles) {
> + result = extractWebAppAndMerge(result, xmlFile.getPath());
> + }
>
> - if (autodeployFolder == null) {
> - return null;
> - }
> + } else {
> + // no .xml files in webdefault directory.
> + throw new IllegalArgumentException("Webdefault is empty directory.");
>
> - // remove ending slash if any
> - // we need to check if the location is not "/"
> - if (autodeployFolder.endsWith("/") && autodeployFolder.length() > 1) {
> - autodeployFolder = autodeployFolder.substring(0, autodeployFolder.length() - 1);
> - }
> -
> - // we try to look of the file's list
> -
> - File folder = new File(autodeployFolder);
> -
> - if (!folder.exists() || !folder.isDirectory()) {
> - return null;
> - }
> -
> - // we only want folders or war files
> - File files[] = folder.listFiles(new FilenameFilter() {
> -
> - public boolean accept(File dir, String name) {
> -
> - if (name.endsWith(".xml")) {
> - return true;
> + }
> } else {
> - return false;
> + // exists && is file
> + result = extractWebAppAndMerge(result, webdefaultFile.getPath());
> +
> }
> + } else {
> + // provided parameter but location is not existent
> + throw new IllegalArgumentException("Webdefault location is not existent.");
>
> }
> - });
> + }
> + return result;
> + }
>
> - // do we have something to deploy
> - if (files == null || files.length == 0) {
> - return null;
> + private static WebApp extractWebAppAndMerge(WebApp mergeTo, String webxmlLocation) throws Exception {
> + WebApp webApp = extractWebXmlInfo(webxmlLocation);
> + if (webApp == null) {
> + throw new Exception("Invalid webdefault: " + webxmlLocation);
> }
> + return mergeTo.mergeWith(webApp);
> + }
>
> - List<WebApp> webappList = new ArrayList<WebApp>(files.length);
> + private static class DeployableFilter implements FilenameFilter {
> + public boolean accept(File dir, String name) {
> + boolean result;
> + if (name.endsWith(".war")) {
> + result = true;
> + } else {
>
> - for (File file : files) {
> - // extract the items from the web.xml
> - WebApp webApp = extractWebxmlInfo(file.getPath());
> + // check if it's a expanded folder
> + // and it doesn't need to contains a web.xml
> + // a php application could be deployed
> + File file = new File(dir + File.separator + name);
>
> - if (webApp == null) {
> - throw new Exception("invalid");
> + result = (file.exists() && file.isDirectory());
> }
> -
> - webappList.add(webApp);
> + return result;
> }
> -
> - return webappList;
> -
> }
>
> - /**
> - * @param args
> - */
> - public static void main(String[] args) {
> + private static class ExtensionFileNameFilter implements FilenameFilter {
> + private List<String> extensions;
>
> - GrizzlyWebServerDeployer ws = new GrizzlyWebServerDeployer();
> + public ExtensionFileNameFilter(List<String> extensions) {
> + this.extensions = Collections.unmodifiableList(extensions);
> + }
>
> - try {
> -
> - /*
> - * We have 4 cases :
> - *
> - * #1 - war #2 - web.xml #3 - folder that contains at least one war
> - * #4 - folder of a deployed war (will use the /WEB-INF/web.xml)
> - */
> -
> - // ready to launch
> - ws.init(args);
> - ws.launch();
> -
> - } catch (Exception e) {
> - e.printStackTrace();
> + public boolean accept(File dir, String name) {
> + boolean result = false;
> + for (String extension : extensions) {
> + if (name.endsWith(extension)) {
> + result = true;
> + break;
> + }
> + }
> + return result;
> }
> }
> }
> Index: modules/bundles/http-servlet-deployer/src/main/java/com/sun/grizzly/http/servlet/deployer/conf/ConfigurationParser.java
> ===================================================================
> --- modules/bundles/http-servlet-deployer/src/main/java/com/sun/grizzly/http/servlet/deployer/conf/ConfigurationParser.java (.../trunk/code) (revision 0)
> +++ modules/bundles/http-servlet-deployer/src/main/java/com/sun/grizzly/http/servlet/deployer/conf/ConfigurationParser.java (.../branches/deployer-refactoring) (revision 3643)
> @@ -0,0 +1,208 @@
> +/**
> + *
> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. *
> + * Copyright 2007-2008 Sun Microsystems, Inc. All rights reserved. *
> + * The contents of this file are subject to the terms of either the GNU
> + * General Public License Version 2 only ("GPL") or the Common Development
> + * and Distribution License("CDDL") (collectively, the "License"). You
> + * may not use this file except in compliance with the License. You can obtain
> + * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
> + * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
> + * language governing permissions and limitations under the License.
> + *
> + * When distributing the software, include this License Header Notice in each
> + * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
> + * Sun designates this particular file as subject to the "Classpath" exception
> + * as provided by Sun in the GPL Version 2 section of the License file that
> + * accompanied this code. If applicable, add the following below the License
> + * Header, with the fields enclosed by brackets [] replaced by your own
> + * identifying information: "Portions Copyrighted [year]
> + * [name of copyright owner]"
> + *
> + * Contributor(s):
> + *
> + * If you wish your version of this file to be governed by only the CDDL or
> + * only the GPL Version 2, indicate your decision by adding "[Contributor]
> + * elects to include this software in this distribution under the [CDDL or GPL
> + * Version 2] license." If you don't indicate a single choice of license, a
> + * recipient has the option to distribute your version of this file under
> + * either the CDDL, the GPL Version 2 or to extend the choice of license to
> + * its licensees as provided above. However, if you add GPL Version 2 code
> + * and therefore, elected the GPL Version 2 license, then the option applies
> + * only if the new code is made subject to such option by the copyright
> + * holder.
> + *
> + */
> +package com.sun.grizzly.http.servlet.deployer.conf;
> +
> +import java.util.logging.Logger;
> +import java.util.logging.Level;
> +
> +/**
> + * {_at_link com.sun.grizzly.http.servlet.deployer.GrizzlyWebServerDeployer} configuration parser.
> + *
> + * @author Hubert Iwaniuk
> + */
> +public class ConfigurationParser {
> +
> + private static Logger logger = Logger.getLogger(ConfigurationParser.class.getName());
> +
> + /**
> + * Parse command line parameters.
> + *
> + * @param args Command line parameters to parse.
> + * @param canonicalName Class canonical name.
> + *
> + * @return Parsed configuration.
> + */
> + public static DeployerConfiguration parseOptions(String[] args, final String canonicalName) {
> + DeployerConfiguration conf = new DeployerConfiguration();
> + if (args.length == 0) {
> + printHelpAndExit(canonicalName);
> + }
> +
> + for (int i = 0; i < args.length; i++) {
> + String arg = args[i];
> +
> + if ("-h".equals(arg) || "--help".equals(arg)) {
> + printHelpAndExit(canonicalName);
> + } else if ("--longhelp".equals(arg)) {
> + printLongHelpAndExit(canonicalName);
> + } else if ("-a".equals(arg)) {
> + i++;
> + if (i < args.length) {
> + conf.locations = args[i];
> + }
> + } else if (arg.startsWith("--application=")) {
> + conf.locations = arg.substring("--application=".length(), arg.length());
> + } else if ("-p".equals(arg)) {
> + i++;
> + if (i < args.length) {
> + conf.port = Integer.parseInt(args[i]);
> + }
> + } else if (arg.startsWith("--port=")) {
> + String num = arg.substring("--port=".length(), arg.length());
> + conf.port = Integer.parseInt(num);
> + } else if ("-c".equals(arg)) {
> + i++;
> + if (i < args.length) {
> + conf.forcedContext = args[i];
> + }
> + } else if (arg.startsWith("--context=")) {
> + conf.forcedContext = arg.substring("--context=".length(), arg.length());
> + } else if (arg.startsWith("--dontstart=")) {
> + conf.waitToStart = Boolean
> + .parseBoolean(arg.substring("--dontstart=".length(), arg.length()));
> + } else if (arg.startsWith("--libraryPath=")) {
> + conf.libraryPath = arg.substring("--libraryPath=".length(), arg.length());
> + } else if (arg.startsWith("--webdefault=")) {
> + conf.webdefault = arg.substring("--webdefault=".length(), arg.length());
> + } else if (arg.startsWith("--autodeploy=")) {
> + conf.webdefault = arg.substring("--autodeploy=".length(), arg.length());
> + } else if (arg.startsWith("--cometEnabled=")) {
> + conf.cometEnabled = Boolean
> + .parseBoolean(arg.substring("--cometEnabled=".length(), arg.length()));
> + } else if (arg.startsWith("--forceWar")) {
> + conf.forceWarDeployment = Boolean
> + .parseBoolean(arg.substring("--forceWar=".length(), arg.length()));
> + } else if (arg.startsWith("--ajpEnabled")) {
> + conf.ajpEnabled = Boolean
> + .parseBoolean(arg.substring("--ajpEnabled=".length(), arg.length()));
> + }
> + }
> +
> + if (conf.locations == null) {
> + logger.log(Level.SEVERE, "Illegal War|Jar file or folder location.");
> + printHelpAndExit(canonicalName);
> + }
> +
> + return conf;
> + }
> +
> + private static void printHelpAndExit(final String canonicalName) {
> + StringBuilder sb = new StringBuilder(1024);
> + sb.append("\nUsage: ").append(canonicalName)
> + .append("\n --application=[path]* Application(s) path(s).\n")
> + .append(" --port=[port] Runs Servlet on the specified port.\n")
> + .append(" --context=[context] Force the context for a servlet.\n")
> + .append(" --dontstart=[true/false] Won't start the server.\n")
> + .append(" --libraryPath=[path] Add a libraries folder to the classpath.\n")
> + .append(" --autodeploy=[path] AutoDeploy to each applications\n")
> + .append(" --webdefault=[path] webdefault to be used by all applications, can be file or dir with multipe web.xmls\n")
> + .append(" --cometEnabled Starts the AsyncFilter for Comet\n")
> + .append(" --forceWar Force war's deployment over a expanded folder.\n")
> + .append(" --ajpEnabled Enable mod_jk.\n")
> + .append(" --help Show this help message.\n")
> + .append(" --longhelp Show detailled help message.\n\n")
> + .append(" * are mandatory");
> + logger.log(Level.SEVERE, sb.toString());
> + System.exit(1);
> + }
> +
> + private static void printLongHelpAndExit(final String canonicalName) {
> + System.err.println();
> + System.err.println("Usage: " + canonicalName);
> + System.err.println();
> + System.err.println(" -a, --application=[path]* Application(s) path(s).");
> + System.err.println();
> + System.err.println(" Application(s) deployed can be :");
> + System.err.println(
> + " Servlet(s), war(s) and expanded war folder(s).");
> + System.err.println(" To deploy multiple applications");
> + System.err.println(" use File.pathSeparator");
> + System.err.println();
> + System.err.println(
> + " Example : -a /app.war:/servlet/web.xml:/warfolder/");
> + System.err.println();
> + System.err.println(" -p, --port=[port] Runs Servlet on the specified port.");
> + System.err.println(" Default: 8080");
> + System.err.println();
> + System.err.println(" -c, --context=[context] Force the context for a servlet.");
> + System.err.println(" Only valid for servlet deployed using");
> + System.err.println(" -a [path]/[filename].xml");
> + System.err.println();
> + System.err.println(" --dontstart=[true/false] Won't start the server.");
> + System.err.println(" You will need to call the start method.");
> + System.err.println(" Useful for Unit testing.");
> + System.err.println(" Default : false");
> + System.err.println();
> + System.err
> + .println(" --libraryPath=[path] Add a libraries folder to the classpath.");
> + System.err.println(" You can append multiple folders using");
> + System.err.println(" File.pathSeparator");
> + System.err.println();
> + System.err
> + .println(" Example : --libraryPath=/libs:/common_libs");
> + System.err.println();
> + System.err.println(" --autodeploy=[path] AutoDeploy to each applications.");
> + System.err.println(" You could add JSP support.");
> + System.err.println(" Just add a web.xml that contains Jasper");
> + System.err.println();
> + System.err.println(" Example : --autodeploy=/autodeploy");
> + System.err.println();
> + System.err.println(" --webdefault=[path] webdefault to be used by all applications, can be file or dir with multipe web.xmls.");
> + System.err.println(" If you want to add only one webdefault point it to web.xml file,");
> + System.err.println(" If you want multiple files to be included put them in one dir and provide this location here.");
> + System.err.println();
> + System.err.println(" Example : --webdefault=webdefault.xml");
> + System.err.println();
> + System.err.println(" --cometEnabled=[true/false] Starts the AsyncFilter for Comet.");
> + System.err.println(
> + " You need to active this for comet applications.");
> + System.err.println(" Default : false");
> + System.err.println();
> + System.err.println(
> + " --forceWar=[true/false] Force war's deployment over a expanded folder.");
> + System.err
> + .println(" Will deploy the war instead of the folder.");
> + System.err.println(" Default : false");
> + System.err.println();
> + System.err.println(" --ajpEnabled=[true/false] Enable mod_jk.");
> + System.err.println(" Default : false");
> + System.err.println();
> + System.err.println(" Default values will be applied if invalid values are passed.");
> + System.err.println();
> + System.err.println(" * are mandatory");
> + System.exit(1);
> + }
> +}
> Index: modules/bundles/http-servlet-deployer/src/main/java/com/sun/grizzly/http/servlet/deployer/conf/DeployerConfiguration.java
> ===================================================================
> --- modules/bundles/http-servlet-deployer/src/main/java/com/sun/grizzly/http/servlet/deployer/conf/DeployerConfiguration.java (.../trunk/code) (revision 0)
> +++ modules/bundles/http-servlet-deployer/src/main/java/com/sun/grizzly/http/servlet/deployer/conf/DeployerConfiguration.java (.../branches/deployer-refactoring) (revision 3643)
> @@ -0,0 +1,68 @@
> +/**
> + *
> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. *
> + * Copyright 2007-2008 Sun Microsystems, Inc. All rights reserved. *
> + * The contents of this file are subject to the terms of either the GNU
> + * General Public License Version 2 only ("GPL") or the Common Development
> + * and Distribution License("CDDL") (collectively, the "License"). You
> + * may not use this file except in compliance with the License. You can obtain
> + * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
> + * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
> + * language governing permissions and limitations under the License.
> + *
> + * When distributing the software, include this License Header Notice in each
> + * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
> + * Sun designates this particular file as subject to the "Classpath" exception
> + * as provided by Sun in the GPL Version 2 section of the License file that
> + * accompanied this code. If applicable, add the following below the License
> + * Header, with the fields enclosed by brackets [] replaced by your own
> + * identifying information: "Portions Copyrighted [year]
> + * [name of copyright owner]"
> + *
> + * Contributor(s):
> + *
> + * If you wish your version of this file to be governed by only the CDDL or
> + * only the GPL Version 2, indicate your decision by adding "[Contributor]
> + * elects to include this software in this distribution under the [CDDL or GPL
> + * Version 2] license." If you don't indicate a single choice of license, a
> + * recipient has the option to distribute your version of this file under
> + * either the CDDL, the GPL Version 2 or to extend the choice of license to
> + * its licensees as provided above. However, if you add GPL Version 2 code
> + * and therefore, elected the GPL Version 2 license, then the option applies
> + * only if the new code is made subject to such option by the copyright
> + * holder.
> + *
> + */
> +package com.sun.grizzly.http.servlet.deployer.conf;
> +
> +/**
> + * Configuration of {_at_link com.sun.grizzly.http.servlet.deployer.GrizzlyWebServerDeployer}.
> + *
> + * @author Hubert Iwaniuk
> + */
> +public class DeployerConfiguration {
> + public String locations;
> + public int port = 8080;
> + public String forcedContext;
> + public boolean waitToStart = false;
> + public String libraryPath;
> + public String webdefault;
> + public boolean cometEnabled = false;
> + public boolean forceWarDeployment = false;
> + public boolean ajpEnabled = false;
> +
> + @Override
> + public String toString() {
> + return "DeployerConfiguration{" +
> + "locations='" + locations + '\'' +
> + ", port=" + port +
> + ", forcedContext='" + forcedContext + '\'' +
> + ", waitToStart=" + waitToStart +
> + ", libraryPath='" + libraryPath + '\'' +
> + ", webdefault='" + webdefault + '\'' +
> + ", cometEnabled=" + cometEnabled +
> + ", forceWarDeployment=" + forceWarDeployment +
> + ", ajpEnabled=" + ajpEnabled +
> + '}';
> + }
> +}




>
> Thanks in advance,
> Hubert.
>
>
> ------------------------------------------------------------------------
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_grizzly.dev.java.net
> For additional commands, e-mail: dev-help_at_grizzly.dev.java.net