mchung@1472: /* mchung@1472: * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. mchung@1472: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. mchung@1472: * mchung@1472: * This code is free software; you can redistribute it and/or modify it mchung@1472: * under the terms of the GNU General Public License version 2 only, as mchung@1472: * published by the Free Software Foundation. Oracle designates this mchung@1472: * particular file as subject to the "Classpath" exception as provided mchung@1472: * by Oracle in the LICENSE file that accompanied this code. mchung@1472: * mchung@1472: * This code is distributed in the hope that it will be useful, but WITHOUT mchung@1472: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or mchung@1472: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License mchung@1472: * version 2 for more details (a copy is included in the LICENSE file that mchung@1472: * accompanied this code). mchung@1472: * mchung@1472: * You should have received a copy of the GNU General Public License version mchung@1472: * 2 along with this work; if not, write to the Free Software Foundation, mchung@1472: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. mchung@1472: * mchung@1472: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA mchung@1472: * or visit www.oracle.com if you need additional information or have any mchung@1472: * questions. mchung@1472: */ mchung@1472: package com.sun.tools.jdeps; mchung@1472: mchung@1472: import java.io.File; mchung@1472: import java.io.IOException; mchung@1472: import java.nio.file.FileVisitResult; mchung@1472: import java.nio.file.Files; mchung@1472: import java.nio.file.Path; mchung@1472: import java.nio.file.SimpleFileVisitor; mchung@1472: import java.nio.file.attribute.BasicFileAttributes; mchung@1472: import java.util.*; mchung@1472: mchung@1472: /** mchung@1472: * ClassPath for Java SE and JDK mchung@1472: */ mchung@1472: class PlatformClassPath { mchung@1472: /* mchung@1472: * Profiles for Java SE mchung@1472: * mchung@1472: * This is a temporary workaround until a common API is defined for langtools mchung@1472: * to determine which profile a given classname belongs to. The list of mchung@1472: * packages and profile names are hardcoded in jdk.properties and mchung@1472: * split packages are not supported. mchung@1472: */ mchung@1472: static class Profile { mchung@1472: final String name; mchung@1472: final Set packages; mchung@1472: mchung@1472: Profile(String name) { mchung@1472: this.name = name; mchung@1472: this.packages = new HashSet(); mchung@1472: } mchung@1472: } mchung@1472: mchung@1472: private final static String JAVAFX = "javafx"; mchung@1472: private final static Map map = getProfilePackages(); mchung@1472: static String getProfileName(String packageName) { mchung@1472: Profile profile = map.get(packageName); mchung@1472: if (packageName.startsWith(JAVAFX + ".")) { mchung@1472: profile = map.get(JAVAFX); mchung@1472: } mchung@1472: return profile != null ? profile.name : ""; mchung@1472: } mchung@1472: mchung@1472: private final static List javaHomeArchives = init(); mchung@1472: static List getArchives() { mchung@1472: return javaHomeArchives; mchung@1472: } mchung@1472: mchung@1472: static boolean contains(Archive archive) { mchung@1472: return javaHomeArchives.contains(archive); mchung@1472: } mchung@1472: mchung@1472: private static List init() { mchung@1472: List result = new ArrayList(); mchung@1472: String javaHome = System.getProperty("java.home"); mchung@1472: List files = new ArrayList(); mchung@1472: File jre = new File(javaHome, "jre"); mchung@1472: File lib = new File(javaHome, "lib"); mchung@1472: mchung@1472: try { mchung@1472: if (jre.exists() && jre.isDirectory()) { mchung@1472: result.addAll(addJarFiles(new File(jre, "lib"))); mchung@1472: result.addAll(addJarFiles(lib)); mchung@1472: } else if (lib.exists() && lib.isDirectory()) { mchung@1472: // either a JRE or a jdk build image mchung@1472: File classes = new File(javaHome, "classes"); mchung@1472: if (classes.exists() && classes.isDirectory()) { mchung@1472: // jdk build outputdir mchung@1472: result.add(new Archive(classes, ClassFileReader.newInstance(classes))); mchung@1472: } mchung@1472: // add other JAR files mchung@1472: result.addAll(addJarFiles(lib)); mchung@1472: } else { mchung@1472: throw new RuntimeException("\"" + javaHome + "\" not a JDK home"); mchung@1472: } mchung@1472: } catch (IOException e) { mchung@1472: throw new RuntimeException(e); mchung@1472: } mchung@1472: mchung@1472: // add a JavaFX profile if there is jfxrt.jar mchung@1472: for (Archive archive : result) { mchung@1472: if (archive.getFileName().equals("jfxrt.jar")) { mchung@1472: map.put(JAVAFX, new Profile("jfxrt.jar")); mchung@1472: } mchung@1472: } mchung@1472: return result; mchung@1472: } mchung@1472: mchung@1472: private static List addJarFiles(File f) throws IOException { mchung@1472: final List result = new ArrayList(); mchung@1472: final Path root = f.toPath(); mchung@1472: final Path ext = root.resolve("ext"); mchung@1472: Files.walkFileTree(root, new SimpleFileVisitor() { mchung@1472: @Override mchung@1472: public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) mchung@1472: throws IOException mchung@1472: { mchung@1472: if (dir.equals(root) || dir.equals(ext)) { mchung@1472: return FileVisitResult.CONTINUE; mchung@1472: } else { mchung@1472: // skip other cobundled JAR files mchung@1472: return FileVisitResult.SKIP_SUBTREE; mchung@1472: } mchung@1472: } mchung@1472: @Override mchung@1472: public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) mchung@1472: throws IOException mchung@1472: { mchung@1472: File f = file.toFile(); mchung@1472: String fn = f.getName(); mchung@1472: if (fn.endsWith(".jar") && !fn.equals("alt-rt.jar")) { mchung@1472: result.add(new Archive(f, ClassFileReader.newInstance(f))); mchung@1472: } mchung@1472: return FileVisitResult.CONTINUE; mchung@1472: } mchung@1472: }); mchung@1472: return result; mchung@1472: } mchung@1472: mchung@1472: private static Map getProfilePackages() { mchung@1472: Map map = new HashMap(); mchung@1472: mchung@1472: // read the properties as a ResourceBundle as the build compiles mchung@1472: // the properties file into Java class. Another alternative is mchung@1472: // to load it as Properties and fix the build to exclude this file. mchung@1472: ResourceBundle profileBundle = mchung@1472: ResourceBundle.getBundle("com.sun.tools.jdeps.resources.jdk"); mchung@1472: mchung@1472: int i=1; mchung@1472: String key; mchung@1472: while (profileBundle.containsKey((key = "profile." + i + ".name"))) { mchung@1472: Profile profile = new Profile(profileBundle.getString(key)); mchung@1472: String n = profileBundle.getString("profile." + i + ".packages"); mchung@1472: String[] pkgs = n.split("\\s+"); mchung@1472: for (String p : pkgs) { mchung@1472: if (p.isEmpty()) continue; mchung@1472: assert(map.containsKey(p) == false); mchung@1472: profile.packages.add(p); mchung@1472: map.put(p, profile); mchung@1472: } mchung@1472: i++; mchung@1472: } mchung@1472: return map; mchung@1472: } mchung@1472: }