/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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.apache.ziplock; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; /** * @version $Revision$ $Date$ */ public class Archive { final Map<String, String> manifest = new HashMap<String, String>(); final Map<String, byte[]> entries = new HashMap<String, byte[]>(); public static Archive archive() { return new Archive(); } public Archive manifest(final String key, final Object value) { manifest.put(key, value.toString()); return this; } public Archive manifest(final String key, final Class value) { manifest.put(key, value.getName()); return this; } public Archive copyTo(final String path, final File file) { if (file.isDirectory()) { for (final File child : file.listFiles()) { copyTo(path + "/" + child.getName(), child); } } else { try { entries.put(path, IO.readBytes(file)); } catch (final IOException e) { throw new RuntimeException(e); } } return this; } public Archive addTo(final String path, final Class<?> clazz) { try { final String name = clazz.getName().replace('.', '/') + ".class"; final URL resource = this.getClass().getClassLoader().getResource(name); final InputStream from = new BufferedInputStream(resource.openStream()); final ByteArrayOutputStream to = new ByteArrayOutputStream(); final byte[] buffer = new byte[1024]; int length; while ((length = from.read(buffer)) != -1) { to.write(buffer, 0, length); } to.flush(); if (path != null && path.length() != 0) { entries.put(path + "/" + name, to.toByteArray()); } else { entries.put(name, to.toByteArray()); } } catch (final IOException e) { throw new IllegalStateException(e); } return this; } public Archive add(final Class<?> clazz) { return addTo(null, clazz); } public File toJar() throws IOException { return toJar("archive-", ".jar"); } public File toJar(final String prefix, final String suffix) throws IOException { final File file = File.createTempFile(prefix, suffix); file.deleteOnExit(); // Create the ZIP file final ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(file))); for (final Map.Entry<String, byte[]> entry : entries().entrySet()) { out.putNextEntry(new ZipEntry(entry.getKey())); out.write(entry.getValue()); } // Complete the ZIP file out.close(); return file; } public File asJar() { try { return toJar(); } catch (final IOException e) { throw new RuntimeException(e); } } public File asJar(final String prefix, final String suffix) { try { return toJar(prefix, suffix); } catch (final IOException e) { throw new RuntimeException(e); } } public File toDir() throws IOException { final File classpath = Files.tmpdir(); for (final Map.Entry<String, byte[]> entry : entries().entrySet()) { final String key = entry.getKey().replace('/', File.separatorChar); final File file = new File(classpath, key); final File d = file.getParentFile(); if (!d.exists()) { if (!d.mkdirs()) { throw new IllegalStateException("Cannot Make Directory: "+d.getAbsolutePath()); } } final BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file)); out.write(entry.getValue()); out.close(); } return classpath; } public File asDir() { try { return toDir(); } catch (final IOException e) { throw new RuntimeException(e); } } private HashMap<String, byte[]> entries() { final HashMap<String, byte[]> entries = new HashMap<String, byte[]>(this.entries); entries.put("META-INF/MANIFEST.MF", buildManifest().getBytes()); return entries; } private String buildManifest() { return Join.join("\r\n", new Join.NameCallback<Map.Entry<String, String>>() { @Override public String getName(final Map.Entry<String, String> entry) { return entry.getKey() + ": " + entry.getValue(); } }, manifest.entrySet()); } }