aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/Specification.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/Specification.java')
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/Specification.java605
1 files changed, 605 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/Specification.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/Specification.java
new file mode 100644
index 00000000..1e4bb7b3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/Specification.java
@@ -0,0 +1,605 @@
+/*
+ * 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.optional.extension;
+
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import org.apache.tools.ant.util.DeweyDecimal;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * <p>Utility class that represents either an available "Optional Package"
+ * (formerly known as "Standard Extension") as described in the manifest
+ * of a JAR file, or the requirement for such an optional package.</p>
+ *
+ * <p>For more information about optional packages, see the document
+ * <em>Optional Package Versioning</em> in the documentation bundle for your
+ * Java2 Standard Edition package, in file
+ * <code>guide/extensions/versioning.html</code>.</p>
+ *
+ */
+public final class Specification {
+
+ private static final String MISSING = "Missing ";
+
+ /**
+ * Manifest Attribute Name object for SPECIFICATION_TITLE.
+ */
+ public static final Attributes.Name SPECIFICATION_TITLE
+ = Attributes.Name.SPECIFICATION_TITLE;
+
+ /**
+ * Manifest Attribute Name object for SPECIFICATION_VERSION.
+ */
+ public static final Attributes.Name SPECIFICATION_VERSION
+ = Attributes.Name.SPECIFICATION_VERSION;
+
+ /**
+ * Manifest Attribute Name object for SPECIFICATION_VENDOR.
+ */
+ public static final Attributes.Name SPECIFICATION_VENDOR
+ = Attributes.Name.SPECIFICATION_VENDOR;
+
+ /**
+ * Manifest Attribute Name object for IMPLEMENTATION_TITLE.
+ */
+ public static final Attributes.Name IMPLEMENTATION_TITLE
+ = Attributes.Name.IMPLEMENTATION_TITLE;
+
+ /**
+ * Manifest Attribute Name object for IMPLEMENTATION_VERSION.
+ */
+ public static final Attributes.Name IMPLEMENTATION_VERSION
+ = Attributes.Name.IMPLEMENTATION_VERSION;
+
+ /**
+ * Manifest Attribute Name object for IMPLEMENTATION_VENDOR.
+ */
+ public static final Attributes.Name IMPLEMENTATION_VENDOR
+ = Attributes.Name.IMPLEMENTATION_VENDOR;
+
+ /**
+ * Enum indicating that extension is compatible with other Package
+ * Specification.
+ */
+ public static final Compatibility COMPATIBLE =
+ new Compatibility("COMPATIBLE");
+
+ /**
+ * Enum indicating that extension requires an upgrade
+ * of specification to be compatible with other Package Specification.
+ */
+ public static final Compatibility REQUIRE_SPECIFICATION_UPGRADE =
+ new Compatibility("REQUIRE_SPECIFICATION_UPGRADE");
+
+ /**
+ * Enum indicating that extension requires a vendor
+ * switch to be compatible with other Package Specification.
+ */
+ public static final Compatibility REQUIRE_VENDOR_SWITCH =
+ new Compatibility("REQUIRE_VENDOR_SWITCH");
+
+ /**
+ * Enum indicating that extension requires an upgrade
+ * of implementation to be compatible with other Package Specification.
+ */
+ public static final Compatibility REQUIRE_IMPLEMENTATION_CHANGE =
+ new Compatibility("REQUIRE_IMPLEMENTATION_CHANGE");
+
+ /**
+ * This enum indicates that an extension is incompatible with
+ * other Package Specification in ways other than other enums
+ * indicate. For example, the other Package Specification
+ * may have a different ID.
+ */
+ public static final Compatibility INCOMPATIBLE =
+ new Compatibility("INCOMPATIBLE");
+
+ /**
+ * The name of the Package Specification.
+ */
+ private String specificationTitle;
+
+ /**
+ * The version number (dotted decimal notation) of the specification
+ * to which this optional package conforms.
+ */
+ private DeweyDecimal specificationVersion;
+
+ /**
+ * The name of the company or organization that originated the
+ * specification to which this specification conforms.
+ */
+ private String specificationVendor;
+
+ /**
+ * The title of implementation.
+ */
+ private String implementationTitle;
+
+ /**
+ * The name of the company or organization that produced this
+ * implementation of this specification.
+ */
+ private String implementationVendor;
+
+ /**
+ * The version string for implementation. The version string is
+ * opaque.
+ */
+ private String implementationVersion;
+
+ /**
+ * The sections of jar that the specification applies to.
+ */
+ private String[] sections;
+
+ /**
+ * Return an array of <code>Package Specification</code> objects.
+ * If there are no such optional packages, a zero-length array is returned.
+ *
+ * @param manifest Manifest to be parsed
+ * @return the Package Specifications extensions in specified manifest
+ * @throws ParseException if the attributes of the specifications cannot
+ * be parsed according to their expected formats.
+ */
+ public static Specification[] getSpecifications(final Manifest manifest)
+ throws ParseException {
+ if (null == manifest) {
+ return new Specification[ 0 ];
+ }
+
+ final ArrayList results = new ArrayList();
+
+ final Map entries = manifest.getEntries();
+ final Iterator keys = entries.keySet().iterator();
+ while (keys.hasNext()) {
+ final String key = (String) keys.next();
+ final Attributes attributes = (Attributes) entries.get(key);
+ final Specification specification
+ = getSpecification(key, attributes);
+ if (null != specification) {
+ results.add(specification);
+ }
+ }
+
+ final ArrayList trimmedResults = removeDuplicates(results);
+ return (Specification[]) trimmedResults.toArray(new Specification[trimmedResults.size()]);
+ }
+
+ /**
+ * The constructor to create Package Specification object.
+ * Note that every component is allowed to be specified
+ * but only the specificationTitle is mandatory.
+ *
+ * @param specificationTitle the name of specification.
+ * @param specificationVersion the specification Version.
+ * @param specificationVendor the specification Vendor.
+ * @param implementationTitle the title of implementation.
+ * @param implementationVersion the implementation Version.
+ * @param implementationVendor the implementation Vendor.
+ */
+ public Specification(final String specificationTitle,
+ final String specificationVersion,
+ final String specificationVendor,
+ final String implementationTitle,
+ final String implementationVersion,
+ final String implementationVendor) {
+ this(specificationTitle, specificationVersion, specificationVendor,
+ implementationTitle, implementationVersion, implementationVendor,
+ null);
+ }
+
+ /**
+ * The constructor to create Package Specification object.
+ * Note that every component is allowed to be specified
+ * but only the specificationTitle is mandatory.
+ *
+ * @param specificationTitle the name of specification.
+ * @param specificationVersion the specification Version.
+ * @param specificationVendor the specification Vendor.
+ * @param implementationTitle the title of implementation.
+ * @param implementationVersion the implementation Version.
+ * @param implementationVendor the implementation Vendor.
+ * @param sections the sections/packages that Specification applies to.
+ */
+ public Specification(final String specificationTitle,
+ final String specificationVersion,
+ final String specificationVendor,
+ final String implementationTitle,
+ final String implementationVersion,
+ final String implementationVendor,
+ final String[] sections) {
+ this.specificationTitle = specificationTitle;
+ this.specificationVendor = specificationVendor;
+
+ if (null != specificationVersion) {
+ try {
+ this.specificationVersion
+ = new DeweyDecimal(specificationVersion);
+ } catch (final NumberFormatException nfe) {
+ final String error = "Bad specification version format '"
+ + specificationVersion + "' in '" + specificationTitle
+ + "'. (Reason: " + nfe + ")";
+ throw new IllegalArgumentException(error);
+ }
+ }
+
+ this.implementationTitle = implementationTitle;
+ this.implementationVendor = implementationVendor;
+ this.implementationVersion = implementationVersion;
+
+ if (null == this.specificationTitle) {
+ throw new NullPointerException("specificationTitle");
+ }
+
+ String[] copy = null;
+ if (null != sections) {
+ copy = new String[ sections.length ];
+ System.arraycopy(sections, 0, copy, 0, sections.length);
+ }
+ this.sections = copy;
+ }
+
+ /**
+ * Get the title of the specification.
+ *
+ * @return the title of specification
+ */
+ public String getSpecificationTitle() {
+ return specificationTitle;
+ }
+
+ /**
+ * Get the vendor of the specification.
+ *
+ * @return the vendor of the specification.
+ */
+ public String getSpecificationVendor() {
+ return specificationVendor;
+ }
+
+ /**
+ * Get the title of the specification.
+ *
+ * @return the title of the specification.
+ */
+ public String getImplementationTitle() {
+ return implementationTitle;
+ }
+
+ /**
+ * Get the version of the specification.
+ *
+ * @return the version of the specification.
+ */
+ public DeweyDecimal getSpecificationVersion() {
+ return specificationVersion;
+ }
+
+ /**
+ * Get the vendor of the extensions implementation.
+ *
+ * @return the vendor of the extensions implementation.
+ */
+ public String getImplementationVendor() {
+ return implementationVendor;
+ }
+
+ /**
+ * Get the version of the implementation.
+ *
+ * @return the version of the implementation.
+ */
+ public String getImplementationVersion() {
+ return implementationVersion;
+ }
+
+ /**
+ * Return an array containing sections to which specification applies
+ * or null if relevant to no sections.
+ *
+ * @return an array containing sections to which specification applies
+ * or null if relevant to no sections.
+ */
+ public String[] getSections() {
+ if (null == sections) {
+ return null;
+ }
+ final String[] newSections = new String[ sections.length ];
+ System.arraycopy(sections, 0, newSections, 0, sections.length);
+ return newSections;
+ }
+
+ /**
+ * Return a Compatibility enum indicating the relationship of this
+ * <code>Package Specification</code> with the specified
+ * <code>Extension</code>.
+ *
+ * @param other the other specification
+ * @return the enum indicating the compatibility (or lack thereof)
+ * of specified Package Specification
+ */
+ public Compatibility getCompatibilityWith(final Specification other) {
+ // Specification Name must match
+ if (!specificationTitle.equals(other.getSpecificationTitle())) {
+ return INCOMPATIBLE;
+ }
+
+ // Available specification version must be >= required
+ final DeweyDecimal otherSpecificationVersion
+ = other.getSpecificationVersion();
+ if (null != specificationVersion) {
+ if (null == otherSpecificationVersion
+ || !isCompatible(specificationVersion, otherSpecificationVersion)) {
+ return REQUIRE_SPECIFICATION_UPGRADE;
+ }
+ }
+
+ // Implementation Vendor ID must match
+ final String otherImplementationVendor
+ = other.getImplementationVendor();
+ if (null != implementationVendor) {
+ if (null == otherImplementationVendor
+ || !implementationVendor.equals(otherImplementationVendor)) {
+ return REQUIRE_VENDOR_SWITCH;
+ }
+ }
+
+ // Implementation version must be >= required
+ final String otherImplementationVersion
+ = other.getImplementationVersion();
+ if (null != implementationVersion) {
+ if (null == otherImplementationVersion
+ || !implementationVersion.equals(otherImplementationVersion)) {
+ return REQUIRE_IMPLEMENTATION_CHANGE;
+ }
+ }
+
+ // This available optional package satisfies the requirements
+ return COMPATIBLE;
+ }
+
+ /**
+ * Return <code>true</code> if the specified <code>package</code>
+ * is satisfied by this <code>Specification</code>. Otherwise, return
+ * <code>false</code>.
+ *
+ * @param other the specification
+ * @return true if the specification is compatible with this specification
+ */
+ public boolean isCompatibleWith(final Specification other) {
+ return (COMPATIBLE == getCompatibilityWith(other));
+ }
+
+ /**
+ * Return a String representation of this object.
+ *
+ * @return string representation of object.
+ */
+ public String toString() {
+ final String brace = ": ";
+
+ final StringBuffer sb
+ = new StringBuffer(SPECIFICATION_TITLE.toString());
+ sb.append(brace);
+ sb.append(specificationTitle);
+ sb.append(StringUtils.LINE_SEP);
+
+ if (null != specificationVersion) {
+ sb.append(SPECIFICATION_VERSION);
+ sb.append(brace);
+ sb.append(specificationVersion);
+ sb.append(StringUtils.LINE_SEP);
+ }
+
+ if (null != specificationVendor) {
+ sb.append(SPECIFICATION_VENDOR);
+ sb.append(brace);
+ sb.append(specificationVendor);
+ sb.append(StringUtils.LINE_SEP);
+ }
+
+ if (null != implementationTitle) {
+ sb.append(IMPLEMENTATION_TITLE);
+ sb.append(brace);
+ sb.append(implementationTitle);
+ sb.append(StringUtils.LINE_SEP);
+ }
+
+ if (null != implementationVersion) {
+ sb.append(IMPLEMENTATION_VERSION);
+ sb.append(brace);
+ sb.append(implementationVersion);
+ sb.append(StringUtils.LINE_SEP);
+ }
+
+ if (null != implementationVendor) {
+ sb.append(IMPLEMENTATION_VENDOR);
+ sb.append(brace);
+ sb.append(implementationVendor);
+ sb.append(StringUtils.LINE_SEP);
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Return <code>true</code> if the first version number is greater than
+ * or equal to the second; otherwise return <code>false</code>.
+ *
+ * @param first First version number (dotted decimal)
+ * @param second Second version number (dotted decimal)
+ */
+ private boolean isCompatible(final DeweyDecimal first,
+ final DeweyDecimal second) {
+ return first.isGreaterThanOrEqual(second);
+ }
+
+ /**
+ * Combine all specifications objects that are identical except
+ * for the sections.
+ *
+ * <p>Note this is very inefficent and should probably be fixed
+ * in the future.</p>
+ *
+ * @param list the array of results to trim
+ * @return an array list with all duplicates removed
+ */
+ private static ArrayList removeDuplicates(final ArrayList list) {
+ final ArrayList results = new ArrayList();
+ final ArrayList sections = new ArrayList();
+ while (list.size() > 0) {
+ final Specification specification = (Specification) list.remove(0);
+ final Iterator iterator = list.iterator();
+ while (iterator.hasNext()) {
+ final Specification other = (Specification) iterator.next();
+ if (isEqual(specification, other)) {
+ final String[] otherSections = other.getSections();
+ if (null != otherSections) {
+ sections.addAll(Arrays.asList(otherSections));
+ }
+ iterator.remove();
+ }
+ }
+
+ final Specification merged =
+ mergeInSections(specification, sections);
+ results.add(merged);
+ //Reset list of sections
+ sections.clear();
+ }
+
+ return results;
+ }
+
+ /**
+ * Test if two specifications are equal except for their sections.
+ *
+ * @param specification one specificaiton
+ * @param other the ohter specification
+ * @return true if two specifications are equal except for their
+ * sections, else false
+ */
+ private static boolean isEqual(final Specification specification,
+ final Specification other) {
+ return
+ specification.getSpecificationTitle().equals(other.getSpecificationTitle())
+ && specification.getSpecificationVersion().isEqual(other.getSpecificationVersion())
+ && specification.getSpecificationVendor().equals(other.getSpecificationVendor())
+ && specification.getImplementationTitle().equals(other.getImplementationTitle())
+ && specification.getImplementationVersion().equals(other.getImplementationVersion())
+ && specification.getImplementationVendor().equals(other.getImplementationVendor());
+ }
+
+ /**
+ * Merge the specified sections into specified section and return result.
+ * If no sections to be added then just return original specification.
+ *
+ * @param specification the specification
+ * @param sectionsToAdd the list of sections to merge
+ * @return the merged specification
+ */
+ private static Specification mergeInSections(final Specification specification,
+ final ArrayList sectionsToAdd) {
+ if (0 == sectionsToAdd.size()) {
+ return specification;
+ }
+ sectionsToAdd.addAll(Arrays.asList(specification.getSections()));
+
+ final String[] sections =
+ (String[]) sectionsToAdd.toArray(new String[sectionsToAdd.size()]);
+
+ return new Specification(specification.getSpecificationTitle(),
+ specification.getSpecificationVersion().toString(),
+ specification.getSpecificationVendor(),
+ specification.getImplementationTitle(),
+ specification.getImplementationVersion(),
+ specification.getImplementationVendor(),
+ sections);
+ }
+
+ /**
+ * Trim the supplied string if the string is non-null
+ *
+ * @param value the string to trim or null
+ * @return the trimmed string or null
+ */
+ private static String getTrimmedString(final String value) {
+ return value == null ? null : value.trim();
+ }
+
+ /**
+ * Extract an Package Specification from Attributes.
+ *
+ * @param attributes Attributes to searched
+ * @return the new Specification object, or null
+ */
+ private static Specification getSpecification(final String section,
+ final Attributes attributes)
+ throws ParseException {
+ //WARNING: We trim the values of all the attributes because
+ //Some extension declarations are badly defined (ie have spaces
+ //after version or vendor)
+ final String name
+ = getTrimmedString(attributes.getValue(SPECIFICATION_TITLE));
+ if (null == name) {
+ return null;
+ }
+
+ final String specVendor
+ = getTrimmedString(attributes.getValue(SPECIFICATION_VENDOR));
+ if (null == specVendor) {
+ throw new ParseException(MISSING + SPECIFICATION_VENDOR, 0);
+ }
+
+ final String specVersion
+ = getTrimmedString(attributes.getValue(SPECIFICATION_VERSION));
+ if (null == specVersion) {
+ throw new ParseException(MISSING + SPECIFICATION_VERSION, 0);
+ }
+
+ final String impTitle
+ = getTrimmedString(attributes.getValue(IMPLEMENTATION_TITLE));
+ if (null == impTitle) {
+ throw new ParseException(MISSING + IMPLEMENTATION_TITLE, 0);
+ }
+
+ final String impVersion
+ = getTrimmedString(attributes.getValue(IMPLEMENTATION_VERSION));
+ if (null == impVersion) {
+ throw new ParseException(MISSING + IMPLEMENTATION_VERSION, 0);
+ }
+
+ final String impVendor
+ = getTrimmedString(attributes.getValue(IMPLEMENTATION_VENDOR));
+ if (null == impVendor) {
+ throw new ParseException(MISSING + IMPLEMENTATION_VENDOR, 0);
+ }
+
+ return new Specification(name, specVersion, specVendor,
+ impTitle, impVersion, impVendor,
+ new String[]{section});
+ }
+}