aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ManifestTask.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ManifestTask.java')
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ManifestTask.java293
1 files changed, 293 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ManifestTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ManifestTask.java
new file mode 100644
index 00000000..9b600db5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ManifestTask.java
@@ -0,0 +1,293 @@
+/*
+ * 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.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.Enumeration;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Manifest.Attribute;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Creates a manifest file for inclusion in a JAR, Ant task wrapper
+ * around {@link Manifest Manifest}. This task can be used to write a
+ * Manifest file, optionally replacing or updating an existing file.
+ *
+ * @since Ant 1.5
+ *
+ * @ant.task category="java"
+ */
+public class ManifestTask extends Task {
+
+ /**
+ * Specifies the valid characters which can be used in attribute names.
+ * {@value}
+ */
+ public static final String VALID_ATTRIBUTE_CHARS =
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
+
+ /**
+ * Holds the real data.
+ */
+ private Manifest nestedManifest = new Manifest();
+
+ /**
+ * The file to which the manifest should be written when used as a task
+ */
+ private File manifestFile;
+
+ /**
+ * The mode with which the manifest file is written
+ */
+ private Mode mode;
+
+ /**
+ * The encoding of the manifest file
+ */
+ private String encoding;
+
+ /**
+ * whether to merge Class-Path attributes.
+ */
+ private boolean mergeClassPaths = false;
+
+ /**
+ * whether to flatten Class-Path attributes into a single one.
+ */
+ private boolean flattenClassPaths = false;
+
+ /**
+ * Helper class for Manifest's mode attribute.
+ */
+ public static class Mode extends EnumeratedAttribute {
+ /**
+ * Get Allowed values for the mode attribute.
+ *
+ * @return a String array of the allowed values.
+ */
+ public String[] getValues() {
+ return new String[] {"update", "replace"};
+ }
+ }
+
+ /**
+ * Default constructor
+ */
+ public ManifestTask() {
+ mode = new Mode();
+ mode.setValue("replace");
+ }
+
+ /**
+ * Add a section to the manifest
+ *
+ * @param section the manifest section to be added
+ *
+ * @exception ManifestException if the section is not valid.
+ */
+ public void addConfiguredSection(Manifest.Section section)
+ throws ManifestException {
+ Enumeration<String> attributeKeys = section.getAttributeKeys();
+ while (attributeKeys.hasMoreElements()) {
+ Attribute attribute = section.getAttribute(
+ attributeKeys.nextElement());
+ checkAttribute(attribute);
+ }
+ nestedManifest.addConfiguredSection(section);
+ }
+
+ /**
+ * Add an attribute to the manifest - it is added to the main section.
+ *
+ * @param attribute the attribute to be added.
+ *
+ * @exception ManifestException if the attribute is not valid.
+ */
+ public void addConfiguredAttribute(Manifest.Attribute attribute)
+ throws ManifestException {
+ checkAttribute(attribute);
+ nestedManifest.addConfiguredAttribute(attribute);
+ }
+
+ /**
+ * Checks the attribute against the Jar-specification.
+ *
+ * Jar-Specification <i>"Name-Value pairs and Sections"</i>: <pre>
+ * name: alphanum *headerchar
+ * alphanum: {A-Z} | {a-z} | {0-9}
+ * headerchar: alphanum | - | _
+ * </pre>
+ * So the resulting regexp would be <tt>[A-Za-z0-9][A-Za-z0-9-_]*</tt>.
+ *
+ * Because of JDK 1.2 compliance and the possible absence of a
+ * regexp matcher we can not use regexps here. Instead we have to
+ * check each character.
+ *
+ * @param attribute The attribute to check
+ * @throws BuildException if the check fails
+ */
+ private void checkAttribute(Manifest.Attribute attribute) throws BuildException {
+ String name = attribute.getName();
+ char ch = name.charAt(0);
+
+ if (ch == '-' || ch == '_') {
+ throw new BuildException("Manifest attribute names must not start with '" + ch + "'.");
+ }
+
+ for (int i = 0; i < name.length(); i++) {
+ ch = name.charAt(i);
+ if (VALID_ATTRIBUTE_CHARS.indexOf(ch) < 0) {
+ throw new BuildException("Manifest attribute names must not contain '" + ch + "'");
+ }
+ }
+ }
+
+ /**
+ * The name of the manifest file to create/update.
+ * Required if used as a task.
+ * @param f the Manifest file to be written
+ */
+ public void setFile(File f) {
+ manifestFile = f;
+ }
+
+ /**
+ * The encoding to use for reading in an existing manifest file
+ * @param encoding the manifest file encoding.
+ */
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
+ * Update policy: either "update" or "replace"; default is "replace".
+ * @param m the mode value - update or replace.
+ */
+ public void setMode(Mode m) {
+ mode = m;
+ }
+
+ /**
+ * Whether to merge Class-Path attributes.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setMergeClassPathAttributes(boolean b) {
+ mergeClassPaths = b;
+ }
+
+ /**
+ * Whether to flatten multi-valued attributes (i.e. Class-Path)
+ * into a single one.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setFlattenAttributes(boolean b) {
+ flattenClassPaths = b;
+ }
+
+ /**
+ * Create or update the Manifest when used as a task.
+ *
+ * @throws BuildException if the manifest cannot be written.
+ */
+ public void execute() throws BuildException {
+ if (manifestFile == null) {
+ throw new BuildException("the file attribute is required");
+ }
+
+ Manifest toWrite = Manifest.getDefaultManifest();
+ Manifest current = null;
+ BuildException error = null;
+
+ if (manifestFile.exists()) {
+ FileInputStream fis = null;
+ InputStreamReader isr = null;
+ try {
+ fis = new FileInputStream(manifestFile);
+ if (encoding == null) {
+ isr = new InputStreamReader(fis, "UTF-8");
+ } else {
+ isr = new InputStreamReader(fis, encoding);
+ }
+ current = new Manifest(isr);
+ } catch (ManifestException m) {
+ error = new BuildException("Existing manifest " + manifestFile
+ + " is invalid", m, getLocation());
+ } catch (IOException e) {
+ error = new BuildException("Failed to read " + manifestFile,
+ e, getLocation());
+ } finally {
+ FileUtils.close(isr);
+ }
+ }
+
+ //look for and print warnings
+ for (Enumeration<String> e = nestedManifest.getWarnings();
+ e.hasMoreElements();) {
+ log("Manifest warning: " + e.nextElement(),
+ Project.MSG_WARN);
+ }
+ try {
+ if (mode.getValue().equals("update") && manifestFile.exists()) {
+ if (current != null) {
+ toWrite.merge(current, false, mergeClassPaths);
+ } else if (error != null) {
+ throw error;
+ }
+ }
+
+ toWrite.merge(nestedManifest, false, mergeClassPaths);
+ } catch (ManifestException m) {
+ throw new BuildException("Manifest is invalid", m, getLocation());
+ }
+
+ if (toWrite.equals(current)) {
+ log("Manifest has not changed, do not recreate",
+ Project.MSG_VERBOSE);
+ return;
+ }
+
+ PrintWriter w = null;
+ try {
+ FileOutputStream fos = new FileOutputStream(manifestFile);
+ OutputStreamWriter osw = new OutputStreamWriter(fos, Manifest.JAR_ENCODING);
+ w = new PrintWriter(osw);
+ toWrite.write(w, flattenClassPaths);
+ if (w.checkError()) {
+ throw new IOException("Encountered an error writing manifest");
+ }
+ } catch (IOException e) {
+ throw new BuildException("Failed to write " + manifestFile,
+ e, getLocation());
+ } finally {
+ FileUtils.close(w);
+ }
+ }
+}