private static ResourceImpl doBuild()

in repository/service/src/main/java/org/apache/karaf/cave/repository/service/bundlerepository/ResourceBuilder.java [84:260]


    private static ResourceImpl doBuild(ResourceImpl resource, String uri, Map<String, String> headerMap, boolean removeServiceRequirements) throws BundleException {
        // Verify that only manifest version 2 is specified.
        String manifestVersion = getManifestVersion(headerMap);
        if (manifestVersion == null || !manifestVersion.equals("2")) {
            throw new BundleException("Unsupported 'Bundle-ManifestVersion' value: " + manifestVersion);
        }

        //
        // Parse bundle version.
        //

        Version bundleVersion = Version.emptyVersion;
        if (headerMap.get(Constants.BUNDLE_VERSION) != null) {
            bundleVersion = VersionTable.getVersion(headerMap.get(Constants.BUNDLE_VERSION));
        }

        //
        // Parse bundle symbolic name.
        //

        String bundleSymbolicName;
        ParsedHeaderClause bundleCap = parseBundleSymbolicName(headerMap);
        if (bundleCap == null) {
            throw new BundleException("Bundle manifest must include bundle symbolic name");
        }
        bundleSymbolicName = (String) bundleCap.attrs.get(BundleRevision.BUNDLE_NAMESPACE);

        // Now that we have symbolic name and version, create the resource
        String type = headerMap.get(Constants.FRAGMENT_HOST) == null ? IdentityNamespace.TYPE_BUNDLE : IdentityNamespace.TYPE_FRAGMENT;
        {
            Map<String, String> dirs = new HashMap<>();
            Map<String, Object> attrs = new HashMap<>();
            attrs.put(IdentityNamespace.IDENTITY_NAMESPACE, bundleSymbolicName);
            attrs.put(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE, type);
            attrs.put(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE, bundleVersion);
            CapabilityImpl identity = new CapabilityImpl(resource, IdentityNamespace.IDENTITY_NAMESPACE, dirs, attrs);
            resource.addCapability(identity);
        }
        if (uri != null) {
            Map<String, Object> attrs = new HashMap<>();
            attrs.put(ContentNamespace.CAPABILITY_URL_ATTRIBUTE, uri);
            resource.addCapability(new CapabilityImpl(resource, ContentNamespace.CONTENT_NAMESPACE, Collections.<String, String>emptyMap(), attrs));
        }

        // Add a bundle and host capability to all
        // non-fragment bundles. A host capability is the same
        // as a require capability, but with a different capability
        // namespace. Bundle capabilities resolve required-bundle
        // dependencies, while host capabilities resolve fragment-host
        // dependencies.
        if (headerMap.get(Constants.FRAGMENT_HOST) == null) {
            // All non-fragment bundles have bundle capability.
            resource.addCapability(new CapabilityImpl(resource, BundleRevision.BUNDLE_NAMESPACE, bundleCap.dirs, bundleCap.attrs));
            // A non-fragment bundle can choose to not have a host capability.
            String attachment = bundleCap.dirs.get(Constants.FRAGMENT_ATTACHMENT_DIRECTIVE);
            attachment = (attachment == null) ? Constants.FRAGMENT_ATTACHMENT_RESOLVETIME : attachment;
            if (!attachment.equalsIgnoreCase(Constants.FRAGMENT_ATTACHMENT_NEVER)) {
                Map<String, Object> hostAttrs = new HashMap<>(bundleCap.attrs);
                Object value = hostAttrs.remove(BundleRevision.BUNDLE_NAMESPACE);
                hostAttrs.put(BundleRevision.HOST_NAMESPACE, value);
                resource.addCapability(new CapabilityImpl(
                        resource, BundleRevision.HOST_NAMESPACE,
                        bundleCap.dirs,
                        hostAttrs));
            }
        }

        //
        // Parse Fragment-Host.
        //

        List<RequirementImpl> hostReqs = parseFragmentHost(resource, headerMap);

        //
        // Parse Require-Bundle
        //

        List<ParsedHeaderClause> rbClauses = parseStandardHeader(headerMap.get(Constants.REQUIRE_BUNDLE));
        rbClauses = normalizeRequireClauses(rbClauses);
        List<Requirement> rbReqs = convertRequires(rbClauses, resource);

        //
        // Parse Import-Package.
        //

        List<ParsedHeaderClause> importClauses = parseStandardHeader(headerMap.get(Constants.IMPORT_PACKAGE));
        importClauses = normalizeImportClauses(importClauses);
        List<Requirement> importReqs = convertImports(importClauses, resource);

        //
        // Parse DynamicImport-Package.
        //

        List<ParsedHeaderClause> dynamicClauses = parseStandardHeader(headerMap.get(Constants.DYNAMICIMPORT_PACKAGE));
        dynamicClauses = normalizeDynamicImportClauses(dynamicClauses);
        List<Requirement> dynamicReqs = convertImports(dynamicClauses, resource);

        //
        // Parse Require-Capability.
        //

        List<ParsedHeaderClause> requireClauses = parseStandardHeader(headerMap.get(Constants.REQUIRE_CAPABILITY));
        requireClauses = normalizeRequireCapabilityClauses(requireClauses);
        List<Requirement> requireReqs = convertRequireCapabilities(requireClauses, resource);

        //
        // Parse Bundle-RequiredExecutionEnvironment.
        //
        List<Requirement> breeReqs =
                parseBreeHeader((String) headerMap.get(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT), resource);

        //
        // Parse Export-Package.
        //

        List<ParsedHeaderClause> exportClauses = parseStandardHeader(headerMap.get(Constants.EXPORT_PACKAGE));
        exportClauses = normalizeExportClauses(exportClauses, bundleSymbolicName, bundleVersion);
        List<Capability> exportCaps = convertExports(exportClauses, resource);

        //
        // Parse Provide-Capability.
        //

        List<ParsedHeaderClause> provideClauses = parseStandardHeader(headerMap.get(Constants.PROVIDE_CAPABILITY));
        provideClauses = normalizeProvideCapabilityClauses(provideClauses);
        List<Capability> provideCaps = convertProvideCapabilities(provideClauses, resource);

        //
        // Parse Import-Service and Export-Service
        // if Require-Capability and Provide-Capability are not set for services
        //

        boolean hasServiceReferenceCapability = false;
        for (Capability cap : exportCaps) {
            hasServiceReferenceCapability |= ServiceNamespace.SERVICE_NAMESPACE.equals(cap.getNamespace());
        }
        if (!hasServiceReferenceCapability) {
            List<ParsedHeaderClause> exportServices = parseStandardHeader(headerMap.get(Constants.EXPORT_SERVICE));
            List<Capability> caps = convertExportService(exportServices, resource);
            provideCaps.addAll(caps);
        }

        boolean hasServiceReferenceRequirement = false;
        for (Requirement req : requireReqs) {
            hasServiceReferenceRequirement |= ServiceNamespace.SERVICE_NAMESPACE.equals(req.getNamespace());
        }
        if (!hasServiceReferenceRequirement) {
            List<ParsedHeaderClause> importServices = parseStandardHeader(headerMap.get(Constants.IMPORT_SERVICE));
            List<Requirement> reqs = convertImportService(importServices, resource);
            if (!reqs.isEmpty()) {
                requireReqs.addAll(reqs);
                hasServiceReferenceRequirement = true;
            }
        }

        if (hasServiceReferenceRequirement && removeServiceRequirements) {
            for (Iterator<Requirement> iterator = requireReqs.iterator(); iterator.hasNext();) {
                Requirement req = iterator.next();
                if (ServiceNamespace.SERVICE_NAMESPACE.equals(req.getNamespace())) {
                    iterator.remove();
                }
            }
        }

        // Combine all capabilities.
        resource.addCapabilities(exportCaps);
        resource.addCapabilities(provideCaps);

        // Combine all requirements.
        resource.addRequirements(hostReqs);
        resource.addRequirements(importReqs);
        resource.addRequirements(rbReqs);
        resource.addRequirements(requireReqs);
        resource.addRequirements(dynamicReqs);

        return resource;
    }