1 11 package org.eclipse.osgi.internal.resolver; 12 13 import java.lang.reflect.Constructor ; 14 import java.util.*; 15 import org.eclipse.osgi.framework.internal.core.Constants; 16 import org.eclipse.osgi.service.resolver.*; 17 import org.eclipse.osgi.util.ManifestElement; 18 import org.eclipse.osgi.util.NLS; 19 import org.osgi.framework.*; 20 21 24 class StateBuilder { 25 static final String [] DEFINED_MATCHING_ATTRS = {Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, Constants.BUNDLE_VERSION_ATTRIBUTE, Constants.PACKAGE_SPECIFICATION_VERSION, Constants.VERSION_ATTRIBUTE}; 26 static final String [] DEFINED_OSGI_VALIDATE_HEADERS = {Constants.IMPORT_PACKAGE, Constants.DYNAMICIMPORT_PACKAGE, Constants.EXPORT_PACKAGE, Constants.FRAGMENT_HOST, Constants.BUNDLE_SYMBOLICNAME, Constants.REEXPORT_PACKAGE, Constants.REQUIRE_BUNDLE}; 27 static final String GENERIC_REQUIRE = "Eclipse-GenericRequire"; static final String GENERIC_CAPABILITY = "Eclipse-GenericCapability"; 30 private static final String ATTR_TYPE_STRING = "string"; private static final String ATTR_TYPE_VERSION = "version"; private static final String ATTR_TYPE_URI = "uri"; private static final String ATTR_TYPE_LONG = "long"; private static final String ATTR_TYPE_DOUBLE = "double"; private static final String ATTR_TYPE_SET = "set"; private static final String OPTIONAL_ATTR = "optional"; private static final String MULTIPLE_ATTR = "multiple"; private static final String TRUE = "true"; 40 static BundleDescription createBundleDescription(StateImpl state, Dictionary manifest, String location) throws BundleException { 41 BundleDescriptionImpl result = new BundleDescriptionImpl(); 42 String manifestVersionHeader = (String ) manifest.get(Constants.BUNDLE_MANIFESTVERSION); 43 boolean jreBundle = "true".equals(manifest.get(Constants.Eclipse_JREBUNDLE)); int manifestVersion = 1; 45 if (manifestVersionHeader != null) 46 manifestVersion = Integer.parseInt(manifestVersionHeader); 47 if (manifestVersion >= 2) 48 validateHeaders(manifest, jreBundle); 49 50 String symbolicNameHeader = (String ) manifest.get(Constants.BUNDLE_SYMBOLICNAME); 52 if (symbolicNameHeader != null) { 53 ManifestElement[] symbolicNameElements = ManifestElement.parseHeader(Constants.BUNDLE_SYMBOLICNAME, symbolicNameHeader); 54 if (symbolicNameElements.length > 0) { 55 result.setSymbolicName(symbolicNameElements[0].getValue()); 56 String singleton = symbolicNameElements[0].getDirective(Constants.SINGLETON_DIRECTIVE); 57 if (singleton == null) singleton = symbolicNameElements[0].getAttribute(Constants.SINGLETON_DIRECTIVE); 59 result.setStateBit(BundleDescriptionImpl.SINGLETON, "true".equals(singleton)); String fragmentAttachment = symbolicNameElements[0].getDirective(Constants.FRAGMENT_ATTACHMENT_DIRECTIVE); 61 if (fragmentAttachment != null) { 62 if (fragmentAttachment.equals(Constants.FRAGMENT_ATTACHMENT_RESOLVETIME)) { 63 result.setStateBit(BundleDescriptionImpl.ATTACH_FRAGMENTS, true); 64 result.setStateBit(BundleDescriptionImpl.DYNAMIC_FRAGMENTS, false); 65 } else if (fragmentAttachment.equals(Constants.FRAGMENT_ATTACHMENT_NEVER)) { 66 result.setStateBit(BundleDescriptionImpl.ATTACH_FRAGMENTS, false); 67 result.setStateBit(BundleDescriptionImpl.DYNAMIC_FRAGMENTS, false); 68 } 69 } 70 } 71 } 72 String version = (String ) manifest.get(Constants.BUNDLE_VERSION); 74 try { 75 result.setVersion((version != null) ? Version.parseVersion(version) : Version.emptyVersion); 76 } catch (IllegalArgumentException ex) { 77 if (manifestVersion >= 2) 78 throw new BundleException(ex.getMessage()); 79 } 82 result.setLocation(location); 83 result.setPlatformFilter((String ) manifest.get(Constants.ECLIPSE_PLATFORMFILTER)); 84 result.setExecutionEnvironments(ManifestElement.getArrayFromList((String ) manifest.get(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT))); 85 ManifestElement[] host = ManifestElement.parseHeader(Constants.FRAGMENT_HOST, (String ) manifest.get(Constants.FRAGMENT_HOST)); 86 if (host != null) 87 result.setHost(createHostSpecification(host[0])); 88 ManifestElement[] exports = ManifestElement.parseHeader(Constants.EXPORT_PACKAGE, (String ) manifest.get(Constants.EXPORT_PACKAGE)); 89 ManifestElement[] reexports = ManifestElement.parseHeader(Constants.REEXPORT_PACKAGE, (String ) manifest.get(Constants.REEXPORT_PACKAGE)); 90 ManifestElement[] provides = ManifestElement.parseHeader(Constants.PROVIDE_PACKAGE, (String ) manifest.get(Constants.PROVIDE_PACKAGE)); boolean strict = state != null && state.inStrictMode(); 92 ArrayList providedExports = new ArrayList(provides == null ? 0 : provides.length); 93 result.setExportPackages(createExportPackages(exports, reexports, provides, providedExports, manifestVersion, strict)); 94 ManifestElement[] imports = ManifestElement.parseHeader(Constants.IMPORT_PACKAGE, (String ) manifest.get(Constants.IMPORT_PACKAGE)); 95 ManifestElement[] dynamicImports = ManifestElement.parseHeader(Constants.DYNAMICIMPORT_PACKAGE, (String ) manifest.get(Constants.DYNAMICIMPORT_PACKAGE)); 96 result.setImportPackages(createImportPackages(result.getExportPackages(), providedExports, imports, dynamicImports, manifestVersion)); 97 ManifestElement[] requires = ManifestElement.parseHeader(Constants.REQUIRE_BUNDLE, (String ) manifest.get(Constants.REQUIRE_BUNDLE)); 98 result.setRequiredBundles(createRequiredBundles(requires)); 99 String [][] genericAliases = getGenericAliases(state); 100 ManifestElement[] genericRequires = getGenericRequires(manifest, genericAliases); 101 result.setGenericRequires(createGenericRequires(genericRequires)); 102 ManifestElement[] genericCapabilities = getGenericCapabilities(manifest, genericAliases); 103 result.setGenericCapabilities(createGenericCapabilities(genericCapabilities)); 104 return result; 105 } 106 107 private static ManifestElement[] getGenericRequires(Dictionary manifest, String [][] genericAliases) throws BundleException { 108 ManifestElement[] genericRequires = ManifestElement.parseHeader(GENERIC_REQUIRE, (String ) manifest.get(GENERIC_REQUIRE)); 109 ArrayList aliasList = null; 110 if (genericAliases.length > 0) { 111 aliasList = new ArrayList(genericRequires == null ? 0 : genericRequires.length); 112 for (int i = 0; i < genericAliases.length; i++) { 113 ManifestElement[] aliasReqs = ManifestElement.parseHeader(genericAliases[i][1], (String ) manifest.get(genericAliases[i][1])); 114 if (aliasReqs == null) 115 continue; 116 for (int j = 0; j < aliasReqs.length; j++) { 117 StringBuffer strBuf = new StringBuffer (); 118 strBuf.append(aliasReqs[j].getValue()).append(':').append(genericAliases[i][2]); 119 String filter = aliasReqs[j].getAttribute(Constants.SELECTION_FILTER_ATTRIBUTE); 120 if (filter != null) 121 strBuf.append("; ").append(Constants.SELECTION_FILTER_ATTRIBUTE).append(filter).append("=\"").append(filter).append("\""); ManifestElement[] withType = ManifestElement.parseHeader(genericAliases[i][1], strBuf.toString()); 123 aliasList.add(withType[0]); 124 } 125 } 126 } 127 if (aliasList == null || aliasList.size() == 0) 128 return genericRequires; 129 if (genericRequires != null) 130 for (int i = 0; i < genericRequires.length; i++) 131 aliasList.add(genericRequires[i]); 132 return (ManifestElement[]) aliasList.toArray(new ManifestElement[aliasList.size()]); 133 } 134 135 private static ManifestElement[] getGenericCapabilities(Dictionary manifest, String [][] genericAliases) throws BundleException { 136 ManifestElement[] genericCapabilities = ManifestElement.parseHeader(GENERIC_CAPABILITY, (String ) manifest.get(GENERIC_CAPABILITY)); 137 ArrayList aliasList = null; 138 if (genericAliases.length > 0) { 139 aliasList = new ArrayList(genericCapabilities == null ? 0 : genericCapabilities.length); 140 for (int i = 0; i < genericAliases.length; i++) { 141 ManifestElement[] aliasCapabilities = ManifestElement.parseHeader(genericAliases[i][0], (String ) manifest.get(genericAliases[i][0])); 142 if (aliasCapabilities == null) 143 continue; 144 for (int j = 0; j < aliasCapabilities.length; j++) { 145 StringBuffer strBuf = new StringBuffer (); 146 strBuf.append(aliasCapabilities[j].getValue()).append(':').append(genericAliases[i][2]); 147 for (Enumeration keys = aliasCapabilities[j].getKeys(); keys != null && keys.hasMoreElements();) { 148 String key = (String ) keys.nextElement(); 149 strBuf.append("; ").append(key).append("=\"").append(aliasCapabilities[j].getAttribute(key)).append("\""); } 151 ManifestElement[] withTypes = ManifestElement.parseHeader(genericAliases[i][0], strBuf.toString()); 152 aliasList.add(withTypes[0]); 153 } 154 } 155 } 156 if (aliasList == null || aliasList.size() == 0) 157 return genericCapabilities; 158 if (genericCapabilities != null) 159 for (int i = 0; i < genericCapabilities.length; i++) 160 aliasList.add(genericCapabilities[i]); 161 return (ManifestElement[]) aliasList.toArray(new ManifestElement[aliasList.size()]); 162 } 163 164 private static String [][] getGenericAliases(StateImpl state) { 165 Dictionary[] platformProps = state == null ? null : state.getPlatformProperties(); 166 String genericAliasesProp = platformProps == null || platformProps.length == 0 ? null : (String ) platformProps[0].get("osgi.genericAliases"); if (genericAliasesProp == null) 168 return new String [0][0]; 169 String [] aliases = ManifestElement.getArrayFromList(genericAliasesProp, ","); String [][] result = new String [aliases.length][]; 171 for (int i = 0; i < aliases.length; i++) 172 result[i] = ManifestElement.getArrayFromList(aliases[i], ":"); return result; 174 } 175 176 private static void validateHeaders(Dictionary manifest, boolean jreBundle) throws BundleException { 177 for (int i = 0; i < DEFINED_OSGI_VALIDATE_HEADERS.length; i++) { 178 String header = (String ) manifest.get(DEFINED_OSGI_VALIDATE_HEADERS[i]); 179 if (header != null) { 180 ManifestElement[] elements = ManifestElement.parseHeader(DEFINED_OSGI_VALIDATE_HEADERS[i], header); 181 checkForDuplicateDirectives(elements); 182 if (DEFINED_OSGI_VALIDATE_HEADERS[i] == Constants.REEXPORT_PACKAGE) 183 checkForUsesDirective(elements); 184 if (DEFINED_OSGI_VALIDATE_HEADERS[i] == Constants.IMPORT_PACKAGE) 185 checkImportExportSyntax(elements, false, false, jreBundle); 186 if (DEFINED_OSGI_VALIDATE_HEADERS[i] == Constants.DYNAMICIMPORT_PACKAGE) 187 checkImportExportSyntax(elements, false, true, jreBundle); 188 if (DEFINED_OSGI_VALIDATE_HEADERS[i] == Constants.EXPORT_PACKAGE) 189 checkImportExportSyntax(elements, true, false, jreBundle); 190 if (DEFINED_OSGI_VALIDATE_HEADERS[i] == Constants.FRAGMENT_HOST) 191 checkExtensionBundle(elements); 192 } else if (DEFINED_OSGI_VALIDATE_HEADERS[i] == Constants.BUNDLE_SYMBOLICNAME) { 193 throw new BundleException(NLS.bind(StateMsg.HEADER_REQUIRED, Constants.BUNDLE_SYMBOLICNAME)); 194 } 195 } 196 } 197 198 private static BundleSpecification[] createRequiredBundles(ManifestElement[] specs) { 199 if (specs == null) 200 return null; 201 BundleSpecification[] result = new BundleSpecification[specs.length]; 202 for (int i = 0; i < specs.length; i++) 203 result[i] = createRequiredBundle(specs[i]); 204 return result; 205 } 206 207 private static BundleSpecification createRequiredBundle(ManifestElement spec) { 208 BundleSpecificationImpl result = new BundleSpecificationImpl(); 209 result.setName(spec.getValue()); 210 result.setVersionRange(getVersionRange(spec.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE))); 211 result.setExported(Constants.VISIBILITY_REEXPORT.equals(spec.getDirective(Constants.VISIBILITY_DIRECTIVE)) || "true".equals(spec.getAttribute(Constants.REPROVIDE_ATTRIBUTE))); result.setOptional(Constants.RESOLUTION_OPTIONAL.equals(spec.getDirective(Constants.RESOLUTION_DIRECTIVE)) || "true".equals(spec.getAttribute(Constants.OPTIONAL_ATTRIBUTE))); return result; 214 } 215 216 private static ImportPackageSpecification[] createImportPackages(ExportPackageDescription[] exported, ArrayList providedExports, ManifestElement[] imported, ManifestElement[] dynamicImported, int manifestVersion) throws BundleException { 217 ArrayList allImports = null; 218 if (manifestVersion < 2) { 219 if (exported.length == 0 && imported == null && dynamicImported == null) 221 return null; 222 allImports = new ArrayList(exported.length + (imported == null ? 0 : imported.length)); 223 for (int i = 0; i < exported.length; i++) { 224 if (providedExports.contains(exported[i].getName())) 225 continue; 226 ImportPackageSpecificationImpl result = new ImportPackageSpecificationImpl(); 227 result.setName(exported[i].getName()); 228 result.setVersionRange(getVersionRange(exported[i].getVersion().toString())); 229 result.setDirective(Constants.RESOLUTION_DIRECTIVE, ImportPackageSpecification.RESOLUTION_STATIC); 230 allImports.add(result); 231 } 232 } else { 233 allImports = new ArrayList(imported == null ? 0 : imported.length); 234 } 235 236 if (dynamicImported != null) 239 for (int i = 0; i < dynamicImported.length; i++) 240 addImportPackages(dynamicImported[i], allImports, manifestVersion, true); 241 if (imported != null) 242 for (int i = 0; i < imported.length; i++) 243 addImportPackages(imported[i], allImports, manifestVersion, false); 244 return (ImportPackageSpecification[]) allImports.toArray(new ImportPackageSpecification[allImports.size()]); 245 } 246 247 private static void addImportPackages(ManifestElement importPackage, ArrayList allImports, int manifestVersion, boolean dynamic) throws BundleException { 248 String [] importNames = importPackage.getValueComponents(); 249 for (int i = 0; i < importNames.length; i++) { 250 if (manifestVersion < 2) { 252 Iterator iter = allImports.iterator(); 253 while (iter.hasNext()) 254 if (importNames[i].equals(((ImportPackageSpecification) iter.next()).getName())) 255 iter.remove(); 256 } 257 258 ImportPackageSpecificationImpl result = new ImportPackageSpecificationImpl(); 259 result.setName(importNames[i]); 260 String versionString = importPackage.getAttribute(Constants.VERSION_ATTRIBUTE); 262 if (versionString == null) versionString = importPackage.getAttribute(Constants.PACKAGE_SPECIFICATION_VERSION); 264 result.setVersionRange(getVersionRange(versionString)); 265 result.setBundleSymbolicName(importPackage.getAttribute(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE)); 266 result.setBundleVersionRange(getVersionRange(importPackage.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE))); 267 if (manifestVersion >= 2) 269 result.setAttributes(getAttributes(importPackage, DEFINED_MATCHING_ATTRS)); 270 271 if (dynamic) 272 result.setDirective(Constants.RESOLUTION_DIRECTIVE, ImportPackageSpecification.RESOLUTION_DYNAMIC); 273 else 274 result.setDirective(Constants.RESOLUTION_DIRECTIVE, getResolution(importPackage.getDirective(Constants.RESOLUTION_DIRECTIVE))); 275 276 allImports.add(result); 277 } 278 } 279 280 private static String getResolution(String resolution) { 281 String result = ImportPackageSpecification.RESOLUTION_STATIC; 282 if (Constants.RESOLUTION_OPTIONAL.equals(resolution)) 283 result = ImportPackageSpecification.RESOLUTION_OPTIONAL; 284 return result; 285 } 286 287 static ExportPackageDescription[] createExportPackages(ManifestElement[] exported, ManifestElement[] reexported, ManifestElement[] provides, ArrayList providedExports, int manifestVersion, boolean strict) throws BundleException { 288 int numExports = (exported == null ? 0 : exported.length) + (reexported == null ? 0 : reexported.length) + (provides == null ? 0 : provides.length); 289 if (numExports == 0) 290 return null; 291 ArrayList allExports = new ArrayList(numExports); 292 if (exported != null) 293 for (int i = 0; i < exported.length; i++) 294 addExportPackages(exported[i], allExports, manifestVersion, false, strict); 295 if (reexported != null) 296 for (int i = 0; i < reexported.length; i++) 297 addExportPackages(reexported[i], allExports, manifestVersion, true, strict); 298 if (provides != null) 299 addProvidePackages(provides, allExports, providedExports); 300 return (ExportPackageDescription[]) allExports.toArray(new ExportPackageDescription[allExports.size()]); 301 } 302 303 private static void addExportPackages(ManifestElement exportPackage, ArrayList allExports, int manifestVersion, boolean reexported, boolean strict) throws BundleException { 304 String [] exportNames = exportPackage.getValueComponents(); 305 for (int i = 0; i < exportNames.length; i++) { 306 if (strict && "true".equals(exportPackage.getDirective(Constants.INTERNAL_DIRECTIVE))) continue; 309 ExportPackageDescriptionImpl result = new ExportPackageDescriptionImpl(); 310 result.setName(exportNames[i]); 311 String versionString = exportPackage.getAttribute(Constants.VERSION_ATTRIBUTE); 312 if (versionString == null) versionString = exportPackage.getAttribute(Constants.PACKAGE_SPECIFICATION_VERSION); 314 if (versionString != null) 315 result.setVersion(Version.parseVersion(versionString)); 316 result.setDirective(Constants.USES_DIRECTIVE, ManifestElement.getArrayFromList(exportPackage.getDirective(Constants.USES_DIRECTIVE))); 317 result.setDirective(Constants.INCLUDE_DIRECTIVE, exportPackage.getDirective(Constants.INCLUDE_DIRECTIVE)); 318 result.setDirective(Constants.EXCLUDE_DIRECTIVE, exportPackage.getDirective(Constants.EXCLUDE_DIRECTIVE)); 319 result.setDirective(Constants.FRIENDS_DIRECTIVE, ManifestElement.getArrayFromList(exportPackage.getDirective(Constants.FRIENDS_DIRECTIVE))); 320 result.setDirective(Constants.INTERNAL_DIRECTIVE, Boolean.valueOf(exportPackage.getDirective(Constants.INTERNAL_DIRECTIVE))); 321 result.setDirective(Constants.MANDATORY_DIRECTIVE, ManifestElement.getArrayFromList(exportPackage.getDirective(Constants.MANDATORY_DIRECTIVE))); 322 result.setAttributes(getAttributes(exportPackage, DEFINED_MATCHING_ATTRS)); 323 result.setRoot(!reexported); 324 allExports.add(result); 325 } 326 } 327 328 private static void addProvidePackages(ManifestElement[] provides, ArrayList allExports, ArrayList providedExports) throws BundleException { 329 ExportPackageDescription[] currentExports = (ExportPackageDescription[]) allExports.toArray(new ExportPackageDescription[allExports.size()]); 330 for (int i = 0; i < provides.length; i++) { 331 boolean duplicate = false; 332 for (int j = 0; j < currentExports.length; j++) 333 if (provides[i].getValue().equals(currentExports[j].getName())) { 334 duplicate = true; 335 break; 336 } 337 if (!duplicate) { 338 ExportPackageDescriptionImpl result = new ExportPackageDescriptionImpl(); 339 result.setName(provides[i].getValue()); 340 result.setRoot(true); 341 allExports.add(result); 342 } 343 providedExports.add(provides[i].getValue()); 344 } 345 } 346 347 private static Map getAttributes(ManifestElement exportPackage, String [] definedAttrs) { 348 Enumeration keys = exportPackage.getKeys(); 349 Map arbitraryAttrs = null; 350 if (keys == null) 351 return null; 352 while (keys.hasMoreElements()) { 353 boolean definedAttr = false; 354 String key = (String ) keys.nextElement(); 355 for (int i = 0; i < definedAttrs.length; i++) { 356 if (definedAttrs[i].equals(key)) { 357 definedAttr = true; 358 break; 359 } 360 } 361 String value = exportPackage.getAttribute(key); 362 int colonIndex = key.indexOf(':'); 363 String type = ATTR_TYPE_STRING; 364 if (colonIndex > 0) { 365 type = key.substring(colonIndex + 1); 366 key = key.substring(0, colonIndex); 367 } 368 if (!definedAttr) { 369 if (arbitraryAttrs == null) 370 arbitraryAttrs = new HashMap(); 371 Object putValue = value; 372 if (ATTR_TYPE_STRING.equals(type)) 373 putValue = value; 374 else if (ATTR_TYPE_DOUBLE.equals(type)) 375 putValue = new Double (value); 376 else if (ATTR_TYPE_LONG.equals(type)) 377 putValue = new Long (value); 378 else if (ATTR_TYPE_URI.equals(type)) 379 try { 380 Class uriClazz = Class.forName("java.net.URI"); Constructor constructor = uriClazz.getConstructor(new Class [] {String .class}); 382 putValue = constructor.newInstance(new Object [] {value}); 383 } catch (ClassNotFoundException e) { 384 putValue = value; 386 } catch (Exception e) { if (e instanceof RuntimeException ) 388 throw (RuntimeException ) e; 389 throw new RuntimeException (e.getMessage()); 390 } 391 else if (ATTR_TYPE_VERSION.equals(type)) 392 putValue = new Version(value); 393 else if (ATTR_TYPE_SET.equals(type)) 394 putValue = ManifestElement.getArrayFromList(value, ","); arbitraryAttrs.put(key, putValue); 396 } 397 } 398 return arbitraryAttrs; 399 } 400 401 private static HostSpecification createHostSpecification(ManifestElement spec) { 402 if (spec == null) 403 return null; 404 HostSpecificationImpl result = new HostSpecificationImpl(); 405 result.setName(spec.getValue()); 406 result.setVersionRange(getVersionRange(spec.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE))); 407 result.setIsMultiHost("true".equals(spec.getDirective("multiple-hosts"))); return result; 409 } 410 411 private static GenericSpecification[] createGenericRequires(ManifestElement[] genericRequires) throws BundleException { 412 if (genericRequires == null) 413 return null; 414 ArrayList results = new ArrayList(genericRequires.length); 415 for (int i = 0; i < genericRequires.length; i++) { 416 String [] genericNames = genericRequires[i].getValueComponents(); 417 for (int j = 0; j < genericNames.length; j++) { 418 GenericSpecificationImpl spec = new GenericSpecificationImpl(); 419 int colonIdx = genericNames[j].indexOf(':'); 420 if (colonIdx > 0) { 421 spec.setName(genericNames[j].substring(0, colonIdx)); 422 spec.setType(genericNames[j].substring(colonIdx + 1)); 423 } else 424 spec.setName(genericNames[j]); 425 try { 426 spec.setMatchingFilter(genericRequires[i].getAttribute(Constants.SELECTION_FILTER_ATTRIBUTE)); 427 } catch (InvalidSyntaxException e) { 428 throw new BundleException(Constants.SELECTION_FILTER_ATTRIBUTE, e); 429 } 430 String optional = genericRequires[i].getAttribute(OPTIONAL_ATTR); 431 String multiple = genericRequires[i].getAttribute(MULTIPLE_ATTR); 432 int resolution = 0; 433 if (TRUE.equals(optional)) 434 resolution |= GenericSpecification.RESOLUTION_OPTIONAL; 435 if (TRUE.equals(multiple)) 436 resolution |= GenericSpecification.RESOLUTION_MULTIPLE; 437 spec.setResolution(resolution); 438 results.add(spec); 439 } 440 } 441 return (GenericSpecification[]) results.toArray(new GenericSpecification[results.size()]); 442 } 443 444 private static GenericDescription[] createGenericCapabilities(ManifestElement[] genericCapabilities) { 445 if (genericCapabilities == null) 446 return null; 447 ArrayList results = new ArrayList(genericCapabilities.length); 448 for (int i = 0; i < genericCapabilities.length; i++) { 449 String [] genericNames = genericCapabilities[i].getValueComponents(); 450 for (int j = 0; j < genericNames.length; j++) { 451 GenericDescriptionImpl desc = new GenericDescriptionImpl(); 452 int colonIdx = genericNames[j].indexOf(':'); 453 if (colonIdx > 0) { 454 desc.setName(genericNames[j].substring(0, colonIdx)); 455 desc.setType(genericNames[j].substring(colonIdx + 1)); 456 } else 457 desc.setName(genericNames[j]); 458 String versionString = genericCapabilities[i].getAttribute(Constants.VERSION_ATTRIBUTE); 459 if (versionString != null) 460 desc.setVersion(Version.parseVersion(versionString)); 461 Map mapAttrs = getAttributes(genericCapabilities[i], new String [] {Constants.VERSION_ATTRIBUTE}); 462 Object version = mapAttrs == null ? null : mapAttrs.remove(Constants.VERSION_ATTRIBUTE); 463 if (version instanceof Version) desc.setVersion((Version) version); 465 Dictionary attrs = new Hashtable(); 466 if (mapAttrs != null) { 467 for (Iterator keys = mapAttrs.keySet().iterator(); keys.hasNext();) { 468 Object key = keys.next(); 469 attrs.put(key, mapAttrs.get(key)); 470 } 471 } 472 desc.setAttributes(attrs); 473 results.add(desc); 474 } 475 } 476 return (GenericDescription[]) results.toArray(new GenericDescription[results.size()]); 477 } 478 479 private static VersionRange getVersionRange(String versionRange) { 480 if (versionRange == null) 481 return null; 482 return new VersionRange(versionRange); 483 } 484 485 private static void checkImportExportSyntax(ManifestElement[] elements, boolean export, boolean dynamic, boolean jreBundle) throws BundleException { 486 if (elements == null) 487 return; 488 int length = elements.length; 489 Set packages = new HashSet(length); 490 for (int i = 0; i < length; i++) { 491 String [] packageNames = elements[i].getValueComponents(); 493 for (int j = 0; j < packageNames.length; j++) { 494 if (!export && !dynamic && packages.contains(packageNames[j])) 495 throw new BundleException(NLS.bind(StateMsg.HEADER_PACKAGE_DUPLICATES, packageNames[j])); 496 if (!jreBundle && packageNames[j].startsWith("java.")) throw new BundleException(NLS.bind(StateMsg.HEADER_PACKAGE_JAVA, packageNames[j])); 499 packages.add(packageNames[j]); 500 } 501 String version = elements[i].getAttribute(Constants.VERSION_ATTRIBUTE); 503 if (version != null) { 504 String specVersion = elements[i].getAttribute(Constants.PACKAGE_SPECIFICATION_VERSION); 505 if (specVersion != null && !specVersion.equals(version)) 506 throw new BundleException(NLS.bind(StateMsg.HEADER_VERSION_ERROR, Constants.VERSION_ATTRIBUTE, Constants.PACKAGE_SPECIFICATION_VERSION)); 507 } 508 if (export) { 511 if (elements[i].getAttribute(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE) != null) 512 throw new BundleException(NLS.bind(StateMsg.HEADER_EXPORT_ATTR_ERROR, Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, Constants.EXPORT_PACKAGE)); 513 if (elements[i].getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE) != null) 514 throw new BundleException(NLS.bind(StateMsg.HEADER_EXPORT_ATTR_ERROR, Constants.BUNDLE_VERSION_ATTRIBUTE, Constants.EXPORT_PACKAGE)); 515 } 516 } 517 } 518 519 private static void checkForDuplicateDirectives(ManifestElement[] elements) throws BundleException { 520 for (int i = 0; i < elements.length; i++) { 522 Enumeration keys = elements[i].getDirectiveKeys(); 523 if (keys != null) { 524 while (keys.hasMoreElements()) { 525 String key = (String ) keys.nextElement(); 526 String [] directives = elements[i].getDirectives(key); 527 if (directives.length > 1) 528 throw new BundleException(NLS.bind(StateMsg.HEADER_DIRECTIVE_DUPLICATES, key)); 529 } 530 } 531 } 532 } 533 534 private static void checkForUsesDirective(ManifestElement[] elements) throws BundleException { 535 for (int i = 0; i < elements.length; i++) 536 if (elements[i].getDirective(Constants.USES_DIRECTIVE) != null) 537 throw new BundleException(NLS.bind(StateMsg.HEADER_REEXPORT_USES, Constants.USES_DIRECTIVE, Constants.REEXPORT_PACKAGE)); 538 } 539 540 private static void checkExtensionBundle(ManifestElement[] elements) throws BundleException { 541 if (elements.length == 0 || elements[0].getDirective(Constants.EXTENSION_DIRECTIVE) == null) 542 return; 543 String hostName = elements[0].getValue(); 544 if (!hostName.equals(Constants.SYSTEM_BUNDLE_SYMBOLICNAME) && !hostName.equals(Constants.getInternalSymbolicName())) 545 throw new BundleException(NLS.bind(StateMsg.HEADER_EXTENSION_ERROR, hostName)); 546 } 547 } 548 | Popular Tags |