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

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

mercurial