1 /* 2 * Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.misc; 27 28 import java.util.StringTokenizer; 29 import java.util.jar.Attributes; 30 import java.util.jar.Attributes.Name; 31 import java.util.ResourceBundle; 32 import java.util.MissingResourceException; 33 import java.text.MessageFormat; 34 import java.lang.Character.*; 35 36 37 /** 38 * This class holds all necessary information to install or 39 * upgrade a extension on the user's disk 40 * 41 * @deprecated this class will be removed in a future release. 42 * @author Jerome Dochez 43 */ 44 @Deprecated 45 public class ExtensionInfo { 46 47 /** 48 * public static values returned by the isCompatible method 49 */ 50 public static final int COMPATIBLE = 0; 51 public static final int REQUIRE_SPECIFICATION_UPGRADE = 1; 52 public static final int REQUIRE_IMPLEMENTATION_UPGRADE = 2; 53 public static final int REQUIRE_VENDOR_SWITCH = 3; 54 public static final int INCOMPATIBLE = 4; 55 56 /** 57 * attributes fully describer an extension. The underlying described 58 * extension may be installed and requested. 59 */ 60 public String title; 61 public String name; 62 public String specVersion; 63 public String specVendor; 64 public String implementationVersion; 65 public String vendor; 66 public String vendorId; 67 public String url; 68 69 // For I18N support 70 private static final ResourceBundle rb = 71 ResourceBundle.getBundle("sun.misc.resources.Messages"); 72 73 74 /** 75 * Create a new uninitialized extension information object 76 */ 77 public ExtensionInfo() { 78 } 79 80 /** 81 * Create and initialize an extension information object. 82 * The initialization uses the attributes passed as being 83 * the content of a manifest file to load the extension 84 * information from. 85 * Since manifest file may contain information on several 86 * extension they may depend on, the extension key parameter 87 * is prepanded to the attribute name to make the key used 88 * to retrieve the attribute from the manifest file 89 * 90 * @param extensionKey unique extension key in the manifest 91 * @param attr Attributes of a manifest file 92 */ 93 public ExtensionInfo(String extensionKey, Attributes attr) 94 throws NullPointerException 95 { 96 String s; 97 if (extensionKey!=null) { 98 s = extensionKey + "-"; 99 } else { 100 s =""; 101 } 102 103 String attrKey = s + Name.EXTENSION_NAME.toString(); 104 name = attr.getValue(attrKey); 105 if (name != null) 106 name = name.trim(); 107 108 attrKey = s + Name.SPECIFICATION_TITLE.toString(); 109 title = attr.getValue(attrKey); 110 if (title != null) 111 title = title.trim(); 112 113 attrKey = s + Name.SPECIFICATION_VERSION.toString(); 114 specVersion = attr.getValue(attrKey); 115 if (specVersion != null) 116 specVersion = specVersion.trim(); 117 118 attrKey = s + Name.SPECIFICATION_VENDOR.toString(); 119 specVendor = attr.getValue(attrKey); 120 if (specVendor != null) 121 specVendor = specVendor.trim(); 122 123 attrKey = s + Name.IMPLEMENTATION_VERSION.toString(); 124 implementationVersion = attr.getValue(attrKey); 125 if (implementationVersion != null) 126 implementationVersion = implementationVersion.trim(); 127 128 attrKey = s + Name.IMPLEMENTATION_VENDOR.toString(); 129 vendor = attr.getValue(attrKey); 130 if (vendor != null) 131 vendor = vendor.trim(); 132 133 attrKey = s + Name.IMPLEMENTATION_VENDOR_ID.toString(); 134 vendorId = attr.getValue(attrKey); 135 if (vendorId != null) 136 vendorId = vendorId.trim(); 137 138 attrKey =s + Name.IMPLEMENTATION_URL.toString(); 139 url = attr.getValue(attrKey); 140 if (url != null) 141 url = url.trim(); 142 } 143 144 /** 145 * @return true if the extension described by this extension information 146 * is compatible with the extension described by the extension 147 * information passed as a parameter 148 * 149 * @param ei the requested extension information to compare to 150 */ 151 public int isCompatibleWith(ExtensionInfo ei) { 152 153 if (name == null || ei.name == null) 154 return INCOMPATIBLE; 155 if (name.compareTo(ei.name)==0) { 156 // is this true, if not spec version is specified, we consider 157 // the value as being "any". 158 if (specVersion == null || ei.specVersion == null) 159 return COMPATIBLE; 160 161 int version = compareExtensionVersion(specVersion, ei.specVersion); 162 if (version<0) { 163 // this extension specification is "older" 164 if (vendorId != null && ei.vendorId !=null) { 165 if (vendorId.compareTo(ei.vendorId)!=0) { 166 return REQUIRE_VENDOR_SWITCH; 167 } 168 } 169 return REQUIRE_SPECIFICATION_UPGRADE; 170 } else { 171 // the extension spec is compatible, let's look at the 172 // implementation attributes 173 if (vendorId != null && ei.vendorId != null) { 174 // They care who provides the extension 175 if (vendorId.compareTo(ei.vendorId)!=0) { 176 // They want to use another vendor implementation 177 return REQUIRE_VENDOR_SWITCH; 178 } else { 179 // Vendor matches, let's see the implementation version 180 if (implementationVersion != null && ei.implementationVersion != null) { 181 // they care about the implementation version 182 version = compareExtensionVersion(implementationVersion, ei.implementationVersion); 183 if (version<0) { 184 // This extension is an older implementation 185 return REQUIRE_IMPLEMENTATION_UPGRADE; 186 } 187 } 188 } 189 } 190 // All othe cases, we consider the extensions to be compatible 191 return COMPATIBLE; 192 } 193 } 194 return INCOMPATIBLE; 195 } 196 197 /** 198 * helper method to print sensible information on the undelying described 199 * extension 200 */ 201 public String toString() { 202 return "Extension : title(" + title + "), name(" + name + "), spec vendor(" + 203 specVendor + "), spec version(" + specVersion + "), impl vendor(" + 204 vendor + "), impl vendor id(" + vendorId + "), impl version(" + 205 implementationVersion + "), impl url(" + url + ")"; 206 } 207 208 /* 209 * helper method to compare two versions. 210 * version are in the x.y.z.t pattern. 211 * 212 * @param source version to compare to 213 * @param target version used to compare against 214 * @return <pre>{@code 215 * < 0 if source < version 216 * > 0 if source > version 217 * = 0 if source = version}</pre> 218 */ 219 private int compareExtensionVersion(String source, String target) 220 throws NumberFormatException 221 { 222 source = source.toLowerCase(); 223 target = target.toLowerCase(); 224 225 return strictCompareExtensionVersion(source, target); 226 } 227 228 229 /* 230 * helper method to compare two versions. 231 * version are in the x.y.z.t pattern. 232 * 233 * @param source version to compare to 234 * @param target version used to compare against 235 * @return <pre>{@code 236 * < 0 if source < version 237 * > 0 if source > version 238 * = 0 if source = version}</pre> 239 */ 240 private int strictCompareExtensionVersion(String source, String target) 241 throws NumberFormatException 242 { 243 if (source.equals(target)) 244 return 0; 245 246 StringTokenizer stk = new StringTokenizer(source, ".,"); 247 StringTokenizer ttk = new StringTokenizer(target, ".,"); 248 249 // Compare number 250 int n = 0, m = 0, result = 0; 251 252 // Convert token into meaning number for comparision 253 if (stk.hasMoreTokens()) 254 n = convertToken(stk.nextToken().toString()); 255 256 // Convert token into meaning number for comparision 257 if (ttk.hasMoreTokens()) 258 m = convertToken(ttk.nextToken().toString()); 259 260 if (n > m) 261 return 1; 262 else if (m > n) 263 return -1; 264 else 265 { 266 // Look for index of "." in the string 267 int sIdx = source.indexOf('.'); 268 int tIdx = target.indexOf('.'); 269 270 if (sIdx == -1) 271 sIdx = source.length() - 1; 272 273 if (tIdx == -1) 274 tIdx = target.length() - 1; 275 276 return strictCompareExtensionVersion(source.substring(sIdx + 1), 277 target.substring(tIdx + 1)); 278 } 279 } 280 281 private int convertToken(String token) 282 { 283 if (token == null || token.equals("")) 284 return 0; 285 286 int charValue = 0; 287 int charVersion = 0; 288 int patchVersion = 0; 289 int strLength = token.length(); 290 int endIndex = strLength; 291 char lastChar; 292 293 Object[] args = {name}; 294 MessageFormat mf = new MessageFormat(rb.getString("optpkg.versionerror")); 295 String versionError = mf.format(args); 296 297 // Look for "-" for pre-release 298 int prIndex = token.indexOf('-'); 299 300 // Look for "_" for patch release 301 int patchIndex = token.indexOf('_'); 302 303 if (prIndex == -1 && patchIndex == -1) 304 { 305 // This is a FCS release 306 try { 307 return Integer.parseInt(token) * 100; 308 } catch (NumberFormatException e) { 309 System.out.println(versionError); 310 return 0; 311 } 312 } 313 else if (patchIndex != -1) 314 { 315 // This is a patch (update) release 316 int prversion; 317 try { 318 // Obtain the version 319 prversion = Integer.parseInt(token.substring(0, patchIndex)); 320 321 // Check to see if the patch version is in the n.n.n_nnl format (special release) 322 lastChar = token.charAt(strLength-1); 323 if (Character.isLetter(lastChar)) { 324 // letters a-z have values from 10-35 325 charValue = Character.getNumericValue(lastChar); 326 endIndex = strLength-1; 327 328 // Obtain the patch version id 329 patchVersion = Integer.parseInt(token.substring(patchIndex+1, endIndex)); 330 331 if (charValue >= Character.getNumericValue('a') && charValue <= Character.getNumericValue('z')) { 332 // This is a special release 333 charVersion = (patchVersion * 100) + charValue; 334 } else { 335 // character is not a a-z letter, ignore 336 charVersion = 0; 337 System.out.println(versionError); 338 } 339 } else { 340 // This is a regular update release. Obtain the patch version id 341 patchVersion = Integer.parseInt(token.substring(patchIndex+1, endIndex)); 342 } 343 } catch (NumberFormatException e) { 344 System.out.println(versionError); 345 return 0; 346 } 347 return prversion * 100 + (patchVersion + charVersion); 348 } 349 else 350 { 351 //This is a milestone release, either a early access, alpha, beta, or RC 352 353 // Obtain the version 354 int mrversion; 355 try { 356 mrversion = Integer.parseInt(token.substring(0, prIndex)); 357 } catch (NumberFormatException e) { 358 System.out.println(versionError); 359 return 0; 360 } 361 362 // Obtain the patch version string, including the milestone + version 363 String prString = token.substring(prIndex + 1); 364 365 // Milestone version 366 String msVersion = ""; 367 int delta = 0; 368 369 if (prString.indexOf("ea") != -1) 370 { 371 msVersion = prString.substring(2); 372 delta = 50; 373 } 374 else if (prString.indexOf("alpha") != -1) 375 { 376 msVersion = prString.substring(5); 377 delta = 40; 378 } 379 else if (prString.indexOf("beta") != -1) 380 { 381 msVersion = prString.substring(4); 382 delta = 30; 383 } 384 else if (prString.indexOf("rc") != -1) 385 { 386 msVersion = prString.substring(2); 387 delta = 20; 388 } 389 390 if (msVersion == null || msVersion.equals("")) 391 { 392 // No version after the milestone, assume 0 393 return mrversion * 100 - delta ; 394 } 395 else 396 { 397 // Convert the milestone version 398 try { 399 return mrversion * 100 - delta + Integer.parseInt(msVersion); 400 } catch (NumberFormatException e) { 401 System.out.println(versionError); 402 return 0; 403 } 404 } 405 } 406 } 407 }