Wed, 23 Jan 2013 13:27:24 -0800
8006775: JSR 308: Compiler changes in JDK8
Reviewed-by: jjg
Contributed-by: mernst@cs.washington.edu, wmdietl@cs.washington.edu, mpapi@csail.mit.edu, mahmood@notnoop.com
1 /*
2 * Copyright (c) 2012, 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 */
25 package com.sun.tools.jdeps;
27 import java.io.File;
28 import java.io.IOException;
29 import java.nio.file.FileVisitResult;
30 import java.nio.file.Files;
31 import java.nio.file.Path;
32 import java.nio.file.SimpleFileVisitor;
33 import java.nio.file.attribute.BasicFileAttributes;
34 import java.util.*;
36 /**
37 * ClassPath for Java SE and JDK
38 */
39 class PlatformClassPath {
40 /*
41 * Profiles for Java SE
42 *
43 * This is a temporary workaround until a common API is defined for langtools
44 * to determine which profile a given classname belongs to. The list of
45 * packages and profile names are hardcoded in jdk.properties and
46 * split packages are not supported.
47 */
48 static class Profile {
49 final String name;
50 final Set<String> packages;
52 Profile(String name) {
53 this.name = name;
54 this.packages = new HashSet<String>();
55 }
56 }
58 private final static String JAVAFX = "javafx";
59 private final static Map<String,Profile> map = getProfilePackages();
60 static String getProfileName(String packageName) {
61 Profile profile = map.get(packageName);
62 if (packageName.startsWith(JAVAFX + ".")) {
63 profile = map.get(JAVAFX);
64 }
65 return profile != null ? profile.name : "";
66 }
68 private final static List<Archive> javaHomeArchives = init();
69 static List<Archive> getArchives() {
70 return javaHomeArchives;
71 }
73 static boolean contains(Archive archive) {
74 return javaHomeArchives.contains(archive);
75 }
77 private static List<Archive> init() {
78 List<Archive> result = new ArrayList<Archive>();
79 String javaHome = System.getProperty("java.home");
80 List<File> files = new ArrayList<File>();
81 File jre = new File(javaHome, "jre");
82 File lib = new File(javaHome, "lib");
84 try {
85 if (jre.exists() && jre.isDirectory()) {
86 result.addAll(addJarFiles(new File(jre, "lib")));
87 result.addAll(addJarFiles(lib));
88 } else if (lib.exists() && lib.isDirectory()) {
89 // either a JRE or a jdk build image
90 File classes = new File(javaHome, "classes");
91 if (classes.exists() && classes.isDirectory()) {
92 // jdk build outputdir
93 result.add(new Archive(classes, ClassFileReader.newInstance(classes)));
94 }
95 // add other JAR files
96 result.addAll(addJarFiles(lib));
97 } else {
98 throw new RuntimeException("\"" + javaHome + "\" not a JDK home");
99 }
100 } catch (IOException e) {
101 throw new RuntimeException(e);
102 }
104 // add a JavaFX profile if there is jfxrt.jar
105 for (Archive archive : result) {
106 if (archive.getFileName().equals("jfxrt.jar")) {
107 map.put(JAVAFX, new Profile("jfxrt.jar"));
108 }
109 }
110 return result;
111 }
113 private static List<Archive> addJarFiles(File f) throws IOException {
114 final List<Archive> result = new ArrayList<Archive>();
115 final Path root = f.toPath();
116 final Path ext = root.resolve("ext");
117 Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
118 @Override
119 public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
120 throws IOException
121 {
122 if (dir.equals(root) || dir.equals(ext)) {
123 return FileVisitResult.CONTINUE;
124 } else {
125 // skip other cobundled JAR files
126 return FileVisitResult.SKIP_SUBTREE;
127 }
128 }
129 @Override
130 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
131 throws IOException
132 {
133 File f = file.toFile();
134 String fn = f.getName();
135 if (fn.endsWith(".jar") && !fn.equals("alt-rt.jar")) {
136 result.add(new Archive(f, ClassFileReader.newInstance(f)));
137 }
138 return FileVisitResult.CONTINUE;
139 }
140 });
141 return result;
142 }
144 private static Map<String,Profile> getProfilePackages() {
145 Map<String,Profile> map = new HashMap<String,Profile>();
147 // read the properties as a ResourceBundle as the build compiles
148 // the properties file into Java class. Another alternative is
149 // to load it as Properties and fix the build to exclude this file.
150 ResourceBundle profileBundle =
151 ResourceBundle.getBundle("com.sun.tools.jdeps.resources.jdk");
153 int i=1;
154 String key;
155 while (profileBundle.containsKey((key = "profile." + i + ".name"))) {
156 Profile profile = new Profile(profileBundle.getString(key));
157 String n = profileBundle.getString("profile." + i + ".packages");
158 String[] pkgs = n.split("\\s+");
159 for (String p : pkgs) {
160 if (p.isEmpty()) continue;
161 assert(map.containsKey(p) == false);
162 profile.packages.add(p);
163 map.put(p, profile);
164 }
165 i++;
166 }
167 return map;
168 }
169 }