[jboss-cvs] JBossAS SVN: r87115 - in projects/bootstrap/trunk/spi/src: main/java/org/jboss/bootstrap/spi/config and 5 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Fri Apr 10 06:26:16 EDT 2009


Author: ALRubinger
Date: 2009-04-10 06:26:15 -0400 (Fri, 10 Apr 2009)
New Revision: 87115

Added:
   projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/Bootstrap.java
   projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/config/AbstractBasicConfigurationValidator.java
   projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/config/ConfigurationValidator.java
   projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/server/AbstractBasicServerInitializer.java
   projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/server/ServerInitializer.java
   projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/
   projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/ConfigInitializationTestCase.java
   projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/ConfigValidationTestCase.java
   projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/Counter.java
   projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/CountingConfigurationValidator.java
   projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/CountingServerInitializer.java
   projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/TestConfigFactory.java
   projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/TestConfigurationValidator.java
   projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/TestNoOpServer.java
   projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/TestServerConfig.java
   projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/TestServerInitializer.java
Removed:
   projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/server/
Modified:
   projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/config/AbstractBasicServerConfig.java
   projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/config/ServerConfig.java
   projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/lifecycle/LifecycleState.java
   projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/server/AbstractServer.java
   projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/server/Server.java
   projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/xml/BootstrapSchemaBinding.java
Log:
[JBBOOT-26] Make pluggable validator, initializer, and put the bootstrap parsing in place

Copied: projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/Bootstrap.java (from rev 87082, projects/bootstrap/trunk/legacy/src/main/java/org/jboss/bootstrap/spi/Bootstrap.java)
===================================================================
--- projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/Bootstrap.java	                        (rev 0)
+++ projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/Bootstrap.java	2009-04-10 10:26:15 UTC (rev 87115)
@@ -0,0 +1,56 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This 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 (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.bootstrap.spi;
+
+import org.jboss.bootstrap.spi.config.ServerConfig;
+import org.jboss.bootstrap.spi.server.Server;
+
+/**
+ * Bootstrap
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public interface Bootstrap
+{
+   /**
+    * Invoked at startup
+    * 
+    * @param server the server instance
+    * @throws Exception for any error
+    */
+   <K extends Server<K, T>, T extends ServerConfig<T>> void start(Server<K, T> server) throws Exception;
+
+   /**
+    * Invoked to say we are preparing shutdown
+    * 
+    * @param server the server
+    */
+   <K extends Server<K, T>, T extends ServerConfig<T>> void prepareShutdown(Server<K, T> server);
+
+   /**
+    * Invoked at shutdown
+    * 
+    * @param server the server instance
+    */
+   <K extends Server<K, T>, T extends ServerConfig<T>> void shutdown(Server<K, T> server);
+}


Property changes on: projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/Bootstrap.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Added: projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/config/AbstractBasicConfigurationValidator.java
===================================================================
--- projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/config/AbstractBasicConfigurationValidator.java	                        (rev 0)
+++ projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/config/AbstractBasicConfigurationValidator.java	2009-04-10 10:26:15 UTC (rev 87115)
@@ -0,0 +1,102 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This 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 (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.bootstrap.spi.config;
+
+import java.net.URL;
+
+import org.jboss.logging.Logger;
+
+/**
+ * AbstractBasicConfigurationValidator
+ * 
+ * Base for validating a server configuration to assert that
+ * it's valid for defining a server 
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public abstract class AbstractBasicConfigurationValidator<T extends ServerConfig<T>>
+      implements
+         ConfigurationValidator<T>
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   private static final Logger log = Logger.getLogger(AbstractBasicConfigurationValidator.class);
+
+   //-------------------------------------------------------------------------------------||
+   // Required Implementations -----------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /* (non-Javadoc)
+    * @see org.jboss.bootstrap.spi.config.ConfigurationValidator#validate(org.jboss.bootstrap.spi.config.ServerConfig)
+    */
+   public void validate(final T config) throws InvalidConfigurationException
+   {
+      // Log
+      if (log.isTraceEnabled())
+      {
+         log.trace("Validating configuration: " + config);
+      }
+
+      // Precondition check
+      if (config == null)
+      {
+         throw new IllegalArgumentException("Configuration is required, but was not supplied");
+      }
+
+      // Get properties
+      final String name = config.getBootstrapName();
+      final URL home = config.getBootstrapHome();
+      final URL direct = config.getBootstrapUrl();
+      final URL conf = config.getBootstrapConfLocation();
+
+      // If no direct bootstrap URL
+      if (direct == null)
+      {
+         // Ensure we may construct this via home+name
+         if (home == null || (name == null || name.length() == 0))
+         {
+            throw new InvalidConfigurationException(
+                  "If the bootstrap URL is not specified, both the bootstrap home and name must be.");
+         }
+      }
+
+      // If no conf
+      if (conf == null)
+      {
+         // Ensure we may construct this from home
+         if (home == null)
+         {
+            throw new InvalidConfigurationException("Bootstrap configuration location must be specified explicity, "
+                  + "or a home must be provided such that it may be constructed");
+         }
+      }
+
+      // Log
+      log.debug("Configuration passed on: " + config);
+   }
+
+}

Modified: projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/config/AbstractBasicServerConfig.java
===================================================================
--- projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/config/AbstractBasicServerConfig.java	2009-04-10 09:16:00 UTC (rev 87114)
+++ projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/config/AbstractBasicServerConfig.java	2009-04-10 10:26:15 UTC (rev 87115)
@@ -22,19 +22,24 @@
 
 package org.jboss.bootstrap.spi.config;
 
+import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.jboss.logging.Logger;
 
 /**
  * BasicServerConfig
  * 
- * Base for simple Object-backed implementations of a Server Configuration
+ * Base for simple Object-backed implementations of a Server 
+ * Configuration.  As this is exported from the Server, this 
+ * is Thread-safe.
  *
  * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
  * @version $Revision: $
@@ -52,21 +57,50 @@
    // Instance Members -------------------------------------------------------------------||
    //-------------------------------------------------------------------------------------||
 
+   /**
+    * Actual class used in casting for covarient return in
+    * method chaining.  Synchronized on "this".
+    */
    private Class<T> actualClass;
 
+   /**
+    * URL of the bootstrap to run.  Synchronized on
+    * "this".   Must
+    * not be exported (so copy on return).
+    */
    private URL bootstrapUrl;
 
+   /**
+    * Bootstrap configuration home (URLs referenced in the 
+    * main bootstrap are relative to this URL).
+    * Synchronized on "this".  Must
+    * not be exported (so copy on return).
+    */
    private URL bootstrapConfLocation;
 
+   /**
+    * Bootstrap home, used in defaulting/construction
+    * of other properties.  Synchronized on "this".  Must
+    * not be exported (so copy on return).
+    */
    private URL bootstrapHome;
 
-   private URL bootstrapLibLocation;
-
+   /**
+    * Name of the bootstrap file.  Synchronized on
+    * "this".
+    */
    private String bootstrapName;
 
-   private Map<String, String> properties;
+   /**
+    * Properties for this configuration.  Must be backed
+    * by a Thread-safe impl.
+    */
+   private ConcurrentMap<String, String> properties;
 
-   private boolean frozen;
+   /**
+    * Whether or not this configuration is frozen
+    */
+   private AtomicBoolean frozen;
 
    //-------------------------------------------------------------------------------------||
    // Constructor ------------------------------------------------------------------------||
@@ -98,7 +132,7 @@
        * Initialize properties
        */
       Properties sysProps = System.getProperties();
-      Map<String, String> properties = new HashMap<String, String>();
+      ConcurrentMap<String, String> properties = new ConcurrentHashMap<String, String>();
       Set<Object> sysPropKeys = sysProps.keySet();
       for (Object sysPropKey : sysPropKeys)
       {
@@ -120,7 +154,11 @@
        * Set properties
        */
       this.properties = properties;
-      this.actualClass = actualClass;
+      synchronized (this)
+      {
+         this.actualClass = actualClass;
+      }
+      this.frozen = new AtomicBoolean(false);
    }
 
    //-------------------------------------------------------------------------------------||
@@ -132,7 +170,12 @@
     */
    public URL getBootstrapConfLocation()
    {
-      return this.bootstrapConfLocation;
+      URL url = null;
+      synchronized (this)
+      {
+         url = this.bootstrapConfLocation;
+      }
+      return this.copyURL(url);
    }
 
    /* (non-Javadoc)
@@ -140,21 +183,18 @@
     */
    public URL getBootstrapHome()
    {
-      return this.bootstrapHome;
+      URL url = null;
+      synchronized (this)
+      {
+         url = this.bootstrapHome;
+      }
+      return this.copyURL(url);
    }
 
    /* (non-Javadoc)
-    * @see org.jboss.bootstrap.spi.config.ServerConfig#getBootstrapLibLocation()
-    */
-   public URL getBootstrapLibLocation()
-   {
-      return this.bootstrapLibLocation;
-   }
-
-   /* (non-Javadoc)
     * @see org.jboss.bootstrap.spi.config.ServerConfig#getBootstrapName()
     */
-   public String getBootstrapName()
+   public synchronized String getBootstrapName()
    {
       return this.bootstrapName;
    }
@@ -164,7 +204,12 @@
     */
    public URL getBootstrapUrl()
    {
-      return this.bootstrapUrl;
+      URL url = null;
+      synchronized (this)
+      {
+         url = this.bootstrapUrl;
+      }
+      return this.copyURL(url);
    }
 
    /* (non-Javadoc)
@@ -178,7 +223,7 @@
    /* (non-Javadoc)
     * @see org.jboss.bootstrap.spi.config.ServerConfig#setBootstrapConfLocation(java.net.URL)
     */
-   public T setBootstrapConfLocation(final URL confLocation) throws IllegalArgumentException
+   public synchronized T setBootstrapConfLocation(final URL confLocation) throws IllegalArgumentException
    {
       // Precondition check
       this.checkMutable();
@@ -196,7 +241,7 @@
    /* (non-Javadoc)
     * @see org.jboss.bootstrap.spi.config.ServerConfig#setBootstrapHome(java.net.URL)
     */
-   public T setBootstrapHome(final URL bootstrapHome) throws IllegalArgumentException
+   public synchronized T setBootstrapHome(final URL bootstrapHome) throws IllegalArgumentException
    {
       // Precondition check
       this.checkMutable();
@@ -212,27 +257,9 @@
    }
 
    /* (non-Javadoc)
-    * @see org.jboss.bootstrap.spi.config.ServerConfig#setBootstrapLibLocation(java.net.URL)
-    */
-   public T setBootstrapLibLocation(final URL libLocation) throws IllegalArgumentException
-   {
-      // Precondition check
-      this.checkMutable();
-
-      // Set property
-      this.setPropertyForUrl(PROP_KEY_BOOTSTRAP_LIB_URL, libLocation);
-
-      // Set URL
-      this.bootstrapLibLocation = libLocation;
-
-      // Return
-      return this.covarientReturn();
-   }
-
-   /* (non-Javadoc)
     * @see org.jboss.bootstrap.spi.config.ServerConfig#setBootstrapName(java.lang.String)
     */
-   public T setBootstrapName(final String name) throws IllegalArgumentException
+   public synchronized T setBootstrapName(final String name) throws IllegalArgumentException
    {
       // Precondition check
       this.checkMutable();
@@ -250,7 +277,7 @@
    /* (non-Javadoc)
     * @see org.jboss.bootstrap.spi.config.ServerConfig#setBootstrapUrl(java.net.URL)
     */
-   public T setBootstrapUrl(final URL bootstrapLocation) throws IllegalArgumentException
+   public synchronized T setBootstrapUrl(final URL bootstrapLocation) throws IllegalArgumentException
    {
       // Precondition check
       this.checkMutable();
@@ -285,7 +312,7 @@
     */
    public void freeze() throws IllegalStateException
    {
-      this.frozen = true;
+      this.frozen.set(true);
    }
 
    /* (non-Javadoc)
@@ -293,7 +320,7 @@
     */
    public boolean isFrozen()
    {
-      return this.frozen;
+      return this.frozen.get();
    }
 
    //-------------------------------------------------------------------------------------||
@@ -317,10 +344,15 @@
    protected void setPropertyForString(final String propertyName, final String value)
    {
       Map<String, String> properties = this.properties;
-      properties.put(propertyName, value);
+      String valueToSet = value;
+      if (valueToSet == null)
+      {
+         valueToSet = "";
+      }
+      properties.put(propertyName, valueToSet);
       if (log.isTraceEnabled())
       {
-         log.trace(("Set property \"" + propertyName + "\" to: ") + (value != null ? "\"" + value + "\"" : "[NULL]"));
+         log.trace(("Set property \"" + propertyName + "\" to: ") + (value != null ? "\"" + value + "\"" : "[EMPTY]"));
       }
    }
 
@@ -369,4 +401,30 @@
                cce);
       }
    }
+
+   /**
+    * Copies and returns the specified URL.  Used
+    * to ensure we don't export mutable URLs (thread safety) 
+    * 
+    * @param url
+    * @return
+    */
+   private URL copyURL(final URL url)
+   {
+      // If null, return
+      if (url == null)
+      {
+         return url;
+      }
+
+      try
+      {
+         // Copy 
+         return new URL(url.toExternalForm());
+      }
+      catch (MalformedURLException e)
+      {
+         throw new RuntimeException("Error in copying URL", e);
+      }
+   }
 }

Added: projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/config/ConfigurationValidator.java
===================================================================
--- projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/config/ConfigurationValidator.java	                        (rev 0)
+++ projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/config/ConfigurationValidator.java	2009-04-10 10:26:15 UTC (rev 87115)
@@ -0,0 +1,42 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This 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 (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.bootstrap.spi.config;
+
+/**
+ * ConfigurationValidator
+ * 
+ * Contract for validators of a supplied ServerConfig
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public interface ConfigurationValidator<T extends ServerConfig<?>>
+{
+   /**
+    * Validates the specified configuration
+    * 
+    * @param config
+    * @throws InvalidConfigurationException
+    */
+   void validate(T config) throws InvalidConfigurationException;
+}

Modified: projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/config/ServerConfig.java
===================================================================
--- projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/config/ServerConfig.java	2009-04-10 09:16:00 UTC (rev 87114)
+++ projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/config/ServerConfig.java	2009-04-10 10:26:15 UTC (rev 87115)
@@ -51,11 +51,6 @@
    String PROP_KEY_BOOTSTRAP_CONF_URL = "jboss.bootstrap.conf.url";
 
    /**
-    * Property denoting the URL of the lib directory
-    */
-   String PROP_KEY_BOOTSTRAP_LIB_URL = "jboss.bootstrap.lib.url";
-
-   /**
     * Property denoting the name of the bootstrap configuration
     */
    String PROP_KEY_BOOTSTRAP_NAME = "jboss.bootstrap.name";
@@ -86,7 +81,7 @@
     * @throws IllegalArgumentException If the bootstrap home location was not specified
     * @throws IllegalStateException If the configuration has been frozen
     */
-   ServerConfig<T> setBootstrapHome(URL bootstrapHome) throws IllegalArgumentException, IllegalStateException;
+   T setBootstrapHome(URL bootstrapHome) throws IllegalArgumentException, IllegalStateException;
 
    /**
     * Obtains the location of the bootstrap file.  This will mirror the 
@@ -105,7 +100,7 @@
     * @throws IllegalArgumentException If the location was not specified
     * @throws IllegalStateException If the configuration has been frozen
     */
-   ServerConfig<T> setBootstrapUrl(URL bootstrapLocation) throws IllegalArgumentException, IllegalStateException;
+   T setBootstrapUrl(URL bootstrapLocation) throws IllegalArgumentException, IllegalStateException;
 
    /**
     * Obtains the name of the bootstrap configuration.  This will
@@ -124,7 +119,7 @@
     * @throws IllegalArgumentException If the name was not specified
     * @throws IllegalStateException If the configuration has been frozen
     */
-   ServerConfig<T> setBootstrapName(String name) throws IllegalArgumentException, IllegalStateException;
+   T setBootstrapName(String name) throws IllegalArgumentException, IllegalStateException;
 
    /**
     * Obtains the location of the bootstrap configuration location.  This will mirror the 
@@ -143,28 +138,9 @@
     * @throws IllegalArgumentException If the location was not specified
     * @throws IllegalStateException If the configuration has been frozen
     */
-   ServerConfig<T> setBootstrapConfLocation(URL confLocation) throws IllegalArgumentException, IllegalStateException;
+   T setBootstrapConfLocation(URL confLocation) throws IllegalArgumentException, IllegalStateException;
 
    /**
-    * Obtains the location of the bootstrap library location.  This will mirror the 
-    * value of {@link ServerConfig#PROP_KEY_BOOTSTRAP_LIB_URL}.
-    * 
-    * @return
-    */
-   URL getBootstrapLibLocation();
-
-   /**
-    * Sets the name of the bootstrap library location.  Will additionally set
-    * {@link ServerConfig#PROP_KEY_BOOTSTRAP_LIB_URL}.
-    * 
-    * @param libLocation
-    * @return This configuration
-    * @throws IllegalArgumentException If the location was not specified
-    * @throws IllegalStateException If the configuration has been frozen
-    */
-   ServerConfig<T> setBootstrapLibLocation(URL libLocation) throws IllegalArgumentException, IllegalStateException;
-
-   /**
     * Returns an immutable copy of the properties used in configuring the server
     * 
     * @return
@@ -180,7 +156,7 @@
     * @throws IllegalArgumentException If the key was not supplied
     * @throws IllegalStateException If the configuration has been frozen
     */
-   ServerConfig<T> setProperty(String key, String value) throws IllegalArgumentException, IllegalStateException;
+   T setProperty(String key, String value) throws IllegalArgumentException, IllegalStateException;
 
    /**
     * Freezes the configuration, marking it as immutable.  Will typically 

Modified: projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/lifecycle/LifecycleState.java
===================================================================
--- projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/lifecycle/LifecycleState.java	2009-04-10 09:16:00 UTC (rev 87114)
+++ projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/lifecycle/LifecycleState.java	2009-04-10 10:26:15 UTC (rev 87115)
@@ -26,6 +26,12 @@
  * LifecycleState
  *
  * Describes current state of the Server lifecycle
+ * 
+ * PREINIT == Instanciated, open to configuration, mutable operations permitted
+ * IDLE == Not yet started, or has stopped.  Awaiting start.
+ * STARTING == In start lifecycle
+ * STARTED == Fully started, in service
+ * STOPPING == In stop lifecycle
  *
  * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
  * @version $Revision: $
@@ -36,5 +42,5 @@
     * Lifecycle States for Servers
     */
 
-   IDLE, STARTING, STARTED, STOPPING
+   PRE_INIT, IDLE, STARTING, STARTED, STOPPING
 }

Added: projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/server/AbstractBasicServerInitializer.java
===================================================================
--- projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/server/AbstractBasicServerInitializer.java	                        (rev 0)
+++ projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/server/AbstractBasicServerInitializer.java	2009-04-10 10:26:15 UTC (rev 87115)
@@ -0,0 +1,237 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This 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 (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.bootstrap.spi.server;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.jboss.bootstrap.spi.config.InvalidConfigurationException;
+import org.jboss.bootstrap.spi.config.ServerConfig;
+import org.jboss.bootstrap.spi.lifecycle.LifecycleState;
+import org.jboss.logging.Logger;
+
+/**
+ * AbstractBasicServerInitializer
+ * 
+ * Simple server initializer which will default the configuration
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public abstract class AbstractBasicServerInitializer<K extends Server<K, T>, T extends ServerConfig<T>>
+      implements
+         ServerInitializer<K, T>
+{
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   private static final Logger log = Logger.getLogger(AbstractBasicServerInitializer.class);
+
+   //-------------------------------------------------------------------------------------||
+   // Required Implementations -----------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /* (non-Javadoc)
+    * @see org.jboss.bootstrap.spi.server.ServerInitializer#initialize(org.jboss.bootstrap.spi.server.Server)
+    */
+   public void initialize(final Server<K, T> server) throws IllegalArgumentException, IllegalStateException
+   {
+      // Log
+      if (log.isTraceEnabled())
+      {
+         log.trace("Request to initialize " + server + " using: " + this);
+      }
+
+      // Precondition checks
+      if (server == null)
+      {
+         throw new IllegalArgumentException("Server must be specified");
+      }
+
+      final LifecycleState state = server.getState();
+      final LifecycleState required = LifecycleState.PRE_INIT;
+      if (!state.equals(required))
+      {
+         throw new IllegalStateException(this + " may only be invoked when " + LifecycleState.class.getSimpleName()
+               + " is " + required + ", was: " + state);
+      }
+
+      // Obtain config
+      final T config = server.getConfiguration();
+
+      /*
+       * Default the config
+       */
+
+      final URL bootstrapUrl = config.getBootstrapUrl();
+      final URL home = config.getBootstrapHome();
+      final URL conf = config.getBootstrapConfLocation();
+      final String name = config.getBootstrapName();
+
+      /*
+       * If bootstrapURL is not directly defined, construct it from
+       * home+name 
+       */
+
+      if (bootstrapUrl == null)
+      {
+         // Log
+         if (log.isTraceEnabled())
+         {
+            log.trace("No bootstrap URL defined, constructing it from home and name...");
+         }
+
+         // Construct
+         assert home != null : "Bootstrap home should not be null, and should have failed validation if so";
+         assert name != null : "Bootstrap name should not be null, and should have failed validation if so";
+         URL newBootstrapUrl = null;
+         try
+         {
+            newBootstrapUrl = new URL(home, name);
+         }
+         catch (MalformedURLException e)
+         {
+            throw new IllegalArgumentException(new InvalidConfigurationException(
+                  "Cannot construct bootstrapURL from home and name", e));
+         }
+
+         // Log
+         if (log.isTraceEnabled())
+         {
+            log.trace("New bootstrap URL: " + newBootstrapUrl.toExternalForm());
+         }
+
+         // Set
+         config.setBootstrapUrl(newBootstrapUrl);
+      }
+
+      /*
+       * If bootstrapConf was not initialized, set it from either home or URL base
+       */
+
+      if (conf == null)
+      {
+         // Make a new conf
+         URL newConf = null;
+
+         // If we've got a home
+         if (home != null)
+         {
+            try
+            {
+               newConf = new URL(home.toExternalForm());
+            }
+            catch (MalformedURLException e)
+            {
+               throw new RuntimeException("Could not default the conf from home", e);
+            }
+         }
+         // If we've got a bootstrapURL
+         else if (bootstrapUrl != null)
+         {
+            try
+            {
+               String bootstrapUrlString = bootstrapUrl.toExternalForm();
+               String bootstrapUrlBase = bootstrapUrlString.substring(0, bootstrapUrlString.lastIndexOf("/") + 1);
+               newConf = new URL(bootstrapUrlBase);
+            }
+            catch (MalformedURLException e)
+            {
+               throw new RuntimeException("Could not default the conf from bootstrapURL base", e);
+            }
+         }
+
+         // Set
+         if (newConf != null)
+         {
+            config.setBootstrapConfLocation(newConf);
+         }
+      }
+
+      // Set System Properties
+      this.setSystemProperties(config);
+
+      // Log
+      log.debug("Initialized " + server + ": " + this);
+
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Functional Methods -----------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Sets system properties from the current configuration; may be overridden to set 
+    * more properties
+    */
+   protected void setSystemProperties(final T configuration)
+   {
+      // Set Properties from Config
+      this.setSystemProperty(ServerConfig.PROP_KEY_BOOTSTRAP_HOME_URL, configuration.getBootstrapHome());
+      this.setSystemProperty(ServerConfig.PROP_KEY_BOOTSTRAP_URL, configuration.getBootstrapUrl());
+      this.setSystemProperty(ServerConfig.PROP_KEY_BOOTSTRAP_CONF_URL, configuration.getBootstrapConfLocation());
+      this.setSystemProperty(ServerConfig.PROP_KEY_BOOTSTRAP_NAME, configuration.getBootstrapName());
+   }
+
+   /**
+    * Sets the specified URL's external form as a system property with the specified key
+    * 
+    * @param key
+    * @param value
+    */
+   protected final void setSystemProperty(final String key, final URL value)
+   {
+      String urlString = value != null ? value.toExternalForm() : "";
+      this.setSystemProperty(key, urlString == null ? null : urlString);
+   }
+
+   /**
+    * Sets the specified system property key to the specified value
+    * 
+    * @param key The non-null key
+    * @param value
+    */
+   protected final void setSystemProperty(final String key, final String value)
+   {
+      // Precondition check
+      assert key != null : "Key for system property was null";
+
+      // Adjust for null
+      String valueToSet = value;
+      if (valueToSet == null)
+      {
+         valueToSet = "";
+      }
+
+      // Set 
+      SecurityActions.setSystemProperty(key, valueToSet);
+
+      // Log
+      if (log.isTraceEnabled())
+      {
+         log.trace(("Set system property \"" + key + "\" to: ")
+               + (value != null ? "\"" + valueToSet + "\"" : "[EMPTY]"));
+      }
+   }
+}

Modified: projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/server/AbstractServer.java
===================================================================
--- projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/server/AbstractServer.java	2009-04-10 09:16:00 UTC (rev 87114)
+++ projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/server/AbstractServer.java	2009-04-10 10:26:15 UTC (rev 87115)
@@ -22,9 +22,11 @@
 
 package org.jboss.bootstrap.spi.server;
 
-import java.net.MalformedURLException;
-import java.net.URL;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
 
+import org.jboss.bootstrap.spi.Bootstrap;
+import org.jboss.bootstrap.spi.config.ConfigurationValidator;
 import org.jboss.bootstrap.spi.config.InvalidConfigurationException;
 import org.jboss.bootstrap.spi.config.ServerConfig;
 import org.jboss.bootstrap.spi.lifecycle.LifecycleState;
@@ -38,7 +40,7 @@
  * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
  * @version $Revision: $
  */
-public abstract class AbstractServer<T extends ServerConfig<?>> implements Server<T>
+public abstract class AbstractServer<K extends Server<K, T>, T extends ServerConfig<T>> implements Server<K, T>
 {
 
    //-------------------------------------------------------------------------------------||
@@ -52,28 +54,62 @@
    //-------------------------------------------------------------------------------------||
 
    /**
-    * Current state of the server
+    * Current state of the server.  Synchronized on "this".
     */
    private LifecycleState state;
 
    /** 
-    * Underlying configuration 
+    * Underlying configuration.  Must be a Thread-safe implementation
+    * as it's exported
     */
    private T configuration;
 
+   /**
+    * Validator for the configuration
+    */
+   private ConfigurationValidator<T> validator;
+
+   /**
+    * Server initializer
+    */
+   private ServerInitializer<K, T> initializer;
+
+   /**
+    * The list of bootstraps to run upon start, requires Thread-safe impl.
+    */
+   private List<Bootstrap> bootstraps;
+
+   /**
+    * The bootstraps that have been started, requires Thread-safe impl.
+    */
+   private List<Bootstrap> startedBootstraps;
+
    //-------------------------------------------------------------------------------------||
    // Constructors -----------------------------------------------------------------------||
    //-------------------------------------------------------------------------------------||
 
    /**
     * Constructor
+    */
+   protected AbstractServer()
+   {
+      this(null);
+   }
+
+   /**
+    * Constructor
     * 
-    * Requires a server configuration in place
+    * @param configuration The configuration to set
     */
-   protected AbstractServer(T configuration) throws IllegalArgumentException, InvalidConfigurationException
+   protected AbstractServer(final T configuration)
    {
       // Check for valid config and set
       this.setConfiguration(configuration);
+
+      // Set properties
+      this.setBootstraps(new CopyOnWriteArrayList<Bootstrap>());
+      this.setStartedBootstraps(new CopyOnWriteArrayList<Bootstrap>());
+      this.setState(LifecycleState.PRE_INIT);
    }
 
    //-------------------------------------------------------------------------------------||
@@ -85,17 +121,33 @@
     */
    public final T getConfiguration()
    {
-      // TODO Auto-generated method stub
       return this.configuration;
    }
 
    /* (non-Javadoc)
+    * @see org.jboss.bootstrap.spi.server.Server#setConfiguration(org.jboss.bootstrap.spi.config.ServerConfig)
+    */
+   public void setConfiguration(final T configuration)
+   {
+      // Log and set
+      if (log.isTraceEnabled())
+      {
+         log.trace("Set configuration: " + configuration);
+      }
+      this.configuration = configuration;
+   }
+
+   /* (non-Javadoc)
     * @see org.jboss.bootstrap.spi.server.Server#getState()
     */
-   public final LifecycleState getState()
+   public final synchronized LifecycleState getState()
    {
-      // TODO Auto-generated method stub
-      return this.state;
+      LifecycleState state = this.state;
+      if (state == null)
+      {
+         throw new IllegalStateException("null state");
+      }
+      return state;
    }
 
    /* (non-Javadoc)
@@ -103,6 +155,12 @@
     */
    public void shutdown() throws IllegalStateException, Exception
    {
+      // Log
+      if (log.isTraceEnabled())
+      {
+         log.trace("Received request to shutdown");
+      }
+
       // Ensure running
       LifecycleState required = LifecycleState.STARTED;
       LifecycleState actual = this.getState();
@@ -110,14 +168,25 @@
 
       // Initiate shutdown sequence
       log.info("Stopping: " + this);
-      this.setLifecycleState(LifecycleState.STOPPING);
+      this.setState(LifecycleState.STOPPING);
 
+      // Shutdown the Bootstraps
+      if (log.isTraceEnabled())
+      {
+         log.trace("Shutting down bootstraps");
+      }
+      this.shutdownBootstraps();
+
       // Shutdown
+      if (log.isTraceEnabled())
+      {
+         log.trace("Calling implementation class shutdown...");
+      }
       this.doShutdown();
 
       // Done
       log.info("Stopped: " + this);
-      this.setLifecycleState(LifecycleState.IDLE);
+      this.setState(LifecycleState.IDLE);
    }
 
    /* (non-Javadoc)
@@ -125,6 +194,19 @@
     */
    public void start() throws IllegalStateException, Exception
    {
+      // Log
+      if (log.isTraceEnabled())
+      {
+         log.trace("Received request to start");
+      }
+
+      // Invoke init() if necessary
+      if (this.getState().equals(LifecycleState.PRE_INIT))
+      {
+         log.debug("Invoking implicit initialization from start()");
+         this.initialize();
+      }
+
       // Ensure idle
       final LifecycleState required = LifecycleState.IDLE;
       final LifecycleState actual = this.getState();
@@ -132,195 +214,239 @@
 
       // Initiate shutdown sequence
       log.info("Starting: " + this);
-      this.setLifecycleState(LifecycleState.STARTING);
+      this.setState(LifecycleState.STARTING);
 
       // Start
+      if (log.isTraceEnabled())
+      {
+         log.trace("Entering implementation class start...");
+      }
       this.doStart();
 
+      // Run the bootstraps
+      if (log.isTraceEnabled())
+      {
+         log.trace("Starting bootstraps...");
+      }
+      this.startBootstraps();
+
       // Done
       log.info("Started: " + this);
-      this.setLifecycleState(LifecycleState.STARTED);
+      this.setState(LifecycleState.STARTED);
    }
 
-   //-------------------------------------------------------------------------------------||
-   // Contracts --------------------------------------------------------------------------||
-   //-------------------------------------------------------------------------------------||
-
-   /**
-    * Implementation-specific start hook
-    * 
-    * @throws Exception
+   /* (non-Javadoc)
+    * @see org.jboss.bootstrap.spi.server.Server#addBootstrap(org.jboss.bootstrap.spi.Bootstrap)
     */
-   protected abstract void doStart() throws Exception;
+   public void addBootstrap(final Bootstrap bootstrap) throws IllegalStateException, IllegalArgumentException
+   {
+      // Precondition check
+      if (bootstrap == null)
+      {
+         throw new IllegalArgumentException("Supplied bootstrap was null");
+      }
 
-   /**
-    * Implementation-specific shutdown hook
-    * 
-    * @throws Exception
-    */
-   protected abstract void doShutdown() throws Exception;
+      // Add
+      this.getBootstraps().add(bootstrap);
+   }
 
-   //-------------------------------------------------------------------------------------||
-   // Functional Methods -----------------------------------------------------------------||
-   //-------------------------------------------------------------------------------------||
-
-   /**
-    * Validates the specified configuration for:
-    * 
-    * 1) Either bootstrapURL or both bootstrapHome+bootstrapName
-    * 2) bootstrapLib!=null
-    * 3) bootstrapConf!=null
-    * 
-    * Subclasses may impose further restrictions.
-    * 
-    * @param configuration
-    * @throws InvalidConfigurationException If the configuration is not valid
-    * @throws IllegalArgumentException If the configuration is not specified
+   /* (non-Javadoc)
+    * @see org.jboss.bootstrap.spi.server.Server#removeBootstrap(org.jboss.bootstrap.spi.Bootstrap)
     */
-   protected void validate(T configuration) throws InvalidConfigurationException, IllegalArgumentException
+   public void removeBootstrap(final Bootstrap bootstrap) throws IllegalStateException, IllegalArgumentException
    {
-      // Precondition check
-      if (configuration == null)
+      // Remove
+      boolean removed = bootstraps.remove(bootstrap);
+
+      // Postcondition check
+      if (!removed)
       {
-         throw new IllegalArgumentException("Configuration is required, but was not supplied");
+         throw new IllegalArgumentException(
+               "Specified bootstrap could not be removed because it is not present in the list");
       }
+   }
 
-      // Get properties
-      String name = configuration.getBootstrapName();
-      URL home = configuration.getBootstrapHome();
-      URL direct = configuration.getBootstrapUrl();
-      URL lib = configuration.getBootstrapLibLocation();
-      URL conf = configuration.getBootstrapConfLocation();
+   /* (non-Javadoc)
+    * @see org.jboss.bootstrap.spi.server.Server#getValidator()
+    */
+   public ConfigurationValidator<T> getValidator()
+   {
+      return this.validator;
+   }
 
-      // If no direct bootstrap URL
-      if (direct == null)
+   /* (non-Javadoc)
+    * @see org.jboss.bootstrap.spi.server.Server#init()
+    */
+   public void initialize() throws IllegalStateException, InvalidConfigurationException
+   {
+      // Log
+      log.debug("Initializing server: " + this);
+
+      /*
+       * Precondition checks
+       */
+
+      // State must be pre-initialized
+      LifecycleState state = this.getState();
+      if (!state.equals(LifecycleState.PRE_INIT))
       {
-         // Ensure we may construct this via home+name
-         if (home == null || (name == null || name.length() == 0))
-         {
-            throw new InvalidConfigurationException(
-                  "If the bootstrap URL is not specified, both the bootstrap home and name must be.");
-         }
+         throw new IllegalStateException("Cannot initialize an already initialized server, state is: " + state);
       }
 
-      // If no lib
-      if (lib == null)
+      // Config must be in place
+      T config = this.getConfiguration();
+      if (config == null)
       {
-         throw new InvalidConfigurationException("Bootstrap library location must be specified");
+         throw new IllegalStateException("Configuration must be supplied before server is initialized");
       }
 
-      // If no conf
-      if (conf == null)
+      // Validate
+      this.validate(config);
+
+      /*
+       * If there's an initializer, use it
+       */
+      ServerInitializer<K, T> initializer = this.getInitializer();
+      if (initializer != null)
       {
-         throw new InvalidConfigurationException("Bootstrap configuration location must be specified");
+         initializer.initialize(this);
       }
+      else
+      {
+         log.debug("No initializer defined, skipping initialization of " + this);
+      }
+
+      // Freeze
+      config.freeze();
    }
 
-   /**
-    * Initializes the bootstrap configuration by
-    * setting appropriate defaults, setting system properties.
-    * 
-    * Subclasses may define further rules.
-    * 
-    * @param configuration
-    * @throws InvalidConfigurationException If the configuration is not able to be 
-    *       initialized due to faulty state
+   /* (non-Javadoc)
+    * @see org.jboss.bootstrap.spi.server.Server#getInitializer()
     */
-   protected void initialize(T configuration) throws InvalidConfigurationException
+   public ServerInitializer<K, T> getInitializer()
    {
-      /*
-       * If bootstrapURL is not directly defined, construct it from
-       * home+name 
-       */
-      URL bootstrapUrl = configuration.getBootstrapUrl();
-      if (bootstrapUrl == null)
+      return this.initializer;
+   }
+
+   /* (non-Javadoc)
+    * @see org.jboss.bootstrap.spi.server.Server#setInitializer(org.jboss.bootstrap.spi.server.ServerInitializer)
+    */
+   public void setInitializer(final ServerInitializer<K, T> initializer) throws IllegalStateException
+   {
+      this.initializer = initializer;
+      log.debug("Set initializer to " + initializer);
+   }
+
+   /* (non-Javadoc)
+    * @see org.jboss.bootstrap.spi.server.Server#setConfigurationValidator(org.jboss.bootstrap.spi.config.ConfigurationValidator)
+    */
+   public void setValidator(final ConfigurationValidator<T> validator)
+   {
+      log.debug("Setting validator to: " + validator);
+      this.validator = validator;
+   }
+
+   /* (non-Javadoc)
+    * @see org.jboss.bootstrap.spi.server.Server#validate()
+    */
+   public void validate(final T configuration) throws InvalidConfigurationException, IllegalArgumentException
+   {
+      // Precondition check
+      if (configuration == null)
       {
-         // Log
-         if (log.isTraceEnabled())
-         {
-            log.trace("No bootstrap URL defined, constructing it from home and name...");
-         }
+         throw new IllegalArgumentException("Configuration was not specified");
+      }
 
-         // Construct
-         URL home = configuration.getBootstrapHome();
-         String name = configuration.getBootstrapName();
-         assert home != null : "Bootstrap home should not be null, and should have failed validation if so";
-         assert name != null : "Bootstrap name should not be null, and should have failed validation if so";
-         try
-         {
-            bootstrapUrl = new URL(home, name);
-         }
-         catch (MalformedURLException e)
-         {
-            throw new InvalidConfigurationException("Cannot construct bootstrapURL from home and name", e);
-         }
+      // Get the validator
+      ConfigurationValidator<T> validator = this.getValidator();
 
-         // Log
+      // Is specified, validate
+      if (validator != null)
+      {
+         log.debug("Validating configuration using: " + validator);
+         validator.validate(this.getConfiguration());
+      }
+      else
+      {
          if (log.isTraceEnabled())
          {
-            log.trace("New bootstrap URL: " + bootstrapUrl.toExternalForm());
+            log.trace("No validator defined, skipping validation upon configuration");
          }
-
-         // Set
-         configuration.setBootstrapUrl(bootstrapUrl);
       }
-
-      // Set System Properties
-      this.setSystemProperties(configuration);
    }
 
+   //-------------------------------------------------------------------------------------||
+   // Contracts --------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
    /**
-    * Sets system properties from the specified configuration
+    * Implementation-specific start hook
     * 
-    * @param The configuration
+    * @throws Exception
     */
-   protected void setSystemProperties(T configuration)
-   {
-      // Set Properties from Config
-      this.setSystemProperty(ServerConfig.PROP_KEY_BOOTSTRAP_HOME_URL, configuration.getBootstrapHome());
-      this.setSystemProperty(ServerConfig.PROP_KEY_BOOTSTRAP_URL, configuration.getBootstrapUrl());
-      this.setSystemProperty(ServerConfig.PROP_KEY_BOOTSTRAP_CONF_URL, configuration.getBootstrapConfLocation());
-      this.setSystemProperty(ServerConfig.PROP_KEY_BOOTSTRAP_LIB_URL, configuration.getBootstrapLibLocation());
-      this.setSystemProperty(ServerConfig.PROP_KEY_BOOTSTRAP_NAME, configuration.getBootstrapName());
-   }
+   protected abstract void doStart() throws Exception;
 
+   /**
+    * Implementation-specific shutdown hook
+    * 
+    * @throws Exception
+    */
+   protected abstract void doShutdown() throws Exception;
+
    //-------------------------------------------------------------------------------------||
-   // Internal Helper Methods ------------------------------------------------------------||
+   // Functional Methods -----------------------------------------------------------------||
    //-------------------------------------------------------------------------------------||
 
    /**
-    * Sets the specified system property key to the specified value
+    * Starts the bootstraps
     * 
-    * @param key The non-null key
-    * @param value
+    * @throws Exception
     */
-   private void setSystemProperty(String key, String value)
+   protected void startBootstraps() throws Exception
    {
-      // Precondition check
-      assert key != null : "Key for system property was null";
+      // Run the bootstraps
+      for (Bootstrap bootstrap : this.getBootstraps())
+      {
+         // Add in reverse order
+         this.getStartedBootstraps().add(0, bootstrap);
 
-      // Set 
-      SecurityActions.setSystemProperty(key, value);
-
-      // Log
-      if (log.isTraceEnabled())
-      {
-         log.trace(("Set system property \"" + key + "\" to: ") + (value != null ? "\"" + value + "\"" : "[NULL]"));
+         // Start
+         bootstrap.start(this);
       }
    }
 
    /**
-    * Sets the specified URL's external form as a system property with the specified key
-    * 
-    * @param key
-    * @param value
+    * Shuts down the bootstraps that have been started
     */
-   private void setSystemProperty(String key, URL value)
+   protected void shutdownBootstraps()
    {
-      String urlString = value.toExternalForm();
-      this.setSystemProperty(key, urlString == null ? null : urlString);
+      // Initialize
+      final List<Bootstrap> startedBootstraps = this.getStartedBootstraps();
+
+      // Signal 
+      for (Bootstrap bootstrap : startedBootstraps)
+      {
+         bootstrap.prepareShutdown(this);
+      }
+
+      // Do the bootstraps in reverse order
+      for (Bootstrap bootstrap : startedBootstraps)
+      {
+         try
+         {
+            bootstrap.shutdown(this);
+         }
+         catch (Throwable t)
+         {
+            log.warn("Error shutting down bootstrap: " + bootstrap, t);
+         }
+      }
    }
 
+   //-------------------------------------------------------------------------------------||
+   // Internal Helper Methods ------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
    /**
     * Ensures the actual state matches the required, throwing {@link IllegalStateException} 
     * if not
@@ -333,7 +459,7 @@
       if (required != actual)
       {
          throw new IllegalStateException("Server must be in " + LifecycleState.class.getSimpleName() + " " + required
-               + " for shutdown; is instead: " + actual);
+               + "; is instead: " + actual);
       }
    }
 
@@ -342,48 +468,48 @@
    //-------------------------------------------------------------------------------------||
 
    /**
-    * Sets the current lifecycle state such that it may be easily reported
+    * @return the bootstraps
     */
-   protected void setLifecycleState(LifecycleState state)
+   private List<Bootstrap> getBootstraps()
    {
-      // Log and set
-      if (log.isTraceEnabled())
-      {
-         log.trace("Setting " + LifecycleState.class.getSimpleName() + " to: " + state);
-      }
-      this.state = state;
+      return bootstraps;
    }
 
    /**
-    * Sets the specified configuration:
-    * 
-    * 1) Checks specified
-    * 2) Validates
-    * 3) Initializes
-    * 4) Freezes to immutable
-    * 5) Sets
-    * 
-    * @param configuration
-    * @throws IllegalArgumentException If the configuration was not specified
-    * @throws InvalidConfigurationException In the configuration was not valid
+    * @param bootstraps the bootstraps to set
     */
-   void setConfiguration(T configuration) throws IllegalArgumentException, InvalidConfigurationException
+   private void setBootstraps(final List<Bootstrap> bootstraps)
    {
-      // Validate
-      this.validate(configuration);
+      this.bootstraps = bootstraps;
+   }
 
-      // Initialize
-      this.initialize(configuration);
+   /**
+    * @return the startedBootstraps
+    */
+   private List<Bootstrap> getStartedBootstraps()
+   {
+      return startedBootstraps;
+   }
 
-      // Freeze
-      configuration.freeze();
+   /**
+    * @param startedBootstraps the startedBootstraps to set
+    */
+   private void setStartedBootstraps(final List<Bootstrap> startedBootstraps)
+   {
+      this.startedBootstraps = startedBootstraps;
+   }
 
+   /**
+    * @param state the state to set
+    */
+   private synchronized final void setState(final LifecycleState state)
+   {
       // Log and set
       if (log.isTraceEnabled())
       {
-         log.trace("Set configuration: " + configuration);
+         log.trace("Setting " + LifecycleState.class.getSimpleName() + " to: " + state);
       }
-      this.configuration = configuration;
+      this.state = state;
    }
 
 }

Modified: projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/server/Server.java
===================================================================
--- projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/server/Server.java	2009-04-10 09:16:00 UTC (rev 87114)
+++ projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/server/Server.java	2009-04-10 10:26:15 UTC (rev 87115)
@@ -22,6 +22,9 @@
 
 package org.jboss.bootstrap.spi.server;
 
+import org.jboss.bootstrap.spi.Bootstrap;
+import org.jboss.bootstrap.spi.config.ConfigurationValidator;
+import org.jboss.bootstrap.spi.config.InvalidConfigurationException;
 import org.jboss.bootstrap.spi.config.ServerConfig;
 import org.jboss.bootstrap.spi.lifecycle.LifecycleState;
 
@@ -33,7 +36,7 @@
  * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
  * @version $Revision: $
  */
-public interface Server<T extends ServerConfig<?>>
+public interface Server<K extends Server<K, T>, T extends ServerConfig<T>>
 {
 
    //-------------------------------------------------------------------------------------||
@@ -41,15 +44,51 @@
    //-------------------------------------------------------------------------------------||
 
    /**
-    * Start lifecycle of the Server
+    * Prepares the server for startup.  If {@link Server#getInitializer()} is not 
+    * null, will invoke {@link ServerInitializer#initialize(Server)}.
+    * Freezes the configuration from further 
+    * mutable actions by invoking {@link ServerConfig#freeze()}.  Finally
+    * sets the current state to {@link LifecycleState#IDLE}
     * 
-    * @throws IllegalStateException If the Server is already started
+    * @throws IllegalStateException  If the server is not in state {@link LifecycleState#PRE_INIT}, 
+    *       or if the configuration has not been defined
+    * @throws InvalidConfigurationException
+    */
+   void initialize() throws IllegalStateException, InvalidConfigurationException;
+
+   /**
+    * Returns the initializer to be used in initialization, or null
+    * if none is defined
+    * 
+    * @return
+    */
+   ServerInitializer<K, T> getInitializer();
+
+   /**
+    * Initializer to use in server initialization.  Pass
+    * null to disable further initialization.
+    * 
+    * @param initializer
+    * @throws IllegalStateException If the server state is anything aside from
+    * {@link LifecycleState#PRE_INIT}
+    */
+   void setInitializer(ServerInitializer<K, T> initializer) throws IllegalStateException;
+
+   /**
+    * Start lifecycle of the Server, optionally invoking upon
+    * {@link Server#initialize()} if the state is {@link LifecycleState#PRE_INIT}.
+    * During execution the state will be {@link LifecycleState#STARTING}, and upon
+    * successful completion will be {@link LifecycleState#STARTED}. 
+    * 
+    * @throws IllegalStateException If the Server is already started or starting
     * @throws Exception
     */
    void start() throws IllegalStateException, Exception;
 
    /**
-    * Stop lifecycle of the Server
+    * Stop lifecycle of the Server.  During execution the state will be 
+    * {@link LifecycleState#STOPPING}, and upon
+    * successful completion will be {@link LifecycleState#IDLE}. 
     * 
     * @throws IllegalStateException If the Server is not started
     * @throws Exception
@@ -59,14 +98,70 @@
    /**
     * Returns the current state of the Server lifecycle
     * 
-    * @return true if started, false otherwise
+    * @return The {@link LifecycleState}
     */
    LifecycleState getState();
 
    /**
-    * Returns the frozen (immutable) underlying server configuration
+    * Returns the underlying server configuration.  If
+    * the server state is anything aside from 
+    * {@link LifecycleState#PRE_INIT}, the configuration 
+    * will be immutable / frozen.
     * 
     * @return
     */
    T getConfiguration();
+
+   /**
+    * Sets the configuration
+    * 
+    * @param config
+    */
+   void setConfiguration(T config);
+
+   /**
+    * If {@link Server#getValidator()} is non-null, will
+    * assert the configuration is valid using the supplied
+    * validator
+    * 
+    * @param config
+    * @throws InvalidConfigurationException If the config is not valid as
+    *       determined by the rules of the validator
+    * @throws IllegalArgumentException If the configuration was not specified
+    */
+   void validate(T config) throws InvalidConfigurationException, IllegalArgumentException;
+
+   /**
+    * Returns the (possibly null) validator
+    * to be used in asserting the validity of a supplied configuration
+    * 
+    * @return
+    */
+   ConfigurationValidator<T> getValidator();
+
+   /**
+    * Sets the specified validator to be used in 
+    * asserting the validity of a supplied configuration. 
+    * May be null to remove validation.
+    * 
+    * @param validator
+    */
+   void setValidator(ConfigurationValidator<T> validator);
+
+   /**
+    * Adds the specified bootstrap to those to be run on {@link Server#start()}
+    * 
+    * @param bootstrap
+    * @throws IllegalArgumentException If the specified bootstrap is null
+    */
+   void addBootstrap(Bootstrap bootstrap) throws IllegalArgumentException;
+
+   /**
+    * Removes the specified bootstrap from those to be run on {@link Server#start()}
+    * 
+    * @param bootstrap
+    * @throws IllegalArgumentException If the specified bootstrap is not currently
+    *       designated as to be run
+    */
+   void removeBootstrap(Bootstrap bootstrap) throws IllegalArgumentException;
 }

Added: projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/server/ServerInitializer.java
===================================================================
--- projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/server/ServerInitializer.java	                        (rev 0)
+++ projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/server/ServerInitializer.java	2009-04-10 10:26:15 UTC (rev 87115)
@@ -0,0 +1,51 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This 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 (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.bootstrap.spi.server;
+
+import org.jboss.bootstrap.spi.config.ServerConfig;
+import org.jboss.bootstrap.spi.lifecycle.LifecycleState;
+
+/**
+ * ServerInitializer
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public interface ServerInitializer<K extends Server<K, T>, T extends ServerConfig<T>>
+{
+   //-------------------------------------------------------------------------------------||
+   // Contracts --------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Initializes the specified server.  May perform tasks such
+    * as validation and defaulting of an underlying configuration.
+    * 
+    * @param server The server to initialize
+    * @throws IllegalArgumentException If the server was not specified / null, or 
+    *       its configuration is somehow invalid
+    * @throws IllegalStateException If the server's state is not 
+    *       {@link LifecycleState#PRE_INIT}
+    */
+   void initialize(Server<K, T> server) throws IllegalArgumentException, IllegalStateException;
+}

Modified: projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/xml/BootstrapSchemaBinding.java
===================================================================
--- projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/xml/BootstrapSchemaBinding.java	2009-04-10 09:16:00 UTC (rev 87114)
+++ projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/xml/BootstrapSchemaBinding.java	2009-04-10 10:26:15 UTC (rev 87115)
@@ -43,24 +43,24 @@
  * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
  * @version $Revision: 71554 $
  */
-public class BootstrapSchemaBinding extends SchemaBinding
+class BootstrapSchemaBinding extends SchemaBinding
 {
    /** The bootstrap namespace */
    public static final String NAMESPACE = "urn:jboss:bootstrap:1.0";
-   
+
    /**
     * Create a new BootstrapSchemaBinding.
     */
    public BootstrapSchemaBinding()
    {
       TypeBinding stringType = getType(SimpleTypeBindings.typeQName(String.class));
-      
+
       setNamespaces(Collections.singleton(NAMESPACE));
       setIgnoreLowLine(true);
       setIgnoreUnresolvedFieldOrClass(false);
       setReplacePropertyRefs(true);
       setStrictSchema(true);
-      
+
       // The bootstrap type
       TypeBinding bootstrapType = new TypeBinding(new QName(NAMESPACE, "bootstrapType"));
       bootstrapType.setSimple(false);
@@ -70,7 +70,7 @@
       ClassMetaData bootstrapClassMetaData = new ClassMetaData();
       bootstrapClassMetaData.setImpl(BootstrapMetaData.class.getName());
       bootstrapType.setClassMetaData(bootstrapClassMetaData);
-      
+
       // Bootstrap can take some urls
       ElementBinding urlElement = new ElementBinding(this, new QName(NAMESPACE, "url"), stringType);
       ParticleBinding urlParticle = new ParticleBinding(urlElement, 0, 1, true);
@@ -90,7 +90,7 @@
             bootstrapURLs.add(url);
          }
       });
-      
+
       // The bootstrap root element
       addElement(new ElementBinding(this, new QName(NAMESPACE, "bootstrap"), bootstrapType));
    }

Added: projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/ConfigInitializationTestCase.java
===================================================================
--- projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/ConfigInitializationTestCase.java	                        (rev 0)
+++ projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/ConfigInitializationTestCase.java	2009-04-10 10:26:15 UTC (rev 87115)
@@ -0,0 +1,232 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This 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 (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.bootstrap.spi.config;
+
+import java.net.URL;
+
+import junit.framework.TestCase;
+
+import org.jboss.logging.Logger;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * ConfigInitializationTestCase
+ * 
+ * Ensures that the base configuration initialization is correct
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class ConfigInitializationTestCase
+{
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   private static final Logger log = Logger.getLogger(ConfigValidationTestCase.class);
+
+   private static CountingServerInitializer initializer;
+
+   //-------------------------------------------------------------------------------------||
+   // Instance Members -------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   private TestNoOpServer server;
+
+   //-------------------------------------------------------------------------------------||
+   // Lifecycle --------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   @BeforeClass
+   public static void createInitializer() throws Throwable
+   {
+      initializer = new TestServerInitializer();
+      log.info("Created: " + initializer);
+   }
+
+   @Before
+   public void createServer()
+   {
+      this.server = new TestNoOpServer();
+      log.info("Created: " + this.server);
+   }
+
+   @After
+   public void resetServer()
+   {
+      this.server = null;
+      log.info("Cleaned up server to null");
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Tests ------------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Ensures that the conf is defaulted from home
+    * 
+    * @throws Throwable
+    */
+   @Test
+   public void testBootstrapConfDefaultedInInitializationFromHome() throws Throwable
+   {
+      // Log
+      log.info("testBootstrapConfDefaultedInInitializationFromHome");
+
+      // Get a populated config and server
+      final TestServerConfig configuration = TestConfigFactory.createConfiguration();
+      final TestNoOpServer server = this.server;
+
+      // Remove conf and set on server
+      configuration.setBootstrapConfLocation(null);
+      server.setConfiguration(configuration);
+
+      // Initialize
+      initializer.initialize(server);
+
+      // Create the expected URL
+      final URL expectedConfigurationURL = configuration.getBootstrapHome();
+
+      // Get the actual URL
+      final URL confURL = configuration.getBootstrapConfLocation();
+
+      // Test
+      TestCase.assertNotNull("Configuration URL was not initialized", confURL);
+      TestCase.assertEquals("Initialized configuration is to incorrect location", expectedConfigurationURL, confURL);
+      log.info("Got expected Configuration URL: " + confURL);
+   }
+
+   /**
+    * Ensures that the conf is required by validation if no home is provided
+    * 
+    * @throws Throwable
+    */
+   @Test
+   public void testBootstrapConfDefaultedInInitializationFromBootstrapUrlBase() throws Throwable
+   {
+      // Get a populated config and server
+      final TestServerConfig configuration = TestConfigFactory.createConfiguration();
+      final TestNoOpServer server = this.server;
+
+      // Remove conf and home
+      configuration.setBootstrapHome(null).setBootstrapConfLocation(null);
+      server.setConfiguration(configuration);
+
+      // Initialize
+      initializer.initialize(server);
+
+      // Create the expected URL
+      final URL expectedConfigurationURL = TestConfigFactory.getResourcesBase();
+
+      // Get the actual URL
+      final URL confURL = configuration.getBootstrapConfLocation();
+
+      // Test
+      TestCase.assertNotNull("Configuration URL was not initialized", confURL);
+      TestCase.assertEquals("Initialized configuration is to incorrect location", expectedConfigurationURL, confURL);
+   }
+
+   /**
+    * Ensures that setting a configuration results in proper defaulting 
+    * of the bootstrap URL if it's not been explicitly specified  
+    * 
+    * @throws Throwable
+    */
+   @Test
+   public void testBootstrapUrlDefaultedInInitialization() throws Throwable
+   {
+      // Get a populated config and server
+      final TestServerConfig configuration = TestConfigFactory.createConfiguration();
+      final TestNoOpServer server = this.server;
+
+      // Remove bootstrapURL
+      configuration.setBootstrapUrl(null);
+      server.setConfiguration(configuration);
+
+      // Initialize
+      initializer.initialize(server);
+
+      // Create the expected URL
+      final URL home = configuration.getBootstrapHome();
+      final String name = configuration.getBootstrapName();
+      final URL expectedBootstrapURL = new URL(home, name);
+
+      // Get the actual URL
+      final URL bootstrapUrl = configuration.getBootstrapUrl();
+
+      // Test
+      TestCase.assertNotNull("Bootstrap URL was not initialized", bootstrapUrl);
+      TestCase.assertEquals("Initialized bootstrap is to incorrect location", expectedBootstrapURL, bootstrapUrl);
+   }
+
+   /**
+    * Ensures that the properties backing the configuration are set 
+    * both on the configuration itself and in the System props
+    * 
+    * @throws Throwable
+    */
+   @Test
+   public void testPropertiesSetInInitialization() throws Throwable
+   {
+      // Get a populated config and server
+      TestServerConfig configuration = TestConfigFactory.createConfiguration();
+      final TestNoOpServer server = this.server;
+      server.setConfiguration(configuration);
+
+      // Initialize
+      initializer.initialize(server);
+
+      // Get Properties from Configuration
+      final String homeFromConfigProp = configuration.getProperties().get(ServerConfig.PROP_KEY_BOOTSTRAP_HOME_URL);
+      final String bootstrapURLFromConfigProp = configuration.getProperties().get(ServerConfig.PROP_KEY_BOOTSTRAP_URL);
+      final String confFromConfigProp = configuration.getProperties().get(ServerConfig.PROP_KEY_BOOTSTRAP_CONF_URL);
+      final String nameFromConfigProp = configuration.getProperties().get(ServerConfig.PROP_KEY_BOOTSTRAP_NAME);
+
+      // Get Properties from System
+      final String homeFromSystem = System.getProperty(ServerConfig.PROP_KEY_BOOTSTRAP_HOME_URL);
+      final String bootstrapURLFromSystem = System.getProperty(ServerConfig.PROP_KEY_BOOTSTRAP_URL);
+      final String confFromSystem = System.getProperty(ServerConfig.PROP_KEY_BOOTSTRAP_CONF_URL);
+      final String nameFromSystem = System.getProperty(ServerConfig.PROP_KEY_BOOTSTRAP_NAME);
+
+      // Get Expected Values
+      final String home = configuration.getBootstrapHome().toExternalForm();
+      final String bootstrapURL = configuration.getBootstrapUrl().toExternalForm();
+      final String conf = configuration.getBootstrapConfLocation().toExternalForm();
+      final String name = configuration.getBootstrapName();
+
+      // Ensure all equal
+      TestCase.assertEquals("home in configuration must match the config property", home, homeFromConfigProp);
+      TestCase.assertEquals("home in configuration must match the system property", home, homeFromSystem);
+      TestCase.assertEquals("bootstrapURL in configuration must match the config property", bootstrapURL,
+            bootstrapURLFromConfigProp);
+      TestCase.assertEquals("bootstrapURL in configuration must match the system property", bootstrapURL,
+            bootstrapURLFromSystem);
+      TestCase.assertEquals("conf in configuration must match the config property", conf, confFromConfigProp);
+      TestCase.assertEquals("conf in configuration must match the system property", conf, confFromSystem);
+      TestCase.assertEquals("name in configuration must match the config property", name, nameFromConfigProp);
+      TestCase.assertEquals("name in configuration must match the system property", name, nameFromSystem);
+   }
+}

Added: projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/ConfigValidationTestCase.java
===================================================================
--- projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/ConfigValidationTestCase.java	                        (rev 0)
+++ projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/ConfigValidationTestCase.java	2009-04-10 10:26:15 UTC (rev 87115)
@@ -0,0 +1,175 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This 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 (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.bootstrap.spi.config;
+
+import junit.framework.TestCase;
+
+import org.jboss.logging.Logger;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * ConfigValidationTestCase
+ * 
+ * Ensures that the base configuration validation is correct
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class ConfigValidationTestCase
+{
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   private static final Logger log = Logger.getLogger(ConfigValidationTestCase.class);
+
+   private static ConfigurationValidator<TestServerConfig> validator;
+
+   //-------------------------------------------------------------------------------------||
+   // Lifecycle --------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   @BeforeClass
+   public static void createValidator() throws Throwable
+   {
+      validator = new TestConfigurationValidator();
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Tests ------------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Ensures that a fully-populated config is returned from
+    * the factory (as a control)
+    */
+   @Test
+   public void testControl() throws Throwable
+   {
+      // Log
+      log.info("testControl");
+
+      // Get a populated config
+      final TestServerConfig configuration = TestConfigFactory.createConfiguration();
+
+      // Test
+      TestCase.assertNotNull("actualClass was not populated", configuration.getActualClass());
+      TestCase.assertNotNull("conf was not populated", configuration.getBootstrapConfLocation());
+      TestCase.assertNotNull("home was not populated", configuration.getBootstrapHome());
+      TestCase.assertNotNull("name was not populated", configuration.getBootstrapName());
+      TestCase.assertNotNull("URL was not populated", configuration.getBootstrapUrl());
+   }
+
+   /**
+    * Ensures that a fully-populated config is valid
+    */
+   @Test
+   public void testValidationPopulatedBootstrap() throws Throwable
+   {
+      // Log
+      log.info("testValidationPopulatedBootstrap");
+
+      // Get a populated config
+      final TestServerConfig configuration = TestConfigFactory.createConfiguration();
+
+      // Validate
+      try
+      {
+         validator.validate(configuration);
+      }
+      catch (InvalidConfigurationException ice)
+      {
+         TestCase.fail("Configuration fully-populated should be valid, but instead got " + ice.getMessage());
+      }
+
+      // OK
+      return;
+   }
+
+   /**
+    * Ensures that an explicit bootstrapURL with no name or home set passes validation
+    * 
+    * @throws Throwable
+    */
+   @Test
+   public void testValidationExplicitBootstrapUrlWithNoHomeOrName() throws Throwable
+   {
+      // Log
+      log.info("testValidationExplicitBootstrapUrlWithNoHomeOrName");
+
+      // Get a populated config
+      final TestServerConfig configuration = TestConfigFactory.createConfiguration();
+
+      // Remove home and name
+      configuration.setBootstrapHome(null).setBootstrapName(null);
+
+      // Validate
+      try
+      {
+         validator.validate(configuration);
+      }
+      catch (InvalidConfigurationException ice)
+      {
+         TestCase.fail("Configuration with bootstrapURL but no home or name should be valid, but instead got "
+               + ice.getMessage());
+      }
+
+      // OK
+      return;
+   }
+
+   /**
+    * Ensures that a configuration with no home, bootstrapURL, or name set fails validation
+    * 
+    * @throws Throwable
+    */
+   @Test
+   public void testValidationNoBootstrapUrlWithNoHomeOrName() throws Throwable
+   {
+      // Log
+      log.info("testValidationNoBootstrapUrlWithNoHomeOrName");
+
+      // Get a populated config
+      final TestServerConfig configuration = TestConfigFactory.createConfiguration();
+
+      // Remove home, name, bootstrapURL
+      configuration.setBootstrapHome(null).setBootstrapName(null).setBootstrapUrl(null);
+
+      // Validate
+      boolean validationFailed = false;
+      try
+      {
+         validator.validate(configuration);
+      }
+      catch (InvalidConfigurationException ice)
+      {
+         // Expected
+         validationFailed = true;
+      }
+
+      // Test
+      TestCase.assertTrue("Configuration with no home, name or bootstrapURL must fail validation", validationFailed);
+   }
+
+}

Added: projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/Counter.java
===================================================================
--- projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/Counter.java	                        (rev 0)
+++ projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/Counter.java	2009-04-10 10:26:15 UTC (rev 87115)
@@ -0,0 +1,44 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This 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 (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.bootstrap.spi.config;
+
+/**
+ * Counter
+ * 
+ * Simple interface which keeps a running counter
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+interface Counter
+{
+   //-------------------------------------------------------------------------------------||
+   // Contracts --------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Returns the number of times that {@link ConfigurationValidator#validate(ServerConfig)}
+    * has been called
+    */
+   int getUsedCount();
+}

Added: projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/CountingConfigurationValidator.java
===================================================================
--- projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/CountingConfigurationValidator.java	                        (rev 0)
+++ projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/CountingConfigurationValidator.java	2009-04-10 10:26:15 UTC (rev 87115)
@@ -0,0 +1,37 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This 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 (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.bootstrap.spi.config;
+
+/**
+ * CountingConfigurationValidator
+ * 
+ * A simple validator which counts the number of times 
+ * it's been used
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+interface CountingConfigurationValidator<T extends ServerConfig<?>> extends ConfigurationValidator<T>, Counter
+{
+
+}

Added: projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/CountingServerInitializer.java
===================================================================
--- projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/CountingServerInitializer.java	                        (rev 0)
+++ projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/CountingServerInitializer.java	2009-04-10 10:26:15 UTC (rev 87115)
@@ -0,0 +1,39 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This 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 (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.bootstrap.spi.config;
+
+import org.jboss.bootstrap.spi.server.ServerInitializer;
+
+/**
+ * CountingServerInitializer
+ * 
+ * A simple initializer which counts the number of times 
+ * it's been used
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+interface CountingServerInitializer extends ServerInitializer<TestNoOpServer, TestServerConfig>, Counter
+{
+
+}

Added: projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/TestConfigFactory.java
===================================================================
--- projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/TestConfigFactory.java	                        (rev 0)
+++ projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/TestConfigFactory.java	2009-04-10 10:26:15 UTC (rev 87115)
@@ -0,0 +1,104 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This 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 (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.bootstrap.spi.config;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+/**
+ * TestConfigFactory
+ * 
+ * Factory to generate fully-populated configuration objects
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+class TestConfigFactory
+{
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   private static final String NAME_CONF = "conf";
+
+   private static final String NAME_BOOTSTRAP = "bootstrap.xml";
+
+   //-------------------------------------------------------------------------------------||
+   // Constructor ------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * No external instanciation
+    */
+   private TestConfigFactory()
+   {
+
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Functional Methods -----------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   static TestServerConfig createConfiguration()
+   {
+      // Create a configuration
+      final TestServerConfig config = new TestServerConfig();
+
+      // Get the home
+      final URL home = getResourcesBase();
+
+      // Construct URLs
+      URL conf = null;
+      URL bootstrap = null;
+      try
+      {
+         conf = new URL(home, NAME_CONF);
+         bootstrap = new URL(home, NAME_BOOTSTRAP);
+      }
+      catch (MalformedURLException e)
+      {
+         throw new RuntimeException("Error in URL (improper setup)", e);
+      }
+
+      // Populate and return
+      return config.setBootstrapHome(home).setBootstrapConfLocation(conf).setBootstrapUrl(bootstrap).setBootstrapName(
+            NAME_BOOTSTRAP);
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Internal Helper Methods ------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Returns the base of these resources
+    * 
+    * @return
+    */
+   static URL getResourcesBase()
+   {
+      // Obtain from codesource
+      final URL base = TestConfigFactory.class.getProtectionDomain().getCodeSource().getLocation();
+      return base;
+   }
+
+}

Added: projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/TestConfigurationValidator.java
===================================================================
--- projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/TestConfigurationValidator.java	                        (rev 0)
+++ projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/TestConfigurationValidator.java	2009-04-10 10:26:15 UTC (rev 87115)
@@ -0,0 +1,78 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This 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 (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.bootstrap.spi.config;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * TestConfigurationValidator
+ * 
+ * A simple validator for TestServerConfig
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+class TestConfigurationValidator extends AbstractBasicConfigurationValidator<TestServerConfig>
+      implements
+         CountingConfigurationValidator<TestServerConfig>
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Instance Members -------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Internal counter
+    */
+   private AtomicInteger count = new AtomicInteger(0);
+
+   //-------------------------------------------------------------------------------------||
+   // Required Implementations -----------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /* (non-Javadoc)
+    * @see org.jboss.bootstrap.spi.config.CountingConfigurationValidator#getUsedCount()
+    */
+   public int getUsedCount()
+   {
+      return this.count.get();
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Overridden Implementations ---------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /* (non-Javadoc)
+    * @see org.jboss.bootstrap.spi.config.AbstractBasicConfigurationValidator#validate(org.jboss.bootstrap.spi.config.ServerConfig)
+    */
+   @Override
+   public void validate(TestServerConfig config) throws InvalidConfigurationException
+   {
+      // Increment the counter
+      this.count.incrementAndGet();
+
+      // Call super
+      super.validate(config);
+   }
+
+}

Added: projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/TestNoOpServer.java
===================================================================
--- projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/TestNoOpServer.java	                        (rev 0)
+++ projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/TestNoOpServer.java	2009-04-10 10:26:15 UTC (rev 87115)
@@ -0,0 +1,70 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This 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 (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.bootstrap.spi.config;
+
+import org.jboss.bootstrap.spi.server.AbstractServer;
+import org.jboss.bootstrap.spi.server.Server;
+import org.jboss.logging.Logger;
+
+/**
+ * TestServer
+ * 
+ * A simple server used in testing
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+class TestNoOpServer extends AbstractServer<TestNoOpServer, TestServerConfig>
+      implements
+         Server<TestNoOpServer, TestServerConfig>
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   private static final Logger log = Logger.getLogger(TestNoOpServer.class);
+
+   //-------------------------------------------------------------------------------------||
+   // Required Implementations -----------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /* (non-Javadoc)
+    * @see org.jboss.bootstrap.spi.server.AbstractServer#doShutdown()
+    */
+   @Override
+   protected void doShutdown() throws Exception
+   {
+      log.debug("NOOP doShutdown");
+   }
+
+   /* (non-Javadoc)
+    * @see org.jboss.bootstrap.spi.server.AbstractServer#doStart()
+    */
+   @Override
+   protected void doStart() throws Exception
+   {
+      log.debug("NOOP doStart");
+   }
+
+}

Added: projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/TestServerConfig.java
===================================================================
--- projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/TestServerConfig.java	                        (rev 0)
+++ projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/TestServerConfig.java	2009-04-10 10:26:15 UTC (rev 87115)
@@ -0,0 +1,44 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This 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 (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.bootstrap.spi.config;
+
+/**
+ * TestServerConfig
+ * 
+ * Simple server configuration used in testing
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+class TestServerConfig extends AbstractBasicServerConfig<TestServerConfig> implements ServerConfig<TestServerConfig>
+{
+   //-------------------------------------------------------------------------------------||
+   // Constructor ------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   TestServerConfig()
+   {
+      super(TestServerConfig.class);
+   }
+
+}

Added: projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/TestServerInitializer.java
===================================================================
--- projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/TestServerInitializer.java	                        (rev 0)
+++ projects/bootstrap/trunk/spi/src/test/java/org/jboss/bootstrap/spi/config/TestServerInitializer.java	2009-04-10 10:26:15 UTC (rev 87115)
@@ -0,0 +1,81 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This 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 (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.bootstrap.spi.config;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.jboss.bootstrap.spi.server.AbstractBasicServerInitializer;
+import org.jboss.bootstrap.spi.server.Server;
+
+/**
+ * TestServerInitializer
+ * 
+ * A simple initializer for the Test Server
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+class TestServerInitializer extends AbstractBasicServerInitializer<TestNoOpServer, TestServerConfig>
+      implements
+         CountingServerInitializer
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Instance Members -------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Internal counter
+    */
+   private AtomicInteger count = new AtomicInteger(0);
+
+   //-------------------------------------------------------------------------------------||
+   // Required Implementations -----------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /* (non-Javadoc)
+    * @see org.jboss.bootstrap.spi.config.CountingConfigurationValidator#getUsedCount()
+    */
+   public int getUsedCount()
+   {
+      return this.count.get();
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Overridden Implementations ---------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /* (non-Javadoc)
+    * @see org.jboss.bootstrap.spi.server.ServerInitializer#initialize(org.jboss.bootstrap.spi.server.Server)
+    */
+   public void initialize(Server<TestNoOpServer, TestServerConfig> server) throws IllegalArgumentException,
+         IllegalStateException
+   {
+      // Increment counter
+      this.count.incrementAndGet();
+
+      // Initialize
+      super.initialize(server);
+   }
+
+}




More information about the jboss-cvs-commits mailing list