void updateRevision()

in framework/src/main/java/org/apache/felix/framework/ExtensionManager.java [236:389]


    void updateRevision(Felix felix, Map<String,?> configMap)
    {
        Map<String,Object> config = new HashMap<>(configMap);
        Properties defaultProperties = Util.loadDefaultProperties(m_logger);

        Util.initializeJPMSEE(felix._getProperty("java.specification.version"), defaultProperties, m_logger);

        String sysprops = felix._getProperty(Constants.FRAMEWORK_SYSTEMPACKAGES);


        boolean subst = "true".equalsIgnoreCase(felix._getProperty(FelixConstants.USE_PROPERTY_SUBSTITUTION_IN_SYSTEMPACKAGES));

        if (sysprops != null && sysprops.isEmpty())
        {
            if (felix.hasConnectFramework())
            {
                subst = true;
                sysprops = "${osgi-exports}";
                config.put(Constants.FRAMEWORK_SYSTEMPACKAGES, sysprops);
            }
        }

        final Map<String, Set<String>> exports = Util.initializeJPMS(defaultProperties);

        if (exports != null && (sysprops == null || "true".equalsIgnoreCase(felix._getProperty(FelixConstants.USE_PROPERTY_SUBSTITUTION_IN_SYSTEMPACKAGES))))
        {
            final ClassParser classParser = new ClassParser();
            final Set<String> imports = new HashSet<>();
            for (Set<String> moduleImport : exports.values())
            {
                for (String pkg : moduleImport)
                {
                    if (!pkg.startsWith("java."))
                    {
                        imports.add(pkg);
                    }
                }
            }
            for (final String moduleKey : exports.keySet())
            {
                int idx = moduleKey.indexOf("@");
                String module = idx == -1 ? moduleKey : moduleKey.substring(0, idx);
                if (felix._getProperty(module) == null && !exports.get(moduleKey).isEmpty() && defaultProperties.getProperty(module) == null)
                {
                    final SortedMap<String, SortedSet<String>> referred = new TreeMap<>();
                    if ("true".equalsIgnoreCase(felix._getProperty(FelixConstants.CALCULATE_SYSTEMPACKAGES_USES)))
                    {
                        java.nio.file.FileSystem fs = java.nio.file.FileSystems.getFileSystem(URI.create("jrt:/"));
                        try
                        {
                            Properties cachedProps = new Properties();
                            File modulesDir = felix.getDataFile(felix, "modules");
                            Felix.m_secureAction.mkdirs(modulesDir);
                            File cached = new File(modulesDir, moduleKey + ".properties");
                            if (Felix.m_secureAction.isFile(cached))
                            {
                                InputStream input = Felix.m_secureAction.getInputStream(cached);
                                cachedProps.load(new InputStreamReader(input, "UTF-8"));
                                input.close();
                                for (Enumeration<?> keys = cachedProps.propertyNames(); keys.hasMoreElements();)
                                {
                                    String pkg = (String) keys.nextElement();
                                    referred.put(pkg, new TreeSet<>(Arrays.asList(cachedProps.getProperty(pkg).split(","))));
                                }
                            }
                            else
                            {
                                java.nio.file.Path path = fs.getPath("modules", module.substring("felix.jpms.".length()));
                                java.nio.file.Files.walkFileTree(path, (java.nio.file.FileVisitor<java.nio.file.Path>) Felix.class.getClassLoader().loadClass("org.apache.felix.framework.util.ClassFileVisitor")
                                    .getConstructor(Set.class, Set.class, ClassParser.class, SortedMap.class).newInstance(imports, exports.get(moduleKey), classParser, referred));
                                for (String pkg : referred.keySet())
                                {
                                    SortedSet<String> uses = referred.get(pkg);
                                    if (uses != null && !uses.isEmpty())
                                    {
                                        cachedProps.setProperty(pkg, String.join(",", uses));
                                    }
                                }
                                OutputStream output = Felix.m_secureAction.getOutputStream(cached);
                                cachedProps.store(new OutputStreamWriter(output, "UTF-8"), null);
                                output.close();
                            }
                        }
                        catch (Throwable e)
                        {
                            m_logger.log(Logger.LOG_WARNING, "Exception calculating JPMS module exports", e);
                        }
                    }

                    StringBuilder pkgs = new StringBuilder();

                    for (String pkg : exports.get(moduleKey))
                    {
                        pkgs.append(",").append(pkg);
                        SortedSet<String> uses = referred.get(pkg);
                        if (uses != null && !uses.isEmpty())
                        {
                            pkgs.append(";uses:=\"");
                            String sep = "";
                            for (String u : uses)
                            {
                                pkgs.append(sep).append(u);
                                sep = ",";
                            }
                            pkgs.append("\"");
                        }
                        pkgs.append(";version=\"").append(defaultProperties.getProperty("felix.detect.java.version")).append("\"");
                    }
                    defaultProperties.put(module, pkgs.toString());
                }
            }
        }

        for (String propName : defaultProperties.stringPropertyNames())
        {
            if (!config.containsKey(propName))
            {
                config.put(propName, defaultProperties.getProperty(propName));
            }
        }

        if(sysprops != null && subst)
        {
            config.put(Constants.FRAMEWORK_SYSTEMPACKAGES, Util.getPropertyWithSubs(Util.toProperties(config), Constants.FRAMEWORK_SYSTEMPACKAGES));
        }
        else if (sysprops == null)
        {
            config.put(Constants.FRAMEWORK_SYSTEMPACKAGES, Util.getPropertyWithSubs(Util.toProperties(config), Constants.FRAMEWORK_SYSTEMPACKAGES));
        }

        String syspropsExtra = felix._getProperty(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA);
        if (syspropsExtra != null && "true".equalsIgnoreCase(felix._getProperty(FelixConstants.USE_PROPERTY_SUBSTITUTION_IN_SYSTEMPACKAGES)))
        {
            config.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, Util.getPropertyWithSubs(Util.toProperties(config), Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA));
        }

        String syscaps = felix._getProperty(Constants.FRAMEWORK_SYSTEMCAPABILITIES);
        if(syscaps != null && "true".equalsIgnoreCase(felix._getProperty(FelixConstants.USE_PROPERTY_SUBSTITUTION_IN_SYSTEMPACKAGES)))
        {
            config.put(Constants.FRAMEWORK_SYSTEMCAPABILITIES, Util.getPropertyWithSubs(Util.toProperties(config), Constants.FRAMEWORK_SYSTEMCAPABILITIES));
        }
        else if(syscaps == null)
        {
            config.put(Constants.FRAMEWORK_SYSTEMCAPABILITIES, Util.getPropertyWithSubs(Util.toProperties(config), Constants.FRAMEWORK_SYSTEMCAPABILITIES));
        }

        String syscapsExtra = felix._getProperty(Constants.FRAMEWORK_SYSTEMCAPABILITIES_EXTRA);
        if (syscapsExtra != null && "true".equalsIgnoreCase(felix._getProperty(FelixConstants.USE_PROPERTY_SUBSTITUTION_IN_SYSTEMPACKAGES)))
        {
            config.put(Constants.FRAMEWORK_SYSTEMCAPABILITIES_EXTRA, Util.getPropertyWithSubs(Util.toProperties(config), Constants.FRAMEWORK_SYSTEMCAPABILITIES_EXTRA));
        }

        m_systemBundleRevision.update(config);
    }