test/tools/javap/classfile/deps/GetDeps.java

Thu, 25 Aug 2011 17:18:25 -0700

author
schien
date
Thu, 25 Aug 2011 17:18:25 -0700
changeset 1067
f497fac86cf9
parent 554
9d9f26857129
child 2525
2eb010b6cb22
permissions
-rw-r--r--

Added tag jdk8-b02 for changeset b3c059de2a61

     1 /*
     2  * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 import java.io.*;
    27 import java.util.*;
    28 import java.util.regex.Pattern;
    29 import javax.tools.*;
    31 import com.sun.tools.classfile.*;
    32 import com.sun.tools.classfile.Dependencies.*;
    33 import com.sun.tools.classfile.Dependency.Location;
    34 import com.sun.tools.javac.file.JavacFileManager;
    35 import com.sun.tools.javac.util.Context;
    37 /**
    38  * Demo utility for using the classfile dependency analysis API framework.
    39  *
    40  * Usage:
    41  *    getdeps [options] classes
    42  * where options include:
    43  *    -classpath path   where to find classes to analyze
    44  *    -p package-name   restrict analysis to classes in this package
    45  *                      (may be given multiple times)
    46  *    -r regex          restrict analysis to packages matching pattern
    47  *                      (-p and -r are exclusive)
    48  *    -rev              invert the dependencies in the output
    49  *    -t                transitive closure of dependencies
    50  */
    51 public class GetDeps {
    52     public static void main(String... args) throws Exception {
    53         new GetDeps().run(args);
    54     }
    56     void run(String... args) throws IOException, ClassFileNotFoundException {
    57         PrintWriter pw = new PrintWriter(System.out);
    58         try {
    59             run(pw, args);
    60         } finally {
    61             pw.flush();
    62         }
    63     }
    65     void run(PrintWriter out, String... args) throws IOException, ClassFileNotFoundException {
    66         decodeArgs(args);
    68         final StandardJavaFileManager fm = new JavacFileManager(new Context(), false, null);
    69         if (classpath != null)
    70             fm.setLocation(StandardLocation.CLASS_PATH, classpath);
    72         ClassFileReader reader = new ClassFileReader(fm);
    74         Dependencies d = new Dependencies();
    76         if (regex != null)
    77             d.setFilter(Dependencies.getRegexFilter(Pattern.compile(regex)));
    79         if (packageNames.size() > 0)
    80             d.setFilter(Dependencies.getPackageFilter(packageNames, false));
    82         SortedRecorder r = new SortedRecorder(reverse);
    84         d.findAllDependencies(reader, rootClassNames, transitiveClosure, r);
    86         SortedMap<Location,SortedSet<Dependency>> deps = r.getMap();
    87         for (Map.Entry<Location, SortedSet<Dependency>> e: deps.entrySet()) {
    88             out.println(e.getKey());
    89             for (Dependency dep: e.getValue()) {
    90                 out.println("    " + dep.getTarget());
    91             }
    92         }
    93     }
    95     void decodeArgs(String... args) {
    96         rootClassNames = new TreeSet<String>();
    97         packageNames = new TreeSet<String>();
    99         for (int i = 0; i < args.length; i++) {
   100             String arg = args[i];
   101             if (arg.equals("-classpath") && (i + 1 < args.length))
   102                 classpath = getPathFiles(args[++i]);
   103             else if (arg.equals("-p") && (i + 1 < args.length))
   104                 packageNames.add(args[++i]);
   105             else if (arg.equals("-r") && (i + 1 < args.length))
   106                 regex = args[++i];
   107             else if (arg.equals("-rev"))
   108                 reverse = true;
   109             else if (arg.equals("-t"))
   110                 transitiveClosure = true;
   111             else if (arg.startsWith("-"))
   112                 throw new Error(arg);
   113             else {
   114                 for ( ; i < args.length; i++)
   115                     rootClassNames.add(args[i]);
   116             }
   117         }
   118     }
   120     List<File> getPathFiles(String path) {
   121         List<File> files = new ArrayList<File>();
   122         for (String p: path.split(File.pathSeparator)) {
   123             if (p.length() > 0)
   124                 files.add(new File(p));
   125         }
   126         return files;
   127     }
   129     boolean transitiveClosure;
   130     List<File> classpath;
   131     Set<String> rootClassNames;
   132     Set<String> packageNames;
   133     String regex;
   134     boolean reverse;
   137     static class ClassFileReader implements Dependencies.ClassFileReader {
   138         private JavaFileManager fm;
   140         ClassFileReader(JavaFileManager fm) {
   141             this.fm = fm;
   142         }
   144         @Override
   145         public ClassFile getClassFile(String className) throws ClassFileNotFoundException {
   146             try {
   147                 JavaFileObject fo = fm.getJavaFileForInput(
   148                         StandardLocation.CLASS_PATH, className, JavaFileObject.Kind.CLASS);
   149                 if (fo == null)
   150                     fo = fm.getJavaFileForInput(
   151                         StandardLocation.PLATFORM_CLASS_PATH, className, JavaFileObject.Kind.CLASS);
   152                 if (fo == null)
   153                     throw new ClassFileNotFoundException(className);
   154                 InputStream in = fo.openInputStream();
   155                 try {
   156                     return ClassFile.read(in);
   157                 } finally {
   158                     in.close();
   159                 }
   160             } catch (ConstantPoolException e) {
   161                 throw new ClassFileNotFoundException(className, e);
   162             } catch (IOException e) {
   163                 throw new ClassFileNotFoundException(className, e);
   164             }
   165         }
   166     };
   168     static class SortedRecorder implements Recorder {
   169         public SortedRecorder(boolean reverse) {
   170             this.reverse = reverse;
   171         }
   173         public void addDependency(Dependency d) {
   174             Location o = (reverse ? d.getTarget() : d.getOrigin());
   175             SortedSet<Dependency> odeps = map.get(o);
   176             if (odeps == null) {
   177                 Comparator<Dependency> c = (reverse ? originComparator : targetComparator);
   178                 map.put(o, odeps = new TreeSet<Dependency>(c));
   179             }
   180             odeps.add(d);
   181         }
   183         public SortedMap<Location, SortedSet<Dependency>> getMap() {
   184             return map;
   185         }
   187         private Comparator<Dependency> originComparator = new Comparator<Dependency>() {
   188             public int compare(Dependency o1, Dependency o2) {
   189                 return o1.getOrigin().toString().compareTo(o2.getOrigin().toString());
   190             }
   191         };
   193         private Comparator<Dependency> targetComparator = new Comparator<Dependency>() {
   194             public int compare(Dependency o1, Dependency o2) {
   195                 return o1.getTarget().toString().compareTo(o2.getTarget().toString());
   196             }
   197         };
   199         private Comparator<Location> locationComparator = new Comparator<Location>() {
   200             public int compare(Location o1, Location o2) {
   201                 return o1.toString().compareTo(o2.toString());
   202             }
   203         };
   205         private final SortedMap<Location, SortedSet<Dependency>> map =
   206                 new TreeMap<Location, SortedSet<Dependency>>(locationComparator);
   208         boolean reverse;
   209     }
   211 }

mercurial