416 lines · 14.2 KB · Java
RawDownload
/* * Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code 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 General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.misc; import java.util.StringTokenizer;import java.util.jar.Attributes;import java.util.jar.Attributes.Name;import java.util.ResourceBundle;import java.util.MissingResourceException;import java.text.MessageFormat;import java.lang.Character.*;  /** * This class holds all necessary information to install or * upgrade a extension on the user's disk * * @author  Jerome Dochez */public class ExtensionInfo {     /**     * <p>     * public static values returned by the isCompatible method     * </p>     */    public static final int COMPATIBLE = 0;    public static final int REQUIRE_SPECIFICATION_UPGRADE = 1;    public static final int REQUIRE_IMPLEMENTATION_UPGRADE = 2;    public static final int REQUIRE_VENDOR_SWITCH = 3;    public static final int INCOMPATIBLE = 4;     /**     * <p>     * attributes fully describer an extension. The underlying described     * extension may be installed and requested.     * <p>     */    public String title;    public String name;    public String specVersion;    public String specVendor;    public String implementationVersion;    public String vendor;    public String vendorId;    public String url;     // For I18N support    private static final ResourceBundle rb =        ResourceBundle.getBundle("sun.misc.resources.Messages");      /**     * <p>     * Create a new uninitialized extension information object     * </p>     */    public ExtensionInfo() {    }     /**     * <p>     * Create and initialize an extension information object.     * The initialization uses the attributes passed as being     * the content of a manifest file to load the extension     * information from.     * Since manifest file may contain information on several     * extension they may depend on, the extension key parameter     * is prepanded to the attribute name to make the key used     * to retrieve the attribute from the manifest file     * <p>     * @param extensionKey unique extension key in the manifest     * @param attr Attributes of a manifest file     */    public ExtensionInfo(String extensionKey, Attributes attr)        throws NullPointerException    {        String s;        if (extensionKey!=null) {            s = extensionKey + "-";        } else {            s ="";        }         String attrKey = s + Name.EXTENSION_NAME.toString();        name = attr.getValue(attrKey);        if (name != null)            name = name.trim();         attrKey = s + Name.SPECIFICATION_TITLE.toString();        title = attr.getValue(attrKey);        if (title != null)            title = title.trim();         attrKey = s + Name.SPECIFICATION_VERSION.toString();        specVersion = attr.getValue(attrKey);        if (specVersion != null)            specVersion = specVersion.trim();         attrKey = s + Name.SPECIFICATION_VENDOR.toString();        specVendor = attr.getValue(attrKey);        if (specVendor != null)            specVendor = specVendor.trim();         attrKey = s + Name.IMPLEMENTATION_VERSION.toString();        implementationVersion = attr.getValue(attrKey);        if (implementationVersion != null)            implementationVersion = implementationVersion.trim();         attrKey = s + Name.IMPLEMENTATION_VENDOR.toString();        vendor = attr.getValue(attrKey);        if (vendor != null)            vendor = vendor.trim();         attrKey = s + Name.IMPLEMENTATION_VENDOR_ID.toString();        vendorId = attr.getValue(attrKey);        if (vendorId != null)            vendorId = vendorId.trim();         attrKey =s + Name.IMPLEMENTATION_URL.toString();        url = attr.getValue(attrKey);        if (url != null)            url = url.trim();    }     /**     * <p>     * @return true if the extension described by this extension information     * is compatible with the extension described by the extension     * information passed as a parameter     * </p>     *     * @param the requested extension information to compare to     */    public int isCompatibleWith(ExtensionInfo ei) {         if (name == null || ei.name == null)            return INCOMPATIBLE;        if (name.compareTo(ei.name)==0) {            // is this true, if not spec version is specified, we consider            // the value as being "any".            if (specVersion == null || ei.specVersion == null)                return COMPATIBLE;             int version = compareExtensionVersion(specVersion, ei.specVersion);            if (version<0) {                // this extension specification is "older"                if (vendorId != null && ei.vendorId !=null) {                    if (vendorId.compareTo(ei.vendorId)!=0) {                        return REQUIRE_VENDOR_SWITCH;                    }                }                return REQUIRE_SPECIFICATION_UPGRADE;            } else {                // the extension spec is compatible, let's look at the                // implementation attributes                if (vendorId != null && ei.vendorId != null) {                    // They care who provides the extension                    if (vendorId.compareTo(ei.vendorId)!=0) {                        // They want to use another vendor implementation                        return REQUIRE_VENDOR_SWITCH;                    } else {                        // Vendor matches, let's see the implementation version                        if (implementationVersion != null && ei.implementationVersion != null) {                            // they care about the implementation version                            version = compareExtensionVersion(implementationVersion, ei.implementationVersion);                            if (version<0) {                                // This extension is an older implementation                                return REQUIRE_IMPLEMENTATION_UPGRADE;                            }                        }                    }                }                // All othe cases, we consider the extensions to be compatible                return COMPATIBLE;            }        }        return INCOMPATIBLE;    }     /**     * <p>     * helper method to print sensible information on the undelying described     * extension     * </p>     */    public String toString() {        return "Extension : title(" + title + "), name(" + name + "), spec vendor(" +            specVendor + "), spec version(" + specVersion + "), impl vendor(" +            vendor + "), impl vendor id(" + vendorId + "), impl version(" +            implementationVersion + "), impl url(" + url + ")";    }     /*     * <p>     * helper method to compare two versions.     * version are in the x.y.z.t pattern.     * </p>     * @param source version to compare to     * @param target version used to compare against     * @return < 0 if source < version     *         > 0 if source > version     *         = 0 if source = version     */    private int compareExtensionVersion(String source, String target)        throws NumberFormatException    {        source = source.toLowerCase();        target = target.toLowerCase();         return strictCompareExtensionVersion(source, target);    }      /*     * <p>     * helper method to compare two versions.     * version are in the x.y.z.t pattern.     * </p>     * @param source version to compare to     * @param target version used to compare against     * @return < 0 if source < version     *         > 0 if source > version     *         = 0 if source = version     */    private int strictCompareExtensionVersion(String source, String target)        throws NumberFormatException    {        if (source.equals(target))            return 0;         StringTokenizer stk = new StringTokenizer(source, ".,");        StringTokenizer ttk = new StringTokenizer(target, ".,");         // Compare number        int n = 0, m = 0, result = 0;         // Convert token into meaning number for comparision        if (stk.hasMoreTokens())            n = convertToken(stk.nextToken().toString());         // Convert token into meaning number for comparision        if (ttk.hasMoreTokens())            m = convertToken(ttk.nextToken().toString());         if (n > m)            return 1;        else if (m > n)            return -1;        else        {            // Look for index of "." in the string            int sIdx = source.indexOf(".");            int tIdx = target.indexOf(".");             if (sIdx == -1)                sIdx = source.length() - 1;             if (tIdx == -1)                tIdx = target.length() - 1;             return strictCompareExtensionVersion(source.substring(sIdx + 1),                                                 target.substring(tIdx + 1));        }    }     private int convertToken(String token)    {        if (token == null || token.equals(""))            return 0;         int charValue = 0;        int charVersion = 0;        int patchVersion = 0;        int strLength = token.length();        int endIndex = strLength;        char lastChar;         Object[] args = {name};        MessageFormat mf = new MessageFormat(rb.getString("optpkg.versionerror"));        String versionError = mf.format(args);         // Look for "-" for pre-release        int prIndex = token.indexOf("-");         // Look for "_" for patch release        int patchIndex = token.indexOf("_");         if (prIndex == -1 && patchIndex == -1)        {            // This is a FCS release            try {                return Integer.parseInt(token) * 100;            } catch (NumberFormatException e) {                System.out.println(versionError);                return 0;            }        }        else if (patchIndex != -1)        {            // This is a patch (update) release            int prversion;            try {                // Obtain the version                prversion = Integer.parseInt(token.substring(0, patchIndex));                 // Check to see if the patch version is in the n.n.n_nnl format (special release)                lastChar = token.charAt(strLength-1);                if (Character.isLetter(lastChar)) {                    // letters a-z have values from 10-35                    charValue = Character.getNumericValue(lastChar);                    endIndex = strLength-1;                     // Obtain the patch version id                    patchVersion = Integer.parseInt(token.substring(patchIndex+1, endIndex));                     if (charValue >= Character.getNumericValue('a') && charValue <= Character.getNumericValue('z')) {                        // This is a special release                        charVersion = (patchVersion * 100) + charValue;                    } else {                        // character is not a a-z letter, ignore                        charVersion = 0;                        System.out.println(versionError);                    }                } else {                    // This is a regular update release. Obtain the patch version id                    patchVersion = Integer.parseInt(token.substring(patchIndex+1, endIndex));                }            } catch (NumberFormatException e) {                System.out.println(versionError);                return 0;            }            return prversion * 100 + (patchVersion + charVersion);        }        else        {            //This is a milestone release, either a early access, alpha, beta, or RC             // Obtain the version            int mrversion;            try {                mrversion = Integer.parseInt(token.substring(0, prIndex));            } catch (NumberFormatException e) {                System.out.println(versionError);                return 0;            }             // Obtain the patch version string, including the milestone + version            String prString = token.substring(prIndex + 1);             // Milestone version            String msVersion = "";            int delta = 0;             if (prString.indexOf("ea") != -1)            {                msVersion = prString.substring(2);                delta = 50;            }            else if (prString.indexOf("alpha") != -1)            {                msVersion = prString.substring(5);                delta = 40;            }            else if (prString.indexOf("beta") != -1)            {                msVersion = prString.substring(4);                delta = 30;            }            else if (prString.indexOf("rc") != -1)            {                msVersion = prString.substring(2);                delta = 20;            }             if (msVersion == null || msVersion.equals(""))            {                // No version after the milestone, assume 0                return mrversion * 100 - delta ;            }            else            {                // Convert the milestone version                try {                    return mrversion * 100 - delta + Integer.parseInt(msVersion);                } catch (NumberFormatException e) {                    System.out.println(versionError);                    return 0;                }            }        }    }}