[jboss-svn-commits] JBoss Common SVN: r3495 - in declarchive/trunk: api/src/main/java/org/jboss/declarchive/api/export and 5 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Aug 27 00:41:37 EDT 2009


Author: johnbailey
Date: 2009-08-27 00:41:36 -0400 (Thu, 27 Aug 2009)
New Revision: 3495

Added:
   declarchive/trunk/api/src/main/java/org/jboss/declarchive/api/export/
   declarchive/trunk/api/src/main/java/org/jboss/declarchive/api/export/ArchiveExportException.java
   declarchive/trunk/api/src/main/java/org/jboss/declarchive/api/export/ExplodedExporter.java
   declarchive/trunk/api/src/main/java/org/jboss/declarchive/api/export/ZipExporter.java
   declarchive/trunk/impl-base/src/main/java/org/jboss/declarchive/impl/base/export/
   declarchive/trunk/impl-base/src/main/java/org/jboss/declarchive/impl/base/export/ExplodedExporterImpl.java
   declarchive/trunk/impl-base/src/main/java/org/jboss/declarchive/impl/base/export/ZipExporterImpl.java
   declarchive/trunk/impl-base/src/test/java/org/jboss/declarchive/impl/base/export/
   declarchive/trunk/impl-base/src/test/java/org/jboss/declarchive/impl/base/export/ExplodedExporterTestCase.java
   declarchive/trunk/impl-base/src/test/java/org/jboss/declarchive/impl/base/export/ZipExporterTestCase.java
Modified:
   declarchive/trunk/impl-base/src/main/java/org/jboss/declarchive/impl/base/io/IOUtil.java
Log:
[TMPARCH-25] - Initial work in the creation of archive exporters (zip, exploded)

Added: declarchive/trunk/api/src/main/java/org/jboss/declarchive/api/export/ArchiveExportException.java
===================================================================
--- declarchive/trunk/api/src/main/java/org/jboss/declarchive/api/export/ArchiveExportException.java	                        (rev 0)
+++ declarchive/trunk/api/src/main/java/org/jboss/declarchive/api/export/ArchiveExportException.java	2009-08-27 04:41:36 UTC (rev 3495)
@@ -0,0 +1,52 @@
+/*
+ * 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.api.export;
+
+/**
+ * ArchiveExportException
+ * 
+ * Exception thrown when an error occurs exporting an Archive.
+ * 
+ * @author <a href="mailto:baileyje at gmail.com">John Bailey</a>
+ * @version $Revision: $
+ */
+public class ArchiveExportException extends RuntimeException
+{
+
+   private static final long serialVersionUID = 1L;
+
+   public ArchiveExportException()
+   {
+      super();
+   }
+
+   public ArchiveExportException(String message, Throwable cause)
+   {
+      super(message, cause);
+   }
+
+   public ArchiveExportException(String message)
+   {
+      super(message);
+   }
+
+   public ArchiveExportException(Throwable cause)
+   {
+      super(cause);
+   }
+
+}

Added: declarchive/trunk/api/src/main/java/org/jboss/declarchive/api/export/ExplodedExporter.java
===================================================================
--- declarchive/trunk/api/src/main/java/org/jboss/declarchive/api/export/ExplodedExporter.java	                        (rev 0)
+++ declarchive/trunk/api/src/main/java/org/jboss/declarchive/api/export/ExplodedExporter.java	2009-08-27 04:41:36 UTC (rev 3495)
@@ -0,0 +1,112 @@
+/*
+ * 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.api.export;
+
+import java.io.File;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.jboss.declarchive.api.Archive;
+
+/**
+ * ExplodedExporter
+ * 
+ * Exporter used to export an Archive as an exploded directory structure. 
+ * 
+ * @author <a href="mailto:baileyje at gmail.com">John Bailey</a>
+ * @version $Revision: $
+ */
+public abstract class ExplodedExporter
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Implementation type as a FQN to avoid direct compile-time dependency
+    */
+   private static final String IMPL_TYPE = "org.jboss.declarchive.impl.base.export.ExplodedExporterImpl";
+
+   /**
+    * Instance of ExplodedExporter implementation
+    */
+   private static ExplodedExporter instance;
+
+   //-------------------------------------------------------------------------------------||
+   // Class Methods ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Exports provided archive as an exploded directory structure.
+    * 
+    * @param archive
+    * @param parentDirectory
+    * @return File for exploded archive contents
+    */
+   public static File exportExploded(Archive<?> archive, File parentDirectory)
+   {
+      return getInstance().doExportExploded(archive, parentDirectory);
+   }
+
+   /**
+    * Get an instance of the ExplodedExporter implementation 
+    * @return
+    */
+   private synchronized static ExplodedExporter getInstance()
+   {
+      if (instance == null)
+      {
+         instance = createInstance();
+      }
+      return instance;
+   }
+
+   private static ExplodedExporter createInstance()
+   {
+      return AccessController.doPrivileged(new PrivilegedAction<ExplodedExporter>()
+      {
+         @SuppressWarnings("unchecked")
+         public ExplodedExporter run()
+         {
+            try
+            {
+               ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+               Class<? extends ExplodedExporter> exporterImpl = (Class<? extends ExplodedExporter>) classLoader.loadClass(IMPL_TYPE);
+               return exporterImpl.newInstance();
+            }
+            catch (Exception e)
+            {
+               throw new IllegalArgumentException("Unable to create ExplodedExporter implemenation.", e);
+            }
+         }
+      });
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Contracts --------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Template export method for concrete implementations  
+    * @param archive
+    * @param parentDirectory
+    * @return File for exploded archive contents
+    */
+   protected abstract File doExportExploded(Archive<?> archive, File parentDirectory);
+
+}

Added: declarchive/trunk/api/src/main/java/org/jboss/declarchive/api/export/ZipExporter.java
===================================================================
--- declarchive/trunk/api/src/main/java/org/jboss/declarchive/api/export/ZipExporter.java	                        (rev 0)
+++ declarchive/trunk/api/src/main/java/org/jboss/declarchive/api/export/ZipExporter.java	2009-08-27 04:41:36 UTC (rev 3495)
@@ -0,0 +1,111 @@
+/*
+ * 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.api.export;
+
+import java.io.InputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.jboss.declarchive.api.Archive;
+
+/**
+ * ZipExporter
+ * 
+ * Exporter used to export an Archive as a Zip format. 
+ * 
+ * @author <a href="mailto:baileyje at gmail.com">John Bailey</a>
+ * @version $Revision: $
+ */
+public abstract class ZipExporter
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Implementation type as a FQN to avoid direct compile-time dependency
+    */
+   private static final String IMPL_TYPE = "org.jboss.declarchive.impl.base.export.ZipExporterImpl";
+
+   /**
+    * Instance of ZipExporter implementation
+    */
+   private static ZipExporter instance;
+
+   //-------------------------------------------------------------------------------------||
+   // Class Methods ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Exports provided archive as a Zip archive.
+    * 
+    * @param archive
+    * @return InputStram for exported Zip
+    */
+   public static InputStream exportZip(Archive<?> archive)
+   {
+      return getInstance().doExportZip(archive);
+   }
+
+   /**
+    * Get an instance of the ZipExporter implementation 
+    * @return
+    */
+   private synchronized static ZipExporter getInstance()
+   {
+      if (instance == null)
+      {
+         instance = createInstance();
+      }
+      return instance;
+   }
+
+   private static ZipExporter createInstance()
+   {
+      return AccessController.doPrivileged(new PrivilegedAction<ZipExporter>()
+      {
+         @SuppressWarnings("unchecked")
+         public ZipExporter run()
+         {
+            try
+            {
+               ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+               Class<? extends ZipExporter> exporterImpl = (Class<? extends ZipExporter>) classLoader
+                     .loadClass(IMPL_TYPE);
+               return exporterImpl.newInstance();
+            }
+            catch (Exception e)
+            {
+               throw new IllegalArgumentException("Unable to create ExplodedExporter implemenation.", e);
+            }
+         }
+      });
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Contracts --------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Template export method for concrete implementations  
+    * @param archive
+    * @return InputStream for exported Zip
+    */
+   protected abstract InputStream doExportZip(Archive<?> archive);
+
+}

Added: declarchive/trunk/impl-base/src/main/java/org/jboss/declarchive/impl/base/export/ExplodedExporterImpl.java
===================================================================
--- declarchive/trunk/impl-base/src/main/java/org/jboss/declarchive/impl/base/export/ExplodedExporterImpl.java	                        (rev 0)
+++ declarchive/trunk/impl-base/src/main/java/org/jboss/declarchive/impl/base/export/ExplodedExporterImpl.java	2009-08-27 04:41:36 UTC (rev 3495)
@@ -0,0 +1,152 @@
+/*
+ * 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.export;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.jboss.declarchive.api.Archive;
+import org.jboss.declarchive.api.Asset;
+import org.jboss.declarchive.api.Path;
+import org.jboss.declarchive.api.export.ArchiveExportException;
+import org.jboss.declarchive.api.export.ExplodedExporter;
+import org.jboss.declarchive.impl.base.Validate;
+import org.jboss.declarchive.impl.base.io.IOUtil;
+
+/**
+ * ExplodedExporterImpl
+ * 
+ * Implementation of ExplodedExporter used to export an Archive as an exploded directory structure. 
+ * 
+ * @author <a href="mailto:baileyje at gmail.com">John Bailey</a>
+ * @version $Revision: $
+ */
+public class ExplodedExporterImpl extends ExplodedExporter
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Logger
+    */
+   private static final Logger log = Logger.getLogger(ExplodedExporterImpl.class.getName());
+
+   //-------------------------------------------------------------------------------------||
+   // Required Implementations - ExplodedExporter ----------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /*
+    * (non-Javadoc)
+    * @see org.jboss.declarchive.api.export.ExplodedExporter#doExportExploded(org.jboss.declarchive.api.Archive, java.io.File)
+    */
+   @Override
+   protected File doExportExploded(Archive<?> archive, File baseDirectory)
+   {
+      Validate.notNull(archive, "No archive provided");
+      Validate.notNull(baseDirectory, "No baseDirectory provided");
+
+      // Directory must exist
+      if (!baseDirectory.exists())
+      {
+         throw new IllegalArgumentException("Parent directory does not exist");
+      }
+      // Must be a directory
+      if (!baseDirectory.isDirectory())
+      {
+         throw new IllegalArgumentException("Provided parent directory is not a valid directory");
+      }
+
+      // Obtain all contents
+      final Map<Path, Asset> content = archive.getContent();
+
+      // Create output directory
+      final File outputDirectory = new File(baseDirectory, archive.getName());
+      if (!outputDirectory.mkdir())
+      {
+         throw new ArchiveExportException("Unable to create archive output directory - " + outputDirectory);
+      }
+
+      // For every Path in the Archive
+      for (final Entry<Path, Asset> contentEntry : content.entrySet())
+      {
+         // Get Asset information
+         final Path path = contentEntry.getKey();
+         final Asset asset = contentEntry.getValue();
+         // Write asset content to file
+         writeAsset(outputDirectory, path, asset);
+      }
+
+      if (log.isLoggable(Level.FINE))
+      {
+         log.fine("Created Exploded Atchive: " + outputDirectory.getAbsolutePath());
+      }
+      // Return the output dir
+      return outputDirectory;
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Internal Helper Methods ------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Write the asset file to the output directory
+    * 
+    * @param outputDirectory
+    * @param path
+    * @param asset
+    */
+   private void writeAsset(File outputDirectory, Path path, Asset asset)
+   {
+      // Get path to file
+      final String assetFilePath = path.get();
+
+      // Create a file for the asset
+      final File assetFile = new File(outputDirectory, assetFilePath);
+
+      // Get the assets parent parent directory and make sure it exists
+      final File assetParent = assetFile.getParentFile();
+      if (!assetParent.exists())
+      {
+         if (!assetParent.mkdirs())
+         {
+            throw new ArchiveExportException("Failed to write asset.  Unable to create parent directory.");
+         }
+      }
+
+      try
+      {
+         // Get the asset streams
+         final InputStream assetInputStream = asset.getStream();
+         final FileOutputStream assetFileOutputStream = new FileOutputStream(assetFile);
+
+         // Write contents
+         IOUtil.copyWithClose(assetInputStream, assetFileOutputStream);
+      }
+      catch (Throwable t)
+      {
+         throw new ArchiveExportException("Failed to write asset " + path + " to " + assetFile);
+      }
+   }
+
+}

Added: declarchive/trunk/impl-base/src/main/java/org/jboss/declarchive/impl/base/export/ZipExporterImpl.java
===================================================================
--- declarchive/trunk/impl-base/src/main/java/org/jboss/declarchive/impl/base/export/ZipExporterImpl.java	                        (rev 0)
+++ declarchive/trunk/impl-base/src/main/java/org/jboss/declarchive/impl/base/export/ZipExporterImpl.java	2009-08-27 04:41:36 UTC (rev 3495)
@@ -0,0 +1,183 @@
+/*
+ * 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.export;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import org.jboss.declarchive.api.Archive;
+import org.jboss.declarchive.api.Asset;
+import org.jboss.declarchive.api.Path;
+import org.jboss.declarchive.api.export.ArchiveExportException;
+import org.jboss.declarchive.api.export.ZipExporter;
+import org.jboss.declarchive.impl.base.Validate;
+import org.jboss.declarchive.impl.base.io.IOUtil;
+
+/**
+ * ZipExporterImpl
+ * 
+ * Implementation of ZipExporter used to export an Archive as a Zip format. 
+ * 
+ * @author <a href="mailto:baileyje at gmail.com">John Bailey</a>
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class ZipExporterImpl extends ZipExporter
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Logger
+    */
+   private static final Logger log = Logger.getLogger(ZipExporterImpl.class.getName());
+
+   //-------------------------------------------------------------------------------------||
+   // Required Implementations - ZipExporter ---------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /*
+    * (non-Javadoc)
+    * @see org.jboss.declarchive.api.export.ZipExporter#doExportZip(org.jboss.declarchive.api.Archive)
+    */
+   @Override
+   protected InputStream doExportZip(Archive<?> archive)
+   {
+      Validate.notNull(archive, "No archive provided");
+
+      // Obtain all contents
+      final Map<Path, Asset> content = archive.getContent();
+
+      // Create OutputStreams
+      final ByteArrayOutputStream output = new ByteArrayOutputStream();
+      ZipOutputStream zipOutputStream = null;
+
+      // Enclose every IO Operation so we can close up cleanly
+      try
+      {
+         // Make a ZipOutputStream
+         zipOutputStream = new ZipOutputStream(output);
+
+         // For every Path in the Archive
+         for (final Entry<Path, Asset> contentEntry : content.entrySet())
+         {
+            // Get Asset information
+            final Path path = contentEntry.getKey();
+            final Asset asset = contentEntry.getValue();
+            // Write asset content to Zip
+            writeAsset(zipOutputStream, path, asset);
+         }
+
+      }
+      // We're done, close
+      finally
+      {
+         try
+         {
+            if (zipOutputStream != null)
+            {
+               zipOutputStream.close();
+            }
+         }
+         catch (final IOException ignored)
+         {
+         }
+      }
+
+      return getContentStream(output);
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Internal Helper Methods ------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Write the content of a single asset to the Zip.
+    * 
+    * @param zipOutputStream
+    * @param path
+    * @param asset
+    */
+   private void writeAsset(ZipOutputStream zipOutputStream, Path path, Asset asset)
+   {
+      final String pathName = path.get();
+      final ZipEntry entry = new ZipEntry(pathName);
+
+      final InputStream in = asset.getStream();
+      // Write the Asset under the same Path name in the Zip
+      try
+      {
+         // Make a Zip Entry
+         zipOutputStream.putNextEntry(entry);
+
+         // Read the contents of the asset and write to the JAR
+         IOUtil.copy(in, zipOutputStream);
+
+         // Close up the instream and the entry
+         zipOutputStream.closeEntry();
+      }
+      // Some error in writing this entry/asset
+      catch (final IOException ioe)
+      {
+         // Throw
+         throw new ArchiveExportException("Could not start new entry for " + pathName, ioe);
+      }
+      finally
+      {
+         // Try to close the instream.  Out stream is closed in finally block below.
+         try
+         {
+            in.close();
+         }
+         catch (IOException ignored)
+         {
+         }
+      }
+   }
+
+   /**
+    * Get an InputStream representing the bytes from the Zip.
+    * 
+    * @param outputStream
+    * @return
+    */
+   private InputStream getContentStream(ByteArrayOutputStream outputStream)
+   {
+      // Flush the output to a byte array
+      final byte[] zipContent = outputStream.toByteArray();
+      if (log.isLoggable(Level.FINE))
+      {
+         log.fine("Created Zip of size: " + zipContent.length + " bytes");
+      }
+
+      // Make an instream
+      final InputStream inputStream = new ByteArrayInputStream(zipContent);
+
+      // Return
+      return inputStream;
+   }
+}

Modified: declarchive/trunk/impl-base/src/main/java/org/jboss/declarchive/impl/base/io/IOUtil.java
===================================================================
--- declarchive/trunk/impl-base/src/main/java/org/jboss/declarchive/impl/base/io/IOUtil.java	2009-08-27 00:51:13 UTC (rev 3494)
+++ declarchive/trunk/impl-base/src/main/java/org/jboss/declarchive/impl/base/io/IOUtil.java	2009-08-27 04:41:36 UTC (rev 3495)
@@ -17,8 +17,10 @@
 package org.jboss.declarchive.impl.base.io;
 
 import java.io.ByteArrayOutputStream;
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 
 import org.jboss.declarchive.impl.base.Validate;
 
@@ -105,6 +107,93 @@
       return content;
    }
 
+   /**
+    * Copies the contents from an InputStream to an OutputStream
+    * 
+    * @param input
+    * @param output
+    */
+   public static void copy(InputStream input, OutputStream output)
+   {
+      final byte[] buffer = new byte[1024];
+      int read = 0;
+      try
+      {
+         while ((read = input.read(buffer)) != -1)
+         {
+            output.write(buffer, 0, read);
+         }
+      }
+      catch (final IOException ioe)
+      {
+         throw new RuntimeException("Error copying contents from " + input + " to " + output, ioe);
+      }
+   }
+
+   /**
+    * Copies the contents from an InputStream to an OutputStream and closes both streams.
+    * 
+    * @param input
+    * @param output
+    */
+   public static void copyWithClose(InputStream input, OutputStream output)
+   {
+      try
+      {
+         copy(input, output);
+      }
+      finally
+      {
+         try
+         {
+            input.close();
+            output.close();
+         }
+         catch (final IOException ignore)
+         {
+
+         }
+      }
+   }
+
+   /**
+    * Recursively deletes a directory and all its contents 
+    * @param directory
+    */
+   public static void deleteDirectory(File directory)
+   {
+      if (directory.isDirectory() && directory.exists())
+      {
+         // For each file in the directory run cleanup
+         for (File file : directory.listFiles())
+         {
+            if (file.isDirectory())
+            {
+               // A nested directory, recurse 
+               deleteDirectory(file);
+            }
+            else
+            {
+               // Just a file delete it
+               if (!file.delete())
+               {
+                  throw new RuntimeException("Failed to delete file: " + file);
+               }
+            }
+         }
+         // Delete the directory
+         if (!directory.delete())
+         {
+            throw new RuntimeException("Failed to delete directory: " + directory);
+         }
+      }
+      else
+      {
+         throw new RuntimeException("Unable to delete directory: " + directory
+               + ".  It is either not a directory or does not exist.");
+      }
+   }
+
    //-------------------------------------------------------------------------------------||
    // Functional Methods -----------------------------------------------------------------||
    //-------------------------------------------------------------------------------------||

Added: declarchive/trunk/impl-base/src/test/java/org/jboss/declarchive/impl/base/export/ExplodedExporterTestCase.java
===================================================================
--- declarchive/trunk/impl-base/src/test/java/org/jboss/declarchive/impl/base/export/ExplodedExporterTestCase.java	                        (rev 0)
+++ declarchive/trunk/impl-base/src/test/java/org/jboss/declarchive/impl/base/export/ExplodedExporterTestCase.java	2009-08-27 04:41:36 UTC (rev 3495)
@@ -0,0 +1,256 @@
+/*
+ * 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.export;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.logging.Logger;
+
+import org.jboss.declarchive.api.Asset;
+import org.jboss.declarchive.api.Path;
+import org.jboss.declarchive.api.export.ExplodedExporter;
+import org.jboss.declarchive.impl.base.MemoryMapArchiveImpl;
+import org.jboss.declarchive.impl.base.asset.ClassLoaderAsset;
+import org.jboss.declarchive.impl.base.io.IOUtil;
+import org.jboss.declarchive.impl.base.path.BasicPath;
+import org.jboss.declarchive.spi.MemoryMapArchive;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * ExplodedExporterTestCase
+ * 
+ * TestCase to ensure that the {@link ExplodedExporter} correctly exports archive.
+ *
+ * @author <a href="mailto:baileyje at gmail.com">John Bailey</a>
+ * @version $Revision: $
+ */
+public class ExplodedExporterTestCase
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Logger
+    */
+   private static final Logger log = Logger.getLogger(ExplodedExporterTestCase.class.getName());
+
+   //-------------------------------------------------------------------------------------||
+   // Instance Members -------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Temp directory
+    */
+   private File tempDirectory;
+
+   //-------------------------------------------------------------------------------------||
+   // Lifecycle Methods ------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /** 
+    * Create the temp directory used as the base for exploded archives
+    *  
+    * @throws Exception
+    */
+   @Before
+   public void createTempDirectory() throws Exception
+   {
+      tempDirectory = File.createTempFile("tmp", "");
+      tempDirectory.delete();
+      tempDirectory.mkdir();
+   }
+
+   /**
+    * Clean up the temp directory
+    * 
+    * @throws Exception
+    */
+   @After
+   public void cleanTempDirectory() throws Exception
+   {
+      IOUtil.deleteDirectory(tempDirectory);
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Tests ------------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Ensure an archive can be exported to an exploded directory.
+    * 
+    * @throws Exception
+    */
+   @Test
+   public void testExportExploded() throws Exception
+   {
+      log.info("testExportExploded");
+
+      // Get an archive instance
+      MemoryMapArchive archive = new MemoryMapArchiveImpl("testArchive.jar");
+
+      // Add some content
+      Asset assetOne = new ClassLoaderAsset("org/jboss/declarchive/impl/base/asset/Test.properties");
+      Path pathOne = new BasicPath("test.properties");
+      archive.add(pathOne, assetOne);
+      Asset assetTwo = new ClassLoaderAsset("org/jboss/declarchive/impl/base/asset/Test2.properties");
+      Path pathTwo = new BasicPath("nested", "test2.properties");
+      archive.add(pathTwo, assetTwo);
+      
+      // Add a nested archive for good measure
+      MemoryMapArchive nestedArchive = new MemoryMapArchiveImpl("nestedArchive.jar");
+      nestedArchive.add(pathOne, assetOne);
+      nestedArchive.add(pathTwo, assetTwo);
+      archive.add(new BasicPath(), nestedArchive);
+
+      // Export as Exploded directory
+      File explodedDirectory = ExplodedExporter.exportExploded(archive, tempDirectory);
+
+      // Validate the exploded directory was created 
+      Assert.assertNotNull(explodedDirectory);
+
+      // Assert the directory has the correct name
+      File expectedDirectory = new File(tempDirectory, archive.getName());
+      Assert.assertEquals(expectedDirectory, explodedDirectory);
+
+      // Validate entries were written out
+      assertAssetInExploded(explodedDirectory, pathOne, assetOne);
+      assertAssetInExploded(explodedDirectory, pathTwo, assetTwo);
+
+      // Validate nested archive entries were written out
+      Path nestedArchivePath = new BasicPath(nestedArchive.getName());
+
+      assertAssetInExploded(explodedDirectory, new BasicPath(nestedArchivePath, pathOne), assetOne);
+      assertAssetInExploded(explodedDirectory, new BasicPath(nestedArchivePath, pathTwo), assetTwo);
+
+   }
+
+   /**
+    * Ensure an archive is required to export.
+    * 
+    * @throws Exception
+    */
+   @Test
+   public void testExportExplodedRequiresArchive() throws Exception
+   {
+      log.info("testExportExplodedRequiresArchive");
+
+      try
+      {
+         ExplodedExporter.exportExploded(null, tempDirectory);
+         Assert.fail("Should have thrown IllegalArgumentException");
+      }
+      catch (IllegalArgumentException expected)
+      {
+      }
+   }
+
+   /**
+    * Ensure an baseDirectory is required to export.
+    * 
+    * @throws Exception
+    */
+   @Test
+   public void testExportExplodedRequiresBaseDirectroy() throws Exception
+   {
+      log.info("testExportExplodedRequiresBaseDirectroy");
+
+      try
+      {
+         ExplodedExporter.exportExploded(new MemoryMapArchiveImpl(), null);
+         Assert.fail("Should have thrown IllegalArgumentException");
+      }
+      catch (IllegalArgumentException expected)
+      {
+      }
+   }
+
+   /**
+    * Ensure an baseDirectory must exist is required to export.
+    * 
+    * @throws Exception
+    */
+   @Test
+   public void testExportExplodedRequiresExisitingDirectroy() throws Exception
+   {
+      log.info("testExportExplodedRequiresExisitingDirectroy");
+
+      try
+      {
+         File directory = new File("someNonExistentDirectory");
+
+         ExplodedExporter.exportExploded(new MemoryMapArchiveImpl(), directory);
+         Assert.fail("Should have thrown IllegalArgumentException");
+      }
+      catch (IllegalArgumentException expected)
+      {
+      }
+   }
+
+   /**
+    * Ensure an baseDirectory must be a directory.
+    * 
+    * @throws Exception
+    */
+   @Test
+   public void testExportExplodedRequiresValidDirectroy() throws Exception
+   {
+      log.info("testExportExplodedRequiresValidDirectroy");
+      try
+      {
+         File directory = File.createTempFile("tmp", "");
+
+         ExplodedExporter.exportExploded(new MemoryMapArchiveImpl(), directory);
+         Assert.fail("Should have thrown IllegalArgumentException");
+      }
+      catch (IllegalArgumentException expected)
+      {
+      }
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Internal Helper Methods ------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Assert an asset is actually in the exploded directory
+    * 
+    * @throws FileNotFoundException 
+    * @throws IOException 
+    * @throws IllegalArgumentException 
+    */
+   private void assertAssetInExploded(File explodedDirectory, Path path, Asset asset) throws FileNotFoundException
+   {
+      File assetFile = new File(explodedDirectory, path.get());
+      Assert.assertNotNull(assetFile);
+      Assert.assertTrue(assetFile.exists());
+      byte[] expectedContents = IOUtil.asByteArray(asset.getStream());
+
+      InputStream inputStream = new FileInputStream(assetFile);
+
+      byte[] actualContents = IOUtil.asByteArray(inputStream);
+      Assert.assertArrayEquals(expectedContents, actualContents);
+   }
+
+}

Added: declarchive/trunk/impl-base/src/test/java/org/jboss/declarchive/impl/base/export/ZipExporterTestCase.java
===================================================================
--- declarchive/trunk/impl-base/src/test/java/org/jboss/declarchive/impl/base/export/ZipExporterTestCase.java	                        (rev 0)
+++ declarchive/trunk/impl-base/src/test/java/org/jboss/declarchive/impl/base/export/ZipExporterTestCase.java	2009-08-27 04:41:36 UTC (rev 3495)
@@ -0,0 +1,163 @@
+/*
+ * 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.export;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.logging.Logger;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.jboss.declarchive.api.Asset;
+import org.jboss.declarchive.api.Path;
+import org.jboss.declarchive.api.export.ZipExporter;
+import org.jboss.declarchive.impl.base.MemoryMapArchiveImpl;
+import org.jboss.declarchive.impl.base.asset.ClassLoaderAsset;
+import org.jboss.declarchive.impl.base.io.IOUtil;
+import org.jboss.declarchive.impl.base.path.BasicPath;
+import org.jboss.declarchive.spi.MemoryMapArchive;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * ZipExporterTestCase
+ * 
+ * TestCase to ensure that the {@link ZipExporter} correctly exports archives to Zip format.
+ *
+ * @author <a href="mailto:baileyje at gmail.com">John Bailey</a>
+ * @version $Revision: $
+ */
+public class ZipExporterTestCase
+{
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Logger
+    */
+   private static final Logger log = Logger.getLogger(ZipExporterTestCase.class.getName());
+
+   //-------------------------------------------------------------------------------------||
+   // Tests ------------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Test to make sue an archive can be exported to Zip and all contents are correctly located in the Zip.
+    * @throws Exception
+    */
+   @Test
+   public void testExportZip() throws Exception
+   {
+      log.info("testExportZip");
+
+      // Get an archive instance
+      MemoryMapArchive archive = new MemoryMapArchiveImpl("testArchive.jar");
+
+      // Add some content
+      Asset assetOne = new ClassLoaderAsset("org/jboss/declarchive/impl/base/asset/Test.properties");
+      Path pathOne = new BasicPath("test.properties");
+      archive.add(pathOne, assetOne);
+      Asset assetTwo = new ClassLoaderAsset("org/jboss/declarchive/impl/base/asset/Test2.properties");
+      Path pathTwo = new BasicPath("nested", "test2.properties");
+      archive.add(pathTwo, assetTwo);
+      
+      // Add a nested archive for good measure
+      MemoryMapArchive nestedArchive = new MemoryMapArchiveImpl("nestedArchive.jar");
+      nestedArchive.add(pathOne, assetOne);
+      nestedArchive.add(pathTwo, assetTwo);
+      archive.add(new BasicPath(), nestedArchive);
+
+      // Export as Zip InputStream
+      InputStream zipStream = ZipExporter.exportZip(archive);
+
+      // Validate the InputStream was created 
+      Assert.assertNotNull(zipStream);
+
+      // Create a temp file
+      File outFile = File.createTempFile("test", ".zip");
+      // Write Zip contents to file
+      writeOutFile(outFile, zipStream);
+
+      // Use standard ZipFile library to read in written Zip file
+      ZipFile expectedZip = new ZipFile(outFile);
+
+      // Validate entries were written out
+      assertAssetInZip(expectedZip, pathOne, assetOne);
+      assertAssetInZip(expectedZip, pathTwo, assetTwo);
+      
+      // Validate nested archive entries were written out
+      Path nestedArchivePath = new BasicPath(nestedArchive.getName());
+
+      assertAssetInZip(expectedZip, new BasicPath(nestedArchivePath, pathOne), assetOne);
+      assertAssetInZip(expectedZip, new BasicPath(nestedArchivePath, pathTwo), assetTwo);
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Internal Helper Methods ------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Ensure an archive is required to export.
+    * 
+    * @throws Exception
+    */
+   @Test
+   public void testExportZipRequiresArchive() throws Exception
+   {
+      log.info("testExportZipRequiresArchive");
+      try
+      {
+         ZipExporter.exportZip(null);
+         Assert.fail("Should have thrown IllegalArgumentException");
+      }
+      catch (IllegalArgumentException expected)
+      {
+      }
+   }
+
+   /**
+    * Assert an asset is actually in the Zip file
+    * @throws IOException 
+    * @throws IllegalArgumentException 
+    */
+   private void assertAssetInZip(ZipFile expectedZip, Path path, Asset asset) throws IllegalArgumentException,
+         IOException
+   {
+      ZipEntry entry = expectedZip.getEntry(path.get());
+      Assert.assertNotNull(entry);
+      byte[] expectedContents = IOUtil.asByteArray(asset.getStream());
+      byte[] actualContents = IOUtil.asByteArray(expectedZip.getInputStream(entry));
+      Assert.assertArrayEquals(expectedContents, actualContents);
+   }
+
+   /**
+    * Write a InputStream out to file.
+    * @param outFile
+    * @param zipInputStream
+    * @throws Exception
+    */
+   private void writeOutFile(File outFile, InputStream inputStream) throws Exception
+   {
+      OutputStream fileOutputStream = new FileOutputStream(outFile);
+      IOUtil.copyWithClose(inputStream, fileOutputStream);
+   }
+
+}



More information about the jboss-svn-commits mailing list