001: /*
002: * @(#)ExtensionInfo.java 1.11 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package sun.misc;
029:
030: import java.util.StringTokenizer;
031: import java.util.jar.Attributes;
032: import java.util.jar.Attributes.Name;
033:
034: /**
035: * This class holds all necessary information to install or
036: * upgrade a extension on the user's disk
037: *
038: * @author Jerome Dochez
039: * @version 1.5, 02/02/00
040: */
041: public class ExtensionInfo {
042:
043: /**
044: * <p>
045: * public static values returned by the isCompatible method
046: * </p>
047: */
048: public static final int COMPATIBLE = 0;
049: public static final int REQUIRE_SPECIFICATION_UPGRADE = 1;
050: public static final int REQUIRE_IMPLEMENTATION_UPGRADE = 2;
051: public static final int REQUIRE_VENDOR_SWITCH = 3;
052: public static final int INCOMPATIBLE = 4;
053:
054: /**
055: * <p>
056: * attributes fully describer an extension. The underlying described
057: * extension may be installed and requested.
058: * <p>
059: */
060: public String title;
061: public String name;
062: public String specVersion;
063: public String specVendor;
064: public String implementationVersion;
065: public String vendor;
066: public String vendorId;
067: public String url;
068:
069: /**
070: * <p>
071: * Create a new unintialized extension information object
072: * </p>
073: */
074: public ExtensionInfo() {
075: }
076:
077: /**
078: * <p>
079: * Create and initialize an extension information object.
080: * The initialization uses the attributes passed as being
081: * the content of a manifest file to load the extension
082: * information from.
083: * Since manifest file may contain information on several
084: * extension they may depend on, the extension key parameter
085: * is prepanded to the attribute name to make the key used
086: * to retrieve the attribute from the manifest file
087: * <p>
088: * @param extensionKey unique extension key in the manifest
089: * @param attr Attributes of a manifest file
090: */
091: public ExtensionInfo(String extensionKey, Attributes attr)
092: throws NullPointerException {
093: String s;
094: if (extensionKey != null) {
095: s = extensionKey + "-";
096: } else {
097: s = "";
098: }
099: String attrKey = s + Name.EXTENSION_NAME.toString();
100: name = attr.getValue(attrKey);
101: attrKey = s + Name.SPECIFICATION_TITLE.toString();
102: title = attr.getValue(attrKey);
103: attrKey = s + Name.SPECIFICATION_VERSION.toString();
104: specVersion = attr.getValue(attrKey);
105: attrKey = s + Name.SPECIFICATION_VERSION.toString();
106: specVersion = attr.getValue(attrKey);
107: attrKey = s + Name.IMPLEMENTATION_VERSION.toString();
108: implementationVersion = attr.getValue(attrKey);
109: attrKey = s + Name.IMPLEMENTATION_VENDOR.toString();
110: vendor = attr.getValue(attrKey);
111: attrKey = s + Name.IMPLEMENTATION_VENDOR_ID.toString();
112: vendorId = attr.getValue(attrKey);
113: attrKey = s + Name.IMPLEMENTATION_URL.toString();
114: url = attr.getValue(attrKey);
115: }
116:
117: /**
118: * <p>
119: * @return true if the extension described by this extension information
120: * is compatible with the extension described by the extension
121: * information passed as a parameter
122: * </p>
123: *
124: * @param the requested extension information to compare to
125: */
126: public int isCompatibleWith(ExtensionInfo ei) {
127:
128: if (name == null || ei.name == null)
129: return INCOMPATIBLE;
130: if (name.compareTo(ei.name) == 0) {
131: System.out.println("Potential match");
132:
133: // is this true, if not spec version is specified, we consider
134: // the value as being "any".
135: if (specVersion == null || ei.specVersion == null)
136: return COMPATIBLE;
137:
138: int version = compareExtensionVersion(specVersion,
139: ei.specVersion);
140: if (version < 0) {
141: // this extension specification is "older"
142: if (vendorId != null && ei.vendorId != null) {
143: if (vendorId.compareTo(ei.vendorId) != 0) {
144: return REQUIRE_VENDOR_SWITCH;
145: }
146: }
147: return REQUIRE_SPECIFICATION_UPGRADE;
148: } else {
149: // the extension spec is compatible, let's look at the
150: // implementation attributes
151: if (vendorId != null && ei.vendorId != null) {
152: // They care who provides the extension
153: if (vendorId.compareTo(ei.vendorId) != 0) {
154: // They want to use another vendor implementation
155: return REQUIRE_VENDOR_SWITCH;
156: } else {
157: // Vendor matches, let's see the implementation version
158: if (implementationVersion != null
159: && ei.implementationVersion != null) {
160: // they care about the implementation version
161: version = compareExtensionVersion(
162: implementationVersion,
163: ei.implementationVersion);
164: if (version < 0) {
165: // This extension is an older implementation
166: return REQUIRE_IMPLEMENTATION_UPGRADE;
167: }
168: }
169: }
170: }
171: // All othe cases, we consider the extensions to be compatible
172: return COMPATIBLE;
173: }
174: }
175: return INCOMPATIBLE;
176: }
177:
178: /**
179: * <p>
180: * helper method to print sensible information on the undelying described
181: * extension
182: * </p>
183: */
184: public String toString() {
185: return "Extension : " + title + "(" + name + "), spec version("
186: + specVersion + "), impl version("
187: + implementationVersion + ") from " + vendor + "("
188: + vendorId + ")";
189: }
190:
191: /*
192: * <p>
193: * helper method to compare two versions.
194: * version are in the x.y.z.t pattern.
195: * </p>
196: * @param source version to compare to
197: * @param target version used to compare against
198: * @return < 0 if source < version
199: * > 0 if source > version
200: * = 0 if source = version
201: */
202: private int compareExtensionVersion(String source, String target)
203: throws NumberFormatException {
204: StringTokenizer stk = new StringTokenizer(source, ".,");
205: StringTokenizer ttk = new StringTokenizer(target, ".,");
206:
207: while (stk.hasMoreTokens() || ttk.hasMoreTokens()) {
208: int sver, tver;
209:
210: if (stk.hasMoreTokens())
211: sver = Integer.parseInt(stk.nextToken());
212: else
213: sver = 0;
214:
215: if (ttk.hasMoreTokens())
216: tver = Integer.parseInt(ttk.nextToken());
217: else
218: tver = 0;
219:
220: if (sver < tver)
221: return -1;
222: if (sver > tver)
223: return 1;
224: // equality, continue with the next version number
225: }
226: // complete equality
227: return 0;
228: }
229:
230: }
|