langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/Module.java
changeset 43767 9cff98a149cb
parent 42407 f3702cff2933
equal deleted inserted replaced
43648:ce7b7f98a236 43767:9cff98a149cb
    24  */
    24  */
    25 
    25 
    26 package com.sun.tools.jdeps;
    26 package com.sun.tools.jdeps;
    27 
    27 
    28 import java.lang.module.ModuleDescriptor;
    28 import java.lang.module.ModuleDescriptor;
    29 import java.lang.module.ModuleDescriptor.Exports;
       
    30 import java.lang.module.ModuleDescriptor.Opens;
       
    31 import java.net.URI;
    29 import java.net.URI;
    32 import java.util.Collections;
    30 import java.util.Collections;
    33 import java.util.HashMap;
    31 import java.util.HashMap;
    34 import java.util.HashSet;
    32 import java.util.HashSet;
    35 import java.util.Map;
    33 import java.util.Map;
    53         }
    51         }
    54     }
    52     }
    55 
    53 
    56     private final ModuleDescriptor descriptor;
    54     private final ModuleDescriptor descriptor;
    57     private final Map<String, Set<String>> exports;
    55     private final Map<String, Set<String>> exports;
       
    56     private final Map<String, Set<String>> opens;
    58     private final boolean isSystem;
    57     private final boolean isSystem;
    59     private final URI location;
    58     private final URI location;
    60 
    59 
    61     protected Module(String name) {
    60     protected Module(String name) {
    62         super(name);
    61         super(name);
    63         this.descriptor = null;
    62         this.descriptor = null;
    64         this.location = null;
    63         this.location = null;
    65         this.exports = Collections.emptyMap();
    64         this.exports = Collections.emptyMap();
       
    65         this.opens = Collections.emptyMap();
    66         this.isSystem = true;
    66         this.isSystem = true;
    67     }
    67     }
    68 
    68 
    69     private Module(String name,
    69     private Module(String name,
    70                    URI location,
    70                    URI location,
    71                    ModuleDescriptor descriptor,
    71                    ModuleDescriptor descriptor,
    72                    Map<String, Set<String>> exports,
    72                    Map<String, Set<String>> exports,
       
    73                    Map<String, Set<String>> opens,
    73                    boolean isSystem,
    74                    boolean isSystem,
    74                    ClassFileReader reader) {
    75                    ClassFileReader reader) {
    75         super(name, location, reader);
    76         super(name, location, reader);
    76         this.descriptor = descriptor;
    77         this.descriptor = descriptor;
    77         this.location = location;
    78         this.location = location;
    78         this.exports = Collections.unmodifiableMap(exports);
    79         this.exports = Collections.unmodifiableMap(exports);
       
    80         this.opens = Collections.unmodifiableMap(opens);
    79         this.isSystem = isSystem;
    81         this.isSystem = isSystem;
    80     }
    82     }
    81 
    83 
    82     /**
    84     /**
    83      * Returns module name
    85      * Returns module name
   122 
   124 
   123     public Set<String> packages() {
   125     public Set<String> packages() {
   124         return descriptor.packages();
   126         return descriptor.packages();
   125     }
   127     }
   126 
   128 
   127     /**
       
   128      * Tests if the package of the given name is exported.
       
   129      */
       
   130     public boolean isExported(String pn) {
       
   131         return exports.containsKey(pn) ? exports.get(pn).isEmpty() : false;
       
   132     }
       
   133 
       
   134     public boolean isJDKUnsupported() {
   129     public boolean isJDKUnsupported() {
   135         return JDK_UNSUPPORTED.equals(this.name());
   130         return JDK_UNSUPPORTED.equals(this.name());
   136     }
   131     }
   137 
   132 
   138     /**
   133     /**
   139      * Converts this module to a strict module with the given dependences
   134      * Converts this module to a normal module with the given dependences
   140      *
   135      *
   141      * @throws IllegalArgumentException if this module is not an automatic module
   136      * @throws IllegalArgumentException if this module is not an automatic module
   142      */
   137      */
   143     public Module toStrictModule(Map<String, Boolean> requires) {
   138     public Module toNormalModule(Map<String, Boolean> requires) {
   144         if (!isAutomatic()) {
   139         if (!isAutomatic()) {
   145             throw new IllegalArgumentException(name() + " already a strict module");
   140             throw new IllegalArgumentException(name() + " not an automatic module");
   146         }
   141         }
   147         return new StrictModule(this, requires);
   142         return new NormalModule(this, requires);
   148     }
   143     }
   149 
   144 
   150     /**
   145     /**
   151      * Tests if the package of the given name is qualifiedly exported
   146      * Tests if the package of the given name is exported.
   152      * to the target.
   147      */
       
   148     public boolean isExported(String pn) {
       
   149         return exports.containsKey(pn) && exports.get(pn).isEmpty();
       
   150     }
       
   151 
       
   152     /**
       
   153      * Tests if the package of the given name is exported to the target
       
   154      * in a qualified fashion.
   153      */
   155      */
   154     public boolean isExported(String pn, String target) {
   156     public boolean isExported(String pn, String target) {
   155         return isExported(pn) || exports.containsKey(pn) && exports.get(pn).contains(target);
   157         return isExported(pn)
       
   158                 || exports.containsKey(pn) && exports.get(pn).contains(target);
       
   159     }
       
   160 
       
   161     /**
       
   162      * Tests if the package of the given name is open.
       
   163      */
       
   164     public boolean isOpen(String pn) {
       
   165         return opens.containsKey(pn) && opens.get(pn).isEmpty();
       
   166     }
       
   167 
       
   168     /**
       
   169      * Tests if the package of the given name is open to the target
       
   170      * in a qualified fashion.
       
   171      */
       
   172     public boolean isOpen(String pn, String target) {
       
   173         return isOpen(pn)
       
   174             || opens.containsKey(pn) && opens.get(pn).contains(target);
   156     }
   175     }
   157 
   176 
   158     @Override
   177     @Override
   159     public String toString() {
   178     public String toString() {
   160         return name();
   179         return name();
   191             if (descriptor.isAutomatic() && isSystem) {
   210             if (descriptor.isAutomatic() && isSystem) {
   192                 throw new InternalError("JDK module: " + name + " can't be automatic module");
   211                 throw new InternalError("JDK module: " + name + " can't be automatic module");
   193             }
   212             }
   194 
   213 
   195             Map<String, Set<String>> exports = new HashMap<>();
   214             Map<String, Set<String>> exports = new HashMap<>();
   196 
   215             Map<String, Set<String>> opens = new HashMap<>();
   197             descriptor.exports().stream()
   216 
   198                 .forEach(exp -> exports.computeIfAbsent(exp.source(), _k -> new HashSet<>())
   217             if (descriptor.isAutomatic()) {
   199                                     .addAll(exp.targets()));
   218                 // ModuleDescriptor::exports and opens returns an empty set
   200 
   219                 descriptor.packages().forEach(pn -> exports.put(pn, Collections.emptySet()));
   201             return new Module(name, location, descriptor, exports, isSystem, reader);
   220                 descriptor.packages().forEach(pn -> opens.put(pn, Collections.emptySet()));
       
   221             } else {
       
   222                 descriptor.exports().stream()
       
   223                           .forEach(exp -> exports.computeIfAbsent(exp.source(), _k -> new HashSet<>())
       
   224                                                  .addAll(exp.targets()));
       
   225                 descriptor.opens().stream()
       
   226                     .forEach(exp -> opens.computeIfAbsent(exp.source(), _k -> new HashSet<>())
       
   227                         .addAll(exp.targets()));
       
   228             }
       
   229             return new Module(name, location, descriptor, exports, opens, isSystem, reader);
   202         }
   230         }
   203     }
   231     }
   204 
   232 
   205     private static class UnnamedModule extends Module {
   233     private static class UnnamedModule extends Module {
   206         private UnnamedModule() {
   234         private UnnamedModule() {
   207             super("unnamed", null, null,
   235             super("unnamed", null, null,
   208                   Collections.emptyMap(),
   236                   Collections.emptyMap(), Collections.emptyMap(),
   209                   false, null);
   237                   false, null);
   210         }
   238         }
   211 
   239 
   212         @Override
   240         @Override
   213         public String name() {
   241         public String name() {
   228         public boolean isExported(String pn) {
   256         public boolean isExported(String pn) {
   229             return true;
   257             return true;
   230         }
   258         }
   231     }
   259     }
   232 
   260 
   233     private static class StrictModule extends Module {
   261     /**
       
   262      * A normal module has a module-info.class
       
   263      */
       
   264     private static class NormalModule extends Module {
   234         private final ModuleDescriptor md;
   265         private final ModuleDescriptor md;
   235 
   266 
   236         /**
   267         /**
   237          * Converts the given automatic module to a strict module.
   268          * Converts the given automatic module to a normal module.
   238          *
   269          *
   239          * Replace this module's dependences with the given requires and also
   270          * Replace this module's dependences with the given requires and also
   240          * declare service providers, if specified in META-INF/services configuration file
   271          * declare service providers, if specified in META-INF/services configuration file
   241          */
   272          */
   242         private StrictModule(Module m, Map<String, Boolean> requires) {
   273         private NormalModule(Module m, Map<String, Boolean> requires) {
   243             super(m.name(), m.location, m.descriptor, m.exports, m.isSystem, m.reader());
   274             super(m.name(), m.location, m.descriptor, m.exports, m.opens, m.isSystem, m.reader());
   244 
   275 
   245             ModuleDescriptor.Builder builder = ModuleDescriptor.module(m.name());
   276             ModuleDescriptor.Builder builder = ModuleDescriptor.newModule(m.name());
   246             requires.keySet().forEach(mn -> {
   277             requires.keySet().forEach(mn -> {
   247                 if (requires.get(mn).equals(Boolean.TRUE)) {
   278                 if (requires.get(mn).equals(Boolean.TRUE)) {
   248                     builder.requires(Set.of(ModuleDescriptor.Requires.Modifier.TRANSITIVE), mn);
   279                     builder.requires(Set.of(ModuleDescriptor.Requires.Modifier.TRANSITIVE), mn);
   249                 } else {
   280                 } else {
   250                     builder.requires(mn);
   281                     builder.requires(mn);
   251                 }
   282                 }
   252             });
   283             });
   253             m.descriptor.exports().forEach(e -> builder.exports(e));
   284             // exports all packages
   254             m.descriptor.opens().forEach(o -> builder.opens(o));
   285             m.descriptor.packages().forEach(builder::exports);
   255             m.descriptor.uses().forEach(s -> builder.uses(s));
   286             m.descriptor.uses().forEach(builder::uses);
   256             m.descriptor.provides().forEach(p -> builder.provides(p));
   287             m.descriptor.provides().forEach(builder::provides);
   257 
       
   258             Set<String> concealed = new HashSet<>(m.descriptor.packages());
       
   259             m.descriptor.exports().stream().map(Exports::source).forEach(concealed::remove);
       
   260             m.descriptor.opens().stream().map(Opens::source).forEach(concealed::remove);
       
   261             concealed.forEach(builder::contains);
       
   262 
       
   263             this.md = builder.build();
   288             this.md = builder.build();
   264         }
   289         }
   265 
   290 
   266         @Override
   291         @Override
   267         public ModuleDescriptor descriptor() {
   292         public ModuleDescriptor descriptor() {