src/share/classes/com/sun/tools/jdeps/PlatformClassPath.java

Fri, 28 Dec 2012 22:25:21 -0800

author
mchung
date
Fri, 28 Dec 2012 22:25:21 -0800
changeset 1472
0c244701188e
child 1638
fd3fdaff0257
permissions
-rw-r--r--

8003562: Provide a CLI tool to analyze class dependencies
Reviewed-by: jjg, alanb, ulfzibis, erikj

mchung@1472 1 /*
mchung@1472 2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
mchung@1472 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
mchung@1472 4 *
mchung@1472 5 * This code is free software; you can redistribute it and/or modify it
mchung@1472 6 * under the terms of the GNU General Public License version 2 only, as
mchung@1472 7 * published by the Free Software Foundation. Oracle designates this
mchung@1472 8 * particular file as subject to the "Classpath" exception as provided
mchung@1472 9 * by Oracle in the LICENSE file that accompanied this code.
mchung@1472 10 *
mchung@1472 11 * This code is distributed in the hope that it will be useful, but WITHOUT
mchung@1472 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
mchung@1472 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
mchung@1472 14 * version 2 for more details (a copy is included in the LICENSE file that
mchung@1472 15 * accompanied this code).
mchung@1472 16 *
mchung@1472 17 * You should have received a copy of the GNU General Public License version
mchung@1472 18 * 2 along with this work; if not, write to the Free Software Foundation,
mchung@1472 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
mchung@1472 20 *
mchung@1472 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
mchung@1472 22 * or visit www.oracle.com if you need additional information or have any
mchung@1472 23 * questions.
mchung@1472 24 */
mchung@1472 25 package com.sun.tools.jdeps;
mchung@1472 26
mchung@1472 27 import java.io.File;
mchung@1472 28 import java.io.IOException;
mchung@1472 29 import java.nio.file.FileVisitResult;
mchung@1472 30 import java.nio.file.Files;
mchung@1472 31 import java.nio.file.Path;
mchung@1472 32 import java.nio.file.SimpleFileVisitor;
mchung@1472 33 import java.nio.file.attribute.BasicFileAttributes;
mchung@1472 34 import java.util.*;
mchung@1472 35
mchung@1472 36 /**
mchung@1472 37 * ClassPath for Java SE and JDK
mchung@1472 38 */
mchung@1472 39 class PlatformClassPath {
mchung@1472 40 /*
mchung@1472 41 * Profiles for Java SE
mchung@1472 42 *
mchung@1472 43 * This is a temporary workaround until a common API is defined for langtools
mchung@1472 44 * to determine which profile a given classname belongs to. The list of
mchung@1472 45 * packages and profile names are hardcoded in jdk.properties and
mchung@1472 46 * split packages are not supported.
mchung@1472 47 */
mchung@1472 48 static class Profile {
mchung@1472 49 final String name;
mchung@1472 50 final Set<String> packages;
mchung@1472 51
mchung@1472 52 Profile(String name) {
mchung@1472 53 this.name = name;
mchung@1472 54 this.packages = new HashSet<String>();
mchung@1472 55 }
mchung@1472 56 }
mchung@1472 57
mchung@1472 58 private final static String JAVAFX = "javafx";
mchung@1472 59 private final static Map<String,Profile> map = getProfilePackages();
mchung@1472 60 static String getProfileName(String packageName) {
mchung@1472 61 Profile profile = map.get(packageName);
mchung@1472 62 if (packageName.startsWith(JAVAFX + ".")) {
mchung@1472 63 profile = map.get(JAVAFX);
mchung@1472 64 }
mchung@1472 65 return profile != null ? profile.name : "";
mchung@1472 66 }
mchung@1472 67
mchung@1472 68 private final static List<Archive> javaHomeArchives = init();
mchung@1472 69 static List<Archive> getArchives() {
mchung@1472 70 return javaHomeArchives;
mchung@1472 71 }
mchung@1472 72
mchung@1472 73 static boolean contains(Archive archive) {
mchung@1472 74 return javaHomeArchives.contains(archive);
mchung@1472 75 }
mchung@1472 76
mchung@1472 77 private static List<Archive> init() {
mchung@1472 78 List<Archive> result = new ArrayList<Archive>();
mchung@1472 79 String javaHome = System.getProperty("java.home");
mchung@1472 80 List<File> files = new ArrayList<File>();
mchung@1472 81 File jre = new File(javaHome, "jre");
mchung@1472 82 File lib = new File(javaHome, "lib");
mchung@1472 83
mchung@1472 84 try {
mchung@1472 85 if (jre.exists() && jre.isDirectory()) {
mchung@1472 86 result.addAll(addJarFiles(new File(jre, "lib")));
mchung@1472 87 result.addAll(addJarFiles(lib));
mchung@1472 88 } else if (lib.exists() && lib.isDirectory()) {
mchung@1472 89 // either a JRE or a jdk build image
mchung@1472 90 File classes = new File(javaHome, "classes");
mchung@1472 91 if (classes.exists() && classes.isDirectory()) {
mchung@1472 92 // jdk build outputdir
mchung@1472 93 result.add(new Archive(classes, ClassFileReader.newInstance(classes)));
mchung@1472 94 }
mchung@1472 95 // add other JAR files
mchung@1472 96 result.addAll(addJarFiles(lib));
mchung@1472 97 } else {
mchung@1472 98 throw new RuntimeException("\"" + javaHome + "\" not a JDK home");
mchung@1472 99 }
mchung@1472 100 } catch (IOException e) {
mchung@1472 101 throw new RuntimeException(e);
mchung@1472 102 }
mchung@1472 103
mchung@1472 104 // add a JavaFX profile if there is jfxrt.jar
mchung@1472 105 for (Archive archive : result) {
mchung@1472 106 if (archive.getFileName().equals("jfxrt.jar")) {
mchung@1472 107 map.put(JAVAFX, new Profile("jfxrt.jar"));
mchung@1472 108 }
mchung@1472 109 }
mchung@1472 110 return result;
mchung@1472 111 }
mchung@1472 112
mchung@1472 113 private static List<Archive> addJarFiles(File f) throws IOException {
mchung@1472 114 final List<Archive> result = new ArrayList<Archive>();
mchung@1472 115 final Path root = f.toPath();
mchung@1472 116 final Path ext = root.resolve("ext");
mchung@1472 117 Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
mchung@1472 118 @Override
mchung@1472 119 public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
mchung@1472 120 throws IOException
mchung@1472 121 {
mchung@1472 122 if (dir.equals(root) || dir.equals(ext)) {
mchung@1472 123 return FileVisitResult.CONTINUE;
mchung@1472 124 } else {
mchung@1472 125 // skip other cobundled JAR files
mchung@1472 126 return FileVisitResult.SKIP_SUBTREE;
mchung@1472 127 }
mchung@1472 128 }
mchung@1472 129 @Override
mchung@1472 130 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
mchung@1472 131 throws IOException
mchung@1472 132 {
mchung@1472 133 File f = file.toFile();
mchung@1472 134 String fn = f.getName();
mchung@1472 135 if (fn.endsWith(".jar") && !fn.equals("alt-rt.jar")) {
mchung@1472 136 result.add(new Archive(f, ClassFileReader.newInstance(f)));
mchung@1472 137 }
mchung@1472 138 return FileVisitResult.CONTINUE;
mchung@1472 139 }
mchung@1472 140 });
mchung@1472 141 return result;
mchung@1472 142 }
mchung@1472 143
mchung@1472 144 private static Map<String,Profile> getProfilePackages() {
mchung@1472 145 Map<String,Profile> map = new HashMap<String,Profile>();
mchung@1472 146
mchung@1472 147 // read the properties as a ResourceBundle as the build compiles
mchung@1472 148 // the properties file into Java class. Another alternative is
mchung@1472 149 // to load it as Properties and fix the build to exclude this file.
mchung@1472 150 ResourceBundle profileBundle =
mchung@1472 151 ResourceBundle.getBundle("com.sun.tools.jdeps.resources.jdk");
mchung@1472 152
mchung@1472 153 int i=1;
mchung@1472 154 String key;
mchung@1472 155 while (profileBundle.containsKey((key = "profile." + i + ".name"))) {
mchung@1472 156 Profile profile = new Profile(profileBundle.getString(key));
mchung@1472 157 String n = profileBundle.getString("profile." + i + ".packages");
mchung@1472 158 String[] pkgs = n.split("\\s+");
mchung@1472 159 for (String p : pkgs) {
mchung@1472 160 if (p.isEmpty()) continue;
mchung@1472 161 assert(map.containsKey(p) == false);
mchung@1472 162 profile.packages.add(p);
mchung@1472 163 map.put(p, profile);
mchung@1472 164 }
mchung@1472 165 i++;
mchung@1472 166 }
mchung@1472 167 return map;
mchung@1472 168 }
mchung@1472 169 }

mercurial