[jboss-svn-commits] JBoss Common SVN: r4552 - in shrinkwrap/trunk: extension-tar and 16 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Thu Jun 24 23:20:54 EDT 2010
Author: ALRubinger
Date: 2010-06-24 23:20:53 -0400 (Thu, 24 Jun 2010)
New Revision: 4552
Added:
shrinkwrap/trunk/extension-tar/
shrinkwrap/trunk/extension-tar/pom.xml
shrinkwrap/trunk/extension-tar/src/
shrinkwrap/trunk/extension-tar/src/main/
shrinkwrap/trunk/extension-tar/src/main/java/
shrinkwrap/trunk/extension-tar/src/main/java/org/
shrinkwrap/trunk/extension-tar/src/main/java/org/jboss/
shrinkwrap/trunk/extension-tar/src/main/java/org/jboss/shrinkwrap/
shrinkwrap/trunk/extension-tar/src/main/java/org/jboss/shrinkwrap/tar/
shrinkwrap/trunk/extension-tar/src/main/java/org/jboss/shrinkwrap/tar/api/
shrinkwrap/trunk/extension-tar/src/main/java/org/jboss/shrinkwrap/tar/api/exporter/
shrinkwrap/trunk/extension-tar/src/main/java/org/jboss/shrinkwrap/tar/api/exporter/TarGzExporter.java
shrinkwrap/trunk/extension-tar/src/main/java/org/jboss/shrinkwrap/tar/impl/
shrinkwrap/trunk/extension-tar/src/main/java/org/jboss/shrinkwrap/tar/impl/exporter/
shrinkwrap/trunk/extension-tar/src/main/java/org/jboss/shrinkwrap/tar/impl/exporter/TarGzExporterDelegate.java
shrinkwrap/trunk/extension-tar/src/main/java/org/jboss/shrinkwrap/tar/impl/exporter/TarGzExporterImpl.java
shrinkwrap/trunk/extension-tar/src/main/resources/
shrinkwrap/trunk/extension-tar/src/main/resources/META-INF/
shrinkwrap/trunk/extension-tar/src/main/resources/META-INF/services/
shrinkwrap/trunk/extension-tar/src/main/resources/META-INF/services/org.jboss.shrinkwrap.tar.api.exporter.TarGzExporter
shrinkwrap/trunk/extension-tar/src/test/
shrinkwrap/trunk/extension-tar/src/test/java/
shrinkwrap/trunk/extension-tar/src/test/resources/
shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/AbstractStreamExporterImpl.java
shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/StreamExporterDelegateBase.java
Modified:
shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/AbstractExporterDelegate.java
shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/ExplodedExporterImpl.java
shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/FutureCompletionInputStream.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/exporter/ZipExporterImpl.java
shrinkwrap/trunk/pom.xml
Log:
[SHRINKWRAP-194] Refactoring to the stream-based export delegates to encourage code reuse before introducing a TAR.GZ exporter. Add a naive, untested TAR.GZ exporter as well. Still needs an importer and tests for all; probably some refactoring of the tests to get reuse there too.
Property changes on: shrinkwrap/trunk/extension-tar
___________________________________________________________________
Name: svn:ignore
+ target
bin
.classpath
.project
.settings
Added: shrinkwrap/trunk/extension-tar/pom.xml
===================================================================
--- shrinkwrap/trunk/extension-tar/pom.xml (rev 0)
+++ shrinkwrap/trunk/extension-tar/pom.xml 2010-06-25 03:20:53 UTC (rev 4552)
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+ <!--
+ vi:ts=2:sw=2:expandtab:
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <!-- Parent -->
+ <parent>
+ <groupId>org.jboss.shrinkwrap</groupId>
+ <artifactId>shrinkwrap-build</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <relativePath>../build/pom.xml</relativePath>
+ </parent>
+
+ <!-- Model Version -->
+ <modelVersion>4.0.0</modelVersion>
+
+ <!-- Artifact Configuration -->
+ <artifactId>shrinkwrap-extension-tar</artifactId>
+ <name>ShrinkWrap Extension TAR</name>
+ <description>ShrinkWrap Extension for TAR Import/Export Support</description>
+
+
+ <!-- Properties -->
+ <properties>
+
+ <!-- Versioning -->
+ <version.org.jboss.javatar>1.0.0-SNAPSHOT</version.org.jboss.javatar>
+
+ </properties>
+
+ <!-- Dependencies -->
+ <dependencies>
+
+ <!--
+ org.jboss.shrinkwrap
+ -->
+ <dependency>
+ <groupId>org.jboss.shrinkwrap</groupId>
+ <artifactId>shrinkwrap-impl-base</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <!--
+ External Projects
+ -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <!-- org.jboss.javatar -->
+ <dependency>
+ <groupId>org.jboss.javatar</groupId>
+ <artifactId>javatar</artifactId>
+ <version>${version.org.jboss.javatar}</version>
+ </dependency>
+
+ </dependencies>
+
+ <!-- Build Configuration -->
+ <build>
+
+ <plugins>
+
+ </plugins>
+
+ </build>
+
+</project>
+
Added: shrinkwrap/trunk/extension-tar/src/main/java/org/jboss/shrinkwrap/tar/api/exporter/TarGzExporter.java
===================================================================
--- shrinkwrap/trunk/extension-tar/src/main/java/org/jboss/shrinkwrap/tar/api/exporter/TarGzExporter.java (rev 0)
+++ shrinkwrap/trunk/extension-tar/src/main/java/org/jboss/shrinkwrap/tar/api/exporter/TarGzExporter.java 2010-06-25 03:20:53 UTC (rev 4552)
@@ -0,0 +1,86 @@
+/*
+ * 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.tar.api.exporter;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.jboss.shrinkwrap.api.Assignable;
+import org.jboss.shrinkwrap.api.exporter.ArchiveExportException;
+import org.jboss.shrinkwrap.api.exporter.FileExistsException;
+
+/**
+ * Exporter used to represent an {@link Assignable} in TAR format encoded w/
+ * GZIP compression
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @see http://www.gnu.org/software/tar/manual/html_node/Standard.html
+ * @see http://www.gzip.org/
+ */
+public interface TarGzExporter extends Assignable
+{
+ //-------------------------------------------------------------------------------------||
+ // Contracts --------------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * Exports this reference as a TAR.GZ archive.
+ *
+ * @return {@link InputStream} for exported TAR.GZ
+ */
+ InputStream exportTarGz();
+
+ /**
+ * Exports provided archive as a TAR.GZ archive, written to the
+ * specified {@link File} target. If the target exists this call will
+ * fail with {@link IllegalArgumentException}
+ *
+ * @param archive
+ * @return {@link InputStream} for exported Zip
+ * @throws IllegalArgumentException If the target is not specified
+ * @throws FileExistsException If the target already exists
+ * @throws ArchiveExportException if the export process fails
+ */
+ void exportTarGz(File target) throws ArchiveExportException, FileExistsException, IllegalArgumentException;
+
+ /**
+ * Exports provided archive as a TAR.GZ archive, written to the
+ * specified {@link OutputStream} target. The specified
+ * target will be closed upon completion.
+ *
+ * @param target
+ * @throws ArchiveExportException
+ * @throws IllegalArgumentException If the target is not specified
+ */
+ void exportTarGz(OutputStream target) throws ArchiveExportException, IllegalArgumentException;
+
+ /**
+ * Exports provided archive as a TAR.GZ archive, written to the
+ * specified {@link File} target. If the target both exists and the "overwrite"
+ * flag is true, this call will allow the existing file to be overwritten, else
+ * the invocation will fail with {@link IllegalArgumentException}
+ *
+ * @param archive
+ * @return {@link InputStream} for exported TAR.GZ
+ * @throws IllegalArgumentException If the target is not specified
+ * @throws FileExistsException If the target both already exists and the overwrite flag is false
+ * @throws ArchiveExportException if the export process fails
+ */
+ void exportTarGz(File target, boolean overwrite) throws ArchiveExportException, FileExistsException,
+ IllegalArgumentException;
+}
Added: shrinkwrap/trunk/extension-tar/src/main/java/org/jboss/shrinkwrap/tar/impl/exporter/TarGzExporterDelegate.java
===================================================================
--- shrinkwrap/trunk/extension-tar/src/main/java/org/jboss/shrinkwrap/tar/impl/exporter/TarGzExporterDelegate.java (rev 0)
+++ shrinkwrap/trunk/extension-tar/src/main/java/org/jboss/shrinkwrap/tar/impl/exporter/TarGzExporterDelegate.java 2010-06-25 03:20:53 UTC (rev 4552)
@@ -0,0 +1,175 @@
+/*
+ * 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.tar.impl.exporter;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.concurrent.Callable;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import org.jboss.javatar.TarEntry;
+import org.jboss.javatar.TarGzOutputStream;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.asset.Asset;
+import org.jboss.shrinkwrap.impl.base.exporter.StreamExporterDelegateBase;
+
+/**
+ * Implementation of an exporter for the TAR format, further encoded as GZIP.
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class TarGzExporterDelegate extends StreamExporterDelegateBase<TarGzOutputStream>
+{
+ //-------------------------------------------------------------------------------------||
+ // Class Members ----------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * Logger
+ */
+ private static final Logger log = Logger.getLogger(TarGzExporterDelegate.class.getName());
+
+ //-------------------------------------------------------------------------------------||
+ // Constructor ------------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * Creates a new exporter delegate for exporting archives as ZIP
+ *
+ * @throws IllegalArgumentException If the archive has no {@link Asset}s; JDK ZIP
+ * handling cannot support writing out to a {@link ZipOutputStream} with no
+ * {@link ZipEntry}s.
+ */
+ public TarGzExporterDelegate(final Archive<?> archive) throws IllegalArgumentException
+ {
+ super(archive);
+
+ //TODO Can this impl export archives with no entries?
+// // Precondition check
+// if (archive.getContent().isEmpty())
+// {
+// throw new IllegalArgumentException(
+// "[SHRINKWRAP-93] Cannot use this JDK-based implementation to export as ZIP an archive with no content: "
+// + archive.toString());
+// }
+ }
+
+ //-------------------------------------------------------------------------------------||
+ // Required Implementations -----------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * {@inheritDoc}
+ * @see org.jboss.shrinkwrap.impl.base.exporter.StreamExporterDelegateBase#closeEntry(java.io.OutputStream)
+ */
+ @Override
+ protected final void closeEntry(final TarGzOutputStream outputStream) throws IOException
+ {
+ // Close the entry
+ outputStream.closeEntry();
+ }
+
+ /**
+ * {@inheritDoc}
+ * @see org.jboss.shrinkwrap.impl.base.exporter.StreamExporterDelegateBase#createOutputStream(java.io.OutputStream)
+ */
+ @Override
+ protected final TarGzOutputStream createOutputStream(final OutputStream out) throws IOException
+ {
+ // Create and return
+ return new TarGzOutputStream(out);
+ }
+
+ /**
+ * {@inheritDoc}
+ * @see org.jboss.shrinkwrap.impl.base.exporter.StreamExporterDelegateBase#putNextExtry(java.io.OutputStream, java.lang.String)
+ */
+ @Override
+ protected final void putNextExtry(final TarGzOutputStream outputStream, final String context) throws IOException
+ {
+ // Put
+ outputStream.putNextEntry(new TarEntry(context));
+ }
+
+ /**
+ * {@inheritDoc}
+ * @see org.jboss.shrinkwrap.impl.base.exporter.StreamExporterDelegateBase#getExportTask()
+ */
+ @Override
+ protected Callable<Void> getExportTask(final Callable<Void> wrappedTask)
+ {
+ assert wrappedTask != null : "Wrapped task must be specified";
+ return new Callable<Void>()
+ {
+
+ @Override
+ public Void call() throws Exception
+ {
+ try
+ {
+ // Attempt the wrapped task
+ wrappedTask.call();
+ }
+ 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);
+
+ //TODO Can this impl export archives with no entries? JDK ZIP impl cannot.
+// // SHRINKWRAP-133 - if the output is empty, it won't close and a deadlock is triggered
+// final Set<ArchivePath> pathsExported = TarGzExporterDelegate.this.getExportedPaths();
+// 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();
+//
+// // Write a dummy entry just so the JDK ZIP impl can close cleanly
+// putNextExtry(outputStream, "dummy.txt");
+// }
+
+ throw e;
+ }
+ finally
+ {
+
+ try
+ {
+ outputStream.close();
+ }
+ catch (final IOException ioe)
+ {
+ // Ignore, but warn of danger
+ log.log(Level.WARNING,
+ "[SHRINKWRAP-120] Possible deadlock scenario: Got exception on closing the TAR.GZ out stream: "
+ + ioe.getMessage(), ioe);
+ }
+ }
+
+ return null;
+ }
+ };
+ }
+}
Added: shrinkwrap/trunk/extension-tar/src/main/java/org/jboss/shrinkwrap/tar/impl/exporter/TarGzExporterImpl.java
===================================================================
--- shrinkwrap/trunk/extension-tar/src/main/java/org/jboss/shrinkwrap/tar/impl/exporter/TarGzExporterImpl.java (rev 0)
+++ shrinkwrap/trunk/extension-tar/src/main/java/org/jboss/shrinkwrap/tar/impl/exporter/TarGzExporterImpl.java 2010-06-25 03:20:53 UTC (rev 4552)
@@ -0,0 +1,135 @@
+/*
+ * 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.tar.impl.exporter;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.logging.Logger;
+
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.exporter.ArchiveExportException;
+import org.jboss.shrinkwrap.api.exporter.FileExistsException;
+import org.jboss.shrinkwrap.impl.base.exporter.AbstractExporterDelegate;
+import org.jboss.shrinkwrap.impl.base.exporter.AbstractStreamExporterImpl;
+import org.jboss.shrinkwrap.impl.base.io.IOUtil;
+import org.jboss.shrinkwrap.tar.api.exporter.TarGzExporter;
+
+/**
+ * Implementation of {@link TarGzExporter} used to export an Archive as a TAR format
+ * encoded in GZIP.
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class TarGzExporterImpl extends AbstractStreamExporterImpl implements TarGzExporter
+{
+
+ //-------------------------------------------------------------------------------------||
+ // Class Members ----------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * Logger
+ */
+ private static final Logger log = Logger.getLogger(TarGzExporterImpl.class.getName());
+
+ //-------------------------------------------------------------------------------------||
+ // Constructor ------------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * Creates a new exporter for the specified archive
+ */
+ public TarGzExporterImpl(final Archive<?> archive)
+ {
+ super(archive);
+ }
+
+ //-------------------------------------------------------------------------------------||
+ // Required Implementations -----------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * {@inheritDoc}
+ * @see org.jboss.shrinkwrap.tar.api.exporter.TarGzExporter#exportTarGz()
+ */
+ @Override
+ public InputStream exportTarGz()
+ {
+ // Create export delegate
+ final AbstractExporterDelegate<InputStream> exportDelegate = new TarGzExporterDelegate(this.getArchive());
+
+ // Execute export
+ return exportDelegate.export();
+ }
+
+ /**
+ * {@inheritDoc}
+ * @see org.jboss.shrinkwrap.tar.api.exporter.TarGzExporter#exportTarGz(java.io.OutputStream)
+ */
+ @Override
+ public void exportTarGz(final OutputStream target) throws ArchiveExportException, IllegalArgumentException
+ {
+ // Precondition checks
+ if (target == null)
+ {
+ throw new IllegalArgumentException("Target must be specified");
+ }
+
+ // Get Stream
+ final InputStream in = this.exportTarGz();
+
+ // Write out
+ try
+ {
+ IOUtil.copyWithClose(in, target);
+ }
+ catch (final IOException e)
+ {
+ throw new ArchiveExportException("Error encountered in exporting archive to " + target, e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * @see org.jboss.shrinkwrap.tar.api.exporter.TarGzExporter#exportTarGz(java.io.File, boolean)
+ */
+ @Override
+ public void exportTarGz(final File target, final boolean overwrite) throws ArchiveExportException,
+ FileExistsException, IllegalArgumentException
+ {
+ // Get stream and perform precondition checks
+ final OutputStream out = this.getOutputStreamToFile(target, overwrite);
+
+ // Write out
+ this.exportTarGz(out);
+ }
+
+ /**
+ * {@inheritDoc}
+ * @see org.jboss.shrinkwrap.tar.api.exporter.TarGzExporter#exportTarGz(java.io.File)
+ */
+ @Override
+ public void exportTarGz(final File target) throws ArchiveExportException, FileExistsException,
+ IllegalArgumentException
+ {
+ this.exportTarGz(target, false);
+ }
+
+}
Added: shrinkwrap/trunk/extension-tar/src/main/resources/META-INF/services/org.jboss.shrinkwrap.tar.api.exporter.TarGzExporter
===================================================================
--- shrinkwrap/trunk/extension-tar/src/main/resources/META-INF/services/org.jboss.shrinkwrap.tar.api.exporter.TarGzExporter (rev 0)
+++ shrinkwrap/trunk/extension-tar/src/main/resources/META-INF/services/org.jboss.shrinkwrap.tar.api.exporter.TarGzExporter 2010-06-25 03:20:53 UTC (rev 4552)
@@ -0,0 +1 @@
+org.jboss.shrinkwrap.tar.impl.exporter.TarGzExporterImpl
\ No newline at end of file
Modified: shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/AbstractExporterDelegate.java
===================================================================
--- shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/AbstractExporterDelegate.java 2010-06-24 08:56:59 UTC (rev 4551)
+++ shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/AbstractExporterDelegate.java 2010-06-25 03:20:53 UTC (rev 4552)
@@ -66,39 +66,52 @@
super();
this.archive = archive;
}
+
+ /**
+ * Runs the export operation, returning the result
+ * @return
+ */
+ public final T export()
+ {
+ // Perform the actual export
+ this.doExport();
+ // Return the result
+ return this.getResult();
+ }
+
/**
* Primary method providing a template for exporting the contents of an archive
*/
- protected void export()
+ protected void doExport()
{
// Get archive
- Archive<?> archive = getArchive();
+ final Archive<?> archive = getArchive();
if (log.isLoggable(Level.FINE))
{
log.fine("Exporting archive - " + archive.getName());
}
- // Obtain all content
- final Node rootNode = archive.get(ArchivePaths.create("/"));
-
- // recursively process the node childs
- for (Node child : rootNode.getChildren())
+ // Obtain the root
+ final Node rootNode = archive.get(ArchivePaths.root());
+
+ // Recursively process the root children
+ for (Node child : rootNode.getChildren())
{
processNode(child);
}
}
-
+
/**
* Recursive call to process all the node hierarchy
* @param node
*/
- protected void processNode(final Node node)
+ private void processNode(final Node node)
{
processNode(node.getPath(), node);
-
+
Set<Node> children = node.getChildren();
- for (Node child : children)
+ for (Node child : children)
{
processNode(child);
}
Added: shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/AbstractStreamExporterImpl.java
===================================================================
--- shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/AbstractStreamExporterImpl.java (rev 0)
+++ shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/AbstractStreamExporterImpl.java 2010-06-25 03:20:53 UTC (rev 4552)
@@ -0,0 +1,113 @@
+/*
+ * 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.impl.base.exporter;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.exporter.ArchiveExportException;
+import org.jboss.shrinkwrap.api.exporter.FileExistsException;
+import org.jboss.shrinkwrap.impl.base.AssignableBase;
+import org.jboss.shrinkwrap.impl.base.Validate;
+
+/**
+ * Base support for I/O Stream-based exporters
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ */
+public abstract class AbstractStreamExporterImpl extends AssignableBase
+{
+
+ //-------------------------------------------------------------------------------------||
+ // Instance Members -------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * Archive to import into.
+ */
+ private final Archive<?> archive;
+
+ //-------------------------------------------------------------------------------------||
+ // Constructor ------------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ public AbstractStreamExporterImpl(final Archive<?> 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;
+ }
+
+ //-------------------------------------------------------------------------------------||
+ // Functional Methods -----------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * Obtains an {@link OuputStream} to the provided {@link File}.
+ * @param target
+ * @param overwrite Whether we may overwrite an existing file
+ * @return
+ * @throws FileExistsException If the specified file exists and the overwrite flag is false
+ * @throws IllegalArgumentException If the file target is not specified
+ */
+ protected final OutputStream getOutputStreamToFile(final File target, final boolean overwrite)
+ throws FileExistsException, IllegalArgumentException
+ {
+ // Precondition checks
+ if (target == null)
+ {
+ throw new IllegalArgumentException("Target file must be specified");
+ }
+ // If target exists and we're not allowed to overwrite it
+ if (target.exists() && !overwrite)
+ {
+ throw new FileExistsException("Target exists and we haven't been flagged to overwrite it: "
+ + target.getAbsolutePath());
+ }
+
+ // Get Stream
+ final OutputStream out;
+ try
+ {
+ out = new FileOutputStream(target);
+ }
+ catch (final FileNotFoundException e)
+ {
+ throw new ArchiveExportException("File could not be created: " + target);
+ }
+
+ // Return
+ return out;
+ }
+
+}
Modified: shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/ExplodedExporterImpl.java
===================================================================
--- shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/ExplodedExporterImpl.java 2010-06-24 08:56:59 UTC (rev 4551)
+++ shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/ExplodedExporterImpl.java 2010-06-25 03:20:53 UTC (rev 4552)
@@ -78,11 +78,12 @@
// Required Implementations - ExplodedExporter ----------------------------------------||
//-------------------------------------------------------------------------------------||
- /* (non-Javadoc)
+ /**
+ * {@inheritDoc}
* @see org.jboss.shrinkwrap.api.exporter.ExplodedExporter#exportExploded(java.io.File)
*/
@Override
- public File exportExploded(File baseDirectory)
+ public File exportExploded(final File baseDirectory)
{
Validate.notNull(archive, "No archive provided");
Validate.notNull(baseDirectory, "No baseDirectory provided");
@@ -99,13 +100,10 @@
}
// Get the export delegate
- ExplodedExporterDelegate exporterDelegate = new ExplodedExporterDelegate(archive, baseDirectory);
-
- // Run the export
- exporterDelegate.export();
+ final ExplodedExporterDelegate exporterDelegate = new ExplodedExporterDelegate(archive, baseDirectory);
- // Get Result
- File explodedDirectory = exporterDelegate.getResult();
+ // Run the export and get the result
+ final File explodedDirectory = exporterDelegate.export();
if (log.isLoggable(Level.FINE))
{
Modified: shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/FutureCompletionInputStream.java
===================================================================
--- shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/FutureCompletionInputStream.java 2010-06-24 08:56:59 UTC (rev 4551)
+++ shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/FutureCompletionInputStream.java 2010-06-25 03:20:53 UTC (rev 4552)
@@ -33,7 +33,7 @@
* @param <T> Response type of the {@link Future}
* @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
*/
-class FutureCompletionInputStream extends PipedInputStream
+public class FutureCompletionInputStream extends PipedInputStream
{
//-------------------------------------------------------------------------------------||
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-06-24 08:56:59 UTC (rev 4551)
+++ shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/JdkZipExporterDelegate.java 2010-06-25 03:20:53 UTC (rev 4552)
@@ -17,32 +17,17 @@
package org.jboss.shrinkwrap.impl.base.exporter;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
-import java.io.PipedOutputStream;
-import java.util.HashSet;
import java.util.Set;
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;
import java.util.zip.ZipEntry;
-import java.util.zip.ZipException;
import java.util.zip.ZipOutputStream;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ArchivePath;
-import org.jboss.shrinkwrap.api.Node;
import org.jboss.shrinkwrap.api.asset.Asset;
-import org.jboss.shrinkwrap.api.exporter.ArchiveExportException;
-import org.jboss.shrinkwrap.impl.base.io.IOUtil;
-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
@@ -52,7 +37,7 @@
* @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
* @version $Revision: $
*/
-public class JdkZipExporterDelegate extends AbstractExporterDelegate<InputStream>
+public class JdkZipExporterDelegate extends StreamExporterDelegateBase<ZipOutputStream>
{
//-------------------------------------------------------------------------------------||
// Class Members ----------------------------------------------------------------------||
@@ -64,35 +49,11 @@
private static final Logger log = Logger.getLogger(JdkZipExporterDelegate.class.getName());
//-------------------------------------------------------------------------------------||
- // Instance Members -------------------------------------------------------------------||
- //-------------------------------------------------------------------------------------||
-
- /**
- * ZipOutputStream used to write the zip entries
- */
- private ZipOutputStream zipOutputStream;
-
- /**
- * {@link InputStream} to be returned to the caller
- */
- private InputStream inputStream;
-
- /**
- * Used to see if we have exported at least one node
- */
- private Set<ArchivePath> pathsExported = new HashSet<ArchivePath>();
-
- /**
- * Synchronization point where the encoding process will wait until all streams have been set up
- */
- private final CountDownLatch latch = new CountDownLatch(1);
-
- //-------------------------------------------------------------------------------------||
// Constructor ------------------------------------------------------------------------||
//-------------------------------------------------------------------------------------||
/**
- * Creates a new exporter delegate for exporting archives as Zip
+ * Creates a new exporter delegate for exporting archives as ZIP
*
* @throws IllegalArgumentException If the archive has no {@link Asset}s; JDK ZIP
* handling cannot support writing out to a {@link ZipOutputStream} with no
@@ -117,13 +78,46 @@
/**
* {@inheritDoc}
- * @see org.jboss.shrinkwrap.impl.base.exporter.AbstractExporterDelegate#export()
+ * @see org.jboss.shrinkwrap.impl.base.exporter.StreamExporterDelegateBase#closeEntry(java.io.OutputStream)
*/
- protected void export()
+ @Override
+ protected final void closeEntry(final ZipOutputStream outputStream) throws IOException
{
+ // Close the entry
+ outputStream.closeEntry();
+ }
- // Define the task to operate in another Thread so we can pipe the output to an InStream
- final Callable<Void> exportTask = new Callable<Void>()
+ /**
+ * {@inheritDoc}
+ * @see org.jboss.shrinkwrap.impl.base.exporter.StreamExporterDelegateBase#createOutputStream(java.io.OutputStream)
+ */
+ @Override
+ protected final ZipOutputStream createOutputStream(final OutputStream out) throws IOException
+ {
+ // Create and return
+ return new ZipOutputStream(out);
+ }
+
+ /**
+ * {@inheritDoc}
+ * @see org.jboss.shrinkwrap.impl.base.exporter.StreamExporterDelegateBase#putNextExtry(java.io.OutputStream, java.lang.String)
+ */
+ @Override
+ protected final void putNextExtry(final ZipOutputStream outputStream, final String context) throws IOException
+ {
+ // Put
+ outputStream.putNextEntry(new ZipEntry(context));
+ }
+
+ /**
+ * {@inheritDoc}
+ * @see org.jboss.shrinkwrap.impl.base.exporter.StreamExporterDelegateBase#getExportTask()
+ */
+ @Override
+ protected Callable<Void> getExportTask(final Callable<Void> wrappedTask)
+ {
+ assert wrappedTask != null : "Wrapped task must be specified";
+ return new Callable<Void>()
{
@Override
@@ -131,7 +125,8 @@
{
try
{
- JdkZipExporterDelegate.super.export();
+ // Attempt the wrapped task
+ wrappedTask.call();
}
catch (final Exception e)
{
@@ -140,7 +135,8 @@
// 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
+ // SHRINKWRAP-133 - if the output is empty, it won't close and a deadlock is triggered
+ final Set<ArchivePath> pathsExported = JdkZipExporterDelegate.this.getExportedPaths();
if (pathsExported.isEmpty())
{
// Ensure the streams are set up before we do any work on them;
@@ -149,7 +145,8 @@
// SHRINKWRAP-137
latch.await();
- zipOutputStream.putNextEntry(new ZipEntry("dummy.txt"));
+ // Write a dummy entry just so the JDK ZIP impl can close cleanly
+ putNextExtry(outputStream, "dummy.txt");
}
throw e;
@@ -159,7 +156,7 @@
try
{
- zipOutputStream.close();
+ outputStream.close();
}
catch (final IOException ioe)
{
@@ -173,156 +170,5 @@
return null;
}
};
-
- // Get an ExecutorService to which we may submit jobs. This is either supplied by the user
- // in a custom domain, or if one has not been specified, we'll make one and shut it down right
- // here. ExecutorServices supplied by the user are under the user's lifecycle, therefore it's
- // user responsibility to shut it down appropriately.
- boolean executorServiceIsOurs = false;
- ExecutorService service = this.getArchive().as(Configurable.class).getConfiguration().getExecutorService();
- if (service == null)
- {
- service = Executors.newSingleThreadExecutor();
- executorServiceIsOurs = true;
- }
-
- // Get a handle and return it to the caller
- final Future<Void> job = service.submit(exportTask);
-
- // If we've created the ES
- if (executorServiceIsOurs)
- {
- // Tell the service to shut down after the job has completed, and accept no new jobs
- service.shutdown();
- }
-
- /*
- * At this point the job will start, but hit the latch until we set up the streams
- * and tell it to proceed.
- */
-
- // Stream to return to the caller
- final FutureCompletionInputStream input = new FutureCompletionInputStream(job);
- inputStream = input;
-
- /**
- * OutputStream which will be associated with the returned InStream, and the
- * chained IO point for the Zip OutStrea,
- */
- final OutputStream output;
- try
- {
- output = new PipedOutputStream(input);
- }
- catch (final IOException e)
- {
- throw new RuntimeException("Error in setting up output stream", e);
- }
-
- // Set up the stream to which we'll write entries, backed by the piped stream
- zipOutputStream = new ZipOutputStream(output);
-
- /*
- * The job is now waiting on us to signal that we've set up the streams;
- * let it continue
- */
- latch.countDown();
}
-
- /**
- * {@inheritDoc}
- * @see org.jboss.shrinkwrap.impl.base.exporter.AbstractExporterDelegate#processNode(ArchivePath, Node)
- */
- @Override
- protected void processNode(final ArchivePath path, final Node node)
- {
- // Precondition checks
- if (path == null)
- {
- throw new IllegalArgumentException("Path must be specified");
- }
- if (node == null)
- {
- 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)
- {
- 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>()
- {
-
- @Override
- public void execute(InputStream stream) throws Exception
- {
- String resolvedPath = pathName;
- if (isDirectory)
- {
- resolvedPath = PathUtil.optionallyAppendSlash(resolvedPath);
- }
-
- // Make a ZipEntry
- final ZipEntry entry = new ZipEntry(resolvedPath);
-
- /*
- * Wait until all streams have been set up for encoding, or
- * do nothing if everything's set up already
- */
- latch.await();
-
- // Write the Asset under the same Path name in the Zip
- try
- {
- zipOutputStream.putNextEntry(entry);
- }
- catch (final ZipException ze)
- {
- log.log(Level.SEVERE, pathsExported.toString());
- throw new RuntimeException(ze);
- }
-
- // Mark that we've written this Path
- pathsExported.add(path);
-
- // Read the contents of the asset and write to the JAR,
- // if we're not just a directory
- if (!isDirectory)
- {
- IOUtil.copy(stream, zipOutputStream);
- }
-
- // Close up the instream and the entry
- zipOutputStream.closeEntry();
- }
-
- }, new StreamErrorHandler()
- {
-
- @Override
- public void handle(Throwable t)
- {
- throw new ArchiveExportException("Failed to write asset to Zip: " + path.get(), t);
- }
-
- });
- }
-
- /* (non-Javadoc)
- * @see org.jboss.shrinkwrap.impl.base.exporter.AbstractExporterDelegate#getResult()
- */
- @Override
- protected InputStream getResult()
- {
- return inputStream;
- }
-
}
Added: shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/StreamExporterDelegateBase.java
===================================================================
--- shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/StreamExporterDelegateBase.java (rev 0)
+++ shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/StreamExporterDelegateBase.java 2010-06-25 03:20:53 UTC (rev 4552)
@@ -0,0 +1,321 @@
+/*
+ * 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.exporter;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PipedOutputStream;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+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;
+
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ArchivePath;
+import org.jboss.shrinkwrap.api.Node;
+import org.jboss.shrinkwrap.api.exporter.ArchiveExportException;
+import org.jboss.shrinkwrap.impl.base.io.IOUtil;
+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;
+
+/**
+ * Base for exporters capable of writing to some implementation
+ * of {@link OutputStream}
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public abstract class StreamExporterDelegateBase<O extends OutputStream> extends AbstractExporterDelegate<InputStream>
+{
+ //-------------------------------------------------------------------------------------||
+ // Class Members ----------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * Logger
+ */
+ private static final Logger log = Logger.getLogger(StreamExporterDelegateBase.class.getName());
+
+ //-------------------------------------------------------------------------------------||
+ // Instance Members -------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * {@link OutputStream} used to write the individual entries
+ */
+ protected O outputStream;
+
+ /**
+ * {@link InputStream} to be returned to the caller
+ */
+ private InputStream inputStream;
+
+ /**
+ * Used to see if we have exported at least one node
+ */
+ private Set<ArchivePath> pathsExported = new HashSet<ArchivePath>();
+
+ /**
+ * Synchronization point where the encoding process will wait until all streams have been set up
+ */
+ protected final CountDownLatch latch = new CountDownLatch(1);
+
+ //-------------------------------------------------------------------------------------||
+ // Constructor ------------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * Creates a new exporter delegate for exporting archives
+ */
+ public StreamExporterDelegateBase(final Archive<?> archive) throws IllegalArgumentException
+ {
+ // Delegate to super
+ super(archive);
+ }
+
+ //-------------------------------------------------------------------------------------||
+ // Required Implementations -----------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * Returns the task used to run the export operation in another Thread. Exposed
+ * such that the specified task (which handles the export) may be wrapped in some
+ * error handling logic specific to the export process.
+ * @param wrappedTask The export task to be wrapped in more specific handling logic
+ */
+ protected abstract Callable<Void> getExportTask(Callable<Void> wrappedTask);
+
+ /**
+ * {@inheritDoc}
+ * @see org.jboss.shrinkwrap.impl.base.exporter.AbstractExporterDelegate#doExport()
+ */
+ protected void doExport()
+ {
+ // Define the task to operate in another Thread so we can pipe the output to an InStream
+ final Callable<Void> exportTask = this.getExportTask(new Callable<Void>()
+ {
+
+ // Wrapped task is the super implementation
+ @Override
+ public Void call() throws Exception
+ {
+ StreamExporterDelegateBase.super.doExport();
+ return null;
+ }
+
+ });
+
+ // Get an ExecutorService to which we may submit jobs. This is either supplied by the user
+ // in a custom domain, or if one has not been specified, we'll make one and shut it down right
+ // here. ExecutorServices supplied by the user are under the user's lifecycle, therefore it's
+ // user responsibility to shut it down appropriately.
+ boolean executorServiceIsOurs = false;
+ ExecutorService service = this.getArchive().as(Configurable.class).getConfiguration().getExecutorService();
+ if (service == null)
+ {
+ service = Executors.newSingleThreadExecutor();
+ executorServiceIsOurs = true;
+ }
+
+ // Get a handle and return it to the caller
+ final Future<Void> job = service.submit(exportTask);
+
+ // If we've created the ES
+ if (executorServiceIsOurs)
+ {
+ // Tell the service to shut down after the job has completed, and accept no new jobs
+ service.shutdown();
+ }
+
+ /*
+ * At this point the job will start, but hit the latch until we set up the streams
+ * and tell it to proceed.
+ */
+
+ // Stream to return to the caller
+ final FutureCompletionInputStream input = new FutureCompletionInputStream(job);
+ inputStream = input;
+
+ /**
+ * OutputStream which will be associated with the returned InStream, and the
+ * chained IO point for the final OutStream
+ */
+ final OutputStream output;
+ try
+ {
+ output = new PipedOutputStream(input);
+ }
+ catch (final IOException e)
+ {
+ throw new RuntimeException("Error in setting up output stream", e);
+ }
+
+ // Set up the stream to which we'll write entries, backed by the piped stream
+ try
+ {
+ outputStream = StreamExporterDelegateBase.this.createOutputStream(output);
+ }
+ catch (final IOException e)
+ {
+ throw new ArchiveExportException("Could not create the underlying stream to export: "
+ + this.getArchive().toString(), e);
+ }
+
+ /*
+ * The job is now waiting on us to signal that we've set up the streams;
+ * let it continue
+ */
+ latch.countDown();
+ }
+
+ /**
+ * Writes the next entry (demarcates a new file/folder
+ * is to be written)
+ * @param outputStream
+ * @param context
+ * @throws IOException If an error occurred writing the entry
+ */
+ protected abstract void putNextExtry(O outputStream, String context) throws IOException;
+
+ /**
+ * Closes the current entry context for the specified {@link OutputStream}
+ * @param outputStream
+ */
+ protected abstract void closeEntry(O outputStream) throws IOException;
+
+ /**
+ * Creates the real {@link OutputStream} to which we'll write,
+ * wrapping the provided target.
+ * @param out
+ * @return
+ * @throws IOException If an error occurred in creating the stream
+ */
+ protected abstract O createOutputStream(OutputStream out) throws IOException;
+
+ /**
+ * {@inheritDoc}
+ * @see org.jboss.shrinkwrap.impl.base.exporter.AbstractExporterDelegate#processNode(ArchivePath, Node)
+ */
+ @Override
+ protected void processNode(final ArchivePath path, final Node node)
+ {
+ // Precondition checks
+ if (path == null)
+ {
+ throw new IllegalArgumentException("Path must be specified");
+ }
+ if (node == null)
+ {
+ 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)
+ {
+ 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>()
+ {
+
+ @Override
+ public void execute(InputStream stream) throws Exception
+ {
+ String resolvedPath = pathName;
+ if (isDirectory)
+ {
+ resolvedPath = PathUtil.optionallyAppendSlash(resolvedPath);
+ }
+
+ /*
+ * Wait until all streams have been set up for encoding, or
+ * do nothing if everything's set up already
+ */
+ latch.await();
+
+ // Write the Asset under the same Path name in the output
+ try
+ {
+ putNextExtry(outputStream, resolvedPath);
+ }
+ catch (final IOException ze)
+ {
+ log.log(Level.SEVERE, pathsExported.toString());
+ throw new RuntimeException(ze);
+ }
+
+ // Mark that we've written this Path
+ pathsExported.add(path);
+
+ // Read the contents of the asset and write to the JAR,
+ // if we're not just a directory
+ if (!isDirectory)
+ {
+ IOUtil.copy(stream, outputStream);
+ }
+
+ // Close up the instream and the entry
+ StreamExporterDelegateBase.this.closeEntry(outputStream);
+ }
+
+ }, new StreamErrorHandler()
+ {
+
+ @Override
+ public void handle(Throwable t)
+ {
+ throw new ArchiveExportException("Failed to write asset to output: " + path.get(), t);
+ }
+
+ });
+ }
+
+ /**
+ * {@inheritDoc}
+ * @see org.jboss.shrinkwrap.impl.base.exporter.AbstractExporterDelegate#getResult()
+ */
+ @Override
+ protected InputStream getResult()
+ {
+ return inputStream;
+ }
+
+ /**
+ * Returns an immutable view of all {@link ArchivePath}s currently exported
+ * @return
+ */
+ protected final Set<ArchivePath> getExportedPaths()
+ {
+ return Collections.unmodifiableSet(this.pathsExported);
+ }
+
+}
Modified: shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/ZipExporterImpl.java
===================================================================
--- shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/ZipExporterImpl.java 2010-06-24 08:56:59 UTC (rev 4551)
+++ shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/ZipExporterImpl.java 2010-06-25 03:20:53 UTC (rev 4552)
@@ -17,8 +17,6 @@
package org.jboss.shrinkwrap.impl.base.exporter;
import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -28,8 +26,6 @@
import org.jboss.shrinkwrap.api.exporter.ArchiveExportException;
import org.jboss.shrinkwrap.api.exporter.FileExistsException;
import org.jboss.shrinkwrap.api.exporter.ZipExporter;
-import org.jboss.shrinkwrap.impl.base.AssignableBase;
-import org.jboss.shrinkwrap.impl.base.Validate;
import org.jboss.shrinkwrap.impl.base.io.IOUtil;
/**
@@ -40,7 +36,7 @@
* @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
* @version $Revision: $
*/
-public class ZipExporterImpl extends AssignableBase implements ZipExporter
+public class ZipExporterImpl extends AbstractStreamExporterImpl implements ZipExporter
{
//-------------------------------------------------------------------------------------||
@@ -52,35 +48,16 @@
*/
private static final Logger log = Logger.getLogger(ZipExporterImpl.class.getName());
- /**
- * Archive to import into.
- */
- private Archive<?> archive;
-
//-------------------------------------------------------------------------------------||
// Constructor ------------------------------------------------------------------------||
//-------------------------------------------------------------------------------------||
public ZipExporterImpl(final Archive<?> archive)
{
- Validate.notNull(archive, "Archive must be specified");
- this.archive = archive;
+ super(archive);
}
//-------------------------------------------------------------------------------------||
- // Required Implementations -----------------------------------------------------------||
- //-------------------------------------------------------------------------------------||
-
- /* (non-Javadoc)
- * @see org.jboss.shrinkwrap.impl.base.SpecializedBase#getArchive()
- */
- @Override
- protected Archive<?> getArchive()
- {
- return archive;
- }
-
- //-------------------------------------------------------------------------------------||
// Required Implementations - ZipExporter ---------------------------------------------||
//-------------------------------------------------------------------------------------||
@@ -92,15 +69,10 @@
public InputStream exportZip()
{
// Create export delegate
- AbstractExporterDelegate<InputStream> exportDelegate = new JdkZipExporterDelegate(archive);
+ AbstractExporterDelegate<InputStream> exportDelegate = new JdkZipExporterDelegate(this.getArchive());
- // Execute export
- exportDelegate.export();
- // Get results
- InputStream stream = exportDelegate.getResult();
-
- // Return
- return stream;
+ // Export and get result
+ return exportDelegate.export();
}
/**
@@ -137,29 +109,9 @@
public void exportZip(final File target, final boolean overwrite) throws ArchiveExportException,
FileExistsException, IllegalArgumentException
{
- // Precondition checks
- if (target == null)
- {
- throw new IllegalArgumentException("Target file must be specified");
- }
- // If target exists and we're not allowed to overwrite it
- if (target.exists() && !overwrite)
- {
- throw new FileExistsException("Target exists and we haven't been flagged to overwrite it: "
- + target.getAbsolutePath());
- }
+ // Get stream and perform precondition checks
+ final OutputStream out = this.getOutputStreamToFile(target, overwrite);
- // Get Stream
- final OutputStream out;
- try
- {
- out = new FileOutputStream(target);
- }
- catch (final FileNotFoundException e)
- {
- throw new ArchiveExportException("File could not be created: " + target);
- }
-
// Write out
this.exportZip(out);
}
Modified: shrinkwrap/trunk/pom.xml
===================================================================
--- shrinkwrap/trunk/pom.xml 2010-06-24 08:56:59 UTC (rev 4551)
+++ shrinkwrap/trunk/pom.xml 2010-06-25 03:20:53 UTC (rev 4552)
@@ -72,6 +72,7 @@
<module>extension-glassfish</module>
<module>extension-jetty</module>
<module>extension-openejb</module>
+ <module>extension-tar</module>
<module>extension-vfs3</module>
<module>extension-vdf</module>
</modules>
More information about the jboss-svn-commits
mailing list