/*
* 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.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.jboss.shrinkwrap.api.ArchivePath;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.Asset;
import org.jboss.shrinkwrap.api.asset.FileAsset;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.exporter.StreamExporter;
import org.jboss.shrinkwrap.api.exporter.ZipExporter;
import org.jboss.shrinkwrap.api.importer.ZipImporter;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.impl.base.io.IOUtil;
import org.jboss.shrinkwrap.impl.base.path.PathUtil;
import org.junit.Assert;
import org.junit.Test;
/**
* TestCase to ensure that the {@link ZipExporter} correctly exports archives to ZIP format.
*
* @author <a href="mailto:baileyje@gmail.com">John Bailey</a>
* @author <a href="mailto:aslak@conduct.no">Aslak Knutsen</a>
* @author <a href="mailto:andrew.rubinger@jboss.org">ALR</a>
* @author <a href="mailto:mmatloka@gmail.com">Michal Matloka</a>
* @version $Revision: $
*/
public final class ZipExporterTestCase 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 ZipExporter.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 to ensure that the {@link ZipExporter} does not accept an empty archive as input
*
* SHRINKWRAP-93
*
* @throws Exception
*/
@Test(expected = IllegalArgumentException.class)
public void exportEmptyArchiveAsZip() throws Exception {
// Attempt to export an empty archive, should fail
ShrinkWrap.create(JavaArchive.class, NAME_ARCHIVE).as(ZipExporter.class).exportAsInputStream();
}
/**
* SHRINKWRAP-377
*/
@Test
public void exportShouldFailIfTargetExist() throws IOException {
File target = new File(createTempDirectory("exportShouldFailIfTargetExist").getAbsolutePath()
+ "exportShouldFailIfTargetExist.jar");
if (target.exists()) {
Assert.assertTrue(target.delete());
}
Assert.assertFalse(target.exists());
createArchiveWithAssets().as(ZipExporter.class).exportTo(target);
Assert.assertTrue(target.exists());
try {
createArchiveWithAssets().as(ZipExporter.class).exportTo(target); // this line should throw a
// FileExistsException
Assert.fail("Expected a FileExistsException when exporting to an existing path");
} catch (Exception e) {
Assert.assertEquals(org.jboss.shrinkwrap.api.exporter.FileExistsException.class, e.getClass());
}
}
/**
* Archive -> WAR -> Archive -> WAR. SHRINKWRAP-444
*/
@Test
public void testExportImportExport() {
// Preconditions
final File target = new File("target");
final File testClasses = new File(target, "test-classes");
final File hsqldbJar = new File(testClasses, "hsqldb.jar");
Assert.assertTrue("test JAR must exist to run this test", hsqldbJar.exists() && !hsqldbJar.isDirectory());
final File file1 = new File(target, "testExportImportExport1.war");
final File file2 = new File(target, "testExportImportExport2.war");
final WebArchive webArchive = ShrinkWrap.create(WebArchive.class).add(new FileAsset(hsqldbJar),
"/WEB-INF/lib/hsqldb.jar");
webArchive.as(ZipExporter.class).exportTo(file1, true);
// when
final WebArchive webArchive2 = ShrinkWrap.createFromZipFile(WebArchive.class, file1);
webArchive2.as(ZipExporter.class).exportTo(file2, true);
// then compare sizes
Assert.assertEquals(file1.length(), file2.length());
}
// -------------------------------------------------------------------------------------||
// 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;
}
}