/* * Copyright 2015 Cel Skeggs. * * This file is part of the CCRE, the Common Chicken Runtime Engine. * * The CCRE is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * The CCRE is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with the CCRE. If not, see <http://www.gnu.org/licenses/>. */ package ccre.deployment; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.jar.Attributes; import java.util.jar.Manifest; /** * A collection of utilities for working with Jar files in the context of * deployment systems. This includes things like merging Jars and creating and * adding manifests. * * @author skeggsc */ public class DepJar { /** * Create a new Manifest from a Map of key-value pairs. If * <code>Manifest-Version</code> is not specified, it will be set to * <code>1.0</code>. * * @param entries the key-value pairs to include. * @return the constructed Manifest. */ public static Manifest manifest(Map<String, String> entries) { Manifest mf = new Manifest(); Attributes attrs = mf.getMainAttributes(); if (!entries.containsKey("Manifest-Version")) { attrs.putValue("Manifest-Version", "1.0"); } for (Map.Entry<String, String> ent : entries.entrySet()) { attrs.putValue(ent.getKey(), ent.getValue()); } return mf; } /** * Create a new Manifest from an array of keys and values. If * <code>Manifest-Version</code> is not specified, it will be set to * <code>1.0</code>. * * The <code>kvs[0]</code> is a key for <code>kvs[1]</code>, which is a * value. The <code>kvs[2]</code> is a key for <code>kvs[3]</code>, which is * a value. And so on and so forth. * * @param kvs the keys and values to include in the manifest. * @return the constructed Manifest. * @throws IllegalArgumentException if <code>kvs</code> does not have an * even number of elements, or if any element is null. */ public static Manifest manifest(String... kvs) throws IllegalArgumentException { if ((kvs.length & 1) != 0) { throw new IllegalArgumentException("Invalid number of keys and values."); } HashMap<String, String> hm = new HashMap<>(); for (int i = 0; i < kvs.length; i += 2) { if (kvs[i] == null || kvs[i + 1] == null) { throw new NullPointerException("Keys and values cannot be null!"); } hm.put(kvs[i], kvs[i + 1]); } return manifest(hm); } /** * Construct a new Jar from a set of artifacts, and a manifest. * * If <code>manifest</code> is null, then it will be obtained from an * artifact that also has a manifest. * * See {@link Jar} for a discussion of what the <code>preserve</code> * argument means. * * Behavior is undefined when the same class file is provided by multiple * artifacts, or if a manifest is not provided but multiple artifacts * provide manifests. * * @param manifest the manifest to include in this Jar, which may be null. * @param preserve if this Jar should be marked for preservation. * @param artifacts the artifacts that contain the class files and resources * to include. * @return the newly-constructed Jar. * @throws IOException if the Jar cannot be constructed. */ public static Jar combine(Manifest manifest, boolean preserve, Artifact... artifacts) throws IOException { JarBuilder jb = new JarBuilder(manifest, preserve); for (Artifact artifact : artifacts) { jb.addAll(artifact, manifest == null); } return jb.build(); } /** * Construct a new Jar from a set of artifacts. * * The manifest then it will be obtained from an artifact that also has a * manifest. * * See {@link Jar} for a discussion of what the <code>preserve</code> * argument means. * * Behavior is undefined when the same class file is provided by multiple * artifacts, or if a manifest is not provided but multiple artifacts * provide manifests. * * @param preserve if this Jar should be marked for preservation. * @param artifacts the artifacts that contain the class files and resources * to include. * @return the newly-constructed Jar. * @throws IOException if the Jar cannot be constructed. */ public static Jar combine(boolean preserve, Artifact... artifacts) throws IOException { return combine(null, preserve, artifacts); } }