[jboss-svn-commits] JBoss Common SVN: r4266 - in shrinkwrap/trunk: api/src/main/java/org/jboss/shrinkwrap/api and 7 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Tue Apr 20 10:19:48 EDT 2010


Author: ALRubinger
Date: 2010-04-20 10:19:46 -0400 (Tue, 20 Apr 2010)
New Revision: 4266

Added:
   shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/ArchiveFactory.java
   shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/Configuration.java
   shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/ConfigurationBuilder.java
   shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/Domain.java
   shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/ShrinkWrap.java
   shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/ConfigurableArchiveImpl.java
   shrinkwrap/trunk/impl-base/src/main/resources/META-INF/services/org.jboss.shrinkwrap.spi.Configurable
   shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/ConfigurationBuilderTestCase.java
   shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/ShrinkWrapTestCase.java
   shrinkwrap/trunk/spi/src/main/java/org/jboss/shrinkwrap/spi/Configurable.java
Modified:
   shrinkwrap/trunk/api/pom.xml
   shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/ArchivePaths.java
   shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/Archives.java
   shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/ArchiveBase.java
   shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/MemoryMapArchiveBase.java
   shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/MemoryMapArchiveImpl.java
   shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/JdkZipExporterDelegate.java
   shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/spec/JavaArchiveImpl.java
   shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/ArchivesTestCase.java
   shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/unit/MemoryMapArchiveTestCase.java
Log:
[SHRINKWRAP-102] Externalize configuration from the Archives factory

Modified: shrinkwrap/trunk/api/pom.xml
===================================================================
--- shrinkwrap/trunk/api/pom.xml	2010-04-17 15:31:39 UTC (rev 4265)
+++ shrinkwrap/trunk/api/pom.xml	2010-04-20 14:19:46 UTC (rev 4266)
@@ -30,6 +30,11 @@
 
   <!-- Dependencies -->
   <dependencies>
+  
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
 
   </dependencies>
   

Added: shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/ArchiveFactory.java
===================================================================
--- shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/ArchiveFactory.java	                        (rev 0)
+++ shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/ArchiveFactory.java	2010-04-20 14:19:46 UTC (rev 4266)
@@ -0,0 +1,95 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.shrinkwrap.api;
+
+/**
+ * 
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public final class ArchiveFactory
+{
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Implementation class name backing {@link Archive}s to be created
+    */
+   private static final String ARCHIVE_IMPL = "org.jboss.shrinkwrap.impl.base.MemoryMapArchiveImpl";
+
+   //-------------------------------------------------------------------------------------||
+   // Instance Members -------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Configuration for all archives created from this factory
+    */
+   private final Configuration configuration;
+
+   //-------------------------------------------------------------------------------------||
+   // Constructor ------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Creates a new {@link ArchiveFactory} which will use the supplied 
+    * {@link Configuration} for each new {@link Archive} it creates.
+    * 
+    * @param configuration
+    */
+   ArchiveFactory(final Configuration configuration) throws IllegalArgumentException
+   {
+      // Precondition checks
+      assert configuration != null : "configuration must be supplied";
+
+      // Set
+      this.configuration = configuration;
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Functional Methods ----------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Creates a new archive of the specified type.  The archive
+    * will be be backed by the {@link Configuration}
+    * specific to this {@link ArchiveFactory}.
+    * 
+    * @param archiveName The name of the archive
+    * @return An {@link Assignable} archive base  
+    * @throws IllegalArgumentException If either argument is not specified
+    */
+   public <T extends Assignable> T create(final String archiveName, final Class<T> type)
+         throws IllegalArgumentException
+   {
+      // Precondition checks
+      if (archiveName == null)
+      {
+         throw new IllegalArgumentException("ArchiveName must be specified");
+      }
+      if (type == null)
+      {
+         throw new IllegalArgumentException("Type must be specified");
+      }
+
+      final Archive<?> archive = SecurityActions.newInstance(ARCHIVE_IMPL, new Class<?>[]
+      {String.class, Configuration.class}, new Object[]
+      {archiveName, configuration}, Archive.class);
+      return archive.as(type);
+   }
+}

Modified: shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/ArchivePaths.java
===================================================================
--- shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/ArchivePaths.java	2010-04-17 15:31:39 UTC (rev 4265)
+++ shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/ArchivePaths.java	2010-04-20 14:19:46 UTC (rev 4266)
@@ -37,7 +37,7 @@
     */
    public static ArchivePath root()
    {
-      return create(null);
+      return RootPathWrapper.INSTANCE.getRoot();
    }
 
    /**
@@ -108,6 +108,21 @@
    {
       return SecurityActions.newInstance(PATH_IMPL, argumentTypes, arguments, ArchivePath.class);
    }
+   
+   /**
+    * Singleton wrapper to obtain a root {@link ArchivePath}
+    *
+    * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+    * @version $Revision: $
+    */
+   private enum RootPathWrapper{
+      INSTANCE;
+      private ArchivePath root = create(null);
+      
+      private ArchivePath getRoot(){
+         return root;
+      }
+   }
 
    //-------------------------------------------------------------------------------------||
    // Constructor ------------------------------------------------------------------------||

Modified: shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/Archives.java
===================================================================
--- shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/Archives.java	2010-04-17 15:31:39 UTC (rev 4265)
+++ shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/Archives.java	2010-04-20 14:19:46 UTC (rev 4266)
@@ -21,44 +21,28 @@
  *
  * @author <a href="mailto:aslak at conduct.no">Aslak Knutsen</a>
  * @version $Revision: $
+ * @deprecated Use {@link ShrinkWrap}
+ * @see {@link ShrinkWrap}
  */
+ at Deprecated
 public final class Archives
 {
    //-------------------------------------------------------------------------------------||
    // Class Members ----------------------------------------------------------------------||
    //-------------------------------------------------------------------------------------||
 
-   private static final String ARCHIVE_IMPL = "org.jboss.shrinkwrap.impl.base.MemoryMapArchiveImpl";
-   
-   private static final String EXTENSION_LOADER_IMPL = "org.jboss.shrinkwrap.impl.base.ServiceExtensionLoader";
-   
-   private static ExtensionLoader extensionLoader = null;
-   
    /**
     * Create a archive as a specific type.
     * 
     * @param archiveName The name of the archive
     * @return A {@link Assignable} archive base  
+    * @deprecated 
+    * @see {@link ShrinkWrap#create(String, Class)}
     */
-   public static <T extends Assignable> T create(String archiveName, Class<T> type) 
+   public static <T extends Assignable> T create(String archiveName, Class<T> type)
    {
-      if(archiveName == null) 
-      {
-         throw new IllegalArgumentException("ArchiveName must be specified");
-      }
-      if(type == null) 
-      {
-         throw new IllegalArgumentException("Type must be specified");
-      }
-      
-      initializeExtensionLoader();
-      
-      Archive<?> archive = SecurityActions.newInstance(
-                                 ARCHIVE_IMPL,
-                                 new Class<?>[]{String.class, ExtensionLoader.class},
-                                 new Object[]{archiveName, extensionLoader},
-                                 Archive.class); 
-      return archive.as(type);
+      // Delegate to ShrinkWrap
+      return ShrinkWrap.create(archiveName, type);
    }
 
    /**
@@ -67,54 +51,15 @@
     * @param <T>
     * @param extensionClass The Extension interface
     * @param extensionImplClass The Extension implementation class
+    * @see {@link Configuration#getExtensionLoader()}
     */
-   public static <T extends Assignable> void addExtensionOverride(
-         Class<T> extensionClass, 
+   public static <T extends Assignable> void addExtensionOverride(Class<T> extensionClass,
          Class<? extends T> extensionImplClass)
    {
-      initializeExtensionLoader();
+      final ExtensionLoader extensionLoader = ShrinkWrap.getDefaultDomain().getConfiguration().getExtensionLoader();
       extensionLoader.addOverride(extensionClass, extensionImplClass);
    }
 
-   /**
-    * 
-    * @param loader The ExtensionLoader to use
-    * @throws IllegalArgumentException if loader is null
-    * @throws IllegalStateException if loader is already set
-    */
-   public synchronized static void setExtensionLoader(ExtensionLoader loader)
-   {
-      if(loader == null) 
-      {
-         throw new IllegalArgumentException("Loader must be specified");
-      }
-      if(extensionLoader != null) 
-      {
-         throw new IllegalStateException(
-               "Loader already specified, call setExtensionLoader " +
-         		"before calling create or addExtensionOverride");
-      }
-      extensionLoader = loader;
-   }
-   
-   private synchronized static void initializeExtensionLoader() 
-   {
-      if(extensionLoader == null) {
-         extensionLoader = SecurityActions.newInstance(
-                              EXTENSION_LOADER_IMPL,
-                              new Class<?>[]{}, 
-                              new Object[]{}, 
-                              ExtensionLoader.class);
-      }
-   }
-   
-   /**
-    * Used by ArchivesTestCase to reset the static state of the Factory. 
-    */
-   static void resetState() {
-      extensionLoader = null;
-   }
-   
    //-------------------------------------------------------------------------------------||
    // Constructor ------------------------------------------------------------------------||
    //-------------------------------------------------------------------------------------||
@@ -122,5 +67,7 @@
    /**
     * No instantiation
     */
-   private Archives() {}
+   private Archives()
+   {
+   }
 }

Added: shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/Configuration.java
===================================================================
--- shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/Configuration.java	                        (rev 0)
+++ shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/Configuration.java	2010-04-20 14:19:46 UTC (rev 4266)
@@ -0,0 +1,97 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.shrinkwrap.api;
+
+import java.util.concurrent.ExecutorService;
+
+/**
+ * Encapsulates all configuration for a given {@link Domain}.
+ * Each {@link Archive} created by the domain's {@link ArchiveFactory}
+ * will consult the configuration internally.  An {@link Archive}'s
+ * configuration may not be changed after construction; if a new config
+ * is required it must be created under a new domain.  The default
+ * configuration is defined by {@link ConfigurationBuilder}, and new
+ * configurations are created via {@link ConfigurationBuilder#build()}. 
+ * 
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class Configuration
+{
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   //-------------------------------------------------------------------------------------||
+   // Instance Members -------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Loader mapping archive types to the appropriate underlying implementation
+    */
+   private final ExtensionLoader extensionLoader;
+
+   /**
+    * {@link ExecutorService} used for all asynchronous operations 
+    */
+   private final ExecutorService executorService;
+
+   //-------------------------------------------------------------------------------------||
+   // Constructor ------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Creates a new configuration instance using properties contained in the specified
+    * {@link ConfigurationBuilder}.
+    * 
+    * @param builder Construction object encapsulating the properties to use in this configuration
+    * @throws IllegalArgumentException If the builder was not specified
+    */
+   Configuration(final ConfigurationBuilder builder) throws IllegalArgumentException
+   {
+      // Precondition checks
+      if (builder == null)
+      {
+         throw new IllegalArgumentException("builder must be specified");
+      }
+
+      // Set 
+      this.extensionLoader = builder.getExtensionLoader();
+      this.executorService = builder.getExecutorService();
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Accessors --------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||   
+
+   /**
+    * @return the extensionLoader
+    */
+   public ExtensionLoader getExtensionLoader()
+   {
+      return extensionLoader;
+   }
+
+   /**
+    * @return the executorService
+    */
+   public ExecutorService getExecutorService()
+   {
+      return executorService;
+   }
+
+}

Added: shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/ConfigurationBuilder.java
===================================================================
--- shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/ConfigurationBuilder.java	                        (rev 0)
+++ shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/ConfigurationBuilder.java	2010-04-20 14:19:46 UTC (rev 4266)
@@ -0,0 +1,196 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.shrinkwrap.api;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Mutable construction object for new instances of {@link Configuration}.
+ * Provides defaults for each property if not specified (null) according to the following:
+ * 
+ * <ul>
+ *   <li><code>executorService</code> - A new {@link Executors#newCachedThreadPool()}</li>
+ *   <li><code>extensionLoader</code> - A new instance of the service extension loader from shrinkwrap-impl</li>
+ * </ul>
+ * 
+ * Not thread-safe.  When done altering proeprties here, a new configuration may be
+ * constructed by calling upon {@link ConfigurationBuilder#build()}.
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class ConfigurationBuilder
+{
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Logger
+    */
+   private static final Logger log = Logger.getLogger(ConfigurationBuilder.class.getName());
+
+   /**
+    * Implementation class name of the default {@link ExtensionLoader} to be used
+    */
+   private static final String EXTENSION_LOADER_IMPL = "org.jboss.shrinkwrap.impl.base.ServiceExtensionLoader";
+
+   /**
+    * Obtains the default {@link ExecutorService} to be used if none is specified
+    * @return
+    */
+   private static ExecutorService createDefaultExecutorService()
+   {
+      return Executors.newCachedThreadPool();
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Instance Members -------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Loader mapping archive types to the appropriate underlying implementation
+    */
+   private ExtensionLoader extensionLoader;
+
+   /**
+    * {@link ExecutorService} used for all asynchronous operations 
+    */
+   private ExecutorService executorService;
+
+   //-------------------------------------------------------------------------------------||
+   // Constructor ------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Creates a new builder initialized to defaults (null) values.  Any properties
+    * not explicitly provided by the user will be defaulted during 
+    * {@link ConfigurationBuilder#build()}.
+    */
+   public ConfigurationBuilder()
+   {
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Functional Methods ----------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||   
+
+   /**
+    * @return the extensionLoader
+    */
+   public ExtensionLoader getExtensionLoader()
+   {
+      return extensionLoader;
+   }
+
+   /**
+    * @return the executorService
+    */
+   public ExecutorService getExecutorService()
+   {
+      return executorService;
+   }
+
+   /**
+    * Sets the {@link ExtensionLoader} to be used, returning this instance
+    * 
+    * @param extensionLoader
+    * @return
+    */
+   public ConfigurationBuilder extensionLoader(final ExtensionLoader extensionLoader)
+   {
+      this.extensionLoader = extensionLoader;
+      return this;
+   }
+
+   /**
+    * Sets the {@link ExecutorService} to be used, returning this instance
+    * @param executorService
+    * @return
+    */
+   public ConfigurationBuilder executorService(final ExecutorService executorService)
+   {
+      this.executorService = executorService;
+      return this;
+   }
+
+   /**
+    * Builds a new {@link Configuration} using the properties contained
+    * in this builder.  In the case a property has not been specified, it will be defaulted
+    * according to the rules set forth in this {@link ConfigurationBuilder}'s contract.
+    * @return
+    */
+   public Configuration build()
+   {
+      // First set all defaults if not explicitly provided by the user
+      this.setDefaults();
+
+      // Make a new configuration and return it.
+      return new Configuration(this);
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Internal Helper Methods -----------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||   
+
+   /**
+    * Sets properties to their default values if they haven't been explicitly
+    * provided by the user
+    */
+   private void setDefaults()
+   {
+      // If no extension loader is present, create one
+      if (getExtensionLoader() == null)
+      {
+         final ExtensionLoader loader = createDefaultExtensionLoader();
+         if (log.isLoggable(Level.FINER))
+         {
+            log.finer("User has not defined an explicit " + ExtensionLoader.class.getSimpleName() + "; defaulting to "
+                  + loader);
+         }
+         this.extensionLoader(loader);
+      }
+
+      // If no executor service is present, create one
+      if (getExecutorService() == null)
+      {
+         final ExecutorService service = createDefaultExecutorService();
+         if (log.isLoggable(Level.FINER))
+         {
+            log.finer("User has not defined an explicit " + ExecutorService.class.getSimpleName() + "; defaulting to "
+                  + service);
+         }
+         this.executorService(service);
+      }
+   }
+
+   /**
+    * Obtains the default {@link ExtensionLoader} to be used if none 
+    * is specified
+    * @return
+    */
+   ExtensionLoader createDefaultExtensionLoader()
+   {
+      return SecurityActions.newInstance(EXTENSION_LOADER_IMPL, new Class<?>[]
+      {}, new Object[]
+      {}, ExtensionLoader.class);
+   }
+
+}

Added: shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/Domain.java
===================================================================
--- shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/Domain.java	                        (rev 0)
+++ shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/Domain.java	2010-04-20 14:19:46 UTC (rev 4266)
@@ -0,0 +1,93 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.shrinkwrap.api;
+
+/**
+ * Encapsulates a shared {@link Configuration} to be used 
+ * by all {@link Archive}s created by this {@link Domain}'s
+ * {@link ArchiveFactory}.  New domains are created via 
+ * {@link ShrinkWrap#createDomain()} (for a default, shared configuration)
+ * or {@link ShrinkWrap#createDomain(ConfigurationBuilder)} (to supply an explicit
+ * configuration property set). 
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public final class Domain
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Instance Members -------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Configuration for this Domain
+    */
+   private final Configuration configuration;
+
+   /**
+    * Factory for creating archives within this {@link Domain}
+    */
+   private final ArchiveFactory archiveFactory;
+
+   //-------------------------------------------------------------------------------------||
+   // Constructor ------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Creates a new instance backed by the supplied {@link Configuration}
+    * 
+    * @param configuration
+    * @throws IllegalArgumentException If the configuration is not supplied
+    */
+   Domain(final Configuration configuration) throws IllegalArgumentException
+   {
+      // Precondition checks
+      if (configuration == null)
+      {
+         throw new IllegalArgumentException("configuration must be specified");
+      }
+
+      // Set
+      this.configuration = configuration;
+      this.archiveFactory = new ArchiveFactory(configuration);
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Functional Methods ----------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Obtains the {@link Configuration} associated with this {@link Domain}
+    * @return the configuration
+    */
+   public Configuration getConfiguration()
+   {
+      return configuration;
+   }
+
+   /**
+    * Obtains the {@link ArchiveFactory} for this domain.  All {@link Archive}s
+    * created from the factory will be backed by this domain's configuration.
+    * @return
+    */
+   public ArchiveFactory getArchiveFactory()
+   {
+      return archiveFactory;
+   }
+
+}

Added: shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/ShrinkWrap.java
===================================================================
--- shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/ShrinkWrap.java	                        (rev 0)
+++ shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/ShrinkWrap.java	2010-04-20 14:19:46 UTC (rev 4266)
@@ -0,0 +1,179 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.shrinkwrap.api;
+
+/**
+ * Main entry point into the ShrinkWrap system.  Each {@link Archive}
+ * has an associated {@link Configuration}
+ * provided at construction by the {@link Domain} under which 
+ * the archive was created.  {@link ShrinkWrap} provides static access to the 
+ * default {@link Domain} (and by extension the default 
+ * {@link Configuration}), as well as a shortcut mechanism to create
+ * {@link Archive}s under these defaults by way of 
+ * {@link ShrinkWrap#create(String, Class)}.  Additionally, this class is
+ * the hook to create new {@link Domain}s via 
+ * {@link ShrinkWrap#createDomain()}.  From here the user may further customize
+ * the new domain's {@link Configuration}.
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public final class ShrinkWrap
+{
+   //-------------------------------------------------------------------------------------||
+   // Constructor ------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Internal constructor; not to be called as this
+    * class provides static utilities only
+    */
+   private ShrinkWrap()
+   {
+      throw new UnsupportedOperationException("No instances permitted");
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Functional Methods ----------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Creates a new {@link Domain} containing a default 
+    * {@link Configuration}.  {@link ArchiveFactory}s created from this
+    * domain will have isolated configuration from archive factories created from
+    * other domains.  Likewise, all {@link ArchiveFactory}s and {@link Archive}s created
+    * from the returned domain will share the same configuration.
+    * 
+    * @return A new {@link Domain} with default configuration
+    */
+   public static Domain createDomain()
+   {
+      return createDomain(new ConfigurationBuilder());
+   }
+
+   /**
+    * Creates a new {@link Domain} containing configuration properties
+    * from the supplied {@link ConfigurationBuilder}.  {@link ArchiveFactory}s 
+    * created from this domain will have isolated configuration from archive 
+    * factories created from other domains.  Likewise, all 
+    * {@link ArchiveFactory}s and {@link Archive}s created
+    * from the returned domain will share the same configuration.
+    * 
+    * @param builder Builder with which we should create a {@link Configuration}
+    *   for this {@link Domain}
+    * @return A new {@link Domain} with default configuration
+    * @throws IllegalArgumentException If the builder is not supplied
+    */
+   public static Domain createDomain(final ConfigurationBuilder builder) throws IllegalArgumentException
+   {
+      if (builder == null)
+      {
+         throw new IllegalArgumentException("builder must be supplied");
+      }
+      return createDomain(builder.build());
+   }
+
+   /**
+    * Creates a new {@link Domain} containing configuration properties
+    * from the supplied {@link Configuration}.  {@link ArchiveFactory}s 
+    * created from this domain will have isolated configuration from archive 
+    * factories created from other domains.  Likewise, all 
+    * {@link ArchiveFactory}s and {@link Archive}s created
+    * from the returned domain will share the same configuration.
+    * 
+    * @param configuration {@link Configuration}
+    *   for this {@link Domain}
+    * @return A new {@link Domain} with default configuration
+    * @throws IllegalArgumentException If the configuration is not supplied
+    */
+   public static Domain createDomain(final Configuration configuration) throws IllegalArgumentException
+   {
+      if (configuration == null)
+      {
+         throw new IllegalArgumentException("configuration must be supplied");
+      }
+      return new Domain(configuration);
+   }
+
+   /**
+    * Returns a single domain with default configuration
+    * for use in applications with no explicit configuration
+    * or isolation requirements.
+    * @return
+    */
+   public static Domain getDefaultDomain()
+   {
+      return DefaultDomainWrapper.SINGLETON.getDefaultDomain();
+   }
+
+   /**
+    * Creates a new archive of the specified type.  The archive
+    * will be be backed by the default {@link Configuration}.
+    * Invoking this method is semantically equivalent to calling
+    * {@link Domain#getArchiveFactory()} upon the domain returned
+    * by {@link ShrinkWrap#getDefaultDomain()}.
+    * 
+    * @param archiveName The name of the archive
+    * @return An {@link Assignable} archive base  
+    * @throws IllegalArgumentException If either argument is not specified
+    */
+   public static <T extends Assignable> T create(final String archiveName, final Class<T> type)
+         throws IllegalArgumentException
+   {
+      // Precondition checks
+      if (archiveName == null || archiveName.length() == 0)
+      {
+         throw new IllegalArgumentException("ArchiveName must be specified");
+      }
+      if (type == null)
+      {
+         throw new IllegalArgumentException("Type must be specified");
+      }
+
+      // Delegate to the default domain's archive factory for creation
+      return ShrinkWrap.getDefaultDomain().getArchiveFactory().create(archiveName, type);
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Internal Helper Members ------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Singleton wrapper to encapsulate a default domain 
+    *
+    * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+    * @version $Revision: $
+    */
+   private enum DefaultDomainWrapper {
+      SINGLETON;
+
+      /**
+       * The wrapped default domain
+       */
+      private Domain domain = ShrinkWrap.createDomain();
+
+      /**
+       * Obtains the default domain for the system
+       * @return
+       */
+      private Domain getDefaultDomain()
+      {
+         return domain;
+      }
+   }
+
+}

Modified: shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/ArchiveBase.java
===================================================================
--- shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/ArchiveBase.java	2010-04-17 15:31:39 UTC (rev 4265)
+++ shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/ArchiveBase.java	2010-04-20 14:19:46 UTC (rev 4266)
@@ -28,14 +28,15 @@
 import org.jboss.shrinkwrap.api.ArchivePaths;
 import org.jboss.shrinkwrap.api.Asset;
 import org.jboss.shrinkwrap.api.Assignable;
-import org.jboss.shrinkwrap.api.ExtensionLoader;
 import org.jboss.shrinkwrap.api.Filter;
 import org.jboss.shrinkwrap.api.Filters;
 import org.jboss.shrinkwrap.api.Node;
+import org.jboss.shrinkwrap.api.Configuration;
 import org.jboss.shrinkwrap.api.formatter.Formatter;
 import org.jboss.shrinkwrap.api.formatter.Formatters;
 import org.jboss.shrinkwrap.impl.base.asset.ArchiveAsset;
 import org.jboss.shrinkwrap.impl.base.path.BasicPath;
+import org.jboss.shrinkwrap.spi.Configurable;
 
 /**
  * ArchiveBase
@@ -49,7 +50,7 @@
  * @author <a href="mailto:baileyje at gmail.com">John Bailey</a>
  * @version $Revision: $
  */
-public abstract class ArchiveBase<T extends Archive<T>> implements Archive<T>
+public abstract class ArchiveBase<T extends Archive<T>> implements Archive<T>, Configurable
 {
 
    //-------------------------------------------------------------------------------------||
@@ -71,10 +72,10 @@
    private final String name;
 
    /**
-    * Defines how the Specializer extensions are loaded. 
+    * Configuration for this archive 
     */
-   private ExtensionLoader extensionLoader = new ServiceExtensionLoader();
-   
+   private final Configuration configuration;
+
    //-------------------------------------------------------------------------------------||
    // Constructor ------------------------------------------------------------------------||
    //-------------------------------------------------------------------------------------||
@@ -85,18 +86,19 @@
     * Creates a new Archive with the specified name
     * 
     * @param name Name of the archive
-    * @param extensionLoader The extensionLoader to be used
+    * @param configuration The configuration for this archive
     * @throws IllegalArgumentException If the name was not specified
     */
-   protected ArchiveBase(final String name, final ExtensionLoader extensionLoader) throws IllegalArgumentException
+   protected ArchiveBase(final String name, final Configuration configuration)
+         throws IllegalArgumentException
    {
       // Precondition checks
       Validate.notNullOrEmpty(name, "name must be specified");
-      Validate.notNull(extensionLoader, "extensionLoader must be specified");
+      Validate.notNull(configuration, "configuration must be specified");
 
       // Set
       this.name = name;
-      this.extensionLoader = extensionLoader;
+      this.configuration = configuration;
    }
 
    //-------------------------------------------------------------------------------------||
@@ -188,11 +190,11 @@
    {
       // Precondition check
       Validate.notNullOrEmpty(path, "path must be specified");
-      
+
       // Delegate and return
       return this.addDirectory(ArchivePaths.create(path));
    }
-   
+
    /**
     * {@inheritDoc}
     * @see org.jboss.shrinkwrap.api.Archive#addDirectories(org.jboss.shrinkwrap.api.ArchivePath[])
@@ -202,13 +204,13 @@
    {
       // Precondition check
       Validate.notNull(paths, "paths must be specified");
-      
+
       // Add
       for (final ArchivePath path : paths)
       {
          this.addDirectory(path);
       }
-      
+
       // Return
       return covariantReturn();
    }
@@ -222,16 +224,17 @@
    {
       // Precondition check
       Validate.notNull(paths, "paths must be specified");
-      
+
       // Represent as array of Paths
       final Collection<ArchivePath> pathsCollection = new ArrayList<ArchivePath>(paths.length);
       for (final String path : paths)
       {
          pathsCollection.add(ArchivePaths.create(path));
       }
-      
+
       // Delegate and return
-      return this.addDirectories(pathsCollection.toArray(new ArchivePath[]{}));
+      return this.addDirectories(pathsCollection.toArray(new ArchivePath[]
+      {}));
    }
 
    /**
@@ -261,8 +264,8 @@
    public T merge(Archive<?> source, Filter<ArchivePath> filter) throws IllegalArgumentException
    {
       return merge(source, new BasicPath(), filter);
-   }   
-   
+   }
+
    /**
     * {@inheritDoc}
     * @see org.jboss.shrinkwrap.api.Archive#merge(org.jboss.shrinkwrap.api.ArchivePath, org.jboss.shrinkwrap.api.Archive)
@@ -272,10 +275,10 @@
    {
       Validate.notNull(source, "No source archive was specified");
       Validate.notNull(path, "No path was specified");
-      
+
       return merge(source, path, Filters.includeAll());
    }
-   
+
    /**
     * {@inheritDoc}
     * @see org.jboss.shrinkwrap.api.Archive#merge(org.jboss.shrinkwrap.api.Archive, org.jboss.shrinkwrap.api.Path, org.jboss.shrinkwrap.api.Filter)
@@ -297,16 +300,16 @@
       {
          final Node node = contentEntry.getValue();
          ArchivePath nodePath = new BasicPath(path, contentEntry.getKey());
-         if( !filter.include(nodePath)) 
+         if (!filter.include(nodePath))
          {
             continue;
          }
          // Delegate
-         if (node.getAsset() == null) 
+         if (node.getAsset() == null)
          {
             addDirectory(nodePath);
-         } 
-         else 
+         }
+         else
          {
             add(node.getAsset(), nodePath);
          }
@@ -316,16 +319,16 @@
 
    /**
     * {@inheritDoc}
-    * @see org.jboss.shrinkwrap.api.Specializer#as(java.lang.Class)
+    * @see org.jboss.shrinkwrap.api.Assignable#as(java.lang.Class)
     */
    @Override
-   public <TYPE extends Assignable> TYPE as(Class<TYPE> clazz)
+   public <TYPE extends Assignable> TYPE as(final Class<TYPE> clazz)
    {
       Validate.notNull(clazz, "Class must be specified");
 
-      return extensionLoader.load(clazz, this);
+      return this.configuration.getExtensionLoader().load(clazz, this);
    }
-   
+
    /**
     * {@inheritDoc}
     * @see org.jboss.shrinkwrap.api.Archive#toString()
@@ -335,7 +338,7 @@
    {
       return this.toString(Formatters.SIMPLE);
    }
-   
+
    /**
     * {@inheritDoc}
     * @see org.jboss.shrinkwrap.api.Archive#toString(boolean)
@@ -354,17 +357,25 @@
    public String toString(final Formatter formatter) throws IllegalArgumentException
    {
       // Precondition check
-      if(formatter==null)
+      if (formatter == null)
       {
          throw new IllegalArgumentException("Formatter must be specified");
       }
-      
+
       // Delegate
       return formatter.format(this);
    }
-   
-   
 
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.shrinkwrap.spi.Configurable#getConfiguration()
+    */
+   @Override
+   public Configuration getConfiguration()
+   {
+      return configuration;
+   }
+
    //-------------------------------------------------------------------------------------||
    // Contracts --------------------------------------------------------------------------||
    //-------------------------------------------------------------------------------------||

Added: shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/ConfigurableArchiveImpl.java
===================================================================
--- shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/ConfigurableArchiveImpl.java	                        (rev 0)
+++ shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/ConfigurableArchiveImpl.java	2010-04-20 14:19:46 UTC (rev 4266)
@@ -0,0 +1,84 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.shrinkwrap.impl.base;
+
+import java.util.logging.Logger;
+
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.Assignable;
+import org.jboss.shrinkwrap.api.Configuration;
+import org.jboss.shrinkwrap.spi.Configurable;
+
+/**
+ * {@link Assignable} implementation view of an {@link ConfigurableArchive}. 
+ * Provides access to the internal {@link Configuration} of an 
+ * {@link Archive}.
+ * 
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class ConfigurableArchiveImpl extends AssignableBase implements Configurable
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Logger
+    */
+   private static final Logger log = Logger.getLogger(ConfigurableArchiveImpl.class.getName());
+
+   /**
+    * Implementation class view 
+    */
+   private final ArchiveBase<?> archive;
+
+   //-------------------------------------------------------------------------------------||
+   // Constructor ------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   public ConfigurableArchiveImpl(final ArchiveBase<?> archive)
+   {
+      Validate.notNull(archive, "Archive must be specified");
+      this.archive = archive;
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Required Implementations -----------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.shrinkwrap.impl.base.AssignableBase#getArchive()
+    */
+   @Override
+   protected Archive<?> getArchive()
+   {
+      return archive;
+   }
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.shrinkwrap.spi.Configurable#getConfiguration()
+    */
+   @Override
+   public Configuration getConfiguration()
+   {
+      return archive.getConfiguration();
+   }
+}

Modified: shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/MemoryMapArchiveBase.java
===================================================================
--- shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/MemoryMapArchiveBase.java	2010-04-17 15:31:39 UTC (rev 4265)
+++ shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/MemoryMapArchiveBase.java	2010-04-20 14:19:46 UTC (rev 4266)
@@ -26,10 +26,10 @@
 import org.jboss.shrinkwrap.api.Archive;
 import org.jboss.shrinkwrap.api.ArchivePath;
 import org.jboss.shrinkwrap.api.Asset;
-import org.jboss.shrinkwrap.api.ExtensionLoader;
 import org.jboss.shrinkwrap.api.Filter;
 import org.jboss.shrinkwrap.api.IllegalArchivePathException;
 import org.jboss.shrinkwrap.api.Node;
+import org.jboss.shrinkwrap.api.Configuration;
 import org.jboss.shrinkwrap.impl.base.asset.ArchiveAsset;
 import org.jboss.shrinkwrap.impl.base.path.BasicPath;
 import org.jboss.shrinkwrap.impl.base.path.PathUtil;
@@ -71,11 +71,12 @@
     * This constructor will generate a 
     * unique {@link Archive#getName()} per instance.
     *  
-    * @param extensionLoader The extensionLoader to be used
+    * @param configuration The configuration for this archive
+    * @throws IllegalArgumentException If the configuration is not specified
     */
-   public MemoryMapArchiveBase(ExtensionLoader extensionLoader)
+   public MemoryMapArchiveBase(final Configuration configuration) throws IllegalArgumentException
    {
-      this("Archive-" + UUID.randomUUID().toString() + ".jar", extensionLoader);
+      this("Archive-" + UUID.randomUUID().toString() + ".jar", configuration);
    }
 
    /**
@@ -84,14 +85,16 @@
     * This constructor will generate an {@link Archive} with the provided name.
     *  
     * @param archiveName
-    * @param extensionLoader The extensionLoader to be used
+    * @param configuration The configuration for this archive
+    * @throws IllegalArgumentException If the name or configuration is not specified
     */
-   public MemoryMapArchiveBase(final String archiveName, ExtensionLoader extensionLoader)
+   public MemoryMapArchiveBase(final String archiveName, final Configuration configuration)
+         throws IllegalArgumentException
    {
-      super(archiveName, extensionLoader);
-      
+      super(archiveName, configuration);
+
       // Add the root node to the content
-      ArchivePath rootPath = new BasicPath("/");
+      final ArchivePath rootPath = new BasicPath("/");
       content.put(rootPath, new NodeImpl(rootPath));
    }
 
@@ -108,27 +111,27 @@
    {
       Validate.notNull(asset, "No asset was specified");
       Validate.notNull(path, "No path was specified");
-      
+
       // Retrieve the parent
       NodeImpl parentNode = obtainParent(path.getParent());
-      
+
       // Check if a the path already contains a node so we remove it from the parent's children
       NodeImpl existingNode = content.get(path);
-      if (parentNode != null && existingNode != null) 
+      if (parentNode != null && existingNode != null)
       {
          parentNode.removeChild(existingNode);
       }
-      
+
       // Add the node to the content of the archive
       NodeImpl node = new NodeImpl(path, asset);
       content.put(path, node);
 
       // Add the new node to the parent as a child
-      if (parentNode != null) 
+      if (parentNode != null)
       {
          parentNode.addChild(node);
       }
-      
+
       return covariantReturn();
    }
 
@@ -158,7 +161,7 @@
 
       return covariantReturn();
    }
-   
+
    /**
     * {@inheritDoc}
     * @see org.jboss.shrinkwrap.api.Archive#addDirectory(org.jboss.shrinkwrap.api.ArchivePath)
@@ -168,24 +171,25 @@
    {
       // Precondition check
       Validate.notNull(path, "path must be specified");
-      
+
       // Adjust the path to remove any trailing slash
       ArchivePath adjustedPath = new BasicPath(PathUtil.optionallyRemoveFollowingSlash(path.get()));
-      
+
       // Check if it exists. If it doesn't, create it and add it. The same with all the
       // non-existing parents
-      if (!contains(adjustedPath)) 
+      if (!contains(adjustedPath))
       {
          NodeImpl node = new NodeImpl(adjustedPath);
          content.put(adjustedPath, node);
-         
+
          // retrieve the parent and add the node as a child
          NodeImpl parentNode = obtainParent(adjustedPath.getParent());
-         if (parentNode != null) {
+         if (parentNode != null)
+         {
             parentNode.addChild(node);
          }
       }
-      
+
       return covariantReturn();
    }
 
@@ -214,19 +218,19 @@
    public boolean delete(ArchivePath path)
    {
       Validate.notNull(path, "No path was specified");
-      
+
       NodeImpl node = content.get(path);
-      if (node == null) 
+      if (node == null)
       {
          return false;
       }
-      
+
       NodeImpl parentNode = content.get(path.getParent());
-      if (parentNode != null) 
+      if (parentNode != null)
       {
          parentNode.removeChild(node);
       }
-      
+
       return content.remove(path) != null;
    }
 
@@ -254,17 +258,17 @@
    public Map<ArchivePath, Node> getContent()
    {
       Map<ArchivePath, Node> ret = new HashMap<ArchivePath, Node>();
-      for (Map.Entry<ArchivePath, NodeImpl> item : content.entrySet()) 
+      for (Map.Entry<ArchivePath, NodeImpl> item : content.entrySet())
       {
-         if (!item.getKey().equals(new BasicPath("/"))) 
+         if (!item.getKey().equals(new BasicPath("/")))
          {
             ret.put(item.getKey(), item.getValue());
          }
       }
-      
+
       return Collections.unmodifiableMap(ret);
    }
-   
+
    /**
     * {@inheritDoc}
     * @see org.jboss.shrinkwrap.api.Archive#getContent(org.jboss.shrinkwrap.api.Filter)
@@ -273,13 +277,13 @@
    public Map<ArchivePath, Node> getContent(Filter<ArchivePath> filter)
    {
       Validate.notNull(filter, "Filter must be specified");
-      
+
       Map<ArchivePath, Node> filteredContent = new HashMap<ArchivePath, Node>();
-      for(Map.Entry<ArchivePath, NodeImpl> contentEntry : content.entrySet())
+      for (Map.Entry<ArchivePath, NodeImpl> contentEntry : content.entrySet())
       {
-         if(filter.include(contentEntry.getKey()))
+         if (filter.include(contentEntry.getKey()))
          {
-            if (!contentEntry.getKey().equals(new BasicPath("/"))) 
+            if (!contentEntry.getKey().equals(new BasicPath("/")))
             {
                filteredContent.put(contentEntry.getKey(), contentEntry.getValue());
             }
@@ -380,10 +384,10 @@
 
       return new BasicPath(nestedArchiveContext);
    }
-   
+
    /**
     * Used to retrieve a {@link Node} from the content of the {@link Archive}. If the 
-    * {@link Node} doesn´t exists in the specified location, it is created and added 
+    * {@link Node} doesn�t exists in the specified location, it is created and added 
     * to the {@link Archive}. The same happens to all its non-existing parents. However, 
     * if the {@link Node} is an asset, an IllegalArchivePathException is thrown.
     *  
@@ -391,39 +395,41 @@
     * @return The {@link Node} in the specified path
     * @throws IllegalArchivePathException if the node is an {@link Asset}
     */
-   private NodeImpl obtainParent(ArchivePath path) 
+   private NodeImpl obtainParent(ArchivePath path)
    {
-      if (path == null) {
+      if (path == null)
+      {
          return null;
       }
-      
+
       NodeImpl node = content.get(path);
-      
+
       // If the node exists, just return it
-      if (node != null) 
+      if (node != null)
       {
          // if the node is an asset, throw an exception
-         if (node.getAsset() != null) 
+         if (node.getAsset() != null)
          {
-            throw new IllegalArchivePathException("Could not create node under " 
-                  + path.getParent() + ". It points to an asset.");
+            throw new IllegalArchivePathException("Could not create node under " + path.getParent()
+                  + ". It points to an asset.");
          }
-         
+
          return node;
       }
-      
+
       // If the node doesn't exists, create it. Also create all possible non-existing 
       // parents
       node = new NodeImpl(path);
       NodeImpl parentNode = obtainParent(path.getParent());
-      
-      if (parentNode != null) {
+
+      if (parentNode != null)
+      {
          parentNode.addChild(node);
       }
-      
+
       // Add the node to the contents of the archive
       content.put(path, node);
-      
+
       return node;
    }
 }

Modified: shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/MemoryMapArchiveImpl.java
===================================================================
--- shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/MemoryMapArchiveImpl.java	2010-04-17 15:31:39 UTC (rev 4265)
+++ shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/MemoryMapArchiveImpl.java	2010-04-20 14:19:46 UTC (rev 4266)
@@ -17,7 +17,7 @@
 package org.jboss.shrinkwrap.impl.base;
 
 import org.jboss.shrinkwrap.api.Archive;
-import org.jboss.shrinkwrap.api.ExtensionLoader;
+import org.jboss.shrinkwrap.api.Configuration;
 import org.jboss.shrinkwrap.spi.MemoryMapArchive;
 
 /**
@@ -41,11 +41,12 @@
     * This constructor will generate a 
     * unique {@link Archive#getName()} per instance.
     *  
-    * @param extensionLoader The extensionLoader to be used
+    * @param configuration The configuration for this archive
+    * @throws IllegalArgumentException If the configuration is not specified
     */
-   public MemoryMapArchiveImpl(ExtensionLoader extensionLoader)
+   public MemoryMapArchiveImpl(final Configuration configuration) throws IllegalArgumentException
    {
-      super(extensionLoader);
+      super(configuration);
    }
 
    /**
@@ -54,16 +55,18 @@
     * This constructor will generate an {@link Archive} with the provided name.
     *  
     * @param archiveName
-    * @param extensionLoader The extensionLoader to be used
+    * @param configuration The configuration for this archive
+    * @throws IllegalArgumentException If the name or configuration is not specified
     */
-   public MemoryMapArchiveImpl(String archiveName, ExtensionLoader extensionLoader)
+   public MemoryMapArchiveImpl(final String archiveName, final Configuration configuration)
+         throws IllegalArgumentException
    {
-      super(archiveName, extensionLoader);
+      super(archiveName, configuration);
    }
 
-   /*
-    * (non-Javadoc)
-    * @see org.jboss.declarchive.impl.base.MemoryMapArchiveBase#getActualClass()
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.shrinkwrap.impl.base.ArchiveBase#getActualClass()
     */
    @Override
    protected Class<MemoryMapArchive> getActualClass()

Modified: shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/JdkZipExporterDelegate.java
===================================================================
--- shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/JdkZipExporterDelegate.java	2010-04-17 15:31:39 UTC (rev 4265)
+++ shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/JdkZipExporterDelegate.java	2010-04-20 14:19:46 UTC (rev 4266)
@@ -25,7 +25,6 @@
 import java.util.concurrent.Callable;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -42,6 +41,7 @@
 import org.jboss.shrinkwrap.impl.base.io.StreamErrorHandler;
 import org.jboss.shrinkwrap.impl.base.io.StreamTask;
 import org.jboss.shrinkwrap.impl.base.path.PathUtil;
+import org.jboss.shrinkwrap.spi.Configurable;
 
 /**
  * JDK-based implementation of a ZIP exporter.  Cannot handle archives
@@ -62,15 +62,6 @@
     */
    private static final Logger log = Logger.getLogger(JdkZipExporterDelegate.class.getName());
 
-   /**
-    * Services used to submit new jobs (encoding occurs in a separate Thread)
-    */
-   private static final ExecutorService service;
-   static
-   {
-      service = Executors.newCachedThreadPool();
-   }
-
    //-------------------------------------------------------------------------------------||
    // Instance Members -------------------------------------------------------------------||
    //-------------------------------------------------------------------------------------||
@@ -84,7 +75,7 @@
     * {@link InputStream} to be returned to the caller
     */
    private InputStream inputStream;
-   
+
    /**
     * Used to see if we have exported at least one node
     */
@@ -143,29 +134,29 @@
             }
             catch (final Exception e)
             {
-               
+
                // Log this and rethrow; otherwise if we go into deadlock we won't ever 
                // be able to get the underlying cause from the Future 
                log.log(Level.WARNING, "Exception encountered during export of archive", e);
-               
+
                // SHRINKWRAP-133 - if the Zip is empty, it won't close and a deadlock is triggered
                //TODO Find a better solution :)
-               if (pathsExported.isEmpty()) 
+               if (pathsExported.isEmpty())
                {
                   // Ensure the streams are set up before we do any work on them;
                   // it's possible that we encountered an exception before 
                   // everything has been initialized by the main Thread
                   // SHRINKWRAP-137
                   latch.await();
-                  
+
                   zipOutputStream.putNextEntry(new ZipEntry("dummy.txt"));
                }
-               
+
                throw e;
             }
             finally
             {
-               
+
                try
                {
                   zipOutputStream.close();
@@ -175,7 +166,7 @@
                   // Ignore, but warn of danger
                   log.log(Level.WARNING,
                         "[SHRINKWRAP-120] Possible deadlock scenario: Got exception on closing the ZIP out stream: "
-                        + ioe.getMessage(), ioe);
+                              + ioe.getMessage(), ioe);
                }
             }
 
@@ -184,6 +175,7 @@
       };
 
       // Get a handle and return it to the caller
+      final ExecutorService service = this.getArchive().as(Configurable.class).getConfiguration().getExecutorService();
       final Future<Void> job = service.submit(exportTask);
 
       /*
@@ -235,18 +227,18 @@
       {
          throw new IllegalArgumentException("asset must be specified");
       }
-      
+
       // Mark if we're writing a directory
       final boolean isDirectory = node.getAsset() == null;
-      
+
       InputStream stream = null;
-      if (!isDirectory) 
+      if (!isDirectory)
       {
          stream = node.getAsset().openStream();
       }
 
       final String pathName = PathUtil.optionallyRemovePrecedingSlash(path.get());
-      
+
       // Make a task for this stream and close when done
       IOUtil.closeOnComplete(stream, new StreamTask<InputStream>()
       {
@@ -315,5 +307,4 @@
       return inputStream;
    }
 
-
 }

Modified: shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/spec/JavaArchiveImpl.java
===================================================================
--- shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/spec/JavaArchiveImpl.java	2010-04-17 15:31:39 UTC (rev 4265)
+++ shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/spec/JavaArchiveImpl.java	2010-04-20 14:19:46 UTC (rev 4266)
@@ -90,8 +90,9 @@
       return PATH_MANIFEST;
    }
    
-   /* (non-Javadoc)
-    * @see org.jboss.declarchive.impl.base.ContainerBase#getClassesPath()
+   /*
+    * (non-Javadoc)
+    * @see org.jboss.shrinkwrap.impl.base.container.ContainerBase#getClassesPath()
     */
    @Override
    protected ArchivePath getClassesPath()

Added: shrinkwrap/trunk/impl-base/src/main/resources/META-INF/services/org.jboss.shrinkwrap.spi.Configurable
===================================================================
--- shrinkwrap/trunk/impl-base/src/main/resources/META-INF/services/org.jboss.shrinkwrap.spi.Configurable	                        (rev 0)
+++ shrinkwrap/trunk/impl-base/src/main/resources/META-INF/services/org.jboss.shrinkwrap.spi.Configurable	2010-04-20 14:19:46 UTC (rev 4266)
@@ -0,0 +1 @@
+org.jboss.shrinkwrap.impl.base.ConfigurableArchiveImpl
\ No newline at end of file

Modified: shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/ArchivesTestCase.java
===================================================================
--- shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/ArchivesTestCase.java	2010-04-17 15:31:39 UTC (rev 4265)
+++ shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/ArchivesTestCase.java	2010-04-20 14:19:46 UTC (rev 4266)
@@ -16,22 +16,15 @@
  */
 package org.jboss.shrinkwrap.impl.base;
 
-import java.lang.reflect.Method;
-import java.security.AccessController;
-import java.security.PrivilegedExceptionAction;
-
 import junit.framework.Assert;
 
 import org.jboss.shrinkwrap.api.Archive;
-import org.jboss.shrinkwrap.api.Archives;
-import org.jboss.shrinkwrap.api.Assignable;
-import org.jboss.shrinkwrap.api.ExtensionLoader;
 import org.jboss.shrinkwrap.api.ArchivePath;
 import org.jboss.shrinkwrap.api.ArchivePaths;
+import org.jboss.shrinkwrap.api.Archives;
 import org.jboss.shrinkwrap.api.formatter.Formatter;
 import org.jboss.shrinkwrap.api.spec.JavaArchive;
 import org.jboss.shrinkwrap.impl.base.container.ContainerBase;
-import org.jboss.shrinkwrap.impl.base.spec.JavaArchiveImpl;
 import org.junit.Test;
 
 
@@ -40,13 +33,14 @@
  *
  * @author <a href="mailto:aslak at conduct.no">Aslak Knutsen</a>
  * @version $Revision: $
+ * @deprecated To be moved / replaced by the {@link ShrinkWrapTestCase}
  */
+ at Deprecated
 public class ArchivesTestCase
 {
    @Test
    public void shouldBeAbleToCreateANewArchive() throws Exception {
       String archiveName = "test.war";
-      reset();
       JavaArchive archive = Archives.create(archiveName, JavaArchive.class);
       
       Assert.assertNotNull(
@@ -60,9 +54,7 @@
    
    @Test
    public void shouldBeAbleToAddOverride() throws Exception {
-      reset();
       Archives.addExtensionOverride(JavaArchive.class, MockJavaArchiveImpl.class);
-      
       JavaArchive archive = Archives.create("test.jar", JavaArchive.class);
       
       Assert.assertEquals(
@@ -70,79 +62,7 @@
             MockJavaArchiveImpl.class, archive.getClass());
       
    }
-
-   private static boolean extensionLoaderCalled = false;   
    
-   @Test
-   public void shouldBeAbleToSetExtensionLoader() throws Exception {
-      reset();
-      Archives.setExtensionLoader(new ExtensionLoader()
-      {
-         @Override
-         public <T extends Assignable> T load(Class<T> extensionClass,
-               Archive<?> baseArchive)
-         {
-            extensionLoaderCalled = true;
-            return (T)new JavaArchiveImpl(baseArchive);
-         }
-         
-         @Override
-         public <T extends Assignable> ExtensionLoader addOverride(
-               Class<T> extensionClass, Class<? extends T> extensionImplClass)
-         {
-            return null;
-         }
-      });
-      Archives.create("test.jar", JavaArchive.class);
-
-      Assert.assertTrue(
-            "Specified ExtensionLoader should have been used", 
-            extensionLoaderCalled);
-   }
-
-   @Test(expected = IllegalArgumentException.class)
-   public void shouldNotBeAbleToSetExtensionLoaderNull() throws Exception {
-      reset();
-      Archives.setExtensionLoader(null);
-   }
-
-   @Test(expected = IllegalStateException.class)
-   public void shouldNotBeAbleToSetExtensionLoaderAfterInitialized() throws Exception {
-      reset();
-      Archives.create("test.jar", JavaArchive.class);
-      Archives.setExtensionLoader(new ExtensionLoader()
-      {
-         @Override
-         public <T extends Assignable> T load(Class<T> extensionClass,
-               Archive<?> baseArchive)
-         {
-            return null;
-         }
-         
-         @Override
-         public <T extends Assignable> ExtensionLoader addOverride(
-               Class<T> extensionClass, Class<? extends T> extensionImplClass)
-         {
-            return null;
-         }
-      });
-   }
-   
-   private void reset() throws Exception {
-      
-      Method method = AccessController.doPrivileged(new PrivilegedExceptionAction<Method>()
-      {
-         @Override
-         public Method run() throws Exception
-         {
-            Method method = Archives.class.getDeclaredMethod("resetState", new Class<?>[]{});
-            method.setAccessible(true);
-            return method;
-         }
-      });
-      method.invoke(null);
-   }
-   
    public static class MockJavaArchiveImpl extends ContainerBase<JavaArchive> implements JavaArchive {
 
       public MockJavaArchiveImpl(Archive<?> archive)

Added: shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/ConfigurationBuilderTestCase.java
===================================================================
--- shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/ConfigurationBuilderTestCase.java	                        (rev 0)
+++ shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/ConfigurationBuilderTestCase.java	2010-04-20 14:19:46 UTC (rev 4266)
@@ -0,0 +1,179 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.shrinkwrap.impl.base;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import junit.framework.TestCase;
+
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.Assignable;
+import org.jboss.shrinkwrap.api.Configuration;
+import org.jboss.shrinkwrap.api.ConfigurationBuilder;
+import org.jboss.shrinkwrap.api.ExtensionLoader;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests to ensure the {@link ConfigurationBuilder} is working 
+ * as contracted
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class ConfigurationBuilderTestCase
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Instance Members -------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * The builder under test
+    */
+   private ConfigurationBuilder builder;
+
+   //-------------------------------------------------------------------------------------||
+   // Lifecycle --------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Creates the {@link ConfigurationBuilder} instance to be tested
+    */
+   @Before
+   public void createDefaultBuilder()
+   {
+      builder = new ConfigurationBuilder();
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Tests ------------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Ensures that the {@link ExecutorService} is defaulted
+    * as contracted to {@link Executors#newCachedThreadPool()}
+    */
+   @Test
+   public void defaultsExecutorService()
+   {
+      // Define the expected type as contracted
+      final Class<?> expectedType = Executors.newCachedThreadPool().getClass();
+
+      // Build and default
+      builder.build();
+
+      // Get the defaulted service
+      final ExecutorService service = builder.getExecutorService();
+
+      // Test
+      Assert.assertNotNull("The builder should default an " + ExecutorService.class.getSimpleName(), service);
+      Assert.assertEquals("The default " + ExecutorService.class.getSimpleName() + " was not of contracted type",
+            expectedType, service.getClass());
+   }
+
+   /**
+    * Ensures that the {@link ExtensionLoader} is defaulted
+    * as contracted to a new instance.
+    */
+   @Test
+   public void defaultsExtensionLoader()
+   {
+      // Build and default
+      builder.build();
+
+      final ExtensionLoader loader = builder.getExtensionLoader();
+      Assert.assertNotNull("The builder should default an " + ExtensionLoader.class.getSimpleName(), loader);
+   }
+
+   /**
+    * Ensures that building does not override a user-supplied 
+    * {@link ExecutorService}
+    */
+   @Test
+   public void allowsUserDefinedExecutorService()
+   {
+      // Define a custom ES
+      final ExecutorService service = Executors.newSingleThreadExecutor();
+
+      // Supply and build
+      builder.executorService(service).build();
+
+      // Test
+      TestCase.assertEquals("Building should not override the user-supplied " + ExecutorService.class.getSimpleName(),
+            service, builder.getExecutorService());
+   }
+
+   /**
+    * Ensures that building does not override a user-supplied 
+    * {@link ExtensionLoader}
+    */
+   @Test
+   public void allowsUserDefinedExtensionLoader()
+   {
+      // Define a custom EL
+      final ExtensionLoader loader = new ExtensionLoader()
+      {
+
+         @Override
+         public <T extends Assignable> T load(final Class<T> extensionClass, final Archive<?> baseArchive)
+         {
+            return null;
+         }
+
+         @Override
+         public <T extends Assignable> ExtensionLoader addOverride(final Class<T> extensionClass,
+               final Class<? extends T> extensionImplClass)
+         {
+            return null;
+         }
+      };
+
+      // Supply and build
+      builder.extensionLoader(loader).build();
+
+      // Test
+      TestCase.assertEquals("Building should not override the user-supplied " + ExtensionLoader.class.getSimpleName(),
+            loader, builder.getExtensionLoader());
+   }
+
+   /**
+    * Ensures that invoking {@link ConfigurationBuilder#build()}
+    * creates a {@link Configuration} with the same properties
+    * as in the builder
+    */
+   public void createsConfiguration()
+   {
+      // Create the config
+      final Configuration configuration = builder.build();
+
+      // Grab props from the builder
+      final ExecutorService service = builder.getExecutorService();
+      final ExtensionLoader loader = builder.getExtensionLoader();
+
+      // Test that they match the props in the config
+      TestCase.assertEquals(
+            ExecutorService.class.getSimpleName() + " in the config does not match that in the builder", service,
+            configuration.getExecutorService());
+      TestCase.assertEquals(
+            ExtensionLoader.class.getSimpleName() + " in the config does not match that in the builder", loader,
+            configuration.getExtensionLoader());
+   }
+
+}

Added: shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/ShrinkWrapTestCase.java
===================================================================
--- shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/ShrinkWrapTestCase.java	                        (rev 0)
+++ shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/ShrinkWrapTestCase.java	2010-04-20 14:19:46 UTC (rev 4266)
@@ -0,0 +1,198 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.shrinkwrap.impl.base;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.Assignable;
+import org.jboss.shrinkwrap.api.Configuration;
+import org.jboss.shrinkwrap.api.ConfigurationBuilder;
+import org.jboss.shrinkwrap.api.Domain;
+import org.jboss.shrinkwrap.api.ExtensionLoader;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.junit.Test;
+
+/**
+ * Tests ensuring that the static entry point {@link ShrinkWrap}
+ * is working as contracted.
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @author <a href="mailto:aslak at conduct.no">Aslak Knutsen</a>
+ * @version $Revision: $
+ */
+public class ShrinkWrapTestCase
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Tests ------------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Ensures we can create a new archive under the default {@link Domain}
+    */
+   @Test
+   public void createNewArchiveUnderDefaultDomain()
+   {
+      final String archiveName = "test.war";
+      final JavaArchive archive = ShrinkWrap.create(archiveName, JavaArchive.class);
+
+      // Test
+      Assert.assertNotNull("A archive should have been created", archive);
+      Assert.assertEquals("Should have the same name as given imput", archiveName, archive.getName());
+   }
+
+   /**
+    * Ensures that we can create isolated {@link Domain}s
+    */
+   @Test
+   public void createIsolatedDomains()
+   {
+      // Make a couple domains
+      final Domain domain1 = ShrinkWrap.createDomain();
+      final Domain domain2 = ShrinkWrap.createDomain();
+
+      // Ensure they exist
+      TestCase.assertNotNull("Domain should exist", domain1);
+      TestCase.assertNotNull("Domain should exist", domain2);
+
+      // Ensure they're not equal
+      TestCase.assertNotSame("Creation of domains should return new instances", domain1, domain2);
+
+      // Ensure the underlying configs are not equal
+      TestCase.assertNotSame("Creation of domains should have unique / isolated configurations", domain1
+            .getConfiguration(), domain2.getConfiguration());
+   }
+
+   /**
+    * Ensures that we can create a new {@link Domain} with explicit
+    * {@link Configuration}
+    */
+   @Test
+   public void createDomainWithExplicitConfiguration()
+   {
+      // Define configuration properties
+      final ExecutorService service = Executors.newSingleThreadExecutor();
+      final ExtensionLoader loader = new MockExtensionLoader();
+
+      // Create a new domain using these config props in a config 
+      final Domain domain = ShrinkWrap.createDomain(new ConfigurationBuilder().executorService(service)
+            .extensionLoader(loader).build());
+
+      // Test
+      TestCase.assertEquals(ExecutorService.class.getSimpleName() + " specified was not contained in resultant "
+            + Domain.class.getSimpleName(), service, domain.getConfiguration().getExecutorService());
+      TestCase.assertEquals(ExtensionLoader.class.getSimpleName() + " specified was not contained in resultant "
+            + Domain.class.getSimpleName(), loader, domain.getConfiguration().getExtensionLoader());
+
+   }
+
+   /**
+    * Ensures that we can create a new {@link Domain} with explicit
+    * {@link ConfigurationBuilder}
+    */
+   @Test
+   public void createDomainWithExplicitConfigurationBuilder()
+   {
+      // Define configuration properties
+      final ExecutorService service = Executors.newSingleThreadExecutor();
+      final ExtensionLoader loader = new MockExtensionLoader();
+
+      // Create a new domain using these config props in a builder
+      final Domain domain = ShrinkWrap.createDomain(new ConfigurationBuilder().executorService(service)
+            .extensionLoader(loader));
+
+      // Test
+      TestCase.assertEquals(ExecutorService.class.getSimpleName() + " specified was not contained in resultant "
+            + Domain.class.getSimpleName(), service, domain.getConfiguration().getExecutorService());
+      TestCase.assertEquals(ExtensionLoader.class.getSimpleName() + " specified was not contained in resultant "
+            + Domain.class.getSimpleName(), loader, domain.getConfiguration().getExtensionLoader());
+
+   }
+
+   /**
+    * Ensures we cannot create a new {@link Domain} with null 
+    * {@link Configuration} specified
+    */
+   @Test(expected = IllegalArgumentException.class)
+   public void newDomainRequiresConfiguration()
+   {
+      ShrinkWrap.createDomain((Configuration) null);
+   }
+
+   /**
+    * Ensures we cannot create a new {@link Domain} with null 
+    * {@link ConfigurationBuilder} specified
+    */
+   @Test(expected = IllegalArgumentException.class)
+   public void newDomainRequiresConfigurationBuilder()
+   {
+      ShrinkWrap.createDomain((ConfigurationBuilder) null);
+   }
+
+   /**
+    * Ensures all calls to get the default domain return the same reference
+    */
+   @Test
+   public void getDefaultDomain()
+   {
+      // Get the default domain twice
+      final Domain domain1 = ShrinkWrap.getDefaultDomain();
+      final Domain domain2 = ShrinkWrap.getDefaultDomain();
+
+      // Ensure they exist
+      TestCase.assertNotNull("Domain should exist", domain1);
+      TestCase.assertNotNull("Domain should exist", domain2);
+
+      // Ensure they're not equal
+      TestCase.assertSame("Obtaining the default domain should always return the same instance (idempotent operation)",
+            domain1, domain2);
+
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Internal Helper Members ------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * A Mock {@link ExtensionLoader} used only in testing reference equality
+    *
+    * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+    * @version $Revision: $
+    */
+   private static class MockExtensionLoader implements ExtensionLoader
+   {
+      @Override
+      public <T extends Assignable> T load(final Class<T> extensionClass, final Archive<?> baseArchive)
+      {
+         return null;
+      }
+
+      @Override
+      public <T extends Assignable> ExtensionLoader addOverride(final Class<T> extensionClass,
+            final Class<? extends T> extensionImplClass)
+      {
+         return null;
+      }
+   }
+
+}

Modified: shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/unit/MemoryMapArchiveTestCase.java
===================================================================
--- shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/unit/MemoryMapArchiveTestCase.java	2010-04-17 15:31:39 UTC (rev 4265)
+++ shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/unit/MemoryMapArchiveTestCase.java	2010-04-20 14:19:46 UTC (rev 4266)
@@ -18,8 +18,8 @@
 
 import junit.framework.Assert;
 
+import org.jboss.shrinkwrap.api.ShrinkWrap;
 import org.jboss.shrinkwrap.impl.base.MemoryMapArchiveImpl;
-import org.jboss.shrinkwrap.impl.base.ServiceExtensionLoader;
 import org.jboss.shrinkwrap.impl.base.test.ArchiveTestBase;
 import org.jboss.shrinkwrap.spi.MemoryMapArchive;
 import org.junit.Before;
@@ -44,7 +44,7 @@
     * @throws Exception
     */
    @Before
-   public void createArchive() throws Exception  
+   public void createArchive() throws Exception
    {
       archive = createNewArchive();
       archive.toString(false);
@@ -53,9 +53,9 @@
    @Override
    protected MemoryMapArchive createNewArchive()
    {
-      return new MemoryMapArchiveImpl(new ServiceExtensionLoader());
+      return new MemoryMapArchiveImpl(ShrinkWrap.getDefaultDomain().getConfiguration());
    }
-   
+
    /**
     * Return the created instance to the super class 
     * so it can perform the common test cases.
@@ -74,7 +74,7 @@
    public void testConstructorWithName() throws Exception
    {
       String name = "test.jar";
-      MemoryMapArchive tmp = new MemoryMapArchiveImpl(name, new ServiceExtensionLoader());
+      MemoryMapArchive tmp = new MemoryMapArchiveImpl(name, ShrinkWrap.getDefaultDomain().getConfiguration());
       Assert.assertEquals("Should return the same name as construtor arg", name, tmp.getName());
    }
 

Added: shrinkwrap/trunk/spi/src/main/java/org/jboss/shrinkwrap/spi/Configurable.java
===================================================================
--- shrinkwrap/trunk/spi/src/main/java/org/jboss/shrinkwrap/spi/Configurable.java	                        (rev 0)
+++ shrinkwrap/trunk/spi/src/main/java/org/jboss/shrinkwrap/spi/Configurable.java	2010-04-20 14:19:46 UTC (rev 4266)
@@ -0,0 +1,40 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.shrinkwrap.spi;
+
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.Assignable;
+import org.jboss.shrinkwrap.api.Configuration;
+
+/**
+ * {@link Assignable} view representing an entity backed by
+ * {@link Configuration}.
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public interface Configurable extends Assignable
+{
+   //-------------------------------------------------------------------------------------||
+   // Contracts --------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Obtains the {@link Configuration} associated with this {@link Archive}
+    */
+   Configuration getConfiguration();
+}



More information about the jboss-svn-commits mailing list