static List<Requirement> parseRequireBundle(String header) throws IllegalArgumentException { if (header == null) { return Collections.emptyList(); } Clause[] clauses = Parser.parseHeader(header); List<Requirement> requirements = new ArrayList<>(clauses.length); for (Clause requireClause : clauses) { String bsn = requireClause.getName(); String versionRangeStr = requireClause.getAttribute(org.osgi.framework.Constants.BUNDLE_VERSION_ATTRIBUTE); String filter = toBundleFilter(bsn, versionRangeStr); Requirement requirement = new RequirementBuilderImpl(BundleNamespace.BUNDLE_NAMESPACE) .addDirective(Namespace.REQUIREMENT_FILTER_DIRECTIVE, filter) .build(); requirements.add(requirement); } return requirements; }
private static String toBundleFilter(String bsn, String versionRangeStr) { final String filterStr; String bsnFilter = String.format("(%s=%s)", BundleNamespace.BUNDLE_NAMESPACE, bsn); if (versionRangeStr == null) { filterStr = bsnFilter; } else { VersionRange versionRange = new VersionRange(versionRangeStr); if (versionRange.isExact()) { String exactVersionFilter = String.format("(%s=%s)", BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE, versionRange.getLeft()); filterStr = String.format("(&%s%s)", bsnFilter, exactVersionFilter); } else if (versionRange.getRight() == null) { filterStr = String.format("(&%s%s)", bsnFilter, lowerVersionFilter(versionRange)); } else { filterStr = String.format("(&%s%s%s)", bsnFilter, lowerVersionFilter(versionRange), upperVersionFilter(versionRange)); } } return filterStr; }
private ModuleRevisionBuilder createBuilder(ModuleReference ref) { ModuleDescriptor desc = ref.descriptor(); ModuleRevisionBuilder builder = new ModuleRevisionBuilder(); builder.setSymbolicName(desc.name()); Version version = desc.version().map((v) -> { try { return Version.valueOf(v.toString()); } catch (IllegalArgumentException e) { return Version.emptyVersion; } }).orElse(Version.emptyVersion); builder.setVersion(version); // add bundle and identity capabilities, do not create host capability for JPMS builder.addCapability( BundleNamespace.BUNDLE_NAMESPACE, Map.of(), Map.of( BundleNamespace.BUNDLE_NAMESPACE, desc.name(), BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE, version)); builder.addCapability( IdentityNamespace.IDENTITY_NAMESPACE, Map.of(), Map.of( IdentityNamespace.IDENTITY_NAMESPACE, desc.name(), IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE, version)); for(Exports exports : desc.exports()) { // TODO map targets to x-friends directive. builder.addCapability( PackageNamespace.PACKAGE_NAMESPACE, Map.of(), Map.of(PackageNamespace.PACKAGE_NAMESPACE, exports.source())); } for(Provides provides : desc.provides()) { builder.addCapability( JpmsServiceNamespace.JPMS_SERVICE_NAMESPACE, Map.of(), Map.of( JpmsServiceNamespace.JPMS_SERVICE_NAMESPACE, provides.service(), JpmsServiceNamespace.CAPABILITY_PROVIDES_WITH, provides.providers())); } for (Requires requires : desc.requires()) { Map<String, String> directives = new HashMap<>(); // determine the resolution value based on the STATIC modifier String resolution = requires.modifiers().contains(Requires.Modifier.STATIC) ? Namespace.RESOLUTION_OPTIONAL : Namespace.RESOLUTION_MANDATORY; directives.put(Namespace.REQUIREMENT_RESOLUTION_DIRECTIVE, resolution); // determine the visibility value based on the TRANSITIVE modifier String visibility = requires.modifiers().contains(Requires.Modifier.TRANSITIVE) ? BundleNamespace.VISIBILITY_REEXPORT : BundleNamespace.VISIBILITY_PRIVATE; directives.put(BundleNamespace.REQUIREMENT_VISIBILITY_DIRECTIVE, visibility); // create a bundle filter based on the requires name directives.put(Namespace.REQUIREMENT_FILTER_DIRECTIVE, "(" + BundleNamespace.BUNDLE_NAMESPACE + "=" + requires.name() + ")"); builder.addRequirement(BundleNamespace.BUNDLE_NAMESPACE, directives, Collections.emptyMap()); } for(String uses : desc.uses()) { builder.addRequirement(JpmsServiceNamespace.JPMS_SERVICE_NAMESPACE, Map.of(Namespace.REQUIREMENT_RESOLUTION_DIRECTIVE, Namespace.RESOLUTION_OPTIONAL, Namespace.REQUIREMENT_FILTER_DIRECTIVE, "(" + JpmsServiceNamespace.JPMS_SERVICE_NAMESPACE + "=" + uses + ")"), Map.of(JpmsServiceNamespace.JPMS_SERVICE_NAMESPACE, uses)); } return builder; }