make/tools/classanalyzer/src/com/sun/classanalyzer/PlatformModuleBuilder.java

Print this page

        

@@ -20,16 +20,14 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
 package com.sun.classanalyzer;
 
+import com.sun.classanalyzer.Module.Factory;
 import com.sun.classanalyzer.ModuleInfo.Dependence;
-import static com.sun.classanalyzer.PlatformModuleBuilder.PlatformModuleNames.*;
+import static com.sun.classanalyzer.PlatformModuleBuilder.PlatformFactory.*;
 
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
 import java.io.IOException;
 import java.util.*;
 
 /**
  * A platform module builder for JDK.  JDK's boot module, base module,

@@ -41,38 +39,11 @@
  *   reexport its public APIs
  *
  * @author Mandy Chung
  */
 public class PlatformModuleBuilder extends ModuleBuilder {
-
-    /**
-     * Platform modules that must be defined in the modules.properties
-     */
-    static class PlatformModuleNames {
-
-        static final String BOOT_MODULE =
-                getValue("platform.boot.module");
-        static final String BASE_MODULE =
-                getValue("platform.base.module");
-        static final String JDK_MODULE =
-                getValue("platform.jdk.module");
-        static final String JRE_MODULE =
-                getValue("platform.jre.module");
-        static final String JRE_TOOLS_MODULE =
-                getValue("platform.jre.tools.module");
-
-        static String getValue(String key) {
-            String value = Module.getModuleProperty(key);
-            if (value == null || value.isEmpty()) {
-                throw new RuntimeException("Null or empty module property: " + key);
-            }
-            return value;
-        }
-    }
-    private BootModule bootModule;
-    private final PlatformModule jdkModule;
-    private final PlatformModule jreModule;
+    private final PlatformFactory factory;
 
     public PlatformModuleBuilder(List<String> configs, String version)
             throws IOException {
         this(configs, null, true, version);
     }

@@ -81,96 +52,88 @@
             List<String> depconfigs,
             boolean merge,
             String version)
             throws IOException {
         super(null, depconfigs, merge, version);
-
-        Module.setBaseModule(BASE_MODULE);
-
-        // create modules based on the input config files
-        for (String file : configs) {
-            for (ModuleConfig mconfig : ModuleConfig.readConfigurationFile(file)) {
-                newModule(mconfig);
-            }
-        }
-
-        // Create the full jdk and jre modules
-        jdkModule = (PlatformModule) newModule(JDK_MODULE);
-        jreModule = (PlatformModule) newModule(JRE_MODULE);
+        // the factory will create the modules for the input config files
+        this.factory = new PlatformFactory(configs, version);
     }
 
     @Override
-    public Module newModule(ModuleConfig mconfig) {
-        return addPlatformModule(mconfig);
+    protected Factory getFactory() {
+        return factory;
     }
 
     @Override
-    public void run() throws IOException {
+    public Set<Module> run() throws IOException {
         // assign classes and resource files to the modules
         // group fine-grained modules per configuration files
         buildModules();
 
         // build public jdk modules to reexport sun.* modules
         buildJDKModules();
 
-        // generate package information
+        // generate package infos and determine if there is any split package
         buildPackageInfos();
 
         // analyze cross-module dependencies and generate ModuleInfo
-        buildModuleInfos();
+        List<ModuleInfo> minfos = buildModuleInfos();
+        
+        // generate an ordered list from the module dependency graph
+        result = Collections.unmodifiableSet(orderedModuleList(minfos));
+        return result;
     }
 
     private void buildJDKModules() {
-        Set<PlatformModule> modules = new LinkedHashSet<PlatformModule>();
+        Set<PlatformModule> pmodules = new LinkedHashSet<PlatformModule>();
         PlatformModule jreToolModule = (PlatformModule)
-                Module.findModule(JRE_TOOLS_MODULE);
+                factory.findModule(JRE_TOOLS_MODULE);
+        BootModule bootModule = (BootModule)
+                factory.findModule(BOOT_MODULE);
+        PlatformModule jdkModule = (PlatformModule) factory.findModule(JDK_MODULE);
+        PlatformModule jreModule = (PlatformModule) factory.findModule(JRE_MODULE);
 
-        for (Module m : Module.getAllModules()) {
+        for (Module m : factory.getAllModules()) {
             if (m.isTopLevel()) {
                 PlatformModule pm = (PlatformModule) m;
-                modules.add(pm);
+                pmodules.add(pm);
             }
         }
 
         // set exporter
-        for (PlatformModule pm : modules) {
+        for (PlatformModule pm : pmodules) {
             PlatformModule exporter = pm;
             String name = pm.name();
             if (name.startsWith("sun.")) {
                 // create an aggregate module for each sun.* module
                 String mn = name.replaceFirst("sun", "jdk");
                 String mainClassName =
                         pm.mainClass() == null ? null : pm.mainClass().getClassName();
 
-                PlatformModule rm = (PlatformModule) Module.findModule(mn);
+                PlatformModule rm = (PlatformModule) factory.findModule(mn);
                 if (rm != null) {
                     if (pm.mainClass() != rm.mainClass()) {
                         // propagate the main class to its aggregator module
                         rm.setMainClass(mainClassName);
                     }
                     exporter = rm;
                 } else if (pm.hasPlatformAPIs()) {
-                    ModuleConfig config = null;
-                    try {
-                        config = new ModuleConfig(mn, mainClassName);
-                    } catch (IOException ex) {
-                        throw new RuntimeException(ex);
-                    }
-                    exporter = addPlatformModule(config);
+                    ModuleConfig config = new ModuleConfig(mn, version, mainClassName);
+                    exporter = factory.addPlatformModule(config);
                 }
 
                 if (pm != exporter) {
                     pm.reexportBy(exporter);
                 }
             }
         }
 
         // base module to reexport boot module
-        bootModule.reexportBy((PlatformModule) Module.findModule(BASE_MODULE));
+        bootModule.reexportBy((PlatformModule) factory.findModule(BASE_MODULE));
 
         // set up the jdk and jdk.jre modules
-        for (Module m : Module.getAllModules()) {
+        for (Module m : factory.getAllModules()) {
             if (m.isTopLevel()) {
                 PlatformModule pm = (PlatformModule) m;
                 String name = pm.name();
                 if (name.startsWith("jdk.") || name.startsWith("sun.")) {
                     if (pm != jdkModule && pm != jreModule) {

@@ -189,54 +152,57 @@
 
     /*
      * Returns an ordered list of platform modules according to
      * their dependencies with jdk.boot always be the first.
      */
-    @Override
-    protected Collection<Module> orderedModuleList(Collection<ModuleInfo> minfos) {
+    private Set<Module> orderedModuleList(Collection<ModuleInfo> minfos) {
         Set<Module> visited = new TreeSet<Module>();
-        Set<Module> result = new LinkedHashSet<Module>();
+        Set<Module> orderedList = new LinkedHashSet<Module>();
         Dependence.Filter filter = new Dependence.Filter() {
 
             @Override
             public boolean accept(Dependence d) {
                 return !d.isOptional();
             }
         };
 
+        BootModule bootModule = (BootModule)
+                factory.findModule(BOOT_MODULE);
 
         // put the boot module first
         visited.add(bootModule);
-        result.add(bootModule);
-        Module.findModule(BASE_MODULE).getModuleInfo().visitDependence(filter, visited, result);
-        jdkModule.getModuleInfo().visitDependence(filter, visited, result);
+        orderedList.add(bootModule);
+        factory.findModule(BASE_MODULE).getModuleInfo().visitDependence(filter, visited, orderedList);
+        factory.findModule(JDK_MODULE).getModuleInfo().visitDependence(filter, visited, orderedList);
         for (ModuleInfo mi : minfos) {
-            mi.visitDependence(filter, visited, result);
+            mi.visitDependence(filter, visited, orderedList);
         }
 
-        return result;
+        return orderedList;
     }
 
     @Override
-    protected Set<Dependence> updateModuleDependences(Module m, Collection<Dependence> requires) {
+    protected ModuleInfo buildModuleInfo(Module m) {    
+        ModuleInfo mi = super.buildModuleInfo(m);
+        
         // use the module's exporter in the dependence
         Set<Dependence> depset = new TreeSet<Dependence>();
-        Module base = Module.findModule(BASE_MODULE);
+        Module base = factory.findModule(BASE_MODULE);
         boolean useExporter = false;
-        for (Dependence d : requires) {
+        for (Dependence d : mi.requires()) {
             // if the config has a "requires jdk.base"
             // this module will depend on its public exporter module
             if (d.getModule() == base) {
                 useExporter = true;
                 break;
             }
         }
 
-        for (Dependence d : requires) {
+        for (Dependence d : mi.requires()) {
             Dependence dep = d;
             if (useExporter && !d.isLocal()) {
-                Module exp = d.getModule().exporter(m);
+                Module exp = ((PlatformModule)d.getModule()).exporter(m);
                 if (exp == null) {
                     throw new RuntimeException(d.getModule() + " null exporter");
                 }
                 if (d.getModule() != exp && exp != m) {
                     dep = new Dependence(exp, d.modifiers());

@@ -249,29 +215,84 @@
                 continue;
             }
             depset.add(dep);
 
         }
-        return depset;
+        
+        // return a new ModuleInfo with patched dependences
+        return new ModuleInfo(m, depset, mi.permits());
     }
 
-    private PlatformModule addPlatformModule(ModuleConfig config) {
-        PlatformModule m;
+    static class PlatformFactory extends Factory {
+       /**
+        * Platform modules that must be defined in the modules.properties
+        */
+        static final String BOOT_MODULE =
+                getValue("platform.boot.module");
+        static final String BASE_MODULE =
+                getValue("platform.base.module");
+        static final String JDK_MODULE =
+                getValue("platform.jdk.module");
+        static final String JRE_MODULE =
+                getValue("platform.jre.module");
+        static final String JRE_TOOLS_MODULE =
+                getValue("platform.jre.tools.module");
+
+        static String getValue(String key) {
+            String value = Module.getModuleProperty(key);
+            if (value == null || value.isEmpty()) {
+                throw new RuntimeException("Null or empty module property: " + key);
+            }
+            return value;
+        }
+        
+        PlatformFactory(List<String> configs, String version) throws IOException {
+            Module.setBaseModule(BASE_MODULE);
+                
+            // create modules based on the input config files
+            List<ModuleConfig> mconfigs = new ArrayList<ModuleConfig>();
+            for (String file : configs) {
+                mconfigs.addAll(ModuleConfig.readConfigurationFile(file, version));
+            }
+            init(mconfigs);
+                    
+            // Create the full jdk and jre modules
+            addModule(new NoClassModule(JDK_MODULE, version));
+            addModule(new NoClassModule(JRE_MODULE, version));
+        }
+        
+        @Override
+        public Module newModule(String name, String version) {
+            return newPlatformModule(new ModuleConfig(name, version));
+        }
+
+        @Override
+        public Module newModule(ModuleConfig config) {
+            return newPlatformModule(config);
+        }
+        
+        private PlatformModule newPlatformModule(ModuleConfig config) {
         if (config.module.equals(BOOT_MODULE)) {
-            bootModule = new BootModule(config);
-            m = bootModule;
+                return new BootModule(config);
         } else {
-            m = new PlatformModule(config);
+                return new PlatformModule(config);
         }
-        Module.addModule(m);
-        return m;
     }
 
-    class PlatformModule extends Module {
+        PlatformModule addPlatformModule(String name, String version) {
+            return addPlatformModule(new ModuleConfig(name, version));
+        }
+        
+        PlatformModule addPlatformModule(ModuleConfig config) {
+            PlatformModule m = newPlatformModule(config);
+            addModule(m);
+            return m;
+        }    
+    }
 
+    static class PlatformModule extends Module {
         private Module exporter;  // module that reexports this platform module
-
         public PlatformModule(ModuleConfig config) {
             super(config);
             this.exporter = this;
         }
 

@@ -291,15 +312,10 @@
             }
 
             mainClassName = classname;
         }
 
-        @Override
-        boolean allowEmpty() {
-            return this == jdkModule || this == jreModule || super.allowEmpty();
-        }
-
         // requires local for JRE modules that are strongly
         // connected with the boot module
         boolean isBootConnected() {
             // ## should it check for local?
             Dependence d = config().requires.get(BOOT_MODULE);

@@ -327,12 +343,11 @@
             return platformAPIs > 0;
         }
 
         // returns the module that is used by the requires statement
         // in other module's module-info
-        @Override
-        public Module exporter(Module from) {
+        Module exporter(Module from) {
             PlatformModule pm = (PlatformModule) from;
             if (pm.isBootConnected()) {
                 // If it's a local module requiring jdk.boot, retain
                 // the original requires; otherwise, use its external
                 // module

@@ -349,17 +364,26 @@
             // jdk.<m> requires public sun.<m>;
             pm.config().reexportModule(this);
         }
     }
 
-    public class BootModule extends PlatformModule {
-
+    static class BootModule extends PlatformModule {
         BootModule(ModuleConfig config) {
             super(config);
         }
 
         @Override
         boolean isBootConnected() {
             return true;
         }
     }
+    static class NoClassModule extends PlatformModule {
+        NoClassModule(String name, String version) {
+            super(new ModuleConfig(name, version));
+        }
+
+        @Override
+        boolean allowEmpty() {
+            return true;
+        }
+    }
 }