private void generateHeaders()

in atomos/src/main/java/org/apache/felix/atomos/impl/modules/AtomosModules.java [498:623]


        private void generateHeaders(Map<String, String> headers, Module m)
        {
            ModuleDescriptor desc = m.getDescriptor();
            StringBuilder capabilities = new StringBuilder();
            StringBuilder requirements = new StringBuilder();
            String bsn = headers.get(Constants.BUNDLE_SYMBOLICNAME);
            if (bsn == null)
            {
                // NOTE that we depend on the framework connect implementation to allow connect bundles
                // to export java.* packages
                headers.put(Constants.BUNDLE_MANIFESTVERSION, "2");
                // set the symbolic name for the module; don't allow fragments to attach
                headers.put(Constants.BUNDLE_SYMBOLICNAME,
                    desc.name() + "; " + Constants.FRAGMENT_ATTACHMENT_DIRECTIVE + ":="
                        + Constants.FRAGMENT_ATTACHMENT_NEVER);

                // set the version
                Version v;
                try
                {
                    v = Version.parseVersion(desc.version().map(
                        java.lang.module.ModuleDescriptor.Version::toString).orElse("0"));
                }
                catch (IllegalArgumentException e)
                {
                    v = Version.emptyVersion;
                }
                headers.put(Constants.BUNDLE_VERSION, v.toString());

                // only do exports for non bundle modules
                // real OSGi bundles already have good export capabilities
                StringBuilder exportPackageHeader = new StringBuilder();

                // ModuleDescriptor.exports() is empty for an automatic module, which is different from
                // JPMS at runtime where all packages in the automatic module are exported
                if (desc.isAutomatic()) {
                    desc.packages().stream().sorted().forEach((packageName) -> {
                        if (exportPackageHeader.length() > 0)
                        {
                            exportPackageHeader.append(", ");
                        }
                        exportPackageHeader.append(packageName);
                    });
                }
                else {
                    desc.exports().stream().sorted().forEach((exported) -> {
                        if (exportPackageHeader.length() > 0)
                        {
                            exportPackageHeader.append(", ");
                        }
                        exportPackageHeader.append(exported.source());
                        // TODO map targets to x-friends directive?
                    });
                }
                if (exportPackageHeader.length() > 0)
                {
                    headers.put(Constants.EXPORT_PACKAGE, exportPackageHeader.toString());
                }

                // Note that for generated manifests based of module descriptor
                // will have their requires calculated later.
                // Place a header indicating this is generated
                headers.put(ATOMOS_GENERATED, Boolean.TRUE.toString());
                if (calculateRequires(headers, m, Function.identity()))
                {
                    // Set a temporary header if we need to recalculate later
                    headers.put(ATOMOS_TEMPORARY_GENERATED_REQUIRES, Boolean.TRUE.toString());
                }
            }
            else
            {
                String origCaps = headers.get(Constants.PROVIDE_CAPABILITY);
                if (origCaps != null)
                {
                    capabilities.append(origCaps);
                }
                String origReqs = headers.get(Constants.REQUIRE_CAPABILITY);
                if (origReqs != null)
                {
                    requirements.append(origReqs);
                }
            }
            // map provides to a made up namespace only to give proper resolution errors
            // (although JPMS will likely complain first
            for (ModuleDescriptor.Provides provides : desc.provides())
            {
                if (capabilities.length() > 0)
                {
                    capabilities.append(", ");
                }
                capabilities.append(JavaServiceNamespace.JAVA_SERVICE_NAMESPACE).append(
                    "; ");
                capabilities.append(JavaServiceNamespace.JAVA_SERVICE_NAMESPACE).append(
                    "=").append(provides.service()).append("; ");
                capabilities.append(
                    JavaServiceNamespace.CAPABILITY_PROVIDES_WITH_ATTRIBUTE).append(
                        "=\"").append(String.join(",", provides.providers())).append(
                            "\"");
            }

            // map uses to a made up namespace only to give proper resolution errors
            // (although JPMS will likely complain first)
            for (String uses : desc.uses())
            {
                if (requirements.length() > 0)
                {
                    requirements.append(", ");
                }
                requirements.append(JavaServiceNamespace.JAVA_SERVICE_NAMESPACE).append(
                    "; ");
                requirements.append(Constants.RESOLUTION_DIRECTIVE).append(":=").append(
                    Constants.RESOLUTION_OPTIONAL).append("; ");
                requirements.append(Constants.FILTER_DIRECTIVE).append(":=").append(
                    "\"(").append(JavaServiceNamespace.JAVA_SERVICE_NAMESPACE).append(
                        "=").append(uses).append(")\"");
            }

            if (capabilities.length() > 0)
            {
                headers.put(Constants.PROVIDE_CAPABILITY, capabilities.toString());
            }
            if (requirements.length() > 0)
            {
                headers.put(Constants.REQUIRE_CAPABILITY, requirements.toString());
            }
        }