/*
* 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 org.jboss.shrinkwrap.api.ArchivePath;
import org.jboss.shrinkwrap.api.ArchivePaths;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.Asset;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.exporter.StreamExporter;
import org.jboss.shrinkwrap.api.exporter.ZipStoredExporter;
import org.jboss.shrinkwrap.api.importer.ZipImporter;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.jboss.shrinkwrap.impl.base.io.IOUtil;
import org.jboss.shrinkwrap.impl.base.path.BasicPath;
import org.jboss.shrinkwrap.impl.base.path.PathUtil;
import org.junit.Assert;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/**
* TestCase to ensure that the {@link ZipStoredExporter} correctly exports archives to ZIP format.
*
* @author <a href="mailto:asotobu@gmail.com">Alex Soto</a>
*/
public final class ZipStoredExporterTestCase extends StreamExporterTestBase<ZipImporter> {
// -------------------------------------------------------------------------------------||
// Class Members ----------------------------------------------------------------------||
// -------------------------------------------------------------------------------------||
/**
* Extension for archives
*/
private static final String EXTENSION = ".jar";
// -------------------------------------------------------------------------------------||
// Required Implementations -----------------------------------------------------------||
// -------------------------------------------------------------------------------------||
/**
* {@inheritDoc}
*
* @see org.jboss.shrinkwrap.impl.base.exporter.StreamExporterTestBase#getExporterClass()
*/
@Override
protected Class<? extends StreamExporter> getExporterClass() {
return ZipStoredExporter.class;
}
/**
* {@inheritDoc}
*
* @see org.jboss.shrinkwrap.impl.base.exporter.StreamExporterTestBase#getImporterClass()
*/
@Override
protected Class<ZipImporter> getImporterClass() {
return ZipImporter.class;
}
/**
* {@inheritDoc}
*
* @see org.jboss.shrinkwrap.impl.base.exporter.StreamExporterTestBase#ensureInExpectedForm(java.io.File)
*/
@Override
protected void ensureInExpectedForm(final File file) throws IOException {
// Precondition check
assert file != null : "file must be specified";
// Get as ZipFile
final ZipFile zip = new ZipFile(file);
// Validate
this.ensureZipFileInExpectedForm(zip);
}
/**
* {@inheritDoc}
*
* @see org.jboss.shrinkwrap.impl.base.exporter.StreamExporterTestBase#getContentsFromExportedFile(java.io.File,
* org.jboss.shrinkwrap.api.ArchivePath)
*/
@Override
protected InputStream getContentsFromExportedFile(final File file, final ArchivePath path) throws IOException {
// Precondition checks
assert file != null : "file must be specified";
assert path != null : "path must be specified";
// Get as Zip File
final ZipFile zipFile = new ZipFile(file);
final ZipEntry entry = zipFile.getEntry(PathUtil.optionallyRemovePrecedingSlash(path.get()));
if (entry == null) {
return null;
}
final byte[] actualContents = IOUtil.asByteArray(zipFile.getInputStream(entry));
return new ByteArrayInputStream(actualContents);
}
/**
* {@inheritDoc
* @see org.jboss.shrinkwrap.impl.base.exporter.ExportTestBase#getArchiveExtension()
*/
@Override
protected String getArchiveExtension() {
return EXTENSION;
}
// -------------------------------------------------------------------------------------||
// Tests ------------------------------------------------------------------------------||
// --------------------------------------
@Test
public void shouldExportToStoredZip() throws IOException {
final File target = new File("target");
ShrinkWrap.create(JavaArchive.class).addClass(ZipStoredExporterTestCase.class)
.add(new StringAsset("My file content"), "content.txt")
.as(ZipStoredExporter.class).exportTo(new File(target, "test-exporter.zip"), true);
final File generatedFile = new File(target, "test-exporter.zip");
Assert.assertTrue(generatedFile.length() > 0);
final InputStream contentsFromExportedFile = getContentsFromExportedFile(generatedFile, ArchivePaths.create("/org/jboss/shrinkwrap/impl/base/exporter/ZipStoredExporterTestCase.class"));
final byte[] content = IOUtil.asByteArray(contentsFromExportedFile);
Assert.assertTrue(content.length > 0);
final InputStream contentsFromExportedFile2 = getContentsFromExportedFile(generatedFile, ArchivePaths.create("/content.txt"));
final byte[] content2 = IOUtil.asByteArray(contentsFromExportedFile2);
Assert.assertTrue(content.length > 0);
Assert.assertEquals("My file content", new String(content2));
}
// -------------------------------------------------------------------------------------||
// Internal Helper Methods ------------------------------------------------------------||
// -------------------------------------------------------------------------------------||
/**
* Ensures that the specified {@link ZipFile} contains entries in the expected form
*
* @param expectedZip
* @throws IOException
*/
private void ensureZipFileInExpectedForm(final ZipFile expectedZip) throws IOException {
// Validate entries were written out
assertAssetInZip(expectedZip, PATH_ONE, ASSET_ONE);
assertAssetInZip(expectedZip, PATH_TWO, ASSET_TWO);
// Validate all paths were written
// SHRINKWRAP-94
getEntryFromZip(expectedZip, NESTED_PATH);
// Ensure we don't write the root Path
// SHRINKWRAP-96
ZipEntry rootEntry = expectedZip.getEntry("/");
Assert.assertNull("ZIP should not have explicit root path written (SHRINKWRAP-96)", rootEntry);
}
/**
* Assert an asset is actually in the Zip file
*
* @throws IOException
* @throws IllegalArgumentException
*/
private void assertAssetInZip(ZipFile expectedZip, ArchivePath path, Asset asset) throws IllegalArgumentException,
IOException {
final ZipEntry entry = this.getEntryFromZip(expectedZip, path);
final byte[] expectedContents = IOUtil.asByteArray(asset.openStream());
final byte[] actualContents = IOUtil.asByteArray(expectedZip.getInputStream(entry));
Assert.assertArrayEquals(expectedContents, actualContents);
}
/**
* Obtains the entry from the specified ZIP file at the specified Path, ensuring it exists along the way
*
* @param expectedZip
* @param path
* @return
* @throws IllegalArgumentException
* @throws IOException
*/
private ZipEntry getEntryFromZip(final ZipFile expectedZip, final ArchivePath path)
throws IllegalArgumentException, IOException {
final String entryPath = PathUtil.optionallyRemovePrecedingSlash(path.get());
final ZipEntry entry = expectedZip.getEntry(entryPath);
Assert.assertNotNull("Expected path not found in ZIP: " + path, entry);
return entry;
}
}