OW2 Consortium jonas

Rev

Rev 22396 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/**
 * JOnAS Configurator
 * Copyright (C) 2008-2010 Bull S.A.S.
 * Copyright (C) 2008-2010 France Telecom R&D
 * Contact: jonas-team@ow2.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id: Jonas53.java 22426 2012-05-04 17:05:04Z cazauxj $
 * --------------------------------------------------------------------------
 */
package org.ow2.jonas.tools.configurator.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Logger;

import org.apache.tools.ant.Project;
import org.apache.tools.ant.listener.TimestampedLogger;
import org.ow2.jonas.antmodular.cluster.clusterdaemon.ClusterDaemon;
import org.ow2.jonas.antmodular.cmi.Cmi;
import org.ow2.jonas.antmodular.jonasbase.bootstrap.JOnASBaseTask;
import org.ow2.jonas.antmodular.jonasbase.bootstrap.JonasProperties;
import org.ow2.jonas.antmodular.jonasbase.bootstrap.Services;
import org.ow2.jonas.antmodular.jonasbase.carol.Carol;
import org.ow2.jonas.antmodular.jonasbase.db.base.Db;
import org.ow2.jonas.antmodular.jonasbase.db.h2.DbH2;
import org.ow2.jonas.antmodular.jonasbase.discovery.multicast.DiscoveryMulticast;
import org.ow2.jonas.antmodular.jonasbase.ha.Ha;
import org.ow2.jonas.antmodular.jonasbase.jms.Jms;
import org.ow2.jonas.antmodular.jonasbase.mail.Mail;
import org.ow2.jonas.antmodular.jonasbase.resource.JdbcXml;
import org.ow2.jonas.antmodular.jonasbase.security.User;
import org.ow2.jonas.antmodular.jonasbase.security.Jaas;
import org.ow2.jonas.antmodular.jonasbase.smartclient.SmartClient;
import org.ow2.jonas.antmodular.jonasbase.web.tomcat.TomcatSessionManager;
import org.ow2.jonas.antmodular.jonasbase.wsdl.WsdlPublish;
import org.ow2.jonas.antmodular.web.base.Ajp;
import org.ow2.jonas.antmodular.web.base.Connectors;
import org.ow2.jonas.antmodular.web.base.Http;
import org.ow2.jonas.antmodular.web.base.Https;
import org.ow2.jonas.antmodular.web.base.SessionReplication;
import org.ow2.jonas.antmodular.web.base.WebContainer;
import org.ow2.jonas.tools.configurator.api.JDBCConfiguration;
import org.ow2.jonas.tools.configurator.api.JdbcXMLConfiguration;
import org.ow2.jonas.tools.configurator.api.JonasConfigurator;

/**
 * JonasConfigurator implementation for Jonas 5.3.x
 * 
 * @author S. Ali Tokmen
 * @author Jeremy Cazaux (support to extensible parameters according to a specific implementation)
 */
public class Jonas53 extends FileReplacerHelper implements JonasConfigurator {

    /**
     * JONAS_BASE
     */
    private File jonasFileBase;

    /**
     * Link to the jonas ant task
     */
    private JOnASBaseTask jonasBase;

    /**
     * To configure databases service
     */
    private DbH2 db;

    /**
     * The cluster daemon configuration
     */
    private ClusterDaemon clusterDaemon;

    /**
     * Configuration logger
     */
    private static Logger logger = Logger.getLogger(Jonas53.class.getName());

    /**
     * To configure protocols
     */
    private Carol carol;

    /**
     * Has JOnAS protocols list been set?
     */
    private boolean isProtocolsListSet = false;

    /**
     * To configure discovery sevice
     */
    private DiscoveryMulticast discovery;

    /**
     * JDBC resources
     */
    private List<JdbcXml> jdbcXmlList;

    /**
     * To configure jms
     */
    private Jms jms;

    /**
     * To configure jonas global properties
     */
    private JonasProperties jonasProperties;

    /**
     * To configure mails
     */
    private List<Mail> mails; 

    /**
     * To configure active services
     */
    private Services services;

    /**
     * To configure web container
     */
    private String webContainer;

    /**
     * To configure web container
     */
    private String jvmRoute;

    /**
     * To configure the algorithm of the web session replication
     */
    private String sessionReplicationAlgorithm;

    /**
     * Cluster name of the web session replication
     */
    private String sessionReplicationClusterName;

    /**
     * Multicast address usefull to configure the web session replication
     */
    private String sessionReplicationMulticastAddress;

    /**
     * Multicast port usefull to configure the web session replication
     */
    private String sessionReplicationMulticastPort;

    /**
     * Listen port usefull to configure the web session replication
     */
    private String sessionReplicationListenPort;

    /**
     * To configure wsdl wsdlPublisherFile
     */
    private org.ow2.jonas.antmodular.jonasbase.wsdl.File wsdlPublisherFile;

    /**
     * To configure WSDL publishing
     */
    private WsdlPublish wsdlPublish;

    /**
     * To configure ejb clustering
     */
    private Cmi cmi;

    /**
     * To configure ha cluster
     */
    private Ha ha;

    /**
     * To configure the smartclient service
     */
    private SmartClient smartClient;

    /**
     * To configure the security
     */
    private Jaas security;

    /**
     * The project, not really usefull, only to have a project to pass to ant
     * task.
     */
    private Project project;

    /**
     * Is jonas root set
     */
    private boolean isJonasRootSet = false;

    /**
     * Is jonas base set
     */
    private boolean isJonasBaseSet = false;

    /**
     * Is http webservice activated
     */
    private Boolean isHttpActivated = false;

    /**
     * Is https webservice activated
     */
    private Boolean isHttpsActivated = false;

    /**
     * Is ajp webservice activated
     */
    private Boolean isAjpActivated = false;

    /**
     * Is http replication webservice activated
     */
    private Boolean isHttpReplicationActivated = false;

    /**
     * Is http session manager activated (only usefull for tomcat7 currently)
     */
    private Boolean isHttpSessionManagerActivated = false;

    /**
     * Is web on demand activated
     */
    private Boolean isWebOnDemandActivated = false;

    /**
     * Web ondemand redirect port
     */
    private String webOnDemandRedirectPort;

    /**
     * The http port to configure
     */
    private String httpPort;

    /**
     * The max http threads to configure
     */
    private String httpMaxThreads;

    /**
     * The min spare threads to configure
     */
    private String httpMinSpareThreads;

    /**
     * The enable http lookups property to configure
     */
    private Boolean httpEnableLookups;

    /**
     * The http connection timeout to configure
     */
    private String httpConnectionTimeout;

    /**
     * The http accept count to configure
     */
    private String httpAcceptCount;

    /**
     * The max keep alive http request 
     */
    private String httpMaxKeepAliveRequest;

    /**
     * The http compression
     */
    private String httpCompression;

    /**
     * The http redirect port
     */
    private String httpRedirectPort;

    /**
     * The https port
     */
    private String httpsPort;

    /**
     * The max https threads
     */
    private String httpsMaxThreads;

    /**
     * The min spare https threads
     */
    private String httpsMinSpareThreads;

    /**
     * The enable https lookups property to configure
     */
    private Boolean httpsEnableLookups;

    /**
     * The https connection timeout
     */
    private String httpsConnectionTimeout;

    /**
     * The https accept count
     */
    private String httpsAcceptCount;

    /**
     * The max keep alive https requests
     */
    private String httpsMaxKeepAliveRequest;

    /**
     * The https compression
     */
    private String httpsCompression;

    /**
     * The https redirect port
     */
    private String httpsRedirectPort;

    /**
     * The https keystore file
     */
    private String httpsKeystoreFile;

    /**
     * The https keystore password
     */
    private String httpsKeystorePass;

    /**
     * The ajp port
     */
    private String ajpPort;

    /**
     * The max ajp threads
     */
    private String ajpMaxThreads;

    /**
     * The min spare ajp threads
     */
    private String ajpMinSpareThreads;

    /**
     * The enable ajp lookups property to configure
     */
    private Boolean ajpEnableLookups;

    /**
     * The ajp connection timeout
     */
    private String ajpConnectionTimeout;

    /**
     * The ajp accept count
     */
    private String ajpAcceptCount;

    /**
     * The ajp redirect port
     */
    private String ajpRedirectPort;

    /**
     * Max active web sessions
     */
    private String maxActiveSession;

    /**
     * Database id
     */
    private String dbId;

    /**
     * List of users 
     */
    List<User> users;

    /**
     * List of admins
     */
    List<User> admins;

    /**
     * Wrapper Configurator api
     */
    JOnASWrapper wrapper;

    /**
     * Derfault constructor
     */
    public Jonas53() {
        this.createProject();
        this.jonasBase = new JOnASBaseTask();
        this.jonasBase.setProject(this.project);
        this.jonasBase.setSkipOptionalDeployablesCopy(true);

        this.jonasProperties = new JonasProperties();
        this.jonasProperties.setProject(this.project);

        this.services = new Services();
        this.services.setProject(this.project);

        this.carol = new Carol();
        this.carol.setProject(this.project);

        this.security = new Jaas();
        this.security.setProject(this.project);

        this.jdbcXmlList = new ArrayList<JdbcXml>();
        this.mails = new ArrayList<Mail>();
        
        this.users = new ArrayList<User>();
        this.admins = new ArrayList<User>();

        Jonas53.logger.finest("Created the JOnAS 5 configurator instance");
    }

    /**
     * Create the project
     */
    private void createProject() {
        this.project = new Project();
        this.project.init();
        this.project.initProperties();

        TimestampedLogger logger = new TimestampedLogger();
        logger.setMessageOutputLevel(Project.MSG_DEBUG);

        logger.setOutputPrintStream(new PrintStream(new OutputStream() {
            StringBuffer buf = new StringBuffer();

            @Override
            public void write(final int b) throws IOException {
                if (b == '\n' || b == '\r') {
                    if (this.buf.length() > 0) {
                        Jonas53.logger.finest(this.buf.toString());
                        this.buf.setLength(0);
                    }
                } else {
                    this.buf.append((char) b);
                }
            }
        }));

        this.project.addBuildListener(logger);
    }

    /* ------------------------------- */
    /* Jonas global parameters */
    /**
     * {@inheritDoc}
     */
    public void setJdk(final String jdk) {
        Jonas53.logger.finest("[GlobalParameters] setting jdk : " + jdk);
        NotApplicableHelper.notApplicable("GlobalParameters.Jdk");
    }

    /**
     * {@inheritDoc}
     */
    public void setJavaOpts(final String javaOpts) {
        Jonas53.logger.finest("[GlobalParameters] setting java opts : " + javaOpts);
        NotApplicableHelper.notApplicable("GlobalParameters.JavaOpts");
    }

    /**
     * {@inheritDoc}
     */
    public void setJonasRoot(final String jonasRoot) {
        Jonas53.logger.finest("[GlobalParameters] setting jonas root : " + jonasRoot);
        this.project.setProperty("jonas.root", jonasRoot);

        this.isJonasRootSet = true;
    }

    /**
     * {@inheritDoc}
     */
    public void setJonasBase(final String jonasBase) {
        Jonas53.logger.finest("[GlobalParameters] setting jonas base : " + jonasBase);
        this.jonasFileBase = new File(jonasBase);
        this.project.setProperty("jonas.base", jonasBase);

        this.isJonasBaseSet = true;
    }

    /**
     * {@inheritDoc}
     */
    public void isJOnASBaseToUpdate(final Boolean update) {
        Jonas53.logger.finest("[GlobalParameters] setting isJonasBaseToUpdate : " + update);
        if (update != null) {
            this.jonasBase.setUpdate(update);
        }
    }

    /**
     * {@inheritDoc}
     */
    public void setJonasName(final String jonasName) {
        Jonas53.logger.finest("[GlobalParameters] setting jonas name : " + jonasName);
        this.addReplacement("jonas.properties", "jonas.name    jonas", "jonas.name    " + jonasName);
    }

    /**
     * {@inheritDoc}
     */
    public void setJonasDomain(final String jonasDomain) {
        Jonas53.logger.finest("[GlobalParameters] setting jonas domain : " + jonasDomain);
        this.addReplacement("jonas.properties", "domain.name    jonas", "domain.name    " + jonasDomain);
    }

    /**
     * {@inheritDoc}
     */
    public void setHost(final String jonasHost) {
        Jonas53.logger.finest("[GlobalParameters] setting host : " + jonasHost);
        NotApplicableHelper.notApplicable("Host.");
    }

    /**
     * {@inheritDoc}
     */
    public void setJonasDevelopment(final boolean development) {
        logger.finest("[GlobalParameters] setting jonas.development : " + development);
        this.jonasProperties.setDevelopment(development);
    }

    /**
     * {@inheritDoc}
     */
    public void setLogConfigFile(final String logConfigFile) {
        this.jonasProperties.setConfigfile(logConfigFile);
    }

    /**
     * {@inheritDoc}
     */
    public void setMaster(final Boolean isMaster) {
        this.jonasProperties.setMaster(isMaster);
    }

    /**
     * {@inheritDoc}
     */
    public void setSecurityPropagation(final Boolean securityPropagation) {
        this.jonasProperties.setSecurityPropagation(securityPropagation);
    }

    /**
     * {@inheritDoc}
     */
    public void setTransactionPropagation(final Boolean transactionPropagation) {
        this.jonasProperties.setTransactionPropagation(transactionPropagation);
    }

    /**
     * {@inheritDoc}
     */
    public void setCsiv2Propagation(final Boolean csiv2Propagation) {
        this.jonasProperties.setCsiv2Propagation(csiv2Propagation);
    }

    /* ------------------------------- */

    /* ------------------------------- */
    /* Jonas protocols configuation */
    /**
     * {@inheritDoc}
     */
    public void setProtocolsList(final String protocolsList) {
        if (protocolsList != null && protocolsList.contains("cmi")) {
            throw new IllegalArgumentException("In JOnAS 5, CMI has become a service. To enable CMI, follow these steps:"
                + "\n\t1) In the CAROL protocols list, use JRMP, IIOP and/or IRMI as usual"
                + "\n\t2) In the JOnAS services list, add the \"cmi\" service");
        }

        Jonas53.logger.finest("[Protocols configuration] setting protocols list : " + protocolsList);
        this.carol.setProtocols(protocolsList);
        this.isProtocolsListSet = true;
    }

    /**
     * {@inheritDoc}
     */
    public void setProtocolsIrmiPort(final String irmiPort) {
        Jonas53.logger.finest("[Protocols configuration] setting irmi port : " + irmiPort);
        this.carol.setIrmiPort(irmiPort);
    }

    /**
     * {@inheritDoc}
     */
    public void setProtocolsIiopPort(final String iiopPort) {
        Jonas53.logger.finest("[Protocols configuration] setting iiop port : " + iiopPort);
        this.carol.setIiopPort(iiopPort);
    }

    /**
     * {@inheritDoc}
     */
    public void setProtocolsJrmpPort(final String jrmpPort) {
        Jonas53.logger.finest("[Protocols configuration] setting jrmp port : " + jrmpPort);
        this.carol.setJrmpPort(jrmpPort);
    }

    /**
     * {@inheritDoc}
     */
    public void setProtocolsJrmLocalRegistry(final Boolean localRegistry) {
        Jonas53.logger.finest("[Protocols configuration] setting jrmp local registry : " + localRegistry);
        this.carol.setLocalRegistry(localRegistry);
    }

    /**
     * {@inheritDoc}
     */
    public void setCarolHost(final String host) {
        Jonas53.logger.finest("[Protocols configuration] setting host : " + host);
        this.carol.setHost(host);
    }

    /**
     * {@inheritDoc}
     */
    public void setProtocolsCmiPort(final String cmiPort) {
        Jonas53.logger.finest("[Protocols configuration] setting cmi port : " + cmiPort);
        NotApplicableHelper.notApplicable("Protocols.CmiPort");
    }

    /**
     * {@inheritDoc}
     */
    public void setProtocolsLocalCallOptimized(final Boolean localCallOptimized) {
        Jonas53.logger.finest("[Protocols configuration] setting jndi local call optimisation : " + localCallOptimized);
        this.carol.setJrmpOptimization(localCallOptimized);
    }

    /* ------------------------------- */

    /* ------------------------------- */
    /* Active services */
    /**
     * {@inheritDoc}
     */
    public void setServices(final String services) {
        Jonas53.logger.finest("setting actives services list : " + services);
        this.services.setNames(services);
        this.jonasProperties.setServices(services);
    }

    /* ------------------------------- */

    /* ------------------------------- */
    /* Service web configuration */
    /**
     * {@inheritDoc}
     */
    public void setWebcontainer(final String webContainer) {
        Jonas53.logger.finest("[Web configuration] setting webContainer : " + webContainer);
        this.webContainer = webContainer;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpConnectorActivation(final Boolean activation) {
        Jonas53.logger.finest("[Web configuration] setting isHttpActivated : " + activation);
        this.isHttpActivated = activation;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpsConnectorActivation(final Boolean activation) {
        Jonas53.logger.finest("[Web configuration] setting isHttpsActivated : " + activation);
        this.isHttpsActivated = activation;
    }

    /**
     * {@inheritDoc}
     */
    public void setAjpConnectorActivation(final Boolean activation) {
        Jonas53.logger.finest("[Web configuration] setting isAjpActivated : " + activation);
        this.isAjpActivated = activation;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpSessionReplicationActivation(final Boolean activation) {
        Jonas53.logger.finest("[Web configuration] setting isHttpReplicationActivated : " + activation);
        this.isHttpReplicationActivated = activation;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpSessionManagerActivation(final Boolean activation) {
        Jonas53.logger.finest("[Web configuration] setting isHttpSessionManagerActivated : " + activation);
        this.isHttpSessionManagerActivated = activation;
    }

    /**
     * {@inheritDoc}
     */
    public void setWebOndemandActivation(final Boolean activation) {
        Jonas53.logger.finest("[Web configuration] setting isWebOnDemandActivated : " + activation);
        this.isWebOnDemandActivated = activation;
    }

    /**
     * {@inheritDoc}
     */
    public void setWebOndemandRedirectPort(final String redirectPort) {
        Jonas53.logger.finest("[Web configuration] setting ondemand redirect port : " + redirectPort);
        this.webOnDemandRedirectPort = redirectPort;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpPort(final String httpPort) {
        Jonas53.logger.finest("[Web configuration] setting http port : " + httpPort);
        this.httpPort = httpPort;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpMaxThreads(final String httpMaxThreads) {
        Jonas53.logger.finest("[Web configuration] setting max http threads : " + httpMaxThreads);
        this.httpMaxThreads = httpMaxThreads;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpMinSpareThreads(final String httpMinSpareThreads) {
        Jonas53.logger.finest("[Web configuration] setting min http spare threads : " + httpMinSpareThreads);
        this.httpMinSpareThreads = httpMinSpareThreads;
    }

    /**
     * {@inheritDoc}
     */
    @Deprecated // not used..
    public void setHttpMaxSpareThreads(final String httpMaxSpareThreads) {
        Jonas53.logger.finest("[Web configuration] setting max http spare threads : " + httpMaxSpareThreads);
        NotApplicableHelper.notApplicable("HTTP.maxSpareThreads");
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpEnableLookups(final Boolean enableLookups) {
        Jonas53.logger.finest("setting http enable lookups : " + enableLookups);
        this.httpEnableLookups = enableLookups;
    } 

    /**
     * {@inheritDoc}
     */
    public void setHttpConnectionTimeout(final String connectionTimeout) {
        Jonas53.logger.finest("setting http connection timeout : " + connectionTimeout);
        this.httpConnectionTimeout = connectionTimeout;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpAcceptCount(final String acceptCount) {
        Jonas53.logger.finest("setting http accept count : " + acceptCount);
        this.httpAcceptCount = acceptCount;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpMaxKeepAliveRequest(final String maxKeepAliveRequest) {
        Jonas53.logger.finest("setting max keep alive http request : " + maxKeepAliveRequest);
        this.httpMaxKeepAliveRequest = maxKeepAliveRequest;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpCompression(final String compression) {
        Jonas53.logger.finest("setting http compression : " + compression);
        this.httpCompression = compression;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpRedirectPort(final String redirectPort) {
        Jonas53.logger.finest("setting http redirect port : " + redirectPort);
        this.httpRedirectPort = redirectPort;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpsPort(final String httpsPort) {
        Jonas53.logger.finest("[Web configuration] setting https port : " + httpsPort);
        this.httpsPort = httpsPort;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpsMaxThreads(final String httpsMaxThreads) {
        Jonas53.logger.finest("[Web configuration] setting max https threads : " + httpsMaxThreads);
        this.httpsMaxThreads = httpsMaxThreads;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpsMinSpareThreads(final String httpsMinSpareThreads) {
        Jonas53.logger.finest("setting min https spare threads : " + httpsMinSpareThreads);
        this.httpsMinSpareThreads = httpsMinSpareThreads;
    }

    /**
     * {@inheritDoc}
     */
    @Deprecated //never used...
    public void setHttpsMaxSpareThreads(final String httpsMaxSpareThreads) {
        Jonas53.logger.finest("setting max https spare threads : " + httpsMaxSpareThreads);
        NotApplicableHelper.notApplicable("HTTPS.maxSpareThreads");
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpsEnableLookups(final Boolean enableLookups) {
        Jonas53.logger.finest("setting https enable lookups property : " + enableLookups);
        this.httpsEnableLookups = enableLookups;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpsConnectionTimeout(final String connectionTimeout) {
        Jonas53.logger.finest("setting https connection timeout : " + connectionTimeout);
        this.httpsConnectionTimeout = connectionTimeout;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpsAcceptCount(final String acceptCount) {
        Jonas53.logger.finest("setting https accept count : " + acceptCount);
        this.httpsAcceptCount = acceptCount;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpsMaxKeepAliveRequest(final String maxKeepAliveRequest) {
        Jonas53.logger.finest("setting max keep alive https request : " + maxKeepAliveRequest);
        this.httpsMaxKeepAliveRequest = maxKeepAliveRequest;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpsCompression(final String compression) {
        Jonas53.logger.finest("setting https compression : " + compression);
        this.httpsCompression = compression;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpsRedirectPort(final String redirectPort) {
        Jonas53.logger.finest("setting https redirect port : " + redirectPort);
        this.httpsRedirectPort = redirectPort;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpsKeystoreFile(final String keystoreFile) {
        Jonas53.logger.finest("setting https keystore file : " + keystoreFile);
        this.httpsKeystoreFile = keystoreFile;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpsKeystorePass(final String keystorePass) {
        Jonas53.logger.finest("setting https keystore password : " + keystorePass);
        this.httpsKeystorePass = keystorePass;
    }

    /**
     * {@inheritDoc}
     */
    public void setAjpPort(final String ajpPort) {
        Jonas53.logger.finest("[Web configuration] setting ajp port : " + ajpPort);
        this.ajpPort = ajpPort;
    }

    /**
     * {@inheritDoc}
     */
    public void setAjpMaxThreads(final String ajpMaxThreads) {
        Jonas53.logger.finest("[Web configuration] setting max ajp threads : " + ajpMaxThreads);
        this.ajpMaxThreads = ajpMaxThreads;
    }

    /**
     * {@inheritDoc}
     */
    public void setAjpMinSpareThreads(final String ajpMinSpareThreads) {
        Jonas53.logger.finest("[Web configuration] setting min ajp spare threads : " + ajpMinSpareThreads);
        this.ajpMinSpareThreads = ajpMinSpareThreads;
    }

    /**
     * {@inheritDoc}
     */
    @Deprecated //never used...
    public void setAjpMaxSpareThreads(final String ajpMaxSpareThreads) {
        Jonas53.logger.finest("[Web configuration] setting max ajp spare threads : " + ajpMaxSpareThreads);
        NotApplicableHelper.notApplicable("AJP.maxSpareThreads");
    }

    /**
     * {@inheritDoc}
     */
    public void setAjpEnableLookups(final Boolean enableLookups) {
        Jonas53.logger.finest("setting ajp enable lookups property : " + enableLookups);
        this.ajpEnableLookups = enableLookups;
    }

    /**
     * {@inheritDoc}
     */
    public void setAjpConnectionTimeout(final String connectionTimeout) {
        Jonas53.logger.finest("setting ajp connection timeout : " + connectionTimeout);
        this.ajpConnectionTimeout = connectionTimeout;        
    }

    /**
     * {@inheritDoc}
     */
    public void setAjpAcceptCount(final String acceptCount) {
        Jonas53.logger.finest("setting ajp accept count : " + acceptCount);
        this.ajpAcceptCount = acceptCount;
    }

    /**
     * {@inheritDoc}
     */
    public void setAjpRedirectPort(final String redirectPort) {
        Jonas53.logger.finest("setting ajp redirect port : " + redirectPort);
        this.ajpRedirectPort = redirectPort;
    }

    /**
     * {@inheritDoc}
     */
    public void setMaxActiveWebSessions(final String maxActiveSession) {
        Jonas53.logger.finest("setting max active session : " + maxActiveSession);
        this.maxActiveSession = maxActiveSession;
    }

    /**
     * {@inheritDoc}
     */
    public void setJmxSecured(final boolean enabled) {
        Jonas53.logger.finest("[Security] setting JMX security:" + enabled);
        security.setSecureJmx(enabled);
    }

    /**
     * {@inheritDoc}
     */
    public void addUser(final String username, final String password, final String roles, final String groups, 
                        final String description) {
        User user = new User();
        user.setName(username);
        user.setPassword(password);
        user.setGroups(groups);
        user.setRoles(roles);
        user.setDescription(description);
        this.users.add(user);
    }

    /**
     * {@inheritDoc}
     */
    public void addAdmin(final String username, final String password) {
        User admin = new User();
        admin.setName(username);
        admin.setPassword(password);
        this.admins.add(admin);
    }

    /**
     * {@inheritDoc}
     */
    public void setJvmRoute(final String jvmRoute) {
        Jonas53.logger.finest("[Web configuration] setting jvm route : " + jvmRoute);
        this.jvmRoute = jvmRoute;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpReplicationClusterName(final String clusterName) {
        Jonas53.logger.finest("[Web configuration] setting cluster name : " + clusterName);
        this.sessionReplicationClusterName = clusterName; 
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpReplicationMulticastAddress(final String mCastAddr) {
        Jonas53.logger.finest("[Web configuration] setting multi cast address : " + mCastAddr);
        this.sessionReplicationMulticastAddress = mCastAddr;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpReplicationMulticastPort(final String mCastPort) {
        Jonas53.logger.finest("[Web configuration] setting multi cast port : " + mCastPort);
        this.sessionReplicationMulticastPort = mCastPort;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpReplicationListenPort(final String listenPort) {
        Jonas53.logger.finest("[Web configuration] setting listen port : " + listenPort);
        this.sessionReplicationListenPort = listenPort;
    }

    /**
     * {@inheritDoc}
     */
    public void setHttpReplicationAlgorithm(final String algorithm) {
        Jonas53.logger.finest("[Web configuration] setting http replication algorithm : " + algorithm);
        this.sessionReplicationAlgorithm = algorithm;
    }

    /* ------------------------------- */

    /* ------------------------------- */
    /**
     * Active db service
     */
    private void initDb() {
        if (this.db == null) {
            this.db = new DbH2();
            this.db.setProject(this.project);
        }
    }

    /* Service db configuration */
    /**
     * {@inheritDoc}
     */
    public void setDbPort(final String port) {
        Jonas53.logger.finest("[Database configuration] setting db port: " + port);
        initDb();
        this.db.setPort(port);
    }

    /**
     * {@inheritDoc}
     */
    public void setDbName(final String name) {
        Jonas53.logger.finest("[Database configuration] setting db name: " + name);
        initDb();
        this.db.setDbName(name);
    }

    /**
     * {@inheritDoc}
     */
    public void setDbUsers(final String users) {
        Jonas53.logger.finest("[Database configuration] setting db users: " + users);
        initDb();
        this.db.setUsers(users);
    }
 
    /**
     * {@inheritDoc}
     */
    public void setDbId(final String dbId) {
        this.dbId = dbId;
    }

    /* ------------------------------- */

    /* ------------------------------- */
    /* Service discovery configuration */
    /**
     * {@inheritDoc}
     */
    public void setDiscoveryMasterActivated(final Boolean masterActivated) {
        Jonas53.logger.finest("[Discovery configuration] setting masterActivated : " + masterActivated);
        this.jonasProperties.setMaster(masterActivated);
    }

    /**
     * {@inheritDoc}
     */
    public void setDiscoverySourcePort(final String sourcePort) {
        Jonas53.logger.finest("[Discovery configuration] setting source port : " + sourcePort);
        initDiscovery();
        this.discovery.setSourcePort(sourcePort);
    }

    /**
     * {@inheritDoc}
     */
    public void setDiscoveryDomainName(final String domainName) {
        Jonas53.logger.finest("[Discovery configuration] setting domain name : " + domainName);
        this.addReplacement("jonas.properties", "domain.name    jonas", "domain.name    " + domainName);
    }

    /**
     * {@inheritDoc}
     */
    public void setDiscoveryGreetingPort(final String greetingPort) {
        Jonas53.logger.finest("[Discovery configuration] setting greeting port : " + greetingPort);
        initDiscovery();
        this.discovery.setGreetingPort(greetingPort);
    }

    /**
     * {@inheritDoc}
     */
    public void setDiscoveryMulticastAddress(final String multicastAddress) {
        Jonas53.logger.finest("[Discovery configuration] setting multicast address : " + multicastAddress);
        initDiscovery();
        this.discovery.setMcastAddr(multicastAddress);
    }

    /**
     * {@inheritDoc}
     */
    public void setDiscoveryMulticastPort(final String multicastPort) {
        Jonas53.logger.finest("[Discovery configuration] setting multicast port : " + multicastPort);
        initDiscovery();
        this.discovery.setMcastPort(multicastPort);
    }

    /**
     * {@inheritDoc}
     */
    public void setDiscoveryTTL(final String ttl) {
        Jonas53.logger.finest("[Discovery configuration] setting ttl : " + ttl);
        initDiscovery();
        this.discovery.setTtl(ttl);
    }

    /**
     * Init discovery object if not set
     */
    private void initDiscovery() {
        if (this.discovery == null) {
            this.discovery = new DiscoveryMulticast();
            this.discovery.setProject(this.project);
        }
    }

    /* ------------------------------- */

    /* ------------------------------- */
    /* Service mail configuration */
    /**
     * {@inheritDoc}
     */
    public void setMailFactoryType(final String factoryType) {
        Jonas53.logger.finest("[Mail Service Configuration] setting mail factory type : " + factoryType);
        NotApplicableHelper.notApplicable("Mail.factoryType");
    }

    /**
     * {@inheritDoc}
     */
    public void setMailFactoryName(final String factoryName) {
        Jonas53.logger.finest("[Mail Service Configuration] setting mail factory name : " + factoryName);
        NotApplicableHelper.notApplicable("Mail.factoryName");
    }

    /**
     * {@inheritDoc}
     */
    public void addMailMimme(final String name, final String host, final String mailto, final String subject) {
        Jonas53.logger.finest("[Mail Service Configuration] addition of a new mail mimme configuration file.");
        Mail mail = new Mail();
        mail.setProject(this.project);
        mail.setName(name);
        mail.setHost(host);
        mail.setMailTo(mailto);
        mail.setSubject(subject);
        mail.setType("MimePartDataSource");
        this.mails.add(mail);
    }

    /**
     * {@inheritDoc}
     */
    public void addMailSession(final String name) {
        Jonas53.logger.finest("[Mail Service Configuration] addition of a new mail session configuration file.");
        Mail mail = new Mail();
        mail.setProject(this.project);
        mail.setName(name);
        mail.setType("Session");
        this.mails.add(mail);
    }

    /* ------------------------------- */

    /* ------------------------------- */
    /* Service WS configuration */

    /**
     * Init WsdlPublisherFile if not set
     */
    private void initWsdlPublisherFile() {
        if (this.wsdlPublisherFile == null) {
            this.wsdlPublisherFile = new org.ow2.jonas.antmodular.jonasbase.wsdl.File();
        }
    }

    /**
     * {@inheritDoc}
     */
    public void setWsdlPublisherFileName(final String fileName) {
        Jonas53.logger.finest("[WS Service configuration] setting wsdlPublisherFile name : " + fileName);
        initWsdlPublisherFile();
        this.wsdlPublisherFile.setName(fileName);
    }

    /**
     * {@inheritDoc}
     */
    public void setWsdlPublisherFileDirectory(final String fileDir) {
        Jonas53.logger.finest("[WS Service configuration] setting wsdlPublisherFile directory : " + fileDir);
        initWsdlPublisherFile();
        this.wsdlPublisherFile.setDir(fileDir);
    }

    /* ------------------------------- */

    /* ------------------------------- */
    /* Service HA configuration */
    /**
     * {@inheritDoc}
     */
    public void setHaActivated(final Boolean activated) {
        Jonas53.logger.finest("[HA Service configuration] setting ha activated : " + activated);
        //do nothing
    }

    /**
     * {@inheritDoc}
     */
    public void setHaMulticastAddress(final String multicastAddr) {
        Jonas53.logger.finest("[HA Service configuration] setting multicast address : " + multicastAddr);
        initHa();
        this.ha.setMcastAddr(multicastAddr);
    }

    /**
     * {@inheritDoc}
     */
    public void setHaMulticastPort(final String multicastPort) {
        Jonas53.logger.finest("[HA Service configuration] setting multicast port : " + multicastPort);
        initHa();
        this.ha.setMcastPort(multicastPort);
    }

    /**
     * Activate HA
     */
    private void initHa() {
        if (this.ha == null) {
            this.ha = new Ha();
            this.ha.setProject(this.project);
        }
    }

    /* ------------------------------- */

    /* ------------------------------- */
    /* Security manager configuration */
    /**
     * {@inheritDoc}
     */
    public void setSecurityManagerActivated(final Boolean activation) {
        Jonas53.logger.finest("[Security Manager configuration] setting isActivates : " + activation);
        this.jonasProperties.setSecurityManager(activation);
    }

    /* ------------------------------- */

    /* ------------------------------- */
    /* Ejb clustering configuration */
    /**
     * {@inheritDoc}
     */
    /**
     * {@inheritDoc}
     */
    public void setEjbClusteringActivated(final Boolean activated) {
        Jonas53.logger.finest("[Ejb Clustering configuration] setting ejb clustering activated activated : " + activated);
        if (activated) {
            this.cmi = new Cmi();
            this.cmi.setProject(this.project);
        }
    }

    public void setEjbClusteringMulticastAddress(final String multicastAddr) {
        Jonas53.logger.finest("[Ejb Clustering configuration] setting multicast address : " + multicastAddr);
        if (this.cmi != null) {
            this.cmi.setMcastAddr(multicastAddr);
        }
    }

    /**
     * {@inheritDoc}
     */
    public void setEjbClusteringMulticastPort(final String multicastPort) {
        Jonas53.logger.finest("[Ejb Clustering configuration] setting multicast port : " + multicastPort);
        if (this.cmi != null) {
            this.cmi.setMcastPort(multicastPort);
        }
    }

    /**
     * {@inheritDoc}
     */
    public void setEjbClusteringReplicationEnable(final Boolean enable) {
        Jonas53.logger.finest("[EJB Clustering configuration] : " + enable);
        if (this.cmi != null) {
            this.cmi.setReplicationEnabled(enable);
        }
    }

    /* ------------------------------- */

    /* ------------------------------- */
    /* Jms configuration */

    /**
     * Initialize JMS if not set
     */
    private void initJms() {
        if (this.jms == null) {
            this.jms = new Jms();
            this.jms.setProject(this.project);
        }
    }

    /**
     * {@inheritDoc}
     */
    public void setJmsPort(final String port) {
        Jonas53.logger.finest("[Jms configuration] setting port : " + port);
        initJms();
        this.jms.setPort(port);
    }

    /**
     * {@inheritDoc}
     */
    public void setJmsQueues(final String queue) {
        Jonas53.logger.finest("[Jms configuration] setting queue : " + queue);
        initJms();
        this.jms.setInitialQueues(queue);
    }

    /**
     * {@inheritDoc}
     */
    public void setJmsTopics(final String topic) {
        Jonas53.logger.finest("[Jms configuration] setting topic : " + topic);
        initJms();
        this.jms.setInitialTopics(topic);
    }

    /**
     * {@inheritDoc}
     */
    public void setJmsHost(final String host) {
        Jonas53.logger.finest("[Jms configuration] setting host : " + host);
        initJms();
        this.jms.setHost(host);
    }

    /**
     * {@inheritDoc}
     */
    public void addJdbcResource(final JdbcXMLConfiguration jdbcXMLConfiguration) {
        JdbcXml jdbcXml = new JdbcXml();
        jdbcXml.setProject(this.project);
        if (jdbcXMLConfiguration.classname != null) {
            Jonas53.logger.finest("[JdbcXML configuration] setting classname: " + jdbcXMLConfiguration.classname);
            jdbcXml.setClassName(jdbcXMLConfiguration.classname);
        }
        if (jdbcXMLConfiguration.mapper != null) {
            Jonas53.logger.finest("[JdbcXML configuration] setting mapper: " + jdbcXMLConfiguration.mapper);
            jdbcXml.setMapper(jdbcXMLConfiguration.mapper);    
        }
        if (jdbcXMLConfiguration.name != null) {
            Jonas53.logger.finest("[JdbcXML configuration] setting name: " + jdbcXMLConfiguration.name);
            jdbcXml.setName(jdbcXMLConfiguration.name);
        }
        if (jdbcXMLConfiguration.username != null) {
            Jonas53.logger.finest("[JdbcXML configuration] setting username: " + jdbcXMLConfiguration.username);
            jdbcXml.setUserName(jdbcXMLConfiguration.username);
        }
        if (jdbcXMLConfiguration.password != null) {
            Jonas53.logger.finest("[JdbcXML configuration] setting password: " + jdbcXMLConfiguration.password);
            jdbcXml.setPassword(jdbcXMLConfiguration.password);
        } 
        if (jdbcXMLConfiguration.url != null) {
            Jonas53.logger.finest("[JdbcXML configuration] setting url: " + jdbcXMLConfiguration.url);
            jdbcXml.setUrl(jdbcXMLConfiguration.url);
        } 
        if (jdbcXMLConfiguration.conCheckLevel != null)  {
            Jonas53.logger.finest("[JdbcXML configuration] setting conCheckLevel: " + jdbcXMLConfiguration.conCheckLevel);
            jdbcXml.setConCheckLevel(jdbcXMLConfiguration.conCheckLevel);
        }
        if (jdbcXMLConfiguration.connMaxAge != null) {
            Jonas53.logger.finest("[JdbcXML configuration] setting connMaxAge: " + jdbcXMLConfiguration.connMaxAge);
            jdbcXml.setConnMaxAge(jdbcXMLConfiguration.connMaxAge);
        }  
        if (jdbcXMLConfiguration.conTestStmt != null) {
            Jonas53.logger.finest("[JdbcXML configuration] setting conTestStmt: " + jdbcXMLConfiguration.conTestStmt);
            jdbcXml.setConTestStmt(jdbcXMLConfiguration.conTestStmt);
        } 
        if (jdbcXMLConfiguration.initConPool != null) {
            Jonas53.logger.finest("[JdbcXML configuration] setting initConPool: " + jdbcXMLConfiguration.initConPool);
            jdbcXml.setInitConPool(jdbcXMLConfiguration.initConPool);
        } 
        if (jdbcXMLConfiguration.maxConPool != null) {
            Jonas53.logger.finest("[JdbcXML configuration] setting maxConPool: " + jdbcXMLConfiguration.maxConPool);
            jdbcXml.setMaxConPool(jdbcXMLConfiguration.maxConPool);
        } 
        if (jdbcXMLConfiguration.maxOpenTime != null) {
            Jonas53.logger.finest("[JdbcXML configuration] setting maxOpenTime: " + jdbcXMLConfiguration.maxOpenTime);
            jdbcXml.setMaxOpenTime(jdbcXMLConfiguration.maxOpenTime);
        }
        if (jdbcXMLConfiguration.maxWaiters != null) {
            Jonas53.logger.finest("[JdbcXML configuration] setting maxWaiters: " + jdbcXMLConfiguration.maxWaiters);
            jdbcXml.setMaxWaiters(jdbcXMLConfiguration.maxWaiters);
        }
        if (jdbcXMLConfiguration.minConPool != null) {
            Jonas53.logger.finest("[JdbcXML configuration] setting minConPool: " + jdbcXMLConfiguration.minConPool);
            jdbcXml.setMinConPool(jdbcXMLConfiguration.minConPool);
        }
        if (jdbcXMLConfiguration.maxWaitTime != null) {
            Jonas53.logger.finest("[JdbcXML configuration] setting maxWaiters: " + jdbcXMLConfiguration.maxWaiters);
            jdbcXml.setMaxWaitTime(jdbcXMLConfiguration.maxWaitTime);
        }
        if (jdbcXMLConfiguration.pstmtCachePolicy != null) {
            Jonas53.logger.finest("[JdbcXML configuration] setting pstmtCachePolicy: " + jdbcXMLConfiguration.pstmtCachePolicy);
            jdbcXml.setPstmtCachePolicy(jdbcXMLConfiguration.pstmtCachePolicy);
        }
        if (jdbcXMLConfiguration.pstmtMax != null) {
            Jonas53.logger.finest("[JdbcXML configuration] setting pstmtMax: " + jdbcXMLConfiguration.pstmtMax);
            jdbcXml.setPstmtMax(jdbcXMLConfiguration.pstmtMax);
        }
        if (jdbcXMLConfiguration.samplingPeriod != null) {
            Jonas53.logger.finest("[JdbcXML configuration] setting samplingPeriod: " + jdbcXMLConfiguration.samplingPeriod);
            jdbcXml.setSamplingPeriod(jdbcXMLConfiguration.samplingPeriod);
        }
        if (jdbcXMLConfiguration.description != null) {
            Jonas53.logger.finest("[JdbcXML configuration] setting description: " + jdbcXMLConfiguration.description);
            jdbcXml.setDescription(jdbcXMLConfiguration.description);
        }
        this.jdbcXmlList.add(jdbcXml);
    }

    /**
     * {@inheritDoc}
     */
    public void addJdbcResource(final String ref, final JdbcXMLConfiguration jdbcXMLConfiguration) {
        if (ref.equals(dbId)) {
            initDb();
            jdbcXMLConfiguration.classname = this.db.getClassname();
            jdbcXMLConfiguration.mapper = this.db.getMapper();
            jdbcXMLConfiguration.url = this.db.getUrl("localhost");
            Map.Entry<String, String> user = this.db.getFirstUsernameAndPassword();
            jdbcXMLConfiguration.username = user.getKey();
            jdbcXMLConfiguration.password = user.getValue();
            addJdbcResource(jdbcXMLConfiguration);
        } else {
            NotApplicableHelper.notApplicable("Resource.Jdbc. The reference " + ref + " is invalid.");
        }
    }

    /**
     * {@inheritDoc}
     */
    public void addJdbcRA(final String raName, final JDBCConfiguration configuration) {
        NotApplicableHelper.notApplicable("resource.addJdbcRa");
    }

    /**
     * Initialize Smartclient if not set
     */
    private void initSmartclient() {
        if (this.smartClient == null) {
            this.smartClient = new SmartClient();
            this.smartClient.setProject(this.project);
        }
    }

    /**
     * {@inheritDoc}
     */
    public void setSmartClientPort(final String port) {
        Jonas53.logger.finest("[Smartclient configuration] setting port: " + port);
        initSmartclient();
        this.smartClient.setPort(port);
    }

    /* ------------------------------- */

    /**
     * {@inheritDoc}
     */
    public void execute() {
        if (!this.isJonasRootSet) {
            throw new IllegalArgumentException("Jonas root is not set.");
        }
        if (!this.isJonasBaseSet) {
            throw new IllegalArgumentException("Jonas base is not set.");
        }

        this.jonasBase.addConfiguredServices(this.services);
        this.jonasBase.execute();
        this.jonasProperties.execute();
        this.doReplacements(new File(this.jonasFileBase, "conf"));

        if (this.ha != null) {
            this.ha.execute();
        }
        if (this.cmi != null) {
            this.cmi.execute();
        }

        WebContainer webContainer = null;
        try {
            if (this.webContainer == null) {
                // If not set, get the webContainer from jonas.properties
                //
                // jonas.service.web.class is for example org.ow2.jonas.web.tomcat7.Tomcat7Service,
                // we therefore split it at each for and get the length - 2 (in our example, tomcat7).
                Properties jonasProperties = new Properties();
                InputStream fis = new FileInputStream(new File(this.jonasFileBase, "conf/jonas.properties"));
                try {
                    jonasProperties.load(fis);
                } finally {
                    fis.close();
                    fis = null;
                    System.gc();
                }
                final String webToken = jonasProperties.getProperty("jonas.service.web.class");
                if (webToken != null) {
                    String[] defaultWebcontainerClass = webToken.split("\\.");
                    this.webContainer = defaultWebcontainerClass[defaultWebcontainerClass.length - 2];
                }
            }

            if (this.webContainer != null) {
                for (String webContainerClassName : getAllClasses((URLClassLoader) this.getClass().getClassLoader(),
                        WebContainer.class.getName())) {

                    if (webContainerClassName.contains(this.webContainer)) {
                        webContainer = (WebContainer)
                                this.getClass().getClassLoader().loadClass(webContainerClassName).newInstance();
                        webContainer.setProject(this.project);
                    }
                }
            }
        } catch (Exception e) {
            throw new IllegalStateException("Cannot create Web container", e);
        }

        if (webContainer != null) {
            //jvm route
            if (this.jvmRoute != null) {
                invokeMethod(webContainer, "setJvmRoute", this.jvmRoute, "Web.jvmRoute",
                        "[Web configuration] cannot set jvm route : " + jvmRoute);
            }

            //web ondemand
            invokeMethod(webContainer, "setOndemandenabled", String.valueOf(this.isWebOnDemandActivated),
                    "webContainer.ondemandenabled", "[Web configuration] cannot set ondemandenable : " + this.isWebOnDemandActivated);

            if (this.isWebOnDemandActivated && this.webOnDemandRedirectPort != null) {
                invokeMethod(webContainer, "setOndemandredirectPort", this.webOnDemandRedirectPort, "webContainer.ondemandRedirectPort",
                        "[Web configuration] cannot set ondemand redirect port : " + this.webOnDemandRedirectPort);
            }

            //create AJP connector
            Ajp ajp = null;
            if (this.isAjpActivated) {
                ajp = (Ajp) instanciateConnector(Ajp.class.getName(), this.webContainer);
                if (ajp != null) {
                    if (this.ajpEnableLookups != null) {
                        invokeMethod(ajp, "setEnableLookups", String.valueOf(this.ajpEnableLookups), "ajp.enableLookups",
                                "[AJP configuration] cannot set enableLookups property : " + this.ajpEnableLookups);
                    }
                    if (this.ajpAcceptCount != null) {
                        invokeMethod(ajp, "setAcceptCount", this.ajpAcceptCount, "ajp.acceptCount",
                                "[AJP configuration] cannot set accept count : " + this.ajpAcceptCount);
                    }
                    if (this.ajpConnectionTimeout != null) {
                        invokeMethod(ajp, "setConnectionTimeout", this.ajpConnectionTimeout, "ajp.connectionTimeout",
                                "[AJP configuration] cannot set connection timeout to: " + this.ajpConnectionTimeout);
                    }
                    if (this.ajpMaxThreads != null) {
                        invokeMethod(ajp, "setMaxThreads", this.ajpMaxThreads, "ajp.maxThreads",
                                "[AJP configuration] cannot set max threads ; " + this.ajpMaxThreads);
                    }
                    if (this.ajpMinSpareThreads != null) {
                        invokeMethod(ajp, "setMinSpareThreads", this.ajpMinSpareThreads, "ajp.minSpareThreads",
                                "[AJP configuration] cannot set min spare threads : " + this.ajpMinSpareThreads);
                    }
                    if (this.ajpPort != null) {
                        invokeMethod(ajp, "setPort", this.ajpPort, "ajp.port", "[AJP configuration] cannot set port : " +
                                this.ajpPort);
                    }
                    if (this.ajpRedirectPort != null) {
                        invokeMethod(ajp, "setRedirectPort", this.ajpRedirectPort, "ajp.redirectPort",
                                "[AJP configuration] cannot set redirect port : " + this.ajpRedirectPort);
                    }
                }
            }

            //create HTTP connector
            Http http = null;
            if (this.isHttpActivated) {
                http = (Http) instanciateConnector(Http.class.getName(), this.webContainer);
                if (http != null) {
                    if (this.httpEnableLookups != null) {
                        invokeMethod(http, "setEnableLookups", String.valueOf(this.httpEnableLookups), "http.enableLookups",
                                "[HTTP configuration] cannot set enableLookups property : " + this.httpEnableLookups);
                    }
                    if (this.httpAcceptCount != null) {
                        invokeMethod(http, "setAcceptCount", this.httpAcceptCount, "http.acceptCount",
                                "[HTTP configuration] cannot set accept count : " + this.httpAcceptCount);
                    }
                    if (this.httpConnectionTimeout != null) {
                        invokeMethod(http, "setConnectionTimeout", this.httpConnectionTimeout, "http.connectionTimeout",
                                "[HTTP configuration] cannot set connection timeout to: " + this.httpConnectionTimeout);
                    }
                    if (this.httpMaxThreads != null) {
                        invokeMethod(http, "setMaxThreads", this.httpMaxThreads, "http.maxThreads",
                                "[HTTP configuration] cannot set max threads ; " + this.httpMaxThreads);
                    }
                    if (this.httpMinSpareThreads != null) {
                        invokeMethod(http, "setMinSpareThreads", this.httpMinSpareThreads, "http.minSpareThreads",
                                "[HTTP configuration] cannot set min spare threads : " + this.httpMinSpareThreads);
                    }
                    if (this.httpPort != null) {
                        invokeMethod(http, "setPort", this.httpPort, "http.port", "[HTTP configuration] cannot set port : " +
                                this.httpPort);
                    }
                    if (this.httpRedirectPort != null) {
                        invokeMethod(http, "setRedirectPort", this.httpRedirectPort, "http.redirectPort",
                                "[HTTP configuration] cannot set redirect port : " + this.httpRedirectPort);
                    }
                    if (this.httpCompression != null) {
                        invokeMethod(http, "setCompression", this.httpCompression, "http.compression",
                                "[HTTP configuration] cannot set compression : " + this.httpCompression);
                    }
                    if (this.httpMaxKeepAliveRequest != null) {
                        invokeMethod(http, "setMaxKeepAliveRequest", this.httpMaxKeepAliveRequest, "http.maxKeepAliveRequest",
                                "[HTTP configuration] cannot set max keep alive request : " + this.httpMaxKeepAliveRequest);
                    }
                }
            }

            //create HTTPS connector
            Https https = null;
            if (this.isHttpsActivated) {
                https = (Https) instanciateConnector(Https.class.getName(), this.webContainer);
                if (https != null) {
                    if (this.httpsEnableLookups != null) {
                        invokeMethod(https, "setEnableLookups", String.valueOf(this.httpsEnableLookups), "https.enableLookups",
                                "[HTTPS configuration] cannot set enableLookups property : " + this.httpsEnableLookups);
                    }
                    if (this.httpsAcceptCount != null) {
                        invokeMethod(https, "setAcceptCount", this.httpsAcceptCount, "https.acceptCount",
                                "[HTTPS configuration] cannot set accept count : " + this.httpsAcceptCount);
                    }
                    if (this.httpsConnectionTimeout != null) {
                        invokeMethod(https, "setConnectionTimeout", this.httpsConnectionTimeout, "https.connectionTimeout",
                                "[HTTPS configuration] cannot set connection timeout to: " + this.httpsConnectionTimeout);
                    }
                    if (this.httpsMaxThreads != null) {
                        invokeMethod(https, "setMaxThreads", this.httpsMaxThreads, "https.maxThreads",
                                "[HTTPS configuration] cannot set max threads ; " + this.httpsMaxThreads);
                    }
                    if (this.httpsMinSpareThreads != null) {
                        invokeMethod(https, "setMinSpareThreads", this.httpsMinSpareThreads, "https.minSpareThreads",
                                "[HTTPS configuration] cannot set min spare threads : " + this.httpsMinSpareThreads);
                    }
                    if (this.httpsPort != null) {
                        invokeMethod(https, "setPort", this.httpsPort, "https.port", "[HTTPS configuration] cannot set port : " +
                                this.httpsPort);
                    }
                    if (this.httpsRedirectPort != null) {
                        invokeMethod(https, "setRedirectPort", this.httpsRedirectPort, "https.redirectPort",
                                "[HTTPS configuration] cannot set redirect port : " + this.httpsRedirectPort);
                    }
                    if (this.httpsCompression != null) {
                        invokeMethod(https, "setCompression", this.httpsCompression, "https.compression",
                                "[HTTPS configuration] cannot set compression : " + this.httpsCompression);
                    }
                    if (this.httpsMaxKeepAliveRequest != null) {
                        invokeMethod(https, "setMaxKeepAliveRequest", this.httpsMaxKeepAliveRequest, "https.maxKeepAliveRequest",
                                "[HTTPS configuration] cannot set max keep alive request : " + this.httpsMaxKeepAliveRequest);
                    }
                    if (this.httpsKeystoreFile != null) {
                        invokeMethod(https, "setKeystoreFile", this.httpsKeystoreFile, "https.keyStoreFile",
                                "[HTTPS configuration] cannot set keystore file : " + this.httpsKeystoreFile);
                    }
                    if (this.httpsKeystorePass != null) {
                        invokeMethod(https, "setKeystorePass", this.httpsKeystorePass, "https.keyStorePass",
                                "[HTTPS configuration] cannot set keystore pass : " + this.httpsKeystorePass);
                    }
                }
            }

            SessionReplication sessionReplication = null;
            if (this.isHttpReplicationActivated) {
                sessionReplication = new SessionReplication();
                if (this.sessionReplicationAlgorithm != null) {
                    sessionReplication.setAlgorithm(this.sessionReplicationAlgorithm);
                }
                if (this.sessionReplicationClusterName != null) {
                    sessionReplication.setName(this.sessionReplicationClusterName);
                }
                if (this.sessionReplicationMulticastAddress != null) {
                    sessionReplication.setMcastAddr(this.sessionReplicationMulticastAddress);
                }
                if (this.sessionReplicationMulticastPort != null) {
                    sessionReplication.setMcastPort(this.sessionReplicationMulticastPort);
                }
                if (this.sessionReplicationListenPort != null) {
                    sessionReplication.setListenPort(this.sessionReplicationListenPort);
                }
            }

            TomcatSessionManager tomcatSessionManager = null;
            if (this.isHttpSessionManagerActivated) {
                tomcatSessionManager = new TomcatSessionManager();
                if (this.maxActiveSession != null) {
                    tomcatSessionManager.setMaxActiveSessions(this.maxActiveSession);
                }
            }

            //instanciate webcontainer Connectors object
            Connectors connectors = null;
            Method connectorsMethod = null;
            for (Method method : webContainer.getClass().getMethods()) {
                if (method.getName().equals("addConfiguredConnectors") && method.getParameterTypes().length == 1) {
                    try {
                        connectors = (Connectors) method.getParameterTypes()[0].newInstance();
                        connectors.setProject(this.project);
                        connectors.setSkipOptionalDeployablesCopy(true);
                    } catch (Exception e) {
                        throw new IllegalStateException("Cannot generate Web connector to configure", e);
                    }
                    connectorsMethod = method;
                    break;
                }
            }
            if (connectors == null) {
                throw new IllegalStateException("Cannot find method for adding configured Web connector");
            }

            //addition of all connector to the Connectors object
            if (http != null) {
                invokeMethod(connectors, "addConfiguredHttp", http, "web.connectors.http",
                        "[Web container] cannot add configured Web HTTP connector");
            }
            if (https != null) {
                invokeMethod(connectors, "addConfiguredHttps", https, "web.connectors.https",
                        "[Web container] cannot add configured Web HTTPS connector");
            }
            if (ajp != null) {
                invokeMethod(connectors, "addConfiguredAjp", ajp, "web.connectors.ajp",
                        "[Web container] cannot add configured Web AJP connector");
            }

            //addition of Connectors object to the WebContainer
            try {
                connectorsMethod.invoke(webContainer, connectors);
            } catch (Exception e) {
                throw new IllegalStateException("Cannot add configured Web connector", e);
            }

            //addition of session manager to the webcontainer
            if (tomcatSessionManager != null) {
                invokeMethod(webContainer, "addConfiguredSessionManager", tomcatSessionManager, "web.sessionManager",
                        "[Web container] cannot add configured Web session manager");
            }

            //addition of session replication object to the webContainer
            if (sessionReplication != null) {
                invokeMethod(webContainer, "addConfiguredSessionReplication", sessionReplication, "web.sessionReplication",
                        "[Web container] cannot add configured Web session replication");
            }

            //execute the webcontainer task
            webContainer.execute();
        }

        if (!this.isProtocolsListSet) {
            this.carol.setProtocols("jrmp");
        }
        this.carol.execute();

        if (this.db != null) {
            this.db.execute();
        }

        //TODO to be able to configure each discovery service
        if (this.discovery != null) {
            this.discovery.execute();
        }

        if (this.smartClient != null) {
            this.smartClient.execute();
        } 

        boolean first = true;
        for (JdbcXml jdbcXml : this.jdbcXmlList) {
            
            // The JdbcXml task will write all DS definitions to a single file
            // called JONAS_BASE/deploy/jdbc-ds.xml
            //
            // Since the file does not exist at the first call, we need to set
            // it as "new file"; after we tell JdbcXml to merge
            jdbcXml.setNewFile(Boolean.toString(first));
            jdbcXml.execute();
            first = false;
        }

        if (this.jms != null) {
            this.jms.execute();
        }

        for (User admin: admins) {
            this.security.addConfiguredAdmin(admin);
        }
        for (User user: users) {
            this.security.addConfiguredUser(user);
        }
        this.security.execute();

        for (Mail mail: this.mails) {
            mail.execute();
        }

        if (this.wsdlPublisherFile != null) {
            this.wsdlPublish = new WsdlPublish();
            this.wsdlPublish.setProject(this.project);
            this.wsdlPublish.addConfiguredFile(this.wsdlPublisherFile);
            this.wsdlPublish.execute();
        }

        if (this.wrapper != null) {
            this.wrapper.execute();
        }
    }

    /* --------------------------------- */
    /* Cluster daemon configuration part */

    /**
     * Initialize ClusterDaemon if not set
     */
    private void initClusterDaemon() {
        if (this.clusterDaemon == null) {
            this.clusterDaemon = new ClusterDaemon();
            this.clusterDaemon.setProject(this.project);
        }
    }

    /**
     * {@inheritDoc}
     */
    public void setCDClusterName(final String clusterName) {
        Jonas53.logger.finest("[Cluster daemon configuration] setting cluster name : " + clusterName);
        initClusterDaemon();
        this.clusterDaemon.setName(clusterName);
    }

    /**
     * {@inheritDoc}
     */
    public void setCDClusterDomain(final String clusterDomain) {
        Jonas53.logger.finest("[Cluster daemon configuration] setting cluster domain name : " + clusterDomain);
        initClusterDaemon();
        this.clusterDaemon.setDomainName(clusterDomain);
    }

    /**
     * {@inheritDoc}
     */
    public void setCDProtocol(final String protocol) {
        Jonas53.logger.finest("[Cluster daemon configuration] setting protocol : " + protocol);
        NotApplicableHelper.notApplicable("clusterdaemon.protocol");
    }

    /**
     * {@inheritDoc}
     */
    public void setCDPort(final String port) {
        Jonas53.logger.finest("[Cluster daemon configuration] setting port : " + port);
        NotApplicableHelper.notApplicable("clusterdaemon.port");
    }

    /**
     * {@inheritDoc}
     */
    public void setCDDestDirPrefix(final String destDirPrefix) {
        Jonas53.logger.finest("[Cluster daemon configuration] setting dest dir prefix : " + destDirPrefix);
        initClusterDaemon();
        this.clusterDaemon.setDestDirPrefix(destDirPrefix);
        this.clusterDaemon.setCdDir(destDirPrefix);
        this.project.setProperty("jonas.base", destDirPrefix);
    }

    /**
     * {@inheritDoc}
     */
    public void setCDInteractionMode(final String interactionMode) {
        Jonas53.logger.finest("[Cluster daemon configuration] setting interaction mode : " + interactionMode);
        initClusterDaemon();
        this.clusterDaemon.setInteractionMode(interactionMode);
    }

    /**
     * {@inheritDoc}
     */
    public void setCDJavaHome(final String javaHome) {
        Jonas53.logger.finest("[Cluster daemon configuration] setting java home : " + javaHome);
        initClusterDaemon();
        this.clusterDaemon.setJdk(javaHome);
    }

    /**
     * {@inheritDoc}
     */
    public void setCDJonasRoot(final String jonasRoot) {
        Jonas53.logger.finest("[Cluster daemon configuration] setting jonas root : " + jonasRoot);
        NotApplicableHelper.notApplicable("jonas.root");
    }

    /**
     * {@inheritDoc}
     */
    public void setCDServerNamePrefix(final String serverNamePrefix) {
        Jonas53.logger.finest("[Cluster daemon configuration] setting server name prefix : " + serverNamePrefix);
        initClusterDaemon();
        this.clusterDaemon.setClusterNodesName(serverNamePrefix);
    }

    /**
     * {@inheritDoc}
     */
    public void setCDXparam(final String xparam) {
        Jonas53.logger.finest("[Cluster daemon configuration] setting xparam : " + xparam);
        initClusterDaemon();
        this.clusterDaemon.setXprm(xparam);
    }

    /**
     * {@inheritDoc}
     */
    public void setCDAutoBoot(final boolean autoBoot) {
        Jonas53.logger.finest("[Cluster daemon configuration] setting auto boot : " + autoBoot);
        initClusterDaemon();
        this.clusterDaemon.setAutoBoot(new Boolean(autoBoot).toString());
    }

    /**
     * {@inheritDoc}
     */
    public void setCDNbInstances(final int nbInsts) {
        Jonas53.logger.finest("[Cluster daemon configuration] setting nb instance : " + nbInsts);
        initClusterDaemon();
        this.clusterDaemon.setInstNb(nbInsts);
    }

    /**
     * {@inheritDoc}
     */
    public void setCDJOnASScript(final String jonasScript) {
        Jonas53.logger.finest("[Cluster daemon configuration] setting jonas script : " + jonasScript);
        initClusterDaemon();
        this.clusterDaemon.setJonasScript(jonasScript);
    }

    /**
     * {@inheritDoc}
     */
    public void executeCDConf() {
        if (this.clusterDaemon != null) {
            this.clusterDaemon.execute();
        }
    }
    /* --------------------------------- */

    /**
     * {@inheritDoc}
     */
    public void setWrapperConfiguration(final String javaHome, final String wrapperHome, final String serviceName,
                                        final String serviceDescription, final Boolean verbosity, final String logfile,
                                        final String logfileRollmode) {
        File wrapperDir = null;
        if (wrapperHome != null) {
            wrapperDir = new File(wrapperHome);
        }
        if (wrapperDir == null || !wrapperDir.exists()) {
            wrapperDir = new File(this.project.getProperty("jonas.root") + File.separator + "wrapper");
        }

        //locate wrapper ANT task
        File wrapperAntTaskFile = new File(wrapperDir + File.separator + "lib" + File.separator + "ant" + File.separator
                + "ow2_jonas_wrapper_ant.jar");
        if (!wrapperAntTaskFile.exists()) {
            Jonas53.logger.finest("Wrapper home is incorrect. Cannot find Wrapper ANT task");
            NotApplicableHelper.notApplicable("wrapper.home");
        } else {
            URL wrapperAntTask = null;
            try {
                wrapperAntTask = wrapperAntTaskFile.toURI().toURL();
            } catch (MalformedURLException e) {
                Jonas53.logger.severe("Cannot get the URL of the file " + wrapperAntTaskFile.getAbsolutePath());
            }

            if (wrapperAntTask != null) {
                ClassLoader classLoader = new URLClassLoader(new URL[] {wrapperAntTask}, this.getClass().getClassLoader());
                Class<? extends JOnASWrapper> clazz = null;
                try {
                    clazz = classLoader.loadClass(JOnASWrapper.class.getName()).asSubclass(JOnASWrapper.class);
                } catch (ClassNotFoundException e) {
                    Jonas53.logger.severe("Cannot found class " + JOnASWrapper.class.getName());
                }
                try {
                    this.wrapper = clazz.newInstance();
                } catch (InstantiationException e) {
                    Jonas53.logger.severe("Cannot instanciate " + Jonas53.class.getName());
                } catch (IllegalAccessException e) {
                    Jonas53.logger.severe("Cannot instanciate " + Jonas53.class.getName());
                }
                if (this.wrapper != null) {
                    this.wrapper.setProject(this.project);
                    if (javaHome != null) {
                        this.wrapper.setJavaHome(javaHome);
                    }
                    if (wrapperHome != null) {
                        this.wrapper.setWrapperHome(wrapperHome);
                    }
                    if (serviceName != null) {
                        this.wrapper.setServiceName(serviceName);
                    }
                    if (serviceDescription != null) {
                        this.wrapper.setServiceDescription(serviceDescription);
                    }
                    if (verbosity != null) {
                        this.wrapper.setVerbosity(verbosity);
                    }
                    if (logfile != null) {
                        this.wrapper.setLogfile(logfile);
                    }
                    if (logfileRollmode != null) {
                        this.wrapper.setLogfileRollmode(logfileRollmode);
                    }
                }
            }
        }
    }


    /**
     * Gets all classes in a given URLClassLoader that are children of a given class or interface.
     * @param urlCL URLClassLoader to scan.
     * @param parent Parent class or interface that returned classes should implement.
     * @return All classes in <code>urlCl</code> that are children of class or interface <code>parent</code>.
     * @throws IOException If the URLClassLoader cannot be read.
     * @throws URISyntaxException If the URLClassLoader cannot be read.
     * @throws ClassNotFoundException If class or interface <code>parent</code> cannot be loaded.
     */
    private SortedSet<String> getAllClasses(URLClassLoader urlCL, String parent)
        throws IOException, URISyntaxException, ClassNotFoundException {

        SortedSet<String> classes = new TreeSet<String>();

        Class<?> parentClass;
        try {
            parentClass = urlCL.loadClass(parent);
        } catch (ClassNotFoundException e) {
            throw new IllegalArgumentException("Class " + parent + " not found in " + urlCL);
        }

        for (URL url : urlCL.getURLs()) {
            classes.addAll(getAllClasses(url, urlCL, parentClass));
        }

        return classes;
    }

    /**
     * Gets all classes in a given JAR file or a URLClassLoader that are children of a given class or interface.
     * @param jarUrl JAR file's URL.
     * @param urlCL URLClassLoader to scan.
     * @param parentClass Parent class or interface that returned classes should implement.
     * @return All classes in <code>jar</code> that are member of <code>urlCl</code> that are children of class or interface
     * <code>parent</code>.
     * @throws IOException If the JAR file cannot be read.
     * @throws URISyntaxException If the JAR file cannot be read.
     * @throws ClassNotFoundException If class or interface <code>parent</code> cannot be loaded.
     */
    private SortedSet<String> getAllClasses(URL jarUrl, URLClassLoader urlCL, Class<?> parentClass)
        throws IOException, URISyntaxException, ClassNotFoundException {

        SortedSet<String> classes = new TreeSet<String>();

        File jarFile = new File(jarUrl.toURI());
        if (!jarFile.isFile()) {
            return classes;
        }

        JarFile jar = new JarFile(jarFile);
        Enumeration<JarEntry> entries = jar.entries();
        while (entries.hasMoreElements()) {
            JarEntry entry = entries.nextElement();
            String entryName = entry.getName();
            if (entryName.endsWith(".class") && !entryName.contains("$")) {
                entryName = entryName.substring(0, entryName.length() - 6);
                entryName = entryName.replace('/', '.');
                entryName = entryName.replace('\\', '.');

                Class<?> entryClass;
                try {
                    entryClass = urlCL.loadClass(entryName);
                } catch (NoClassDefFoundError ignored) {
                    continue;
                }
                if (!entryClass.isInterface() && ! Modifier.isAbstract(entryClass.getModifiers())
                    && parentClass.isAssignableFrom(entryClass)) {

                    classes.add(entryName);
                }
            }
        }

        return classes;
    }

    /**
     * Generic method in order to invoke a method
     * @param object The object which contains the method to invoke
     * @param methodToInvoke Name of the method to invoke
     * @param parameter The parameter of the method to invoke.
     * @param notApplicableLog Log if no such method is defined in the given object class
     * @param invocationExceptionLog Log if the method invocation failed
     */
    private void invokeMethod(final Object object, final String methodToInvoke,
                              final Object parameter, final String notApplicableLog,
                              final String invocationExceptionLog) {
        List<Object> parameters = new ArrayList<Object>();
        parameters.add(parameter);
        invokeMethod(object, methodToInvoke, parameters, notApplicableLog, invocationExceptionLog);
    }

    /**
     * Generic method in order to invoke a method
     * @param object The object which contains the method to invoke
     * @param methodToInvoke Name of the method to invoke
     * @param parameters  List of parameters of the method to invoke.
     * @param notApplicableLog Log if no such method is defined in the given object class
     * @param invocationExceptionLog Log if the method invocation failed
     */
    private void invokeMethod(final Object object, final String methodToInvoke,
                              final List<Object> parameters, final String notApplicableLog,
                              final String invocationExceptionLog) {
        if (object == null) {
            throw new IllegalArgumentException("'object' parameter shouldn't be null");
        }
        if (parameters == null) {
            throw new IllegalArgumentException("'parameters' parameter shouldn't be null");
        }

        List<Class<?>> parametersClass = new ArrayList<Class<?>>();
        for (Object parameter: parameters) {
            parametersClass.add(parameter.getClass());
        } 
        Method method = null;
        try {
            method = object.getClass().getMethod(methodToInvoke, parametersClass.toArray(new Class<?>[parametersClass.size()]));
        } catch (NoSuchMethodException e) {
            NotApplicableHelper.notApplicable(notApplicableLog);
        }
        if (method != null) {
            try {
                method.invoke(object, parameters.toArray(new Object[parameters.size()]));
            } catch (Exception e) {
                throw new IllegalArgumentException(invocationExceptionLog, e);
            }
        }
    }

    /**
     * Instanciate a connector (HTTP, HTTPS, AJP) according to the webcontainer implementation
     * @param connectorClassName Name of the generic connector class 
     * @param webContainer Name of the webcontainer implementation
     * @return the instance of a connector
     */
    private Object instanciateConnector(final String connectorClassName, final String webContainer) {
        try {
            //try to find a connector classname with a name equals to ${connector.name} + ${webcontainer.name}
            SortedSet<String> classesName = getAllClasses((URLClassLoader) this.getClass().getClassLoader(), connectorClassName);
            for (String className: classesName) {
                if (className.contains(webContainer)) {
                    return this.getClass().getClassLoader().loadClass(className).newInstance();
                }
            }

            //try to find a connector classname with a name equals to ${connector.name} + ${webcontainer.nameWithoutVersions}
            String webContainerWitoutVersion =  webContainer.trim(); 
            while (Character.isDigit(webContainerWitoutVersion.charAt(webContainerWitoutVersion.length() - 1))) {
                webContainerWitoutVersion = webContainerWitoutVersion.substring(0, webContainerWitoutVersion.length() - 1);
            }
            for (String className: classesName) {
                if (className.contains(webContainerWitoutVersion)) {
                    return this.getClass().getClassLoader().loadClass(className).newInstance();
                }
            }

            //nothing found...so just return a super instance of the connector
            return this.getClass().getClassLoader().loadClass(connectorClassName).newInstance();

        } catch (Exception e) {
            throw new IllegalStateException("Cannot create an AJP connector", e);
        }
    }
}