src/jdk.jdeps/share/classes/com/sun/tools/jdeps/Analyzer.java
changeset 52650 c16b6cc93272
parent 47216 71c04702a3d5
equal deleted inserted replaced
52649:e00cf18e2593 52650:c16b6cc93272
    30 import java.io.BufferedReader;
    30 import java.io.BufferedReader;
    31 import java.io.IOException;
    31 import java.io.IOException;
    32 import java.io.InputStream;
    32 import java.io.InputStream;
    33 import java.io.InputStreamReader;
    33 import java.io.InputStreamReader;
    34 import java.io.UncheckedIOException;
    34 import java.io.UncheckedIOException;
       
    35 import java.lang.module.ModuleDescriptor;
    35 import java.util.Collections;
    36 import java.util.Collections;
    36 import java.util.Comparator;
    37 import java.util.Comparator;
    37 import java.util.HashMap;
    38 import java.util.HashMap;
    38 import java.util.HashSet;
    39 import java.util.HashSet;
    39 import java.util.Map;
    40 import java.util.Map;
    40 import java.util.Objects;
    41 import java.util.Objects;
    41 import java.util.Set;
    42 import java.util.Set;
       
    43 import java.util.function.Predicate;
    42 import java.util.stream.Collectors;
    44 import java.util.stream.Collectors;
    43 import java.util.stream.Stream;
    45 import java.util.stream.Stream;
    44 
    46 
    45 /**
    47 /**
    46  * Dependency Analyzer.
    48  * Dependency Analyzer.
    72     protected final Filter filter;
    74     protected final Filter filter;
    73     protected final Map<Archive, Dependences> results = new HashMap<>();
    75     protected final Map<Archive, Dependences> results = new HashMap<>();
    74     protected final Map<Location, Archive> locationToArchive = new HashMap<>();
    76     protected final Map<Location, Archive> locationToArchive = new HashMap<>();
    75     static final Archive NOT_FOUND
    77     static final Archive NOT_FOUND
    76         = new Archive(JdepsTask.getMessage("artifact.not.found"));
    78         = new Archive(JdepsTask.getMessage("artifact.not.found"));
       
    79     static final Predicate<Archive> ANY = a -> true;
    77 
    80 
    78     /**
    81     /**
    79      * Constructs an Analyzer instance.
    82      * Constructs an Analyzer instance.
    80      *
    83      *
    81      * @param type Type of the dependency analysis
    84      * @param type Type of the dependency analysis
   159 
   162 
   160     /**
   163     /**
   161      * Visit the dependencies of the given source.
   164      * Visit the dependencies of the given source.
   162      * If the requested level is SUMMARY, it will visit the required archives list.
   165      * If the requested level is SUMMARY, it will visit the required archives list.
   163      */
   166      */
   164     void visitDependences(Archive source, Visitor v, Type level) {
   167     void visitDependences(Archive source, Visitor v, Type level, Predicate<Archive> targetFilter) {
   165         if (level == Type.SUMMARY) {
   168         if (level == Type.SUMMARY) {
   166             final Dependences result = results.get(source);
   169             final Dependences result = results.get(source);
   167             final Set<Archive> reqs = result.requires();
   170             final Set<Archive> reqs = result.requires();
   168             Stream<Archive> stream = reqs.stream();
   171             Stream<Archive> stream = reqs.stream();
   169             if (reqs.isEmpty()) {
   172             if (reqs.isEmpty()) {
   182                   });
   185                   });
   183         } else {
   186         } else {
   184             Dependences result = results.get(source);
   187             Dependences result = results.get(source);
   185             if (level != type) {
   188             if (level != type) {
   186                 // requesting different level of analysis
   189                 // requesting different level of analysis
   187                 result = new Dependences(source, level);
   190                 result = new Dependences(source, level, targetFilter);
   188                 source.visitDependences(result);
   191                 source.visitDependences(result);
   189             }
   192             }
   190             result.dependencies().stream()
   193             result.dependencies().stream()
   191                   .sorted(Comparator.comparing(Dep::origin)
   194                   .sorted(Comparator.comparing(Dep::origin)
   192                                     .thenComparing(Dep::target))
   195                                     .thenComparing(Dep::target))
   194                                                   d.target(), d.targetArchive()));
   197                                                   d.target(), d.targetArchive()));
   195         }
   198         }
   196     }
   199     }
   197 
   200 
   198     void visitDependences(Archive source, Visitor v) {
   201     void visitDependences(Archive source, Visitor v) {
   199         visitDependences(source, v, type);
   202         visitDependences(source, v, type, ANY);
       
   203     }
       
   204 
       
   205     void visitDependences(Archive source, Visitor v, Type level) {
       
   206         visitDependences(source, v, level, ANY);
   200     }
   207     }
   201 
   208 
   202     /**
   209     /**
   203      * Dependences contains the dependencies for an Archive that can have one or
   210      * Dependences contains the dependencies for an Archive that can have one or
   204      * more classes.
   211      * more classes.
   206     class Dependences implements Archive.Visitor {
   213     class Dependences implements Archive.Visitor {
   207         protected final Archive archive;
   214         protected final Archive archive;
   208         protected final Set<Archive> requires;
   215         protected final Set<Archive> requires;
   209         protected final Set<Dep> deps;
   216         protected final Set<Dep> deps;
   210         protected final Type level;
   217         protected final Type level;
       
   218         protected final Predicate<Archive> targetFilter;
   211         private Profile profile;
   219         private Profile profile;
   212         Dependences(Archive archive, Type level) {
   220         Dependences(Archive archive, Type level) {
       
   221             this(archive, level, ANY);
       
   222         }
       
   223         Dependences(Archive archive, Type level, Predicate<Archive> targetFilter) {
   213             this.archive = archive;
   224             this.archive = archive;
   214             this.deps = new HashSet<>();
   225             this.deps = new HashSet<>();
   215             this.requires = new HashSet<>();
   226             this.requires = new HashSet<>();
   216             this.level = level;
   227             this.level = level;
       
   228             this.targetFilter = targetFilter;
   217         }
   229         }
   218 
   230 
   219         Set<Dep> dependencies() {
   231         Set<Dep> dependencies() {
   220             return deps;
   232             return deps;
   221         }
   233         }
   264         }
   276         }
   265 
   277 
   266         @Override
   278         @Override
   267         public void visit(Location o, Location t) {
   279         public void visit(Location o, Location t) {
   268             Archive targetArchive = findArchive(t);
   280             Archive targetArchive = findArchive(t);
   269             if (filter.accepts(o, archive, t, targetArchive)) {
   281             if (filter.accepts(o, archive, t, targetArchive) && targetFilter.test(targetArchive)) {
   270                 addDep(o, t);
   282                 addDep(o, t);
   271                 if (archive != targetArchive && !requires.contains(targetArchive)) {
   283                 if (archive != targetArchive && !requires.contains(targetArchive)) {
   272                     requires.add(targetArchive);
   284                     requires.add(targetArchive);
   273                 }
   285                 }
   274             }
   286             }
   366                     origin, originArchive.getName(),
   378                     origin, originArchive.getName(),
   367                     target, targetArchive.getName());
   379                     target, targetArchive.getName());
   368         }
   380         }
   369     }
   381     }
   370 
   382 
       
   383     /*
       
   384      * Returns true if the given archive represents not found.
       
   385      */
       
   386     static boolean notFound(Archive archive) {
       
   387         return archive == NOT_FOUND || archive == REMOVED_JDK_INTERNALS;
       
   388     }
       
   389 
   371     static final Jdk8Internals REMOVED_JDK_INTERNALS = new Jdk8Internals();
   390     static final Jdk8Internals REMOVED_JDK_INTERNALS = new Jdk8Internals();
   372 
   391 
   373     static class Jdk8Internals extends Module {
   392     static class Jdk8Internals extends Module {
   374         private final String JDK8_INTERNALS = "/com/sun/tools/jdeps/resources/jdk8_internals.txt";
   393         private static final String NAME = "JDK removed internal API";
       
   394         private static final String JDK8_INTERNALS = "/com/sun/tools/jdeps/resources/jdk8_internals.txt";
   375         private final Set<String> jdk8Internals;
   395         private final Set<String> jdk8Internals;
   376         private Jdk8Internals() {
   396         private Jdk8Internals() {
   377             super("JDK removed internal API");
   397             super(NAME, ModuleDescriptor.newModule("jdk8internals").build(), true);
   378             try (InputStream in = JdepsTask.class.getResourceAsStream(JDK8_INTERNALS);
   398             try (InputStream in = JdepsTask.class.getResourceAsStream(JDK8_INTERNALS);
   379                  BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
   399                  BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
   380                 this.jdk8Internals = reader.lines()
   400                 this.jdk8Internals = reader.lines()
   381                                           .filter(ln -> !ln.startsWith("#"))
   401                                           .filter(ln -> !ln.startsWith("#"))
   382                                           .collect(Collectors.toSet());
   402                                           .collect(Collectors.toSet());
   392 
   412 
   393             return jdk8Internals.contains(pn);
   413             return jdk8Internals.contains(pn);
   394         }
   414         }
   395 
   415 
   396         @Override
   416         @Override
   397         public String name() {
       
   398             return getName();
       
   399         }
       
   400 
       
   401         @Override
       
   402         public boolean isJDK() {
   417         public boolean isJDK() {
   403             return true;
   418             return true;
   404         }
   419         }
   405 
   420 
   406         @Override
   421         @Override