Index: impl-base/src/test/java/org/jboss/declarchive/impl/base/resource/TestUtils.java
===================================================================
--- impl-base/src/test/java/org/jboss/declarchive/impl/base/resource/TestUtils.java	(revision 0)
+++ impl-base/src/test/java/org/jboss/declarchive/impl/base/resource/TestUtils.java	(revision 0)
@@ -0,0 +1,35 @@
+package org.jboss.declarchive.impl.base.resource;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+/**
+ * @author <a href="mailto:aslak@conduct.no">Aslak Knutsen</a>
+ *
+ */
+class TestUtils
+{
+   private TestUtils() {}
+
+   /**
+    * Convert a inputstream to a string. 
+    * 
+    * Helper for testing the content of loaded resources.
+    * 
+    * @param in Open inputstream
+    * @return The inputstream as a String
+    * @throws Exception
+    */
+   static String convertToString(InputStream in) throws Exception
+   {
+      ByteArrayOutputStream out = new ByteArrayOutputStream();
+      int b;
+      while ((b = in.read()) != -1)
+      {
+         out.write(b);
+      }
+      out.close();
+      in.close();
+      return new String(out.toByteArray());
+   }
+}
\ No newline at end of file
Index: impl-base/src/test/java/org/jboss/declarchive/impl/base/resource/ClassloaderResourceTest.java
===================================================================
--- impl-base/src/test/java/org/jboss/declarchive/impl/base/resource/ClassloaderResourceTest.java	(revision 0)
+++ impl-base/src/test/java/org/jboss/declarchive/impl/base/resource/ClassloaderResourceTest.java	(revision 0)
@@ -0,0 +1,77 @@
+package org.jboss.declarchive.impl.base.resource;
+
+import java.io.InputStream;
+
+import junit.framework.Assert;
+
+import org.jboss.declarchive.spi.Resource;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:aslak@conduct.no">Aslak Knutsen</a>
+ *
+ */
+public class ClassloaderResourceTest
+{
+   private static final String EXISTING_RESOURCE = "org/jboss/declarchive/impl/base/resource/Test.properties";
+   private static final String NON_EXISTING_RESOURCE = "org/jboss/declarchive/impl/base/resource/NoFileShouldBePlacedHere.properties";
+   
+   @Test
+   public void shouldBeAbleToReadResource() throws Exception 
+   {
+      Resource resource = new ClassloaderResource(EXISTING_RESOURCE);
+      InputStream io = resource.getStream();
+
+      Assert.assertNotNull(io);
+      Assert.assertEquals("declarch=true", TestUtils.convertToString(io));
+   }
+
+   @Test
+   public void shouldBeAbleToReadDefaultName() throws Exception 
+   {
+      Resource resource = new ClassloaderResource(EXISTING_RESOURCE);
+      Assert.assertEquals("Test.properties", resource.getDefaultName());
+   }
+
+   @Test
+   public void shouldThrowExceptionOnNullName() 
+   {
+      try
+      {
+         new ClassloaderResource(null);
+         Assert.fail("Should have thrown IllegalArgumentException");
+      } 
+      catch (Exception e)
+      {
+         Assert.assertEquals(IllegalArgumentException.class, e.getClass());
+      }
+   }
+
+   @Test
+   public void shouldThrowExceptionOnNullClassloader() 
+   {
+      try
+      {
+         new ClassloaderResource(EXISTING_RESOURCE, null);
+         Assert.fail("Should have thrown IllegalArgumentException");
+      } 
+      catch (Exception e)
+      {
+         Assert.assertEquals(IllegalArgumentException.class, e.getClass());
+      }
+   }
+
+   @Test
+   public void shouldThrowExceptionOnMissingResource() 
+   {
+      try
+      {
+         new ClassloaderResource(NON_EXISTING_RESOURCE);
+         Assert.fail("Should have thrown IllegalArgumentException");
+      } 
+      catch (Exception e)
+      {
+         Assert.assertEquals(IllegalArgumentException.class, e.getClass());
+      }
+   }
+}
Index: impl-base/src/test/java/org/jboss/declarchive/impl/base/resource/FileResourceTest.java
===================================================================
--- impl-base/src/test/java/org/jboss/declarchive/impl/base/resource/FileResourceTest.java	(revision 0)
+++ impl-base/src/test/java/org/jboss/declarchive/impl/base/resource/FileResourceTest.java	(revision 0)
@@ -0,0 +1,61 @@
+package org.jboss.declarchive.impl.base.resource;
+
+import java.io.File;
+import java.io.InputStream;
+
+import junit.framework.Assert;
+
+import org.jboss.declarchive.spi.Resource;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:aslak@conduct.no">Aslak Knutsen</a>
+ *
+ */
+public class FileResourceTest
+{
+   private static final String BASE_PATH = "src/test/resources/org/jboss/declarchive/impl/base/resource/";
+   private static final String EXISTING_FILE = BASE_PATH + "Test.properties";
+   private static final String NON_EXISTING_FILE = BASE_PATH + "NoFileShouldBePlacedHere.properties";
+   
+   @Test
+   public void shouldBeAbleToReadFile() throws Exception 
+   {
+      Resource resource = new FileResource(new File(EXISTING_FILE));
+      InputStream io = resource.getStream();
+      
+      Assert.assertNotNull(io);
+      Assert.assertEquals("declarch=true", TestUtils.convertToString(io));
+   }
+   
+   @Test
+   public void shouldBeAbleToReadDefaultName() throws Exception 
+   {
+      Resource resource = new FileResource(new File(EXISTING_FILE));
+      Assert.assertEquals("Test.properties", resource.getDefaultName());
+   }
+   
+   @Test
+   public void shouldThrowExceptionOnNullFile() throws Exception 
+   {
+      try 
+      {
+         new FileResource(null);
+         Assert.fail("Should have thrown IllegalArgumentException");
+      } catch (Exception e) {
+         Assert.assertEquals(IllegalArgumentException.class, e.getClass());
+      }
+   }
+
+   @Test
+   public void shouldThrowExceptionOnMissingFile() throws Exception 
+   {
+      try 
+      {
+         new FileResource(new File(NON_EXISTING_FILE));
+         Assert.fail("Should have thrown IllegalArgumentException");
+      } catch (Exception e) {
+         Assert.assertEquals(IllegalArgumentException.class, e.getClass());
+      }
+   }
+}
Index: impl-base/src/test/java/org/jboss/declarchive/impl/base/resource/URLResourceTest.java
===================================================================
--- impl-base/src/test/java/org/jboss/declarchive/impl/base/resource/URLResourceTest.java	(revision 0)
+++ impl-base/src/test/java/org/jboss/declarchive/impl/base/resource/URLResourceTest.java	(revision 0)
@@ -0,0 +1,55 @@
+package org.jboss.declarchive.impl.base.resource;
+
+import java.io.InputStream;
+
+import junit.framework.Assert;
+
+import org.jboss.declarchive.spi.Resource;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:aslak@conduct.no">Aslak Knutsen</a>
+ *
+ */
+public class URLResourceTest
+{
+   private static final String EXISTING_RESOURCE = "org/jboss/declarchive/impl/base/resource/Test.properties";
+
+   @Test
+   public void shouldBeAbleToReadURL() throws Exception
+   {
+      Resource resource = new URLResource(
+            Thread.currentThread().getContextClassLoader()
+            .getResource(EXISTING_RESOURCE));
+
+      InputStream io = resource.getStream();
+
+      Assert.assertNotNull(io);
+      Assert.assertEquals("declarch=true", TestUtils.convertToString(io));
+   }
+
+   @Test
+   public void shouldBeAbleToReadDefaultName() throws Exception 
+   {
+      Resource resource = new URLResource(
+            Thread.currentThread().getContextClassLoader()
+            .getResource(EXISTING_RESOURCE));
+      
+      Assert.assertEquals("Test.properties", resource.getDefaultName());
+   }
+   
+   @Test
+   public void shouldThrowExceptionOnNullURL() throws Exception
+   {
+      try
+      {
+         new URLResource(null);
+         Assert.fail("Should have thrown IllegalArgumentException");
+      } 
+      catch (Exception e)
+      {
+         Assert.assertEquals(IllegalArgumentException.class, e.getClass());
+      }
+   }
+
+}
Index: impl-base/src/test/java/org/jboss/declarchive/impl/base/resource/ClassResourceTest.java
===================================================================
--- impl-base/src/test/java/org/jboss/declarchive/impl/base/resource/ClassResourceTest.java	(revision 0)
+++ impl-base/src/test/java/org/jboss/declarchive/impl/base/resource/ClassResourceTest.java	(revision 0)
@@ -0,0 +1,47 @@
+package org.jboss.declarchive.impl.base.resource;
+
+import java.io.InputStream;
+
+import org.jboss.declarchive.spi.Resource;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:aslak@conduct.no">Aslak Knutsen</a>
+ *
+ */
+public class ClassResourceTest
+{
+   
+   @Test
+   public void shouldBeAbleToReadThis() throws Exception 
+   {
+      Resource resource = new ClassResource(ClassResourceTest.class);
+      InputStream io = resource.getStream();
+
+      Assert.assertNotNull(io);      
+   }
+   
+   @Test
+   public void shouldBeAbleToReadDefaultName() throws Exception 
+   {
+      Resource resource = new ClassResource(ClassResourceTest.class);
+      Assert.assertEquals(
+            "org/jboss/declarchive/impl/base/resource/ClassResourceTest.class", 
+            resource.getDefaultName());
+   }
+
+   @Test
+   public void shouldThrowExceptionOnNullClass() throws Exception 
+   {
+      try 
+      {
+         new ClassResource(null);
+         Assert.fail("Should have thrown IllegalArgumentException");
+      } 
+      catch (Exception e) 
+      {
+         Assert.assertEquals(IllegalArgumentException.class, e.getClass());
+      }
+   }
+}
Index: impl-base/src/main/java/org/jboss/declarchive/impl/base/resource/ClassloaderResource.java
===================================================================
--- impl-base/src/main/java/org/jboss/declarchive/impl/base/resource/ClassloaderResource.java	(revision 0)
+++ impl-base/src/main/java/org/jboss/declarchive/impl/base/resource/ClassloaderResource.java	(revision 0)
@@ -0,0 +1,92 @@
+package org.jboss.declarchive.impl.base.resource;
+
+import java.io.InputStream;
+import java.net.URL;
+
+import org.jboss.declarchive.spi.Resource;
+
+/**
+ * Loads the content of any resource located in the Classloader.
+ * 
+ * @author <a href="mailto:aslak@conduct.no">Aslak Knutsen</a>
+ *
+ */
+public class ClassloaderResource implements Resource
+{
+   private String resourceName;
+   private ClassLoader classLoader;
+   
+   /**
+    * Load a named resource using the current threads context classloader.
+    * 
+    * @param resourceName The name of the resource to load
+    * @throws IllegalArgumentException Name can not be null
+    * @throws IllegalArgumentException name must be found in given classloader
+    */
+   public ClassloaderResource(String resourceName) 
+   {
+      this(resourceName, SecurityActions.getThreadContextClassLoader());
+   }
+
+   /**
+    * Load a named resource using the given classloader.
+    * 
+    * @param resourceName The name of the resource to load
+    * @param classLoader The ClassLoader to use
+    * @throws IllegalArgumentException name can not be null
+    * @throws IllegalArgumentException classloader can not be null
+    * @throws IllegalArgumentException name must be found in given classloader
+    */
+   public ClassloaderResource(String resourceName, ClassLoader classLoader) 
+   {
+      if(resourceName == null) 
+      {
+         throw new IllegalArgumentException("Name must be specified");
+      }
+      if(classLoader == null) 
+      {
+         throw new IllegalArgumentException("ClassLoader must be specified");
+      }
+      if(classLoader.getResource(resourceName) == null) 
+      {
+         throw new IllegalArgumentException(resourceName + " not found in classloader " + classLoader);
+      }
+      this.resourceName = resourceName;
+      this.classLoader = classLoader;
+   }
+   
+   /**
+    * Get the default name using Resource URL.getFile().
+    */
+   @Override
+   public String getDefaultName()
+   {
+      return extractFileName(
+            classLoader.getResource(resourceName));
+   }
+
+   /**
+    * Opens up the given resource as a stream.
+    */
+   @Override
+   public InputStream getStream()
+   {
+      return classLoader.getResourceAsStream(resourceName);
+   }
+   
+   /*
+    * Extract the file name part of a URL excluding the directory structure.
+    * ie: /user/test/file.properties = file.properties
+    */
+   private String extractFileName(URL url) 
+   {
+      String fileName = url.getFile();
+      if(fileName.indexOf('/') != -1) 
+      {
+         return fileName.substring(
+               fileName.lastIndexOf('/') +1, 
+               fileName.length()); 
+      }
+      return fileName;
+   }
+}
Index: impl-base/src/main/java/org/jboss/declarchive/impl/base/resource/FileResource.java
===================================================================
--- impl-base/src/main/java/org/jboss/declarchive/impl/base/resource/FileResource.java	(revision 0)
+++ impl-base/src/main/java/org/jboss/declarchive/impl/base/resource/FileResource.java	(revision 0)
@@ -0,0 +1,70 @@
+package org.jboss.declarchive.impl.base.resource;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import org.jboss.declarchive.spi.Resource;
+
+/**
+ * Loads any File.
+ * 
+ * @author <a href="mailto:aslak@conduct.no">Aslak Knutsen</a>
+ *
+ */
+public class FileResource implements Resource
+{
+   private File file;
+   
+   /**
+    * Load the specified File. 
+    * 
+    * @param file The file to load
+    * @throws IllegalArgumentException File can not be null
+    * @throws IllegalArgumentException File must exist
+    */
+   public FileResource(File file) 
+   {
+      // Precondition check
+      if (file == null)
+      {
+         throw new IllegalArgumentException("File must be specified");
+      }
+      if(!file.exists()) 
+      {
+         throw new IllegalArgumentException("File must exist");
+      }
+      this.file = file;
+   }
+
+   /**
+    * Get the default name using File.getName();
+    */
+   @Override
+   public String getDefaultName()
+   {
+      return file.getName();
+   }
+   
+   /**
+    * Opens a new FileInputStream for the given File.
+    * 
+    * Can throw a Runtime exception if the file has been deleted inbetween 
+    * the FileResource was created and the stream is opened. 
+    * 
+    * @throws RuntimeException If the file is not found.
+    */
+   @Override
+   public InputStream getStream()
+   {
+      try 
+      {
+         return new FileInputStream(file);
+      }
+      catch (FileNotFoundException e)   
+      {
+         throw new RuntimeException("Could not open file " + file, e);
+      }
+   }
+}
Index: impl-base/src/main/java/org/jboss/declarchive/impl/base/resource/SecurityActions.java
===================================================================
--- impl-base/src/main/java/org/jboss/declarchive/impl/base/resource/SecurityActions.java	(revision 0)
+++ impl-base/src/main/java/org/jboss/declarchive/impl/base/resource/SecurityActions.java	(revision 0)
@@ -0,0 +1,63 @@
+/*
+ * 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.declarchive.impl.base.resource;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * SecurityActions
+ * 
+ * A set of privileged actions that are not to leak out
+ * of this package 
+ *
+ * @author <a href="mailto:andrew.rubinger@jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+class SecurityActions
+{
+
+   //-------------------------------------------------------------------------------||
+   // Constructor ------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------||
+
+   /**
+    * No external instanciation
+    */
+   private SecurityActions()
+   {
+
+   }
+
+   //-------------------------------------------------------------------------------||
+   // Utility Methods --------------------------------------------------------------||
+   //-------------------------------------------------------------------------------||
+
+   /**
+    * Obtains the Thread Context ClassLoader
+    */
+   static ClassLoader getThreadContextClassLoader()
+   {
+      return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
+      {
+         public ClassLoader run()
+         {
+            return Thread.currentThread().getContextClassLoader();
+         }
+      });
+   }
+}

Property changes on: impl-base/src/main/java/org/jboss/declarchive/impl/base/resource/SecurityActions.java
___________________________________________________________________
Added: svn:executable
   + *

Index: impl-base/src/main/java/org/jboss/declarchive/impl/base/resource/URLResource.java
===================================================================
--- impl-base/src/main/java/org/jboss/declarchive/impl/base/resource/URLResource.java	(revision 0)
+++ impl-base/src/main/java/org/jboss/declarchive/impl/base/resource/URLResource.java	(revision 0)
@@ -0,0 +1,76 @@
+package org.jboss.declarchive.impl.base.resource;
+
+import java.io.InputStream;
+import java.net.URL;
+
+import org.jboss.declarchive.spi.Resource;
+
+/**
+ * Loads the content of any URL supported by the runtime.
+ * 
+ * @author <a href="mailto:aslak@conduct.no">Aslak Knutsen</a>
+ *
+ */
+public class URLResource implements Resource
+{
+   private URL url;
+   
+   /**
+    * Create a new resource with a URL source.
+    * 
+    * @param url A valid URL
+    * @throws IllegalArgumentException URL can not be null
+    */
+   public URLResource(URL url) 
+   {
+      // Precondition check
+      if (url == null)
+      {
+         throw new IllegalArgumentException("URL must be specified");
+      }
+      this.url = url;
+   }
+   
+   /**
+    * Get the default name using URL.getFile().
+    */
+   @Override
+   public String getDefaultName()
+   {
+      return extractFileName(url);
+   }
+
+   /**
+    * Open the URL stream.
+    * 
+    * @return A open stream with the content of the URL
+    */
+   @Override
+   public InputStream getStream()
+   {
+      try
+      {
+         return url.openStream();
+      } 
+      catch (Exception e) 
+      {
+         throw new RuntimeException("Could not open stream for url " + url.toExternalForm(), e);
+      }
+   }
+   
+   /*
+    * Extract the file name part of a URL excluding the directory structure.
+    * ie: /user/test/file.properties = file.properties
+    */
+   private String extractFileName(URL url) 
+   {
+      String fileName = url.getFile();
+      if(fileName.indexOf('/') != -1) 
+      {
+         return fileName.substring(
+               fileName.lastIndexOf('/') +1, 
+               fileName.length()); 
+      }
+      return fileName;
+   }
+}
Index: impl-base/src/main/java/org/jboss/declarchive/impl/base/resource/ClassResource.java
===================================================================
--- impl-base/src/main/java/org/jboss/declarchive/impl/base/resource/ClassResource.java	(revision 0)
+++ impl-base/src/main/java/org/jboss/declarchive/impl/base/resource/ClassResource.java	(revision 0)
@@ -0,0 +1,87 @@
+package org.jboss.declarchive.impl.base.resource;
+
+import java.io.InputStream;
+
+import org.jboss.declarchive.spi.Resource;
+
+/**
+ * Loads the given class using the class's ClassLoader.
+ * 
+ * @author <a href="mailto:aslak@conduct.no">Aslak Knutsen</a>
+ *
+ */
+public class ClassResource implements Resource
+{
+   /**
+    * Delimiter for paths while looking for resources 
+    */
+   private static final char DELIMITER_RESOURCE_PATH = '/';
+
+   /**
+    * Delimiter for paths in fully-qualified class names 
+    */
+   private static final char DELIMITER_CLASS_NAME_PATH = '.';
+
+   /**
+    * The filename extension appended to classes
+    */
+   private static final String EXTENSION_CLASS = ".class";
+
+   private Class<?> clazz;
+   
+   /**
+    * Load any class as a resource.
+    * 
+    * @param clazz The class to load
+    * @throws IllegalArgumentException Class can not be null
+    */
+   public ClassResource(Class<?> clazz) 
+   {
+      // Precondition check
+      if (clazz == null)
+      {
+         throw new IllegalArgumentException("Class must be specified");
+      }
+      this.clazz = clazz;
+   }
+   
+   /**
+    * Get the default name using Class.getSimpleName().
+    */
+   @Override
+   public String getDefaultName()
+   {
+      return getResourceNameOfClass(clazz);
+   }
+   
+   /**
+    * Converts the Class name into a Resource URL and uses the 
+    * ClassloaderResource for loading the Class.
+    */
+   @Override
+   public InputStream getStream()
+   {
+      return new ClassloaderResource(
+            getResourceNameOfClass(clazz), 
+            clazz.getClassLoader()
+         ).getStream();
+   }
+   
+
+   /**
+    * Returns the name of the class such that it may be accessed via ClassLoader.getResource()
+    * 
+    * @param clazz The class
+    * @throws IllegalArgumentException If the class was not specified
+    */
+   private String getResourceNameOfClass(final Class<?> clazz) throws IllegalArgumentException
+   {
+      // Build the name
+      final String fqn = clazz.getName();
+      final String nameAsResourcePath = fqn.replace(DELIMITER_CLASS_NAME_PATH, DELIMITER_RESOURCE_PATH);
+      final String resourceName = nameAsResourcePath + EXTENSION_CLASS;
+
+      // Return 
+      return resourceName;
+   }
+}
Index: impl-base/pom.xml
===================================================================
--- impl-base/pom.xml	(revision 3441)
+++ impl-base/pom.xml	(working copy)
@@ -43,6 +43,15 @@
       <version>${version.org.jboss.declarchive_declarchive.spi}</version>
     </dependency>
 
+    <!-- 
+    External Projects
+     -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+
   </dependencies>
 
 </project>
Index: spi/src/main/java/org/jboss/declarchive/spi/Resource.java
===================================================================
--- spi/src/main/java/org/jboss/declarchive/spi/Resource.java	(revision 0)
+++ spi/src/main/java/org/jboss/declarchive/spi/Resource.java	(revision 0)
@@ -0,0 +1,30 @@
+package org.jboss.declarchive.spi;
+
+import java.io.InputStream;
+
+/**
+ * Generic interface for resource loading. 
+ * 
+ * Used to move the resource loading logic out of the archive backends.  
+ * 
+ * @author <a href="mailto:aslak@conduct.no">Aslak Knutsen</a>
+ *
+ */
+public interface Resource
+{
+
+   /**
+    * Get the default name for this resource, can be overriden by the user.
+    * 
+    * @return A name for this Resource
+    */
+   String getDefaultName();
+   
+   /**
+    * Get a open stream for the resource content.
+    * The caller is responsible for closing the stream. 
+    * 
+    * @return A new open inputstream for each call.
+    */
+   InputStream getStream();
+}
