Sat, 19 Dec 2009 10:26:47 -0800
Merge
src/share/classes/com/sun/tools/javac/file/CloseableURLClassLoader.java | file | annotate | diff | comparison | revisions |
1.1 --- a/make/build.properties Thu Dec 17 14:10:44 2009 -0800 1.2 +++ b/make/build.properties Sat Dec 19 10:26:47 2009 -0800 1.3 @@ -149,11 +149,26 @@ 1.4 # 1.5 1.6 # The following files require the import JDK to be available 1.7 -require.import.jdk.files = 1.8 +require.import.jdk.files = \ 1.9 + com/sun/tools/javac/nio/*.java 1.10 1.11 # The following files in the import jdk source directory are required 1.12 # in order to compile the files defined in ${require.import.jdk.files} 1.13 -import.jdk.stub.files = 1.14 +# 1.15 +# For NIO, the list of stub files is defined by the contents of the primary 1.16 +# API packages, together with such types that may be required in order to 1.17 +# compile the stubs. Some of these dependencies would go away if the stub 1.18 +# generator were to be improved -- e.g. by removing unnecessary imports. 1.19 +# 1.20 +import.jdk.stub.files = \ 1.21 + java/io/File.java \ 1.22 + java/nio/file/**.java \ 1.23 + java/nio/file/attribute/**.java \ 1.24 + java/nio/file/spi/**.java \ 1.25 + java/nio/channels/AsynchronousChannel.java \ 1.26 + java/nio/channels/AsynchronousFileChannel.java \ 1.27 + java/nio/channels/CompletionHandler.java \ 1.28 + java/nio/channels/SeekableByteChannel.java 1.29 1.30 # The following value is used by the main jtreg target. 1.31 # An empty value means all tests
2.1 --- a/make/build.xml Thu Dec 17 14:10:44 2009 -0800 2.2 +++ b/make/build.xml Sat Dec 19 10:26:47 2009 -0800 2.3 @@ -98,7 +98,7 @@ 2.4 import.jdk should be unset, or set to jdk home (to use rt.jar) 2.5 or to jdk repo (to use src/share/classes). 2.6 Based on the value, if any, set up default values for javac's sourcepath, 2.7 - classpath and bootclasspath. Note: the default values are overridden 2.8 + classpath and bootclasspath. Note: the default values are overridden 2.9 in the build-bootstrap-classes macro. --> 2.10 2.11 <available property="import.jdk.src.dir" value="${import.jdk}/src/share/classes" 2.12 @@ -552,8 +552,8 @@ 2.13 <compilerarg line="${javac.version.opt}"/> 2.14 <compilerarg line="${javac.lint.opts}"/> 2.15 </javac> 2.16 - <copy todir="@{classes.dir}"> 2.17 - <fileset dir="${src.classes.dir}" includes="@{includes}"> 2.18 + <copy todir="@{classes.dir}" includeemptydirs="false"> 2.19 + <fileset dir="${src.classes.dir}" includes="@{includes}" excludes="@{excludes}"> 2.20 <exclude name="**/*.java"/> 2.21 <exclude name="**/*.properties"/> 2.22 <exclude name="**/*-template"/>
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/share/classes/com/sun/tools/classfile/Dependencies.java Sat Dec 19 10:26:47 2009 -0800 3.3 @@ -0,0 +1,718 @@ 3.4 +/* 3.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.7 + * 3.8 + * This code is free software; you can redistribute it and/or modify it 3.9 + * under the terms of the GNU General Public License version 2 only, as 3.10 + * published by the Free Software Foundation. Sun designates this 3.11 + * particular file as subject to the "Classpath" exception as provided 3.12 + * by Sun in the LICENSE file that accompanied this code. 3.13 + * 3.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 3.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 3.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 3.17 + * version 2 for more details (a copy is included in the LICENSE file that 3.18 + * accompanied this code). 3.19 + * 3.20 + * You should have received a copy of the GNU General Public License version 3.21 + * 2 along with this work; if not, write to the Free Software Foundation, 3.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 3.23 + * 3.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 3.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 3.26 + * have any questions. 3.27 + */ 3.28 +package com.sun.tools.classfile; 3.29 + 3.30 +import java.util.Deque; 3.31 +import java.util.HashMap; 3.32 +import java.util.HashSet; 3.33 +import java.util.LinkedList; 3.34 +import java.util.List; 3.35 +import java.util.Map; 3.36 +import java.util.Set; 3.37 +import java.util.regex.Pattern; 3.38 + 3.39 +import com.sun.tools.classfile.Dependency.Finder; 3.40 +import com.sun.tools.classfile.Dependency.Filter; 3.41 +import com.sun.tools.classfile.Dependency.Location; 3.42 +import com.sun.tools.classfile.Type.ArrayType; 3.43 +import com.sun.tools.classfile.Type.ClassSigType; 3.44 +import com.sun.tools.classfile.Type.ClassType; 3.45 +import com.sun.tools.classfile.Type.MethodType; 3.46 +import com.sun.tools.classfile.Type.SimpleType; 3.47 +import com.sun.tools.classfile.Type.TypeParamType; 3.48 +import com.sun.tools.classfile.Type.WildcardType; 3.49 + 3.50 +import static com.sun.tools.classfile.ConstantPool.*; 3.51 + 3.52 +/** 3.53 + * A framework for determining {@link Dependency dependencies} between class files. 3.54 + * 3.55 + * A {@link Dependency.Finder finder} is used to identify the dependencies of 3.56 + * individual classes. Some finders may return subtypes of {@code Dependency} to 3.57 + * further characterize the type of dependency, such as a dependency on a 3.58 + * method within a class. 3.59 + * 3.60 + * A {@link Dependency.Filter filter} may be used to restrict the set of 3.61 + * dependencies found by a finder. 3.62 + * 3.63 + * Dependencies that are found may be passed to a {@link Dependencies.Recorder 3.64 + * recorder} so that the dependencies can be stored in a custom data structure. 3.65 + */ 3.66 +public class Dependencies { 3.67 + /** 3.68 + * Thrown when a class file cannot be found. 3.69 + */ 3.70 + public static class ClassFileNotFoundException extends Exception { 3.71 + private static final long serialVersionUID = 3632265927794475048L; 3.72 + 3.73 + public ClassFileNotFoundException(String className) { 3.74 + super(className); 3.75 + this.className = className; 3.76 + } 3.77 + 3.78 + public ClassFileNotFoundException(String className, Throwable cause) { 3.79 + this(className); 3.80 + initCause(cause); 3.81 + } 3.82 + 3.83 + public final String className; 3.84 + } 3.85 + 3.86 + /** 3.87 + * Thrown when an exception is found processing a class file. 3.88 + */ 3.89 + public static class ClassFileError extends Error { 3.90 + private static final long serialVersionUID = 4111110813961313203L; 3.91 + 3.92 + public ClassFileError(Throwable cause) { 3.93 + initCause(cause); 3.94 + } 3.95 + } 3.96 + 3.97 + /** 3.98 + * Service provider interface to locate and read class files. 3.99 + */ 3.100 + public interface ClassFileReader { 3.101 + /** 3.102 + * Get the ClassFile object for a specified class. 3.103 + * @param className the name of the class to be returned. 3.104 + * @return the ClassFile for the given class 3.105 + * @throws Dependencies#ClassFileNotFoundException if the classfile cannot be 3.106 + * found 3.107 + */ 3.108 + public ClassFile getClassFile(String className) 3.109 + throws ClassFileNotFoundException; 3.110 + } 3.111 + 3.112 + /** 3.113 + * Service provide interface to handle results. 3.114 + */ 3.115 + public interface Recorder { 3.116 + /** 3.117 + * Record a dependency that has been found. 3.118 + * @param d 3.119 + */ 3.120 + public void addDependency(Dependency d); 3.121 + } 3.122 + 3.123 + /** 3.124 + * Get the default finder used to locate the dependencies for a class. 3.125 + * @return the default finder 3.126 + */ 3.127 + public static Finder getDefaultFinder() { 3.128 + return new APIDependencyFinder(AccessFlags.ACC_PRIVATE); 3.129 + } 3.130 + 3.131 + /** 3.132 + * Get a finder used to locate the API dependencies for a class. 3.133 + * These include the superclass, superinterfaces, and classes referenced in 3.134 + * the declarations of fields and methods. The fields and methods that 3.135 + * are checked can be limited according to a specified access. 3.136 + * The access parameter must be one of {@link AccessFlags#ACC_PUBLIC ACC_PUBLIC}, 3.137 + * {@link AccessFlags#ACC_PRIVATE ACC_PRIVATE}, 3.138 + * {@link AccessFlags#ACC_PROTECTED ACC_PROTECTED}, or 0 for 3.139 + * package private access. Members with greater than or equal accessibility 3.140 + * to that specified will be searched for dependencies. 3.141 + * @param access the access of members to be checked 3.142 + * @return an API finder 3.143 + */ 3.144 + public static Finder getAPIFinder(int access) { 3.145 + return new APIDependencyFinder(access); 3.146 + } 3.147 + 3.148 + /** 3.149 + * Get the finder used to locate the dependencies for a class. 3.150 + * @return the finder 3.151 + */ 3.152 + public Finder getFinder() { 3.153 + if (finder == null) 3.154 + finder = getDefaultFinder(); 3.155 + return finder; 3.156 + } 3.157 + 3.158 + /** 3.159 + * Set the finder used to locate the dependencies for a class. 3.160 + * @param f the finder 3.161 + */ 3.162 + public void setFinder(Finder f) { 3.163 + f.getClass(); // null check 3.164 + finder = f; 3.165 + } 3.166 + 3.167 + /** 3.168 + * Get the default filter used to determine included when searching 3.169 + * the transitive closure of all the dependencies. 3.170 + * Unless overridden, the default filter accepts all dependencies. 3.171 + * @return the default filter. 3.172 + */ 3.173 + public static Filter getDefaultFilter() { 3.174 + return DefaultFilter.instance(); 3.175 + } 3.176 + 3.177 + /** 3.178 + * Get a filter which uses a regular expression on the target's class name 3.179 + * to determine if a dependency is of interest. 3.180 + * @param pattern the pattern used to match the target's class name 3.181 + * @return a filter for matching the target class name with a regular expression 3.182 + */ 3.183 + public static Filter getRegexFilter(Pattern pattern) { 3.184 + return new TargetRegexFilter(pattern); 3.185 + } 3.186 + 3.187 + /** 3.188 + * Get a filter which checks the package of a target's class name 3.189 + * to determine if a dependency is of interest. The filter checks if the 3.190 + * package of the target's class matches any of a set of given package 3.191 + * names. The match may optionally match subpackages of the given names as well. 3.192 + * @param packageNames the package names used to match the target's class name 3.193 + * @param matchSubpackages whether or not to match subpackages as well 3.194 + * @return a filter for checking the target package name against a list of package names 3.195 + */ 3.196 + public static Filter getPackageFilter(Set<String> packageNames, boolean matchSubpackages) { 3.197 + return new TargetPackageFilter(packageNames, matchSubpackages); 3.198 + } 3.199 + 3.200 + /** 3.201 + * Get the filter used to determine the dependencies included when searching 3.202 + * the transitive closure of all the dependencies. 3.203 + * Unless overridden, the default filter accepts all dependencies. 3.204 + * @return the filter 3.205 + */ 3.206 + public Filter getFilter() { 3.207 + if (filter == null) 3.208 + filter = getDefaultFilter(); 3.209 + return filter; 3.210 + } 3.211 + 3.212 + /** 3.213 + * Set the filter used to determine the dependencies included when searching 3.214 + * the transitive closure of all the dependencies. 3.215 + * @param f the filter 3.216 + */ 3.217 + public void setFilter(Filter f) { 3.218 + f.getClass(); // null check 3.219 + filter = f; 3.220 + } 3.221 + 3.222 + /** 3.223 + * Find the dependencies of a class, using the current 3.224 + * {@link Dependencies#getFinder finder} and 3.225 + * {@link Dependencies#getFilter filter}. 3.226 + * The search may optionally include the transitive closure of all the 3.227 + * filtered dependencies, by also searching in the classes named in those 3.228 + * dependencies. 3.229 + * @param classFinder a finder to locate class files 3.230 + * @param rootClassNames the names of the root classes from which to begin 3.231 + * searching 3.232 + * @param transitiveClosure whether or not to also search those classes 3.233 + * named in any filtered dependencies that are found. 3.234 + * @return the set of dependencies that were found 3.235 + * @throws ClassFileNotFoundException if a required class file cannot be found 3.236 + * @throws ClassFileError if an error occurs while processing a class file, 3.237 + * such as an error in the internal class file structure. 3.238 + */ 3.239 + public Set<Dependency> findAllDependencies( 3.240 + ClassFileReader classFinder, Set<String> rootClassNames, 3.241 + boolean transitiveClosure) 3.242 + throws ClassFileNotFoundException { 3.243 + final Set<Dependency> results = new HashSet<Dependency>(); 3.244 + Recorder r = new Recorder() { 3.245 + public void addDependency(Dependency d) { 3.246 + results.add(d); 3.247 + } 3.248 + }; 3.249 + findAllDependencies(classFinder, rootClassNames, transitiveClosure, r); 3.250 + return results; 3.251 + } 3.252 + 3.253 + 3.254 + 3.255 + /** 3.256 + * Find the dependencies of a class, using the current 3.257 + * {@link Dependencies#getFinder finder} and 3.258 + * {@link Dependencies#getFilter filter}. 3.259 + * The search may optionally include the transitive closure of all the 3.260 + * filtered dependencies, by also searching in the classes named in those 3.261 + * dependencies. 3.262 + * @param classFinder a finder to locate class files 3.263 + * @param rootClassNames the names of the root classes from which to begin 3.264 + * searching 3.265 + * @param transitiveClosure whether or not to also search those classes 3.266 + * named in any filtered dependencies that are found. 3.267 + * @param recorder a recorder for handling the results 3.268 + * @throws ClassFileNotFoundException if a required class file cannot be found 3.269 + * @throws ClassFileError if an error occurs while processing a class file, 3.270 + * such as an error in the internal class file structure. 3.271 + */ 3.272 + public void findAllDependencies( 3.273 + ClassFileReader classFinder, Set<String> rootClassNames, 3.274 + boolean transitiveClosure, Recorder recorder) 3.275 + throws ClassFileNotFoundException { 3.276 + Set<String> doneClasses = new HashSet<String>(); 3.277 + 3.278 + getFinder(); // ensure initialized 3.279 + getFilter(); // ensure initialized 3.280 + 3.281 + // Work queue of names of classfiles to be searched. 3.282 + // Entries will be unique, and for classes that do not yet have 3.283 + // dependencies in the results map. 3.284 + Deque<String> deque = new LinkedList<String>(rootClassNames); 3.285 + 3.286 + String className; 3.287 + while ((className = deque.poll()) != null) { 3.288 + assert (!doneClasses.contains(className)); 3.289 + doneClasses.add(className); 3.290 + 3.291 + ClassFile cf = classFinder.getClassFile(className); 3.292 + 3.293 + // The following code just applies the filter to the dependencies 3.294 + // followed for the transitive closure. 3.295 + for (Dependency d: finder.findDependencies(cf)) { 3.296 + recorder.addDependency(d); 3.297 + if (transitiveClosure && filter.accepts(d)) { 3.298 + String cn = d.getTarget().getClassName(); 3.299 + if (!doneClasses.contains(cn)) 3.300 + deque.add(cn); 3.301 + } 3.302 + } 3.303 + } 3.304 + } 3.305 + 3.306 + private Filter filter; 3.307 + private Finder finder; 3.308 + 3.309 + /** 3.310 + * A location identifying a class. 3.311 + */ 3.312 + static class SimpleLocation implements Location { 3.313 + public SimpleLocation(String className) { 3.314 + this.className = className; 3.315 + } 3.316 + 3.317 + /** 3.318 + * Get the name of the class being depended on. This name will be used to 3.319 + * locate the class file for transitive dependency analysis. 3.320 + * @return the name of the class being depended on 3.321 + */ 3.322 + public String getClassName() { 3.323 + return className; 3.324 + } 3.325 + 3.326 + @Override 3.327 + public boolean equals(Object other) { 3.328 + if (this == other) 3.329 + return true; 3.330 + if (!(other instanceof SimpleLocation)) 3.331 + return false; 3.332 + return (className.equals(((SimpleLocation) other).className)); 3.333 + } 3.334 + 3.335 + @Override 3.336 + public int hashCode() { 3.337 + return className.hashCode(); 3.338 + } 3.339 + 3.340 + @Override 3.341 + public String toString() { 3.342 + return className; 3.343 + } 3.344 + 3.345 + private String className; 3.346 + } 3.347 + 3.348 + /** 3.349 + * A dependency of one class on another. 3.350 + */ 3.351 + static class SimpleDependency implements Dependency { 3.352 + public SimpleDependency(Location origin, Location target) { 3.353 + this.origin = origin; 3.354 + this.target = target; 3.355 + } 3.356 + 3.357 + public Location getOrigin() { 3.358 + return origin; 3.359 + } 3.360 + 3.361 + public Location getTarget() { 3.362 + return target; 3.363 + } 3.364 + 3.365 + @Override 3.366 + public boolean equals(Object other) { 3.367 + if (this == other) 3.368 + return true; 3.369 + if (!(other instanceof SimpleDependency)) 3.370 + return false; 3.371 + SimpleDependency o = (SimpleDependency) other; 3.372 + return (origin.equals(o.origin) && target.equals(o.target)); 3.373 + } 3.374 + 3.375 + @Override 3.376 + public int hashCode() { 3.377 + return origin.hashCode() * 31 + target.hashCode(); 3.378 + } 3.379 + 3.380 + @Override 3.381 + public String toString() { 3.382 + return origin + ":" + target; 3.383 + } 3.384 + 3.385 + private Location origin; 3.386 + private Location target; 3.387 + } 3.388 + 3.389 + 3.390 + /** 3.391 + * This class accepts all dependencies. 3.392 + */ 3.393 + static class DefaultFilter implements Filter { 3.394 + private static DefaultFilter instance; 3.395 + 3.396 + static DefaultFilter instance() { 3.397 + if (instance == null) 3.398 + instance = new DefaultFilter(); 3.399 + return instance; 3.400 + } 3.401 + 3.402 + public boolean accepts(Dependency dependency) { 3.403 + return true; 3.404 + } 3.405 + } 3.406 + 3.407 + /** 3.408 + * This class accepts those dependencies whose target's class name matches a 3.409 + * regular expression. 3.410 + */ 3.411 + static class TargetRegexFilter implements Filter { 3.412 + TargetRegexFilter(Pattern pattern) { 3.413 + this.pattern = pattern; 3.414 + } 3.415 + 3.416 + public boolean accepts(Dependency dependency) { 3.417 + return pattern.matcher(dependency.getTarget().getClassName()).matches(); 3.418 + } 3.419 + 3.420 + private final Pattern pattern; 3.421 + } 3.422 + 3.423 + /** 3.424 + * This class accepts those dependencies whose class name is in a given 3.425 + * package. 3.426 + */ 3.427 + static class TargetPackageFilter implements Filter { 3.428 + TargetPackageFilter(Set<String> packageNames, boolean matchSubpackages) { 3.429 + for (String pn: packageNames) { 3.430 + if (pn.length() == 0) // implies null check as well 3.431 + throw new IllegalArgumentException(); 3.432 + } 3.433 + this.packageNames = packageNames; 3.434 + this.matchSubpackages = matchSubpackages; 3.435 + } 3.436 + 3.437 + public boolean accepts(Dependency dependency) { 3.438 + String cn = dependency.getTarget().getClassName(); 3.439 + int lastSep = cn.lastIndexOf("/"); 3.440 + String pn = (lastSep == -1 ? "" : cn.substring(0, lastSep)); 3.441 + if (packageNames.contains(pn)) 3.442 + return true; 3.443 + 3.444 + if (matchSubpackages) { 3.445 + for (String n: packageNames) { 3.446 + if (pn.startsWith(n + ".")) 3.447 + return true; 3.448 + } 3.449 + } 3.450 + 3.451 + return false; 3.452 + } 3.453 + 3.454 + private final Set<String> packageNames; 3.455 + private final boolean matchSubpackages; 3.456 + } 3.457 + 3.458 + 3.459 + 3.460 + /** 3.461 + * This class identifies class names directly or indirectly in the constant pool. 3.462 + */ 3.463 + static class ClassDependencyFinder extends BasicDependencyFinder { 3.464 + public Iterable<? extends Dependency> findDependencies(ClassFile classfile) { 3.465 + Visitor v = new Visitor(classfile); 3.466 + for (CPInfo cpInfo: classfile.constant_pool.entries()) { 3.467 + v.scan(cpInfo); 3.468 + } 3.469 + return v.deps; 3.470 + } 3.471 + } 3.472 + 3.473 + /** 3.474 + * This class identifies class names in the signatures of classes, fields, 3.475 + * and methods in a class. 3.476 + */ 3.477 + static class APIDependencyFinder extends BasicDependencyFinder { 3.478 + APIDependencyFinder(int access) { 3.479 + switch (access) { 3.480 + case AccessFlags.ACC_PUBLIC: 3.481 + case AccessFlags.ACC_PROTECTED: 3.482 + case AccessFlags.ACC_PRIVATE: 3.483 + case 0: 3.484 + showAccess = access; 3.485 + break; 3.486 + default: 3.487 + throw new IllegalArgumentException("invalid access 0x" 3.488 + + Integer.toHexString(access)); 3.489 + } 3.490 + } 3.491 + 3.492 + public Iterable<? extends Dependency> findDependencies(ClassFile classfile) { 3.493 + try { 3.494 + Visitor v = new Visitor(classfile); 3.495 + v.addClass(classfile.super_class); 3.496 + v.addClasses(classfile.interfaces); 3.497 + // inner classes? 3.498 + for (Field f : classfile.fields) { 3.499 + if (checkAccess(f.access_flags)) 3.500 + v.scan(f.descriptor, f.attributes); 3.501 + } 3.502 + for (Method m : classfile.methods) { 3.503 + if (checkAccess(m.access_flags)) { 3.504 + v.scan(m.descriptor, m.attributes); 3.505 + Exceptions_attribute e = 3.506 + (Exceptions_attribute) m.attributes.get(Attribute.Exceptions); 3.507 + if (e != null) 3.508 + v.addClasses(e.exception_index_table); 3.509 + } 3.510 + } 3.511 + return v.deps; 3.512 + } catch (ConstantPoolException e) { 3.513 + throw new ClassFileError(e); 3.514 + } 3.515 + } 3.516 + 3.517 + boolean checkAccess(AccessFlags flags) { 3.518 + // code copied from javap.Options.checkAccess 3.519 + boolean isPublic = flags.is(AccessFlags.ACC_PUBLIC); 3.520 + boolean isProtected = flags.is(AccessFlags.ACC_PROTECTED); 3.521 + boolean isPrivate = flags.is(AccessFlags.ACC_PRIVATE); 3.522 + boolean isPackage = !(isPublic || isProtected || isPrivate); 3.523 + 3.524 + if ((showAccess == AccessFlags.ACC_PUBLIC) && (isProtected || isPrivate || isPackage)) 3.525 + return false; 3.526 + else if ((showAccess == AccessFlags.ACC_PROTECTED) && (isPrivate || isPackage)) 3.527 + return false; 3.528 + else if ((showAccess == 0) && (isPrivate)) 3.529 + return false; 3.530 + else 3.531 + return true; 3.532 + } 3.533 + 3.534 + private int showAccess; 3.535 + } 3.536 + 3.537 + static abstract class BasicDependencyFinder implements Finder { 3.538 + private Map<String,Location> locations = new HashMap<String,Location>(); 3.539 + 3.540 + Location getLocation(String className) { 3.541 + Location l = locations.get(className); 3.542 + if (l == null) 3.543 + locations.put(className, l = new SimpleLocation(className)); 3.544 + return l; 3.545 + } 3.546 + 3.547 + class Visitor implements ConstantPool.Visitor<Void,Void>, Type.Visitor<Void, Void> { 3.548 + private ConstantPool constant_pool; 3.549 + private Location origin; 3.550 + Set<Dependency> deps; 3.551 + 3.552 + Visitor(ClassFile classFile) { 3.553 + try { 3.554 + constant_pool = classFile.constant_pool; 3.555 + origin = getLocation(classFile.getName()); 3.556 + deps = new HashSet<Dependency>(); 3.557 + } catch (ConstantPoolException e) { 3.558 + throw new ClassFileError(e); 3.559 + } 3.560 + } 3.561 + 3.562 + void scan(Descriptor d, Attributes attrs) { 3.563 + try { 3.564 + scan(new Signature(d.index).getType(constant_pool)); 3.565 + Signature_attribute sa = (Signature_attribute) attrs.get(Attribute.Signature); 3.566 + if (sa != null) 3.567 + scan(new Signature(sa.signature_index).getType(constant_pool)); 3.568 + } catch (ConstantPoolException e) { 3.569 + throw new ClassFileError(e); 3.570 + } 3.571 + } 3.572 + 3.573 + void scan(CPInfo cpInfo) { 3.574 + cpInfo.accept(this, null); 3.575 + } 3.576 + 3.577 + void scan(Type t) { 3.578 + t.accept(this, null); 3.579 + } 3.580 + 3.581 + void addClass(int index) throws ConstantPoolException { 3.582 + if (index != 0) { 3.583 + String name = constant_pool.getClassInfo(index).getBaseName(); 3.584 + if (name != null) 3.585 + addDependency(name); 3.586 + } 3.587 + } 3.588 + 3.589 + void addClasses(int[] indices) throws ConstantPoolException { 3.590 + for (int i: indices) 3.591 + addClass(i); 3.592 + } 3.593 + 3.594 + private void addDependency(String name) { 3.595 + deps.add(new SimpleDependency(origin, getLocation(name))); 3.596 + } 3.597 + 3.598 + // ConstantPool.Visitor methods 3.599 + 3.600 + public Void visitClass(CONSTANT_Class_info info, Void p) { 3.601 + try { 3.602 + if (info.getName().startsWith("[")) 3.603 + new Signature(info.name_index).getType(constant_pool).accept(this, null); 3.604 + else 3.605 + addDependency(info.getBaseName()); 3.606 + return null; 3.607 + } catch (ConstantPoolException e) { 3.608 + throw new ClassFileError(e); 3.609 + } 3.610 + } 3.611 + 3.612 + public Void visitDouble(CONSTANT_Double_info info, Void p) { 3.613 + return null; 3.614 + } 3.615 + 3.616 + public Void visitFieldref(CONSTANT_Fieldref_info info, Void p) { 3.617 + return visitRef(info, p); 3.618 + } 3.619 + 3.620 + public Void visitFloat(CONSTANT_Float_info info, Void p) { 3.621 + return null; 3.622 + } 3.623 + 3.624 + public Void visitInteger(CONSTANT_Integer_info info, Void p) { 3.625 + return null; 3.626 + } 3.627 + 3.628 + public Void visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Void p) { 3.629 + return visitRef(info, p); 3.630 + } 3.631 + 3.632 + public Void visitLong(CONSTANT_Long_info info, Void p) { 3.633 + return null; 3.634 + } 3.635 + 3.636 + public Void visitNameAndType(CONSTANT_NameAndType_info info, Void p) { 3.637 + try { 3.638 + new Signature(info.type_index).getType(constant_pool).accept(this, null); 3.639 + return null; 3.640 + } catch (ConstantPoolException e) { 3.641 + throw new ClassFileError(e); 3.642 + } 3.643 + } 3.644 + 3.645 + public Void visitMethodref(CONSTANT_Methodref_info info, Void p) { 3.646 + return visitRef(info, p); 3.647 + } 3.648 + 3.649 + public Void visitString(CONSTANT_String_info info, Void p) { 3.650 + return null; 3.651 + } 3.652 + 3.653 + public Void visitUtf8(CONSTANT_Utf8_info info, Void p) { 3.654 + return null; 3.655 + } 3.656 + 3.657 + private Void visitRef(CPRefInfo info, Void p) { 3.658 + try { 3.659 + visitClass(info.getClassInfo(), p); 3.660 + return null; 3.661 + } catch (ConstantPoolException e) { 3.662 + throw new ClassFileError(e); 3.663 + } 3.664 + } 3.665 + 3.666 + // Type.Visitor methods 3.667 + 3.668 + private void findDependencies(Type t) { 3.669 + if (t != null) 3.670 + t.accept(this, null); 3.671 + } 3.672 + 3.673 + private void findDependencies(List<? extends Type> ts) { 3.674 + if (ts != null) { 3.675 + for (Type t: ts) 3.676 + t.accept(this, null); 3.677 + } 3.678 + } 3.679 + 3.680 + public Void visitSimpleType(SimpleType type, Void p) { 3.681 + return null; 3.682 + } 3.683 + 3.684 + public Void visitArrayType(ArrayType type, Void p) { 3.685 + findDependencies(type.elemType); 3.686 + return null; 3.687 + } 3.688 + 3.689 + public Void visitMethodType(MethodType type, Void p) { 3.690 + findDependencies(type.paramTypes); 3.691 + findDependencies(type.returnType); 3.692 + findDependencies(type.throwsTypes); 3.693 + return null; 3.694 + } 3.695 + 3.696 + public Void visitClassSigType(ClassSigType type, Void p) { 3.697 + findDependencies(type.superclassType); 3.698 + findDependencies(type.superinterfaceTypes); 3.699 + return null; 3.700 + } 3.701 + 3.702 + public Void visitClassType(ClassType type, Void p) { 3.703 + findDependencies(type.outerType); 3.704 + addDependency(type.name); 3.705 + findDependencies(type.typeArgs); 3.706 + return null; 3.707 + } 3.708 + 3.709 + public Void visitTypeParamType(TypeParamType type, Void p) { 3.710 + findDependencies(type.classBound); 3.711 + findDependencies(type.interfaceBounds); 3.712 + return null; 3.713 + } 3.714 + 3.715 + public Void visitWildcardType(WildcardType type, Void p) { 3.716 + findDependencies(type.boundType); 3.717 + return null; 3.718 + } 3.719 + } 3.720 + } 3.721 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/share/classes/com/sun/tools/classfile/Dependency.java Sat Dec 19 10:26:47 2009 -0800 4.3 @@ -0,0 +1,90 @@ 4.4 +/* 4.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.7 + * 4.8 + * This code is free software; you can redistribute it and/or modify it 4.9 + * under the terms of the GNU General Public License version 2 only, as 4.10 + * published by the Free Software Foundation. Sun designates this 4.11 + * particular file as subject to the "Classpath" exception as provided 4.12 + * by Sun in the LICENSE file that accompanied this code. 4.13 + * 4.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 4.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.17 + * version 2 for more details (a copy is included in the LICENSE file that 4.18 + * accompanied this code). 4.19 + * 4.20 + * You should have received a copy of the GNU General Public License version 4.21 + * 2 along with this work; if not, write to the Free Software Foundation, 4.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.23 + * 4.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 4.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 4.26 + * have any questions. 4.27 + */ 4.28 + 4.29 +package com.sun.tools.classfile; 4.30 + 4.31 + 4.32 +/** 4.33 + * A directed relationship between two {@link Dependency.Location Location}s. 4.34 + * Subtypes of {@code Dependency} may provide additional detail about the dependency. 4.35 + * 4.36 + * @see Dependency.Finder 4.37 + * @see Dependency.Filter 4.38 + * @see Dependencies 4.39 + */ 4.40 +public interface Dependency { 4.41 + /** 4.42 + * A filter used to select dependencies of interest, and to discard others. 4.43 + */ 4.44 + public interface Filter { 4.45 + /** 4.46 + * Return true if the dependency is of interest. 4.47 + * @param dependency the dependency to be considered 4.48 + * @return true if and only if the dependency is of interest. 4.49 + */ 4.50 + boolean accepts(Dependency dependency); 4.51 + } 4.52 + 4.53 + /** 4.54 + * An interface for finding the immediate dependencies of a given class file. 4.55 + */ 4.56 + public interface Finder { 4.57 + /** 4.58 + * Find the immediate dependencies of a given class file. 4.59 + * @param classfile the class file to be examined 4.60 + * @return the dependencies located in the given class file. 4.61 + */ 4.62 + public Iterable<? extends Dependency> findDependencies(ClassFile classfile); 4.63 + } 4.64 + 4.65 + 4.66 + /** 4.67 + * A location somewhere within a class. Subtypes of {@code Location} 4.68 + * may be used to provide additional detail about the location. 4.69 + */ 4.70 + public interface Location { 4.71 + /** 4.72 + * Get the name of the class containing the location. 4.73 + * This name will be used to locate the class file for transitive 4.74 + * dependency analysis. 4.75 + * @return the name of the class containing the location. 4.76 + */ 4.77 + String getClassName(); 4.78 + } 4.79 + 4.80 + 4.81 + /** 4.82 + * Get the location that has the dependency. 4.83 + * @return the location that has the dependency. 4.84 + */ 4.85 + Location getOrigin(); 4.86 + 4.87 + /** 4.88 + * Get the location that is being depended upon. 4.89 + * @return the location that is being depended upon. 4.90 + */ 4.91 + Location getTarget(); 4.92 +} 4.93 +
5.1 --- a/src/share/classes/com/sun/tools/javac/file/BaseFileObject.java Thu Dec 17 14:10:44 2009 -0800 5.2 +++ b/src/share/classes/com/sun/tools/javac/file/BaseFileObject.java Sat Dec 19 10:26:47 2009 -0800 5.3 @@ -39,6 +39,8 @@ 5.4 5.5 import static javax.tools.JavaFileObject.Kind.*; 5.6 5.7 +import com.sun.tools.javac.util.BaseFileManager; 5.8 + 5.9 /** 5.10 * <p><b>This is NOT part of any API supported by Sun Microsystems. 5.11 * If you write code that depends on this, you do so at your own risk. 5.12 @@ -74,14 +76,7 @@ 5.13 protected abstract String inferBinaryName(Iterable<? extends File> path); 5.14 5.15 protected static JavaFileObject.Kind getKind(String filename) { 5.16 - if (filename.endsWith(CLASS.extension)) 5.17 - return CLASS; 5.18 - else if (filename.endsWith(SOURCE.extension)) 5.19 - return SOURCE; 5.20 - else if (filename.endsWith(HTML.extension)) 5.21 - return HTML; 5.22 - else 5.23 - return OTHER; 5.24 + return BaseFileManager.getKind(filename); 5.25 } 5.26 5.27 protected static String removeExtension(String fileName) {
6.1 --- a/src/share/classes/com/sun/tools/javac/file/CloseableURLClassLoader.java Thu Dec 17 14:10:44 2009 -0800 6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 6.3 @@ -1,107 +0,0 @@ 6.4 -/* 6.5 - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. 6.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.7 - * 6.8 - * This code is free software; you can redistribute it and/or modify it 6.9 - * under the terms of the GNU General Public License version 2 only, as 6.10 - * published by the Free Software Foundation. Sun designates this 6.11 - * particular file as subject to the "Classpath" exception as provided 6.12 - * by Sun in the LICENSE file that accompanied this code. 6.13 - * 6.14 - * This code is distributed in the hope that it will be useful, but WITHOUT 6.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 6.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 6.17 - * version 2 for more details (a copy is included in the LICENSE file that 6.18 - * accompanied this code). 6.19 - * 6.20 - * You should have received a copy of the GNU General Public License version 6.21 - * 2 along with this work; if not, write to the Free Software Foundation, 6.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 6.23 - * 6.24 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 6.25 - * CA 95054 USA or visit www.sun.com if you need additional information or 6.26 - * have any questions. 6.27 - */ 6.28 - 6.29 -package com.sun.tools.javac.file; 6.30 - 6.31 -import java.io.Closeable; 6.32 -import java.io.IOException; 6.33 -import java.lang.reflect.Field; 6.34 -import java.net.URL; 6.35 -import java.net.URLClassLoader; 6.36 -import java.util.ArrayList; 6.37 -import java.util.jar.JarFile; 6.38 - 6.39 -/** 6.40 - * A URLClassLoader that also implements Closeable. 6.41 - * Reflection is used to access internal data structures in the URLClassLoader, 6.42 - * since no public API exists for this purpose. Therefore this code is somewhat 6.43 - * fragile. Caveat emptor. 6.44 - * @throws Error if the internal data structures are not as expected. 6.45 - * 6.46 - * <p><b>This is NOT part of any API supported by Sun Microsystems. If 6.47 - * you write code that depends on this, you do so at your own risk. 6.48 - * This code and its internal interfaces are subject to change or 6.49 - * deletion without notice.</b> 6.50 - */ 6.51 -class CloseableURLClassLoader 6.52 - extends URLClassLoader implements Closeable { 6.53 - CloseableURLClassLoader(URL[] urls, ClassLoader parent) throws Error { 6.54 - super(urls, parent); 6.55 - try { 6.56 - getLoaders(); //proactive check that URLClassLoader is as expected 6.57 - } catch (Throwable t) { 6.58 - throw new Error("cannot create CloseableURLClassLoader", t); 6.59 - } 6.60 - } 6.61 - 6.62 - /** 6.63 - * Close any jar files that may have been opened by the class loader. 6.64 - * Reflection is used to access the jar files in the URLClassLoader's 6.65 - * internal data structures. 6.66 - * @throws java.io.IOException if the jar files cannot be found for any 6.67 - * reson, or if closing the jar file itself causes an IOException. 6.68 - */ 6.69 - public void close() throws IOException { 6.70 - try { 6.71 - for (Object l: getLoaders()) { 6.72 - if (l.getClass().getName().equals("sun.misc.URLClassPath$JarLoader")) { 6.73 - Field jarField = l.getClass().getDeclaredField("jar"); 6.74 - JarFile jar = (JarFile) getField(l, jarField); 6.75 - if (jar != null) { 6.76 - //System.err.println("CloseableURLClassLoader: closing " + jar); 6.77 - jar.close(); 6.78 - } 6.79 - } 6.80 - } 6.81 - } catch (Throwable t) { 6.82 - IOException e = new IOException("cannot close class loader"); 6.83 - e.initCause(t); 6.84 - throw e; 6.85 - } 6.86 - } 6.87 - 6.88 - private ArrayList<?> getLoaders() 6.89 - throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException 6.90 - { 6.91 - Field ucpField = URLClassLoader.class.getDeclaredField("ucp"); 6.92 - Object urlClassPath = getField(this, ucpField); 6.93 - if (urlClassPath == null) 6.94 - throw new AssertionError("urlClassPath not set in URLClassLoader"); 6.95 - Field loadersField = urlClassPath.getClass().getDeclaredField("loaders"); 6.96 - return (ArrayList<?>) getField(urlClassPath, loadersField); 6.97 - } 6.98 - 6.99 - private Object getField(Object o, Field f) 6.100 - throws IllegalArgumentException, IllegalAccessException { 6.101 - boolean prev = f.isAccessible(); 6.102 - try { 6.103 - f.setAccessible(true); 6.104 - return f.get(o); 6.105 - } finally { 6.106 - f.setAccessible(prev); 6.107 - } 6.108 - } 6.109 - 6.110 -}
7.1 --- a/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Thu Dec 17 14:10:44 2009 -0800 7.2 +++ b/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Sat Dec 19 10:26:47 2009 -0800 7.3 @@ -26,29 +26,16 @@ 7.4 package com.sun.tools.javac.file; 7.5 7.6 import java.io.ByteArrayOutputStream; 7.7 -import java.io.Closeable; 7.8 import java.io.File; 7.9 -import java.io.FileInputStream; 7.10 import java.io.FileNotFoundException; 7.11 import java.io.IOException; 7.12 -import java.io.InputStream; 7.13 import java.io.OutputStreamWriter; 7.14 -import java.lang.ref.SoftReference; 7.15 -import java.lang.reflect.Constructor; 7.16 import java.net.MalformedURLException; 7.17 import java.net.URI; 7.18 import java.net.URISyntaxException; 7.19 import java.net.URL; 7.20 -import java.net.URLClassLoader; 7.21 -import java.nio.ByteBuffer; 7.22 import java.nio.CharBuffer; 7.23 -import java.nio.channels.FileChannel; 7.24 import java.nio.charset.Charset; 7.25 -import java.nio.charset.CharsetDecoder; 7.26 -import java.nio.charset.CoderResult; 7.27 -import java.nio.charset.CodingErrorAction; 7.28 -import java.nio.charset.IllegalCharsetNameException; 7.29 -import java.nio.charset.UnsupportedCharsetException; 7.30 import java.util.ArrayList; 7.31 import java.util.Arrays; 7.32 import java.util.Collection; 7.33 @@ -66,18 +53,13 @@ 7.34 import javax.tools.JavaFileObject; 7.35 import javax.tools.StandardJavaFileManager; 7.36 7.37 -import com.sun.tools.javac.code.Source; 7.38 import com.sun.tools.javac.file.RelativePath.RelativeFile; 7.39 import com.sun.tools.javac.file.RelativePath.RelativeDirectory; 7.40 -import com.sun.tools.javac.main.JavacOption; 7.41 import com.sun.tools.javac.main.OptionName; 7.42 -import com.sun.tools.javac.main.RecognizedOptions; 7.43 +import com.sun.tools.javac.util.BaseFileManager; 7.44 import com.sun.tools.javac.util.Context; 7.45 -import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition; 7.46 import com.sun.tools.javac.util.List; 7.47 import com.sun.tools.javac.util.ListBuffer; 7.48 -import com.sun.tools.javac.util.Log; 7.49 -import com.sun.tools.javac.util.Options; 7.50 7.51 import static javax.tools.StandardLocation.*; 7.52 import static com.sun.tools.javac.main.OptionName.*; 7.53 @@ -91,7 +73,7 @@ 7.54 * This code and its internal interfaces are subject to change or 7.55 * deletion without notice.</b> 7.56 */ 7.57 -public class JavacFileManager implements StandardJavaFileManager { 7.58 +public class JavacFileManager extends BaseFileManager implements StandardJavaFileManager { 7.59 7.60 boolean useZipFileIndex; 7.61 7.62 @@ -102,17 +84,10 @@ 7.63 return buffer.toString().toCharArray(); 7.64 } 7.65 7.66 - /** 7.67 - * The log to be used for error reporting. 7.68 - */ 7.69 - protected Log log; 7.70 - 7.71 /** Encapsulates knowledge of paths 7.72 */ 7.73 private Paths paths; 7.74 7.75 - private Options options; 7.76 - 7.77 private FSInfo fsInfo; 7.78 7.79 private final File uninited = new File("U N I N I T E D"); 7.80 @@ -134,12 +109,6 @@ 7.81 7.82 protected boolean mmappedIO; 7.83 protected boolean ignoreSymbolFile; 7.84 - protected String classLoaderClass; 7.85 - 7.86 - /** 7.87 - * User provided charset (through javax.tools). 7.88 - */ 7.89 - protected Charset charset; 7.90 7.91 /** 7.92 * Register a Context.Factory to create a JavacFileManager. 7.93 @@ -157,18 +126,18 @@ 7.94 * it as the JavaFileManager for that context. 7.95 */ 7.96 public JavacFileManager(Context context, boolean register, Charset charset) { 7.97 + super(charset); 7.98 if (register) 7.99 context.put(JavaFileManager.class, this); 7.100 - byteBufferCache = new ByteBufferCache(); 7.101 - this.charset = charset; 7.102 setContext(context); 7.103 } 7.104 7.105 /** 7.106 * Set the context for JavacFileManager. 7.107 */ 7.108 + @Override 7.109 public void setContext(Context context) { 7.110 - log = Log.instance(context); 7.111 + super.setContext(context); 7.112 if (paths == null) { 7.113 paths = Paths.instance(context); 7.114 } else { 7.115 @@ -177,14 +146,12 @@ 7.116 paths.setContext(context); 7.117 } 7.118 7.119 - options = Options.instance(context); 7.120 fsInfo = FSInfo.instance(context); 7.121 7.122 useZipFileIndex = System.getProperty("useJavaUtilZip") == null;// TODO: options.get("useJavaUtilZip") == null; 7.123 7.124 mmappedIO = options.get("mmappedIO") != null; 7.125 ignoreSymbolFile = options.get("ignore.symbol.file") != null; 7.126 - classLoaderClass = options.get("procloader"); 7.127 } 7.128 7.129 public JavaFileObject getFileForInput(String name) { 7.130 @@ -214,17 +181,6 @@ 7.131 return getJavaFileObjectsFromStrings(Arrays.asList(nullCheck(names))); 7.132 } 7.133 7.134 - protected JavaFileObject.Kind getKind(String extension) { 7.135 - if (extension.equals(JavaFileObject.Kind.CLASS.extension)) 7.136 - return JavaFileObject.Kind.CLASS; 7.137 - else if (extension.equals(JavaFileObject.Kind.SOURCE.extension)) 7.138 - return JavaFileObject.Kind.SOURCE; 7.139 - else if (extension.equals(JavaFileObject.Kind.HTML.extension)) 7.140 - return JavaFileObject.Kind.HTML; 7.141 - else 7.142 - return JavaFileObject.Kind.OTHER; 7.143 - } 7.144 - 7.145 private static boolean isValidName(String name) { 7.146 // Arguably, isValidName should reject keywords (such as in SourceVersion.isName() ), 7.147 // but the set of keywords depends on the source level, and we don't want 7.148 @@ -359,9 +315,7 @@ 7.149 } 7.150 7.151 private boolean isValidFile(String s, Set<JavaFileObject.Kind> fileKinds) { 7.152 - int lastDot = s.lastIndexOf("."); 7.153 - String extn = (lastDot == -1 ? s : s.substring(lastDot)); 7.154 - JavaFileObject.Kind kind = getKind(extn); 7.155 + JavaFileObject.Kind kind = getKind(s); 7.156 return fileKinds.contains(kind); 7.157 } 7.158 7.159 @@ -564,18 +518,6 @@ 7.160 } 7.161 } 7.162 7.163 - CharBuffer getCachedContent(JavaFileObject file) { 7.164 - SoftReference<CharBuffer> r = contentCache.get(file); 7.165 - return (r == null ? null : r.get()); 7.166 - } 7.167 - 7.168 - void cache(JavaFileObject file, CharBuffer cb) { 7.169 - contentCache.put(file, new SoftReference<CharBuffer>(cb)); 7.170 - } 7.171 - 7.172 - private final Map<JavaFileObject, SoftReference<CharBuffer>> contentCache 7.173 - = new HashMap<JavaFileObject, SoftReference<CharBuffer>>(); 7.174 - 7.175 private String defaultEncodingName; 7.176 private String getDefaultEncodingName() { 7.177 if (defaultEncodingName == null) { 7.178 @@ -585,161 +527,6 @@ 7.179 return defaultEncodingName; 7.180 } 7.181 7.182 - protected String getEncodingName() { 7.183 - String encName = options.get(OptionName.ENCODING); 7.184 - if (encName == null) 7.185 - return getDefaultEncodingName(); 7.186 - else 7.187 - return encName; 7.188 - } 7.189 - 7.190 - protected Source getSource() { 7.191 - String sourceName = options.get(OptionName.SOURCE); 7.192 - Source source = null; 7.193 - if (sourceName != null) 7.194 - source = Source.lookup(sourceName); 7.195 - return (source != null ? source : Source.DEFAULT); 7.196 - } 7.197 - 7.198 - /** 7.199 - * Make a byte buffer from an input stream. 7.200 - */ 7.201 - ByteBuffer makeByteBuffer(InputStream in) 7.202 - throws IOException { 7.203 - int limit = in.available(); 7.204 - if (mmappedIO && in instanceof FileInputStream) { 7.205 - // Experimental memory mapped I/O 7.206 - FileInputStream fin = (FileInputStream)in; 7.207 - return fin.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, limit); 7.208 - } 7.209 - if (limit < 1024) limit = 1024; 7.210 - ByteBuffer result = byteBufferCache.get(limit); 7.211 - int position = 0; 7.212 - while (in.available() != 0) { 7.213 - if (position >= limit) 7.214 - // expand buffer 7.215 - result = ByteBuffer. 7.216 - allocate(limit <<= 1). 7.217 - put((ByteBuffer)result.flip()); 7.218 - int count = in.read(result.array(), 7.219 - position, 7.220 - limit - position); 7.221 - if (count < 0) break; 7.222 - result.position(position += count); 7.223 - } 7.224 - return (ByteBuffer)result.flip(); 7.225 - } 7.226 - 7.227 - void recycleByteBuffer(ByteBuffer bb) { 7.228 - byteBufferCache.put(bb); 7.229 - } 7.230 - 7.231 - /** 7.232 - * A single-element cache of direct byte buffers. 7.233 - */ 7.234 - private static class ByteBufferCache { 7.235 - private ByteBuffer cached; 7.236 - ByteBuffer get(int capacity) { 7.237 - if (capacity < 20480) capacity = 20480; 7.238 - ByteBuffer result = 7.239 - (cached != null && cached.capacity() >= capacity) 7.240 - ? (ByteBuffer)cached.clear() 7.241 - : ByteBuffer.allocate(capacity + capacity>>1); 7.242 - cached = null; 7.243 - return result; 7.244 - } 7.245 - void put(ByteBuffer x) { 7.246 - cached = x; 7.247 - } 7.248 - } 7.249 - 7.250 - private final ByteBufferCache byteBufferCache; 7.251 - 7.252 - CharsetDecoder getDecoder(String encodingName, boolean ignoreEncodingErrors) { 7.253 - Charset cs = (this.charset == null) 7.254 - ? Charset.forName(encodingName) 7.255 - : this.charset; 7.256 - CharsetDecoder decoder = cs.newDecoder(); 7.257 - 7.258 - CodingErrorAction action; 7.259 - if (ignoreEncodingErrors) 7.260 - action = CodingErrorAction.REPLACE; 7.261 - else 7.262 - action = CodingErrorAction.REPORT; 7.263 - 7.264 - return decoder 7.265 - .onMalformedInput(action) 7.266 - .onUnmappableCharacter(action); 7.267 - } 7.268 - 7.269 - /** 7.270 - * Decode a ByteBuffer into a CharBuffer. 7.271 - */ 7.272 - CharBuffer decode(ByteBuffer inbuf, boolean ignoreEncodingErrors) { 7.273 - String encodingName = getEncodingName(); 7.274 - CharsetDecoder decoder; 7.275 - try { 7.276 - decoder = getDecoder(encodingName, ignoreEncodingErrors); 7.277 - } catch (IllegalCharsetNameException e) { 7.278 - log.error("unsupported.encoding", encodingName); 7.279 - return (CharBuffer)CharBuffer.allocate(1).flip(); 7.280 - } catch (UnsupportedCharsetException e) { 7.281 - log.error("unsupported.encoding", encodingName); 7.282 - return (CharBuffer)CharBuffer.allocate(1).flip(); 7.283 - } 7.284 - 7.285 - // slightly overestimate the buffer size to avoid reallocation. 7.286 - float factor = 7.287 - decoder.averageCharsPerByte() * 0.8f + 7.288 - decoder.maxCharsPerByte() * 0.2f; 7.289 - CharBuffer dest = CharBuffer. 7.290 - allocate(10 + (int)(inbuf.remaining()*factor)); 7.291 - 7.292 - while (true) { 7.293 - CoderResult result = decoder.decode(inbuf, dest, true); 7.294 - dest.flip(); 7.295 - 7.296 - if (result.isUnderflow()) { // done reading 7.297 - // make sure there is at least one extra character 7.298 - if (dest.limit() == dest.capacity()) { 7.299 - dest = CharBuffer.allocate(dest.capacity()+1).put(dest); 7.300 - dest.flip(); 7.301 - } 7.302 - return dest; 7.303 - } else if (result.isOverflow()) { // buffer too small; expand 7.304 - int newCapacity = 7.305 - 10 + dest.capacity() + 7.306 - (int)(inbuf.remaining()*decoder.maxCharsPerByte()); 7.307 - dest = CharBuffer.allocate(newCapacity).put(dest); 7.308 - } else if (result.isMalformed() || result.isUnmappable()) { 7.309 - // bad character in input 7.310 - 7.311 - // report coding error (warn only pre 1.5) 7.312 - if (!getSource().allowEncodingErrors()) { 7.313 - log.error(new SimpleDiagnosticPosition(dest.limit()), 7.314 - "illegal.char.for.encoding", 7.315 - charset == null ? encodingName : charset.name()); 7.316 - } else { 7.317 - log.warning(new SimpleDiagnosticPosition(dest.limit()), 7.318 - "illegal.char.for.encoding", 7.319 - charset == null ? encodingName : charset.name()); 7.320 - } 7.321 - 7.322 - // skip past the coding error 7.323 - inbuf.position(inbuf.position() + result.length()); 7.324 - 7.325 - // undo the flip() to prepare the output buffer 7.326 - // for more translation 7.327 - dest.position(dest.limit()); 7.328 - dest.limit(dest.capacity()); 7.329 - dest.put((char)0xfffd); // backward compatible 7.330 - } else { 7.331 - throw new AssertionError(result); 7.332 - } 7.333 - } 7.334 - // unreached 7.335 - } 7.336 - 7.337 public ClassLoader getClassLoader(Location location) { 7.338 nullCheck(location); 7.339 Iterable<? extends File> path = getLocation(location); 7.340 @@ -754,39 +541,7 @@ 7.341 } 7.342 } 7.343 7.344 - URL[] urls = lb.toArray(new URL[lb.size()]); 7.345 - ClassLoader thisClassLoader = getClass().getClassLoader(); 7.346 - 7.347 - // Bug: 6558476 7.348 - // Ideally, ClassLoader should be Closeable, but before JDK7 it is not. 7.349 - // On older versions, try the following, to get a closeable classloader. 7.350 - 7.351 - // 1: Allow client to specify the class to use via hidden option 7.352 - if (classLoaderClass != null) { 7.353 - try { 7.354 - Class<? extends ClassLoader> loader = 7.355 - Class.forName(classLoaderClass).asSubclass(ClassLoader.class); 7.356 - Class<?>[] constrArgTypes = { URL[].class, ClassLoader.class }; 7.357 - Constructor<? extends ClassLoader> constr = loader.getConstructor(constrArgTypes); 7.358 - return constr.newInstance(new Object[] { urls, thisClassLoader }); 7.359 - } catch (Throwable t) { 7.360 - // ignore errors loading user-provided class loader, fall through 7.361 - } 7.362 - } 7.363 - 7.364 - // 2: If URLClassLoader implements Closeable, use that. 7.365 - if (Closeable.class.isAssignableFrom(URLClassLoader.class)) 7.366 - return new URLClassLoader(urls, thisClassLoader); 7.367 - 7.368 - // 3: Try using private reflection-based CloseableURLClassLoader 7.369 - try { 7.370 - return new CloseableURLClassLoader(urls, thisClassLoader); 7.371 - } catch (Throwable t) { 7.372 - // ignore errors loading workaround class loader, fall through 7.373 - } 7.374 - 7.375 - // 4: If all else fails, use plain old standard URLClassLoader 7.376 - return new URLClassLoader(urls, thisClassLoader); 7.377 + return getClassLoader(lb.toArray(new URL[lb.size()])); 7.378 } 7.379 7.380 public Iterable<JavaFileObject> list(Location location, 7.381 @@ -836,38 +591,6 @@ 7.382 return a.equals(b); 7.383 } 7.384 7.385 - public boolean handleOption(String current, Iterator<String> remaining) { 7.386 - for (JavacOption o: javacFileManagerOptions) { 7.387 - if (o.matches(current)) { 7.388 - if (o.hasArg()) { 7.389 - if (remaining.hasNext()) { 7.390 - if (!o.process(options, current, remaining.next())) 7.391 - return true; 7.392 - } 7.393 - } else { 7.394 - if (!o.process(options, current)) 7.395 - return true; 7.396 - } 7.397 - // operand missing, or process returned false 7.398 - throw new IllegalArgumentException(current); 7.399 - } 7.400 - } 7.401 - 7.402 - return false; 7.403 - } 7.404 - // where 7.405 - private static JavacOption[] javacFileManagerOptions = 7.406 - RecognizedOptions.getJavacFileManagerOptions( 7.407 - new RecognizedOptions.GrumpyHelper()); 7.408 - 7.409 - public int isSupportedOption(String option) { 7.410 - for (JavacOption o : javacFileManagerOptions) { 7.411 - if (o.matches(option)) 7.412 - return o.hasArg() ? 1 : 0; 7.413 - } 7.414 - return -1; 7.415 - } 7.416 - 7.417 public boolean hasLocation(Location location) { 7.418 return getLocation(location) != null; 7.419 } 7.420 @@ -1115,15 +838,4 @@ 7.421 } 7.422 throw new IllegalArgumentException("Invalid relative path: " + file); 7.423 } 7.424 - 7.425 - private static <T> T nullCheck(T o) { 7.426 - o.getClass(); // null check 7.427 - return o; 7.428 - } 7.429 - 7.430 - private static <T> Iterable<T> nullCheck(Iterable<T> it) { 7.431 - for (T t : it) 7.432 - t.getClass(); // null check 7.433 - return it; 7.434 - } 7.435 }
8.1 --- a/src/share/classes/com/sun/tools/javac/file/Paths.java Thu Dec 17 14:10:44 2009 -0800 8.2 +++ b/src/share/classes/com/sun/tools/javac/file/Paths.java Sat Dec 19 10:26:47 2009 -0800 8.3 @@ -66,7 +66,7 @@ 8.4 * @param context the context 8.5 * @return the Paths instance for this context 8.6 */ 8.7 - static Paths instance(Context context) { 8.8 + public static Paths instance(Context context) { 8.9 Paths instance = context.get(pathsKey); 8.10 if (instance == null) 8.11 instance = new Paths(context);
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java Sat Dec 19 10:26:47 2009 -0800 9.3 @@ -0,0 +1,543 @@ 9.4 +/* 9.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 9.7 + * 9.8 + * This code is free software; you can redistribute it and/or modify it 9.9 + * under the terms of the GNU General Public License version 2 only, as 9.10 + * published by the Free Software Foundation. Sun designates this 9.11 + * particular file as subject to the "Classpath" exception as provided 9.12 + * by Sun in the LICENSE file that accompanied this code. 9.13 + * 9.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 9.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 9.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 9.17 + * version 2 for more details (a copy is included in the LICENSE file that 9.18 + * accompanied this code). 9.19 + * 9.20 + * You should have received a copy of the GNU General Public License version 9.21 + * 2 along with this work; if not, write to the Free Software Foundation, 9.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 9.23 + * 9.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 9.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 9.26 + * have any questions. 9.27 + */ 9.28 + 9.29 +package com.sun.tools.javac.nio; 9.30 + 9.31 + 9.32 +import java.io.File; 9.33 +import java.io.FileNotFoundException; 9.34 +import java.io.IOException; 9.35 +import java.net.MalformedURLException; 9.36 +import java.net.URL; 9.37 +import java.nio.charset.Charset; 9.38 +import java.nio.file.Files; 9.39 +import java.nio.file.FileSystem; 9.40 +import java.nio.file.FileSystems; 9.41 +import java.nio.file.FileVisitOption; 9.42 +import java.nio.file.FileVisitResult; 9.43 +import java.nio.file.Path; 9.44 +import java.nio.file.SimpleFileVisitor; 9.45 +import java.nio.file.attribute.Attributes; 9.46 +import java.nio.file.attribute.BasicFileAttributes; 9.47 +import java.util.ArrayList; 9.48 +import java.util.Arrays; 9.49 +import java.util.Collection; 9.50 +import java.util.Collections; 9.51 +import java.util.EnumSet; 9.52 +import java.util.HashMap; 9.53 +import java.util.Iterator; 9.54 +import java.util.LinkedHashSet; 9.55 +import java.util.Map; 9.56 +import java.util.Set; 9.57 +import javax.lang.model.SourceVersion; 9.58 +import javax.tools.FileObject; 9.59 +import javax.tools.JavaFileManager; 9.60 +import javax.tools.JavaFileObject; 9.61 +import javax.tools.JavaFileObject.Kind; 9.62 +import javax.tools.StandardLocation; 9.63 + 9.64 +import static java.nio.file.FileVisitOption.*; 9.65 +import static javax.tools.StandardLocation.*; 9.66 + 9.67 +import com.sun.tools.javac.file.Paths; 9.68 +import com.sun.tools.javac.util.BaseFileManager; 9.69 +import com.sun.tools.javac.util.Context; 9.70 +import com.sun.tools.javac.util.List; 9.71 +import com.sun.tools.javac.util.ListBuffer; 9.72 + 9.73 +import static com.sun.tools.javac.main.OptionName.*; 9.74 + 9.75 + 9.76 +// NOTE the imports carefully for this compilation unit. 9.77 +// 9.78 +// Path: java.nio.file.Path -- the new NIO type for which this file manager exists 9.79 +// 9.80 +// Paths: com.sun.tools.javac.file.Paths -- legacy javac type for handling path options 9.81 +// The other Paths (java.nio.file.Paths) is not used 9.82 + 9.83 +// NOTE this and related classes depend on new API in JDK 7. 9.84 +// This requires special handling while bootstrapping the JDK build, 9.85 +// when these classes might not yet have been compiled. To workaround 9.86 +// this, the build arranges to make stubs of these classes available 9.87 +// when compiling this and related classes. The set of stub files 9.88 +// is specified in make/build.properties. 9.89 + 9.90 +/** 9.91 + * Implementation of PathFileManager: a JavaFileManager based on the use 9.92 + * of java.nio.file.Path. 9.93 + * 9.94 + * <p>Just as a Path is somewhat analagous to a File, so too is this 9.95 + * JavacPathFileManager analogous to JavacFileManager, as it relates to the 9.96 + * support of FileObjects based on File objects (i.e. just RegularFileObject, 9.97 + * not ZipFileObject and its variants.) 9.98 + * 9.99 + * <p>The default values for the standard locations supported by this file 9.100 + * manager are the same as the default values provided by JavacFileManager -- 9.101 + * i.e. as determined by the javac.file.Paths class. To override these values, 9.102 + * call {@link #setLocation}. 9.103 + * 9.104 + * <p>To reduce confusion with Path objects, the locations such as "class path", 9.105 + * "source path", etc, are generically referred to here as "search paths". 9.106 + * 9.107 + * <p><b>This is NOT part of any API supported by Sun Microsystems. If 9.108 + * you write code that depends on this, you do so at your own risk. 9.109 + * This code and its internal interfaces are subject to change or 9.110 + * deletion without notice.</b> 9.111 + */ 9.112 +public class JavacPathFileManager extends BaseFileManager implements PathFileManager { 9.113 + protected FileSystem defaultFileSystem; 9.114 + 9.115 + /** 9.116 + * Create a JavacPathFileManager using a given context, optionally registering 9.117 + * it as the JavaFileManager for that context. 9.118 + */ 9.119 + public JavacPathFileManager(Context context, boolean register, Charset charset) { 9.120 + super(charset); 9.121 + if (register) 9.122 + context.put(JavaFileManager.class, this); 9.123 + pathsForLocation = new HashMap<Location, PathsForLocation>(); 9.124 + fileSystems = new HashMap<Path,FileSystem>(); 9.125 + setContext(context); 9.126 + } 9.127 + 9.128 + /** 9.129 + * Set the context for JavacPathFileManager. 9.130 + */ 9.131 + @Override 9.132 + protected void setContext(Context context) { 9.133 + super.setContext(context); 9.134 + searchPaths = Paths.instance(context); 9.135 + } 9.136 + 9.137 + @Override 9.138 + public FileSystem getDefaultFileSystem() { 9.139 + if (defaultFileSystem == null) 9.140 + defaultFileSystem = FileSystems.getDefault(); 9.141 + return defaultFileSystem; 9.142 + } 9.143 + 9.144 + @Override 9.145 + public void setDefaultFileSystem(FileSystem fs) { 9.146 + defaultFileSystem = fs; 9.147 + } 9.148 + 9.149 + @Override 9.150 + public void flush() throws IOException { 9.151 + contentCache.clear(); 9.152 + } 9.153 + 9.154 + @Override 9.155 + public void close() throws IOException { 9.156 + for (FileSystem fs: fileSystems.values()) 9.157 + fs.close(); 9.158 + } 9.159 + 9.160 + @Override 9.161 + public ClassLoader getClassLoader(Location location) { 9.162 + nullCheck(location); 9.163 + Iterable<? extends Path> path = getLocation(location); 9.164 + if (path == null) 9.165 + return null; 9.166 + ListBuffer<URL> lb = new ListBuffer<URL>(); 9.167 + for (Path p: path) { 9.168 + try { 9.169 + lb.append(p.toUri().toURL()); 9.170 + } catch (MalformedURLException e) { 9.171 + throw new AssertionError(e); 9.172 + } 9.173 + } 9.174 + 9.175 + return getClassLoader(lb.toArray(new URL[lb.size()])); 9.176 + } 9.177 + 9.178 + // <editor-fold defaultstate="collapsed" desc="Location handling"> 9.179 + 9.180 + public boolean hasLocation(Location location) { 9.181 + return (getLocation(location) != null); 9.182 + } 9.183 + 9.184 + public Iterable<? extends Path> getLocation(Location location) { 9.185 + nullCheck(location); 9.186 + lazyInitSearchPaths(); 9.187 + PathsForLocation path = pathsForLocation.get(location); 9.188 + if (path == null && !pathsForLocation.containsKey(location)) { 9.189 + setDefaultForLocation(location); 9.190 + path = pathsForLocation.get(location); 9.191 + } 9.192 + return path; 9.193 + } 9.194 + 9.195 + private Path getOutputLocation(Location location) { 9.196 + Iterable<? extends Path> paths = getLocation(location); 9.197 + return (paths == null ? null : paths.iterator().next()); 9.198 + } 9.199 + 9.200 + public void setLocation(Location location, Iterable<? extends Path> searchPath) 9.201 + throws IOException 9.202 + { 9.203 + nullCheck(location); 9.204 + lazyInitSearchPaths(); 9.205 + if (searchPath == null) { 9.206 + setDefaultForLocation(location); 9.207 + } else { 9.208 + if (location.isOutputLocation()) 9.209 + checkOutputPath(searchPath); 9.210 + PathsForLocation pl = new PathsForLocation(); 9.211 + for (Path p: searchPath) 9.212 + pl.add(p); // TODO -Xlint:path warn if path not found 9.213 + pathsForLocation.put(location, pl); 9.214 + } 9.215 + } 9.216 + 9.217 + private void checkOutputPath(Iterable<? extends Path> searchPath) throws IOException { 9.218 + Iterator<? extends Path> pathIter = searchPath.iterator(); 9.219 + if (!pathIter.hasNext()) 9.220 + throw new IllegalArgumentException("empty path for directory"); 9.221 + Path path = pathIter.next(); 9.222 + if (pathIter.hasNext()) 9.223 + throw new IllegalArgumentException("path too long for directory"); 9.224 + if (!path.exists()) 9.225 + throw new FileNotFoundException(path + ": does not exist"); 9.226 + else if (!isDirectory(path)) 9.227 + throw new IOException(path + ": not a directory"); 9.228 + } 9.229 + 9.230 + private void setDefaultForLocation(Location locn) { 9.231 + Collection<File> files = null; 9.232 + if (locn instanceof StandardLocation) { 9.233 + switch ((StandardLocation) locn) { 9.234 + case CLASS_PATH: 9.235 + files = searchPaths.userClassPath(); 9.236 + break; 9.237 + case PLATFORM_CLASS_PATH: 9.238 + files = searchPaths.bootClassPath(); 9.239 + break; 9.240 + case SOURCE_PATH: 9.241 + files = searchPaths.sourcePath(); 9.242 + break; 9.243 + case CLASS_OUTPUT: { 9.244 + String arg = options.get(D); 9.245 + files = (arg == null ? null : Collections.singleton(new File(arg))); 9.246 + break; 9.247 + } 9.248 + case SOURCE_OUTPUT: { 9.249 + String arg = options.get(S); 9.250 + files = (arg == null ? null : Collections.singleton(new File(arg))); 9.251 + break; 9.252 + } 9.253 + } 9.254 + } 9.255 + 9.256 + PathsForLocation pl = new PathsForLocation(); 9.257 + if (files != null) { 9.258 + for (File f: files) 9.259 + pl.add(f.toPath()); 9.260 + } 9.261 + pathsForLocation.put(locn, pl); 9.262 + } 9.263 + 9.264 + private void lazyInitSearchPaths() { 9.265 + if (!inited) { 9.266 + setDefaultForLocation(PLATFORM_CLASS_PATH); 9.267 + setDefaultForLocation(CLASS_PATH); 9.268 + setDefaultForLocation(SOURCE_PATH); 9.269 + inited = true; 9.270 + } 9.271 + } 9.272 + // where 9.273 + private boolean inited = false; 9.274 + 9.275 + private Map<Location, PathsForLocation> pathsForLocation; 9.276 + private Paths searchPaths; 9.277 + 9.278 + private static class PathsForLocation extends LinkedHashSet<Path> { 9.279 + private static final long serialVersionUID = 6788510222394486733L; 9.280 + } 9.281 + 9.282 + // </editor-fold> 9.283 + 9.284 + // <editor-fold defaultstate="collapsed" desc="FileObject handling"> 9.285 + 9.286 + @Override 9.287 + public Path getPath(FileObject fo) { 9.288 + nullCheck(fo); 9.289 + if (!(fo instanceof PathFileObject)) 9.290 + throw new IllegalArgumentException(); 9.291 + return ((PathFileObject) fo).getPath(); 9.292 + } 9.293 + 9.294 + @Override 9.295 + public boolean isSameFile(FileObject a, FileObject b) { 9.296 + nullCheck(a); 9.297 + nullCheck(b); 9.298 + if (!(a instanceof PathFileObject)) 9.299 + throw new IllegalArgumentException("Not supported: " + a); 9.300 + if (!(b instanceof PathFileObject)) 9.301 + throw new IllegalArgumentException("Not supported: " + b); 9.302 + return ((PathFileObject) a).isSameFile((PathFileObject) b); 9.303 + } 9.304 + 9.305 + @Override 9.306 + public Iterable<JavaFileObject> list(Location location, 9.307 + String packageName, Set<Kind> kinds, boolean recurse) 9.308 + throws IOException { 9.309 + // validatePackageName(packageName); 9.310 + nullCheck(packageName); 9.311 + nullCheck(kinds); 9.312 + 9.313 + Iterable<? extends Path> paths = getLocation(location); 9.314 + if (paths == null) 9.315 + return List.nil(); 9.316 + ListBuffer<JavaFileObject> results = new ListBuffer<JavaFileObject>(); 9.317 + 9.318 + for (Path path : paths) 9.319 + list(path, packageName, kinds, recurse, results); 9.320 + 9.321 + return results.toList(); 9.322 + } 9.323 + 9.324 + private void list(Path path, String packageName, final Set<Kind> kinds, 9.325 + boolean recurse, final ListBuffer<JavaFileObject> results) 9.326 + throws IOException { 9.327 + if (!path.exists()) 9.328 + return; 9.329 + 9.330 + final Path pathDir; 9.331 + if (isDirectory(path)) 9.332 + pathDir = path; 9.333 + else { 9.334 + FileSystem fs = getFileSystem(path); 9.335 + if (fs == null) 9.336 + return; 9.337 + pathDir = fs.getRootDirectories().iterator().next(); 9.338 + } 9.339 + String sep = path.getFileSystem().getSeparator(); 9.340 + Path packageDir = packageName.isEmpty() ? pathDir 9.341 + : pathDir.resolve(packageName.replace(".", sep)); 9.342 + if (!packageDir.exists()) 9.343 + return; 9.344 + 9.345 +/* Alternate impl of list, superceded by use of Files.walkFileTree */ 9.346 +// Deque<Path> queue = new LinkedList<Path>(); 9.347 +// queue.add(packageDir); 9.348 +// 9.349 +// Path dir; 9.350 +// while ((dir = queue.poll()) != null) { 9.351 +// DirectoryStream<Path> ds = dir.newDirectoryStream(); 9.352 +// try { 9.353 +// for (Path p: ds) { 9.354 +// String name = p.getName().toString(); 9.355 +// if (isDirectory(p)) { 9.356 +// if (recurse && SourceVersion.isIdentifier(name)) { 9.357 +// queue.add(p); 9.358 +// } 9.359 +// } else { 9.360 +// if (kinds.contains(getKind(name))) { 9.361 +// JavaFileObject fe = 9.362 +// PathFileObject.createDirectoryPathFileObject(this, p, pathDir); 9.363 +// results.append(fe); 9.364 +// } 9.365 +// } 9.366 +// } 9.367 +// } finally { 9.368 +// ds.close(); 9.369 +// } 9.370 +// } 9.371 + int maxDepth = (recurse ? Integer.MAX_VALUE : 1); 9.372 + Set<FileVisitOption> opts = EnumSet.of(DETECT_CYCLES, FOLLOW_LINKS); 9.373 + Files.walkFileTree(packageDir, opts, maxDepth, 9.374 + new SimpleFileVisitor<Path>() { 9.375 + @Override 9.376 + public FileVisitResult preVisitDirectory(Path dir) { 9.377 + if (SourceVersion.isIdentifier(dir.getName().toString())) // JSR 292? 9.378 + return FileVisitResult.CONTINUE; 9.379 + else 9.380 + return FileVisitResult.SKIP_SUBTREE; 9.381 + } 9.382 + 9.383 + @Override 9.384 + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { 9.385 + if (attrs.isRegularFile() && kinds.contains(getKind(file.getName().toString()))) { 9.386 + JavaFileObject fe = 9.387 + PathFileObject.createDirectoryPathFileObject( 9.388 + JavacPathFileManager.this, file, pathDir); 9.389 + results.append(fe); 9.390 + } 9.391 + return FileVisitResult.CONTINUE; 9.392 + } 9.393 + }); 9.394 + } 9.395 + 9.396 + @Override 9.397 + public Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths( 9.398 + Iterable<? extends Path> paths) { 9.399 + ArrayList<PathFileObject> result; 9.400 + if (paths instanceof Collection<?>) 9.401 + result = new ArrayList<PathFileObject>(((Collection<?>)paths).size()); 9.402 + else 9.403 + result = new ArrayList<PathFileObject>(); 9.404 + for (Path p: paths) 9.405 + result.add(PathFileObject.createSimplePathFileObject(this, nullCheck(p))); 9.406 + return result; 9.407 + } 9.408 + 9.409 + @Override 9.410 + public Iterable<? extends JavaFileObject> getJavaFileObjects(Path... paths) { 9.411 + return getJavaFileObjectsFromPaths(Arrays.asList(nullCheck(paths))); 9.412 + } 9.413 + 9.414 + @Override 9.415 + public JavaFileObject getJavaFileForInput(Location location, 9.416 + String className, Kind kind) throws IOException { 9.417 + return getFileForInput(location, getRelativePath(className, kind)); 9.418 + } 9.419 + 9.420 + @Override 9.421 + public FileObject getFileForInput(Location location, 9.422 + String packageName, String relativeName) throws IOException { 9.423 + return getFileForInput(location, getRelativePath(packageName, relativeName)); 9.424 + } 9.425 + 9.426 + private JavaFileObject getFileForInput(Location location, String relativePath) 9.427 + throws IOException { 9.428 + for (Path p: getLocation(location)) { 9.429 + if (isDirectory(p)) { 9.430 + Path f = resolve(p, relativePath); 9.431 + if (f.exists()) 9.432 + return PathFileObject.createDirectoryPathFileObject(this, f, p); 9.433 + } else { 9.434 + FileSystem fs = getFileSystem(p); 9.435 + if (fs != null) { 9.436 + Path file = getPath(fs, relativePath); 9.437 + if (file.exists()) 9.438 + return PathFileObject.createJarPathFileObject(this, file); 9.439 + } 9.440 + } 9.441 + } 9.442 + return null; 9.443 + } 9.444 + 9.445 + @Override 9.446 + public JavaFileObject getJavaFileForOutput(Location location, 9.447 + String className, Kind kind, FileObject sibling) throws IOException { 9.448 + return getFileForOutput(location, getRelativePath(className, kind), sibling); 9.449 + } 9.450 + 9.451 + @Override 9.452 + public FileObject getFileForOutput(Location location, String packageName, 9.453 + String relativeName, FileObject sibling) 9.454 + throws IOException { 9.455 + return getFileForOutput(location, getRelativePath(packageName, relativeName), sibling); 9.456 + } 9.457 + 9.458 + private JavaFileObject getFileForOutput(Location location, 9.459 + String relativePath, FileObject sibling) { 9.460 + Path dir = getOutputLocation(location); 9.461 + if (dir == null) { 9.462 + if (location == CLASS_OUTPUT) { 9.463 + Path siblingDir = null; 9.464 + if (sibling != null && sibling instanceof PathFileObject) { 9.465 + siblingDir = ((PathFileObject) sibling).getPath().getParent(); 9.466 + } 9.467 + return PathFileObject.createSiblingPathFileObject(this, 9.468 + siblingDir.resolve(getBaseName(relativePath)), 9.469 + relativePath); 9.470 + } else if (location == SOURCE_OUTPUT) { 9.471 + dir = getOutputLocation(CLASS_OUTPUT); 9.472 + } 9.473 + } 9.474 + 9.475 + Path file; 9.476 + if (dir != null) { 9.477 + file = resolve(dir, relativePath); 9.478 + return PathFileObject.createDirectoryPathFileObject(this, file, dir); 9.479 + } else { 9.480 + file = getPath(getDefaultFileSystem(), relativePath); 9.481 + return PathFileObject.createSimplePathFileObject(this, file); 9.482 + } 9.483 + 9.484 + } 9.485 + 9.486 + @Override 9.487 + public String inferBinaryName(Location location, JavaFileObject fo) { 9.488 + nullCheck(fo); 9.489 + // Need to match the path semantics of list(location, ...) 9.490 + Iterable<? extends Path> paths = getLocation(location); 9.491 + if (paths == null) { 9.492 + return null; 9.493 + } 9.494 + 9.495 + if (!(fo instanceof PathFileObject)) 9.496 + throw new IllegalArgumentException(fo.getClass().getName()); 9.497 + 9.498 + return ((PathFileObject) fo).inferBinaryName(paths); 9.499 + } 9.500 + 9.501 + private FileSystem getFileSystem(Path p) throws IOException { 9.502 + FileSystem fs = fileSystems.get(p); 9.503 + if (fs == null) { 9.504 + fs = FileSystems.newFileSystem(p, Collections.<String,Void>emptyMap(), null); 9.505 + fileSystems.put(p, fs); 9.506 + } 9.507 + return fs; 9.508 + } 9.509 + 9.510 + private Map<Path,FileSystem> fileSystems; 9.511 + 9.512 + // </editor-fold> 9.513 + 9.514 + // <editor-fold defaultstate="collapsed" desc="Utility methods"> 9.515 + 9.516 + private static String getRelativePath(String className, Kind kind) { 9.517 + return className.replace(".", "/") + kind.extension; 9.518 + } 9.519 + 9.520 + private static String getRelativePath(String packageName, String relativeName) { 9.521 + return packageName.replace(".", "/") + relativeName; 9.522 + } 9.523 + 9.524 + private static String getBaseName(String relativePath) { 9.525 + int lastSep = relativePath.lastIndexOf("/"); 9.526 + return relativePath.substring(lastSep + 1); // safe if "/" not found 9.527 + } 9.528 + 9.529 + private static boolean isDirectory(Path path) throws IOException { 9.530 + BasicFileAttributes attrs = Attributes.readBasicFileAttributes(path); 9.531 + return attrs.isDirectory(); 9.532 + } 9.533 + 9.534 + private static Path getPath(FileSystem fs, String relativePath) { 9.535 + return fs.getPath(relativePath.replace("/", fs.getSeparator())); 9.536 + } 9.537 + 9.538 + private static Path resolve(Path base, String relativePath) { 9.539 + FileSystem fs = base.getFileSystem(); 9.540 + Path rp = fs.getPath(relativePath.replace("/", fs.getSeparator())); 9.541 + return base.resolve(rp); 9.542 + } 9.543 + 9.544 + // </editor-fold> 9.545 + 9.546 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/src/share/classes/com/sun/tools/javac/nio/PathFileManager.java Sat Dec 19 10:26:47 2009 -0800 10.3 @@ -0,0 +1,125 @@ 10.4 +/* 10.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 10.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10.7 + * 10.8 + * This code is free software; you can redistribute it and/or modify it 10.9 + * under the terms of the GNU General Public License version 2 only, as 10.10 + * published by the Free Software Foundation. Sun designates this 10.11 + * particular file as subject to the "Classpath" exception as provided 10.12 + * by Sun in the LICENSE file that accompanied this code. 10.13 + * 10.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 10.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 10.17 + * version 2 for more details (a copy is included in the LICENSE file that 10.18 + * accompanied this code). 10.19 + * 10.20 + * You should have received a copy of the GNU General Public License version 10.21 + * 2 along with this work; if not, write to the Free Software Foundation, 10.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 10.23 + * 10.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 10.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 10.26 + * have any questions. 10.27 + */ 10.28 + 10.29 +package com.sun.tools.javac.nio; 10.30 + 10.31 +import java.io.IOException; 10.32 +import java.nio.file.FileSystem; 10.33 +import java.nio.file.Path; 10.34 +import javax.tools.FileObject; 10.35 +import javax.tools.JavaFileManager; 10.36 +import javax.tools.JavaFileObject; 10.37 + 10.38 +/** 10.39 + * File manager based on {@linkplain File java.nio.file.Path}. 10.40 + * 10.41 + * Eventually, this should be moved to javax.tools. 10.42 + * Also, JavaCompiler might reasonably provide a method getPathFileManager, 10.43 + * similar to {@link javax.tools.JavaCompiler#getStandardFileManager 10.44 + * getStandardFileManager}. However, would need to be handled carefully 10.45 + * as another forward reference from langtools to jdk. 10.46 + * 10.47 + * <p><b>This is NOT part of any API supported by Sun Microsystems. If 10.48 + * you write code that depends on this, you do so at your own risk. 10.49 + * This code and its internal interfaces are subject to change or 10.50 + * deletion without notice.</b> 10.51 + */ 10.52 +public interface PathFileManager extends JavaFileManager { 10.53 + /** 10.54 + * Get the default file system used to create paths. If no value has been 10.55 + * set, the default file system is {@link FileSystems#getDefault}. 10.56 + */ 10.57 + FileSystem getDefaultFileSystem(); 10.58 + 10.59 + /** 10.60 + * Set the default file system used to create paths. 10.61 + * @param fs the default file system used to create any new paths. 10.62 + */ 10.63 + void setDefaultFileSystem(FileSystem fs); 10.64 + 10.65 + /** 10.66 + * Get file objects representing the given files. 10.67 + * 10.68 + * @param paths a list of paths 10.69 + * @return a list of file objects 10.70 + * @throws IllegalArgumentException if the list of paths includes 10.71 + * a directory 10.72 + */ 10.73 + Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths( 10.74 + Iterable<? extends Path> paths); 10.75 + 10.76 + /** 10.77 + * Get file objects representing the given paths. 10.78 + * Convenience method equivalent to: 10.79 + * 10.80 + * <pre> 10.81 + * getJavaFileObjectsFromPaths({@linkplain java.util.Arrays#asList Arrays.asList}(paths)) 10.82 + * </pre> 10.83 + * 10.84 + * @param paths an array of paths 10.85 + * @return a list of file objects 10.86 + * @throws IllegalArgumentException if the array of files includes 10.87 + * a directory 10.88 + * @throws NullPointerException if the given array contains null 10.89 + * elements 10.90 + */ 10.91 + Iterable<? extends JavaFileObject> getJavaFileObjects(Path... paths); 10.92 + 10.93 + /** 10.94 + * Return the Path for a file object that has been obtained from this 10.95 + * file manager. 10.96 + * 10.97 + * @param fo A file object that has been obtained from this file manager. 10.98 + * @return The underlying Path object. 10.99 + * @throws IllegalArgumentException is the file object was not obtained from 10.100 + * from this file manager. 10.101 + */ 10.102 + Path getPath(FileObject fo); 10.103 + 10.104 + /** 10.105 + * Get the search path associated with the given location. 10.106 + * 10.107 + * @param location a location 10.108 + * @return a list of paths or {@code null} if this location has no 10.109 + * associated search path 10.110 + * @see #setLocation 10.111 + */ 10.112 + Iterable<? extends Path> getLocation(Location location); 10.113 + 10.114 + /** 10.115 + * Associate the given search path with the given location. Any 10.116 + * previous value will be discarded. 10.117 + * 10.118 + * @param location a location 10.119 + * @param searchPath a list of files, if {@code null} use the default 10.120 + * search path for this location 10.121 + * @see #getLocation 10.122 + * @throws IllegalArgumentException if location is an output 10.123 + * location and searchpath does not contain exactly one element 10.124 + * @throws IOException if location is an output location and searchpath 10.125 + * does not represent an existing directory 10.126 + */ 10.127 + void setLocation(Location location, Iterable<? extends Path> searchPath) throws IOException; 10.128 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/src/share/classes/com/sun/tools/javac/nio/PathFileObject.java Sat Dec 19 10:26:47 2009 -0800 11.3 @@ -0,0 +1,319 @@ 11.4 +/* 11.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11.7 + * 11.8 + * This code is free software; you can redistribute it and/or modify it 11.9 + * under the terms of the GNU General Public License version 2 only, as 11.10 + * published by the Free Software Foundation. Sun designates this 11.11 + * particular file as subject to the "Classpath" exception as provided 11.12 + * by Sun in the LICENSE file that accompanied this code. 11.13 + * 11.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 11.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11.17 + * version 2 for more details (a copy is included in the LICENSE file that 11.18 + * accompanied this code). 11.19 + * 11.20 + * You should have received a copy of the GNU General Public License version 11.21 + * 2 along with this work; if not, write to the Free Software Foundation, 11.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 11.23 + * 11.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 11.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 11.26 + * have any questions. 11.27 + */ 11.28 + 11.29 +package com.sun.tools.javac.nio; 11.30 + 11.31 +import java.io.IOException; 11.32 +import java.io.InputStream; 11.33 +import java.io.InputStreamReader; 11.34 +import java.io.OutputStream; 11.35 +import java.io.OutputStreamWriter; 11.36 +import java.io.Reader; 11.37 +import java.io.Writer; 11.38 +import java.net.URI; 11.39 +import java.nio.ByteBuffer; 11.40 +import java.nio.CharBuffer; 11.41 +import java.nio.charset.CharsetDecoder; 11.42 +import java.nio.file.Files; 11.43 +import java.nio.file.Path; 11.44 +import java.nio.file.attribute.Attributes; 11.45 +import java.nio.file.attribute.BasicFileAttributes; 11.46 +import javax.lang.model.element.Modifier; 11.47 +import javax.lang.model.element.NestingKind; 11.48 +import javax.tools.JavaFileObject; 11.49 + 11.50 +import com.sun.tools.javac.util.BaseFileManager; 11.51 + 11.52 + 11.53 +/** 11.54 + * Implementation of JavaFileObject using java.nio.file API. 11.55 + * 11.56 + * <p>PathFileObjects are, for the most part, straightforward wrappers around 11.57 + * Path objects. The primary complexity is the support for "inferBinaryName". 11.58 + * This is left as an abstract method, implemented by each of a number of 11.59 + * different factory methods, which compute the binary name based on 11.60 + * information available at the time the file object is created. 11.61 + * 11.62 + * <p><b>This is NOT part of any API supported by Sun Microsystems. If 11.63 + * you write code that depends on this, you do so at your own risk. 11.64 + * This code and its internal interfaces are subject to change or 11.65 + * deletion without notice.</b> 11.66 + */ 11.67 +abstract class PathFileObject implements JavaFileObject { 11.68 + private JavacPathFileManager fileManager; 11.69 + private Path path; 11.70 + 11.71 + /** 11.72 + * Create a PathFileObject within a directory, such that the binary name 11.73 + * can be inferred from the relationship to the parent directory. 11.74 + */ 11.75 + static PathFileObject createDirectoryPathFileObject(JavacPathFileManager fileManager, 11.76 + final Path path, final Path dir) { 11.77 + return new PathFileObject(fileManager, path) { 11.78 + @Override 11.79 + String inferBinaryName(Iterable<? extends Path> paths) { 11.80 + return toBinaryName(dir.relativize(path)); 11.81 + } 11.82 + }; 11.83 + } 11.84 + 11.85 + /** 11.86 + * Create a PathFileObject in a file system such as a jar file, such that 11.87 + * the binary name can be inferred from its position within the filesystem. 11.88 + */ 11.89 + static PathFileObject createJarPathFileObject(JavacPathFileManager fileManager, 11.90 + final Path path) { 11.91 + return new PathFileObject(fileManager, path) { 11.92 + @Override 11.93 + String inferBinaryName(Iterable<? extends Path> paths) { 11.94 + return toBinaryName(path); 11.95 + } 11.96 + }; 11.97 + } 11.98 + 11.99 + /** 11.100 + * Create a PathFileObject whose binary name can be inferred from the 11.101 + * relative path to a sibling. 11.102 + */ 11.103 + static PathFileObject createSiblingPathFileObject(JavacPathFileManager fileManager, 11.104 + final Path path, final String relativePath) { 11.105 + return new PathFileObject(fileManager, path) { 11.106 + @Override 11.107 + String inferBinaryName(Iterable<? extends Path> paths) { 11.108 + return toBinaryName(relativePath, "/"); 11.109 + } 11.110 + }; 11.111 + } 11.112 + 11.113 + /** 11.114 + * Create a PathFileObject whose binary name might be inferred from its 11.115 + * position on a search path. 11.116 + */ 11.117 + static PathFileObject createSimplePathFileObject(JavacPathFileManager fileManager, 11.118 + final Path path) { 11.119 + return new PathFileObject(fileManager, path) { 11.120 + @Override 11.121 + String inferBinaryName(Iterable<? extends Path> paths) { 11.122 + Path absPath = path.toAbsolutePath(); 11.123 + for (Path p: paths) { 11.124 + Path ap = p.toAbsolutePath(); 11.125 + if (absPath.startsWith(ap)) { 11.126 + try { 11.127 + Path rp = ap.relativize(absPath); 11.128 + if (rp != null) // maybe null if absPath same as ap 11.129 + return toBinaryName(rp); 11.130 + } catch (IllegalArgumentException e) { 11.131 + // ignore this p if cannot relativize path to p 11.132 + } 11.133 + } 11.134 + } 11.135 + return null; 11.136 + } 11.137 + }; 11.138 + } 11.139 + 11.140 + protected PathFileObject(JavacPathFileManager fileManager, Path path) { 11.141 + fileManager.getClass(); // null check 11.142 + path.getClass(); // null check 11.143 + this.fileManager = fileManager; 11.144 + this.path = path; 11.145 + } 11.146 + 11.147 + abstract String inferBinaryName(Iterable<? extends Path> paths); 11.148 + 11.149 + /** 11.150 + * Return the Path for this object. 11.151 + * @return the Path for this object. 11.152 + */ 11.153 + Path getPath() { 11.154 + return path; 11.155 + } 11.156 + 11.157 + @Override 11.158 + public Kind getKind() { 11.159 + return BaseFileManager.getKind(path.getName().toString()); 11.160 + } 11.161 + 11.162 + @Override 11.163 + public boolean isNameCompatible(String simpleName, Kind kind) { 11.164 + simpleName.getClass(); 11.165 + // null check 11.166 + if (kind == Kind.OTHER && getKind() != kind) { 11.167 + return false; 11.168 + } 11.169 + String sn = simpleName + kind.extension; 11.170 + String pn = path.getName().toString(); 11.171 + if (pn.equals(sn)) { 11.172 + return true; 11.173 + } 11.174 + if (pn.equalsIgnoreCase(sn)) { 11.175 + try { 11.176 + // allow for Windows 11.177 + return path.toRealPath(false).getName().toString().equals(sn); 11.178 + } catch (IOException e) { 11.179 + } 11.180 + } 11.181 + return false; 11.182 + } 11.183 + 11.184 + @Override 11.185 + public NestingKind getNestingKind() { 11.186 + return null; 11.187 + } 11.188 + 11.189 + @Override 11.190 + public Modifier getAccessLevel() { 11.191 + return null; 11.192 + } 11.193 + 11.194 + @Override 11.195 + public URI toUri() { 11.196 + return path.toUri(); 11.197 + } 11.198 + 11.199 + @Override 11.200 + public String getName() { 11.201 + return path.toString(); 11.202 + } 11.203 + 11.204 + @Override 11.205 + public InputStream openInputStream() throws IOException { 11.206 + return path.newInputStream(); 11.207 + } 11.208 + 11.209 + @Override 11.210 + public OutputStream openOutputStream() throws IOException { 11.211 + ensureParentDirectoriesExist(); 11.212 + return path.newOutputStream(); 11.213 + } 11.214 + 11.215 + @Override 11.216 + public Reader openReader(boolean ignoreEncodingErrors) throws IOException { 11.217 + CharsetDecoder decoder = fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors); 11.218 + return new InputStreamReader(openInputStream(), decoder); 11.219 + } 11.220 + 11.221 + @Override 11.222 + public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { 11.223 + CharBuffer cb = fileManager.getCachedContent(this); 11.224 + if (cb == null) { 11.225 + InputStream in = openInputStream(); 11.226 + try { 11.227 + ByteBuffer bb = fileManager.makeByteBuffer(in); 11.228 + JavaFileObject prev = fileManager.log.useSource(this); 11.229 + try { 11.230 + cb = fileManager.decode(bb, ignoreEncodingErrors); 11.231 + } finally { 11.232 + fileManager.log.useSource(prev); 11.233 + } 11.234 + fileManager.recycleByteBuffer(bb); 11.235 + if (!ignoreEncodingErrors) { 11.236 + fileManager.cache(this, cb); 11.237 + } 11.238 + } finally { 11.239 + in.close(); 11.240 + } 11.241 + } 11.242 + return cb; 11.243 + } 11.244 + 11.245 + @Override 11.246 + public Writer openWriter() throws IOException { 11.247 + ensureParentDirectoriesExist(); 11.248 + return new OutputStreamWriter(path.newOutputStream(), fileManager.getEncodingName()); 11.249 + } 11.250 + 11.251 + @Override 11.252 + public long getLastModified() { 11.253 + try { 11.254 + BasicFileAttributes attrs = Attributes.readBasicFileAttributes(path); 11.255 + return attrs.lastModifiedTime().toMillis(); 11.256 + } catch (IOException e) { 11.257 + return -1; 11.258 + } 11.259 + } 11.260 + 11.261 + @Override 11.262 + public boolean delete() { 11.263 + try { 11.264 + path.delete(); 11.265 + return true; 11.266 + } catch (IOException e) { 11.267 + return false; 11.268 + } 11.269 + } 11.270 + 11.271 + public boolean isSameFile(PathFileObject other) { 11.272 + try { 11.273 + return path.isSameFile(other.path); 11.274 + } catch (IOException e) { 11.275 + return false; 11.276 + } 11.277 + } 11.278 + 11.279 + @Override 11.280 + public boolean equals(Object other) { 11.281 + return (other instanceof PathFileObject && path.equals(((PathFileObject) other).path)); 11.282 + } 11.283 + 11.284 + @Override 11.285 + public int hashCode() { 11.286 + return path.hashCode(); 11.287 + } 11.288 + 11.289 + @Override 11.290 + public String toString() { 11.291 + return getClass().getSimpleName() + "[" + path + "]"; 11.292 + } 11.293 + 11.294 + private void ensureParentDirectoriesExist() throws IOException { 11.295 + Path parent = path.getParent(); 11.296 + if (parent != null) 11.297 + Files.createDirectories(parent); 11.298 + } 11.299 + 11.300 + private long size() { 11.301 + try { 11.302 + BasicFileAttributes attrs = Attributes.readBasicFileAttributes(path); 11.303 + return attrs.size(); 11.304 + } catch (IOException e) { 11.305 + return -1; 11.306 + } 11.307 + } 11.308 + 11.309 + protected static String toBinaryName(Path relativePath) { 11.310 + return toBinaryName(relativePath.toString(), 11.311 + relativePath.getFileSystem().getSeparator()); 11.312 + } 11.313 + 11.314 + protected static String toBinaryName(String relativePath, String sep) { 11.315 + return removeExtension(relativePath).replaceAll(sep, "."); 11.316 + } 11.317 + 11.318 + protected static String removeExtension(String fileName) { 11.319 + int lastDot = fileName.lastIndexOf("."); 11.320 + return (lastDot == -1 ? fileName : fileName.substring(0, lastDot)); 11.321 + } 11.322 +}
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/src/share/classes/com/sun/tools/javac/util/BaseFileManager.java Sat Dec 19 10:26:47 2009 -0800 12.3 @@ -0,0 +1,355 @@ 12.4 +/* 12.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 12.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 12.7 + * 12.8 + * This code is free software; you can redistribute it and/or modify it 12.9 + * under the terms of the GNU General Public License version 2 only, as 12.10 + * published by the Free Software Foundation. Sun designates this 12.11 + * particular file as subject to the "Classpath" exception as provided 12.12 + * by Sun in the LICENSE file that accompanied this code. 12.13 + * 12.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 12.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12.17 + * version 2 for more details (a copy is included in the LICENSE file that 12.18 + * accompanied this code). 12.19 + * 12.20 + * You should have received a copy of the GNU General Public License version 12.21 + * 2 along with this work; if not, write to the Free Software Foundation, 12.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 12.23 + * 12.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 12.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 12.26 + * have any questions. 12.27 + */ 12.28 + 12.29 +package com.sun.tools.javac.util; 12.30 + 12.31 +import com.sun.tools.javac.code.Source; 12.32 +import com.sun.tools.javac.main.JavacOption; 12.33 +import com.sun.tools.javac.main.OptionName; 12.34 +import com.sun.tools.javac.main.RecognizedOptions; 12.35 +import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition; 12.36 +import java.io.ByteArrayOutputStream; 12.37 +import java.io.Closeable; 12.38 +import java.io.IOException; 12.39 +import java.io.InputStream; 12.40 +import java.io.OutputStreamWriter; 12.41 +import java.lang.ref.SoftReference; 12.42 +import java.lang.reflect.Constructor; 12.43 +import java.net.URL; 12.44 +import java.net.URLClassLoader; 12.45 +import java.nio.ByteBuffer; 12.46 +import java.nio.CharBuffer; 12.47 +import java.nio.charset.Charset; 12.48 +import java.nio.charset.CharsetDecoder; 12.49 +import java.nio.charset.CoderResult; 12.50 +import java.nio.charset.CodingErrorAction; 12.51 +import java.nio.charset.IllegalCharsetNameException; 12.52 +import java.nio.charset.UnsupportedCharsetException; 12.53 +import java.util.Collection; 12.54 +import java.util.HashMap; 12.55 +import java.util.Iterator; 12.56 +import java.util.Map; 12.57 +import javax.tools.JavaFileObject; 12.58 +import javax.tools.JavaFileObject.Kind; 12.59 + 12.60 +/** 12.61 + * Utility methods for building a filemanager. 12.62 + * There are no references here to file-system specific objects such as 12.63 + * java.io.File or java.nio.file.Path. 12.64 + */ 12.65 +public class BaseFileManager { 12.66 + protected BaseFileManager(Charset charset) { 12.67 + this.charset = charset; 12.68 + byteBufferCache = new ByteBufferCache(); 12.69 + } 12.70 + 12.71 + /** 12.72 + * Set the context for JavacPathFileManager. 12.73 + */ 12.74 + protected void setContext(Context context) { 12.75 + log = Log.instance(context); 12.76 + options = Options.instance(context); 12.77 + classLoaderClass = options.get("procloader"); 12.78 + } 12.79 + 12.80 + /** 12.81 + * The log to be used for error reporting. 12.82 + */ 12.83 + public Log log; 12.84 + 12.85 + /** 12.86 + * User provided charset (through javax.tools). 12.87 + */ 12.88 + protected Charset charset; 12.89 + 12.90 + protected Options options; 12.91 + 12.92 + protected String classLoaderClass; 12.93 + 12.94 + protected Source getSource() { 12.95 + String sourceName = options.get(OptionName.SOURCE); 12.96 + Source source = null; 12.97 + if (sourceName != null) 12.98 + source = Source.lookup(sourceName); 12.99 + return (source != null ? source : Source.DEFAULT); 12.100 + } 12.101 + 12.102 + protected ClassLoader getClassLoader(URL[] urls) { 12.103 + ClassLoader thisClassLoader = getClass().getClassLoader(); 12.104 + 12.105 + // Bug: 6558476 12.106 + // Ideally, ClassLoader should be Closeable, but before JDK7 it is not. 12.107 + // On older versions, try the following, to get a closeable classloader. 12.108 + 12.109 + // 1: Allow client to specify the class to use via hidden option 12.110 + if (classLoaderClass != null) { 12.111 + try { 12.112 + Class<? extends ClassLoader> loader = 12.113 + Class.forName(classLoaderClass).asSubclass(ClassLoader.class); 12.114 + Class<?>[] constrArgTypes = { URL[].class, ClassLoader.class }; 12.115 + Constructor<? extends ClassLoader> constr = loader.getConstructor(constrArgTypes); 12.116 + return constr.newInstance(new Object[] { urls, thisClassLoader }); 12.117 + } catch (Throwable t) { 12.118 + // ignore errors loading user-provided class loader, fall through 12.119 + } 12.120 + } 12.121 + 12.122 + // 2: If URLClassLoader implements Closeable, use that. 12.123 + if (Closeable.class.isAssignableFrom(URLClassLoader.class)) 12.124 + return new URLClassLoader(urls, thisClassLoader); 12.125 + 12.126 + // 3: Try using private reflection-based CloseableURLClassLoader 12.127 + try { 12.128 + return new CloseableURLClassLoader(urls, thisClassLoader); 12.129 + } catch (Throwable t) { 12.130 + // ignore errors loading workaround class loader, fall through 12.131 + } 12.132 + 12.133 + // 4: If all else fails, use plain old standard URLClassLoader 12.134 + return new URLClassLoader(urls, thisClassLoader); 12.135 + } 12.136 + 12.137 + // <editor-fold defaultstate="collapsed" desc="Option handling"> 12.138 + public boolean handleOption(String current, Iterator<String> remaining) { 12.139 + for (JavacOption o: javacFileManagerOptions) { 12.140 + if (o.matches(current)) { 12.141 + if (o.hasArg()) { 12.142 + if (remaining.hasNext()) { 12.143 + if (!o.process(options, current, remaining.next())) 12.144 + return true; 12.145 + } 12.146 + } else { 12.147 + if (!o.process(options, current)) 12.148 + return true; 12.149 + } 12.150 + // operand missing, or process returned false 12.151 + throw new IllegalArgumentException(current); 12.152 + } 12.153 + } 12.154 + 12.155 + return false; 12.156 + } 12.157 + // where 12.158 + private static JavacOption[] javacFileManagerOptions = 12.159 + RecognizedOptions.getJavacFileManagerOptions( 12.160 + new RecognizedOptions.GrumpyHelper()); 12.161 + 12.162 + public int isSupportedOption(String option) { 12.163 + for (JavacOption o : javacFileManagerOptions) { 12.164 + if (o.matches(option)) 12.165 + return o.hasArg() ? 1 : 0; 12.166 + } 12.167 + return -1; 12.168 + } 12.169 + // </editor-fold> 12.170 + 12.171 + // <editor-fold defaultstate="collapsed" desc="Encoding"> 12.172 + private String defaultEncodingName; 12.173 + private String getDefaultEncodingName() { 12.174 + if (defaultEncodingName == null) { 12.175 + defaultEncodingName = 12.176 + new OutputStreamWriter(new ByteArrayOutputStream()).getEncoding(); 12.177 + } 12.178 + return defaultEncodingName; 12.179 + } 12.180 + 12.181 + public String getEncodingName() { 12.182 + String encName = options.get(OptionName.ENCODING); 12.183 + if (encName == null) 12.184 + return getDefaultEncodingName(); 12.185 + else 12.186 + return encName; 12.187 + } 12.188 + 12.189 + public CharBuffer decode(ByteBuffer inbuf, boolean ignoreEncodingErrors) { 12.190 + String encodingName = getEncodingName(); 12.191 + CharsetDecoder decoder; 12.192 + try { 12.193 + decoder = getDecoder(encodingName, ignoreEncodingErrors); 12.194 + } catch (IllegalCharsetNameException e) { 12.195 + log.error("unsupported.encoding", encodingName); 12.196 + return (CharBuffer)CharBuffer.allocate(1).flip(); 12.197 + } catch (UnsupportedCharsetException e) { 12.198 + log.error("unsupported.encoding", encodingName); 12.199 + return (CharBuffer)CharBuffer.allocate(1).flip(); 12.200 + } 12.201 + 12.202 + // slightly overestimate the buffer size to avoid reallocation. 12.203 + float factor = 12.204 + decoder.averageCharsPerByte() * 0.8f + 12.205 + decoder.maxCharsPerByte() * 0.2f; 12.206 + CharBuffer dest = CharBuffer. 12.207 + allocate(10 + (int)(inbuf.remaining()*factor)); 12.208 + 12.209 + while (true) { 12.210 + CoderResult result = decoder.decode(inbuf, dest, true); 12.211 + dest.flip(); 12.212 + 12.213 + if (result.isUnderflow()) { // done reading 12.214 + // make sure there is at least one extra character 12.215 + if (dest.limit() == dest.capacity()) { 12.216 + dest = CharBuffer.allocate(dest.capacity()+1).put(dest); 12.217 + dest.flip(); 12.218 + } 12.219 + return dest; 12.220 + } else if (result.isOverflow()) { // buffer too small; expand 12.221 + int newCapacity = 12.222 + 10 + dest.capacity() + 12.223 + (int)(inbuf.remaining()*decoder.maxCharsPerByte()); 12.224 + dest = CharBuffer.allocate(newCapacity).put(dest); 12.225 + } else if (result.isMalformed() || result.isUnmappable()) { 12.226 + // bad character in input 12.227 + 12.228 + // report coding error (warn only pre 1.5) 12.229 + if (!getSource().allowEncodingErrors()) { 12.230 + log.error(new SimpleDiagnosticPosition(dest.limit()), 12.231 + "illegal.char.for.encoding", 12.232 + charset == null ? encodingName : charset.name()); 12.233 + } else { 12.234 + log.warning(new SimpleDiagnosticPosition(dest.limit()), 12.235 + "illegal.char.for.encoding", 12.236 + charset == null ? encodingName : charset.name()); 12.237 + } 12.238 + 12.239 + // skip past the coding error 12.240 + inbuf.position(inbuf.position() + result.length()); 12.241 + 12.242 + // undo the flip() to prepare the output buffer 12.243 + // for more translation 12.244 + dest.position(dest.limit()); 12.245 + dest.limit(dest.capacity()); 12.246 + dest.put((char)0xfffd); // backward compatible 12.247 + } else { 12.248 + throw new AssertionError(result); 12.249 + } 12.250 + } 12.251 + // unreached 12.252 + } 12.253 + 12.254 + public CharsetDecoder getDecoder(String encodingName, boolean ignoreEncodingErrors) { 12.255 + Charset cs = (this.charset == null) 12.256 + ? Charset.forName(encodingName) 12.257 + : this.charset; 12.258 + CharsetDecoder decoder = cs.newDecoder(); 12.259 + 12.260 + CodingErrorAction action; 12.261 + if (ignoreEncodingErrors) 12.262 + action = CodingErrorAction.REPLACE; 12.263 + else 12.264 + action = CodingErrorAction.REPORT; 12.265 + 12.266 + return decoder 12.267 + .onMalformedInput(action) 12.268 + .onUnmappableCharacter(action); 12.269 + } 12.270 + // </editor-fold> 12.271 + 12.272 + // <editor-fold defaultstate="collapsed" desc="ByteBuffers"> 12.273 + /** 12.274 + * Make a byte buffer from an input stream. 12.275 + */ 12.276 + public ByteBuffer makeByteBuffer(InputStream in) 12.277 + throws IOException { 12.278 + int limit = in.available(); 12.279 + if (limit < 1024) limit = 1024; 12.280 + ByteBuffer result = byteBufferCache.get(limit); 12.281 + int position = 0; 12.282 + while (in.available() != 0) { 12.283 + if (position >= limit) 12.284 + // expand buffer 12.285 + result = ByteBuffer. 12.286 + allocate(limit <<= 1). 12.287 + put((ByteBuffer)result.flip()); 12.288 + int count = in.read(result.array(), 12.289 + position, 12.290 + limit - position); 12.291 + if (count < 0) break; 12.292 + result.position(position += count); 12.293 + } 12.294 + return (ByteBuffer)result.flip(); 12.295 + } 12.296 + 12.297 + public void recycleByteBuffer(ByteBuffer bb) { 12.298 + byteBufferCache.put(bb); 12.299 + } 12.300 + 12.301 + /** 12.302 + * A single-element cache of direct byte buffers. 12.303 + */ 12.304 + private static class ByteBufferCache { 12.305 + private ByteBuffer cached; 12.306 + ByteBuffer get(int capacity) { 12.307 + if (capacity < 20480) capacity = 20480; 12.308 + ByteBuffer result = 12.309 + (cached != null && cached.capacity() >= capacity) 12.310 + ? (ByteBuffer)cached.clear() 12.311 + : ByteBuffer.allocate(capacity + capacity>>1); 12.312 + cached = null; 12.313 + return result; 12.314 + } 12.315 + void put(ByteBuffer x) { 12.316 + cached = x; 12.317 + } 12.318 + } 12.319 + 12.320 + private final ByteBufferCache byteBufferCache; 12.321 + // </editor-fold> 12.322 + 12.323 + // <editor-fold defaultstate="collapsed" desc="Content cache"> 12.324 + public CharBuffer getCachedContent(JavaFileObject file) { 12.325 + SoftReference<CharBuffer> r = contentCache.get(file); 12.326 + return (r == null ? null : r.get()); 12.327 + } 12.328 + 12.329 + public void cache(JavaFileObject file, CharBuffer cb) { 12.330 + contentCache.put(file, new SoftReference<CharBuffer>(cb)); 12.331 + } 12.332 + 12.333 + protected final Map<JavaFileObject, SoftReference<CharBuffer>> contentCache 12.334 + = new HashMap<JavaFileObject, SoftReference<CharBuffer>>(); 12.335 + // </editor-fold> 12.336 + 12.337 + public static Kind getKind(String name) { 12.338 + if (name.endsWith(Kind.CLASS.extension)) 12.339 + return Kind.CLASS; 12.340 + else if (name.endsWith(Kind.SOURCE.extension)) 12.341 + return Kind.SOURCE; 12.342 + else if (name.endsWith(Kind.HTML.extension)) 12.343 + return Kind.HTML; 12.344 + else 12.345 + return Kind.OTHER; 12.346 + } 12.347 + 12.348 + protected static <T> T nullCheck(T o) { 12.349 + o.getClass(); // null check 12.350 + return o; 12.351 + } 12.352 + 12.353 + protected static <T> Collection<T> nullCheck(Collection<T> it) { 12.354 + for (T t : it) 12.355 + t.getClass(); // null check 12.356 + return it; 12.357 + } 12.358 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/src/share/classes/com/sun/tools/javac/util/CloseableURLClassLoader.java Sat Dec 19 10:26:47 2009 -0800 13.3 @@ -0,0 +1,108 @@ 13.4 +/* 13.5 + * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. 13.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 13.7 + * 13.8 + * This code is free software; you can redistribute it and/or modify it 13.9 + * under the terms of the GNU General Public License version 2 only, as 13.10 + * published by the Free Software Foundation. Sun designates this 13.11 + * particular file as subject to the "Classpath" exception as provided 13.12 + * by Sun in the LICENSE file that accompanied this code. 13.13 + * 13.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 13.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13.17 + * version 2 for more details (a copy is included in the LICENSE file that 13.18 + * accompanied this code). 13.19 + * 13.20 + * You should have received a copy of the GNU General Public License version 13.21 + * 2 along with this work; if not, write to the Free Software Foundation, 13.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 13.23 + * 13.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 13.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 13.26 + * have any questions. 13.27 + */ 13.28 + 13.29 +package com.sun.tools.javac.util; 13.30 + 13.31 +import java.io.Closeable; 13.32 +import java.io.IOException; 13.33 +import java.lang.reflect.Field; 13.34 +import java.net.URL; 13.35 +import java.net.URLClassLoader; 13.36 +import java.util.ArrayList; 13.37 +import java.util.jar.JarFile; 13.38 + 13.39 +/** 13.40 + * A URLClassLoader that also implements Closeable. 13.41 + * Reflection is used to access internal data structures in the URLClassLoader, 13.42 + * since no public API exists for this purpose. Therefore this code is somewhat 13.43 + * fragile. Caveat emptor. 13.44 + * @throws Error if the internal data structures are not as expected. 13.45 + * 13.46 + * <p><b>This is NOT part of any API supported by Sun Microsystems. If 13.47 + * you write code that depends on this, you do so at your own risk. 13.48 + * This code and its internal interfaces are subject to change or 13.49 + * deletion without notice.</b> 13.50 + */ 13.51 +public class CloseableURLClassLoader 13.52 + extends URLClassLoader implements Closeable { 13.53 + public CloseableURLClassLoader(URL[] urls, ClassLoader parent) throws Error { 13.54 + super(urls, parent); 13.55 + try { 13.56 + getLoaders(); //proactive check that URLClassLoader is as expected 13.57 + } catch (Throwable t) { 13.58 + throw new Error("cannot create CloseableURLClassLoader", t); 13.59 + } 13.60 + } 13.61 + 13.62 + /** 13.63 + * Close any jar files that may have been opened by the class loader. 13.64 + * Reflection is used to access the jar files in the URLClassLoader's 13.65 + * internal data structures. 13.66 + * @throws java.io.IOException if the jar files cannot be found for any 13.67 + * reson, or if closing the jar file itself causes an IOException. 13.68 + */ 13.69 + @Override 13.70 + public void close() throws IOException { 13.71 + try { 13.72 + for (Object l: getLoaders()) { 13.73 + if (l.getClass().getName().equals("sun.misc.URLClassPath$JarLoader")) { 13.74 + Field jarField = l.getClass().getDeclaredField("jar"); 13.75 + JarFile jar = (JarFile) getField(l, jarField); 13.76 + if (jar != null) { 13.77 + //System.err.println("CloseableURLClassLoader: closing " + jar); 13.78 + jar.close(); 13.79 + } 13.80 + } 13.81 + } 13.82 + } catch (Throwable t) { 13.83 + IOException e = new IOException("cannot close class loader"); 13.84 + e.initCause(t); 13.85 + throw e; 13.86 + } 13.87 + } 13.88 + 13.89 + private ArrayList<?> getLoaders() 13.90 + throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException 13.91 + { 13.92 + Field ucpField = URLClassLoader.class.getDeclaredField("ucp"); 13.93 + Object urlClassPath = getField(this, ucpField); 13.94 + if (urlClassPath == null) 13.95 + throw new AssertionError("urlClassPath not set in URLClassLoader"); 13.96 + Field loadersField = urlClassPath.getClass().getDeclaredField("loaders"); 13.97 + return (ArrayList<?>) getField(urlClassPath, loadersField); 13.98 + } 13.99 + 13.100 + private Object getField(Object o, Field f) 13.101 + throws IllegalArgumentException, IllegalAccessException { 13.102 + boolean prev = f.isAccessible(); 13.103 + try { 13.104 + f.setAccessible(true); 13.105 + return f.get(o); 13.106 + } finally { 13.107 + f.setAccessible(prev); 13.108 + } 13.109 + } 13.110 + 13.111 +}
14.1 --- a/src/share/classes/javax/lang/model/element/package-info.java Thu Dec 17 14:10:44 2009 -0800 14.2 +++ b/src/share/classes/javax/lang/model/element/package-info.java Sat Dec 19 10:26:47 2009 -0800 14.3 @@ -26,6 +26,16 @@ 14.4 /** 14.5 * Interfaces used to model elements of the Java programming language. 14.6 * 14.7 + * The term "element" in this package is used to refer to program 14.8 + * elements, the declared entities that make up a program. Elements 14.9 + * include classes, interfaces, methods, constructors, and fields. 14.10 + * The interfaces in this package do not model the structure of a 14.11 + * program inside a method body; for example there is no 14.12 + * representation of a {@code for} loop or {@code try}-{@code finally} 14.13 + * block. However, the interfaces can model some structures only 14.14 + * appearing inside method bodies, such as local variables and 14.15 + * anonymous classes. 14.16 + * 14.17 * <p>When used in the context of annotation processing, an accurate 14.18 * model of the element being represented must be returned. As this 14.19 * is a language model, the source code provides the fiducial
15.1 --- a/src/share/classes/javax/tools/StandardJavaFileManager.java Thu Dec 17 14:10:44 2009 -0800 15.2 +++ b/src/share/classes/javax/tools/StandardJavaFileManager.java Sat Dec 19 10:26:47 2009 -0800 15.3 @@ -28,7 +28,6 @@ 15.4 import java.io.File; 15.5 import java.io.IOException; 15.6 import java.util.*; 15.7 -import java.util.concurrent.*; 15.8 15.9 /** 15.10 * File manager based on {@linkplain File java.io.File}. A common way
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/test/tools/javac/nio/compileTest/CompileTest.java Sat Dec 19 10:26:47 2009 -0800 16.3 @@ -0,0 +1,165 @@ 16.4 +/* 16.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 16.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 16.7 + * 16.8 + * This code is free software; you can redistribute it and/or modify it 16.9 + * under the terms of the GNU General Public License version 2 only, as 16.10 + * published by the Free Software Foundation. 16.11 + * 16.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 16.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16.15 + * version 2 for more details (a copy is included in the LICENSE file that 16.16 + * accompanied this code). 16.17 + * 16.18 + * You should have received a copy of the GNU General Public License version 16.19 + * 2 along with this work; if not, write to the Free Software Foundation, 16.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 16.21 + * 16.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 16.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 16.24 + * have any questions. 16.25 + */ 16.26 + 16.27 +/** 16.28 + * @test 16.29 + * @compile HelloPathWorld.java 16.30 + * @run main CompileTest 16.31 + */ 16.32 + 16.33 +import java.io.*; 16.34 +import java.nio.file.*; 16.35 +import java.util.*; 16.36 +import java.util.jar.*; 16.37 +import javax.tools.*; 16.38 + 16.39 +import com.sun.tools.javac.nio.*; 16.40 +import com.sun.tools.javac.util.Context; 16.41 +import java.nio.file.spi.FileSystemProvider; 16.42 + 16.43 + 16.44 +public class CompileTest { 16.45 + public static void main(String[] args) throws Exception { 16.46 + new CompileTest().run(); 16.47 + } 16.48 + 16.49 + public void run() throws Exception { 16.50 + File rtDir = new File("rt.dir"); 16.51 + File javaHome = new File(System.getProperty("java.home")); 16.52 + if (javaHome.getName().equals("jre")) 16.53 + javaHome = javaHome.getParentFile(); 16.54 + File rtJar = new File(new File(new File(javaHome, "jre"), "lib"), "rt.jar"); 16.55 + expand(rtJar, rtDir); 16.56 + 16.57 + String[] rtDir_opts = { 16.58 + "-bootclasspath", rtDir.toString(), 16.59 + "-classpath", "", 16.60 + "-sourcepath", "", 16.61 + "-extdirs", "" 16.62 + }; 16.63 + test(rtDir_opts, "HelloPathWorld"); 16.64 + 16.65 + if (isJarFileSystemAvailable()) { 16.66 + String[] rtJar_opts = { 16.67 + "-bootclasspath", rtJar.toString(), 16.68 + "-classpath", "", 16.69 + "-sourcepath", "", 16.70 + "-extdirs", "" 16.71 + }; 16.72 + test(rtJar_opts, "HelloPathWorld"); 16.73 + 16.74 + String[] default_opts = { }; 16.75 + test(default_opts, "HelloPathWorld"); 16.76 + 16.77 + // finally, a non-trivial program 16.78 + test(default_opts, "CompileTest"); 16.79 + } else 16.80 + System.err.println("jar file system not available: test skipped"); 16.81 + } 16.82 + 16.83 + void test(String[] opts, String className) throws Exception { 16.84 + count++; 16.85 + System.err.println("Test " + count + " " + Arrays.asList(opts) + " " + className); 16.86 + Path testSrcDir = Paths.get(System.getProperty("test.src")); 16.87 + Path testClassesDir = Paths.get(System.getProperty("test.classes")); 16.88 + Path classes = Paths.get("classes." + count); 16.89 + classes.createDirectory(); 16.90 + 16.91 + Context ctx = new Context(); 16.92 + PathFileManager fm = new JavacPathFileManager(ctx, true, null); 16.93 + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 16.94 + List<String> options = new ArrayList<String>(); 16.95 + options.addAll(Arrays.asList(opts)); 16.96 + options.addAll(Arrays.asList( 16.97 + "-verbose", "-XDverboseCompilePolicy", 16.98 + "-d", classes.toString() 16.99 + )); 16.100 + Iterable<? extends JavaFileObject> compilationUnits = 16.101 + fm.getJavaFileObjects(testSrcDir.resolve(className + ".java")); 16.102 + StringWriter sw = new StringWriter(); 16.103 + PrintWriter out = new PrintWriter(sw); 16.104 + JavaCompiler.CompilationTask t = 16.105 + compiler.getTask(out, fm, null, options, null, compilationUnits); 16.106 + boolean ok = t.call(); 16.107 + System.err.println(sw.toString()); 16.108 + if (!ok) { 16.109 + throw new Exception("compilation failed"); 16.110 + } 16.111 + 16.112 + File expect = new File("classes." + count + "/" + className + ".class"); 16.113 + if (!expect.exists()) 16.114 + throw new Exception("expected file not found: " + expect); 16.115 + long expectedSize = new File(testClassesDir.toString(), className + ".class").length(); 16.116 + long actualSize = expect.length(); 16.117 + if (expectedSize != actualSize) 16.118 + throw new Exception("wrong size found: " + actualSize + "; expected: " + expectedSize); 16.119 + } 16.120 + 16.121 + boolean isJarFileSystemAvailable() { 16.122 + boolean result = false; 16.123 + for (FileSystemProvider fsp: FileSystemProvider.installedProviders()) { 16.124 + String scheme = fsp.getScheme(); 16.125 + System.err.println("Provider: " + scheme + " " + fsp); 16.126 + if (scheme.equalsIgnoreCase("jar") || scheme.equalsIgnoreCase("zip")) 16.127 + result = true; 16.128 + } 16.129 + return result; 16.130 + } 16.131 + 16.132 + void expand(File jar, File dir) throws IOException { 16.133 + JarFile jarFile = new JarFile(jar); 16.134 + try { 16.135 + Enumeration<JarEntry> entries = jarFile.entries(); 16.136 + while (entries.hasMoreElements()) { 16.137 + JarEntry je = entries.nextElement(); 16.138 + if (!je.isDirectory()) { 16.139 + copy(jarFile.getInputStream(je), new File(dir, je.getName())); 16.140 + } 16.141 + } 16.142 + } finally { 16.143 + jarFile.close(); 16.144 + } 16.145 + } 16.146 + 16.147 + void copy(InputStream in, File dest) throws IOException { 16.148 + dest.getParentFile().mkdirs(); 16.149 + OutputStream out = new BufferedOutputStream(new FileOutputStream(dest)); 16.150 + try { 16.151 + byte[] data = new byte[8192]; 16.152 + int n; 16.153 + while ((n = in.read(data, 0, data.length)) > 0) 16.154 + out.write(data, 0, n); 16.155 + } finally { 16.156 + out.close(); 16.157 + in.close(); 16.158 + } 16.159 + } 16.160 + 16.161 + void error(String message) { 16.162 + System.err.println("Error: " + message); 16.163 + errors++; 16.164 + } 16.165 + 16.166 + int errors; 16.167 + int count; 16.168 +}
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/test/tools/javac/nio/compileTest/HelloPathWorld.java Sat Dec 19 10:26:47 2009 -0800 17.3 @@ -0,0 +1,28 @@ 17.4 +/* 17.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 17.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 17.7 + * 17.8 + * This code is free software; you can redistribute it and/or modify it 17.9 + * under the terms of the GNU General Public License version 2 only, as 17.10 + * published by the Free Software Foundation. 17.11 + * 17.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 17.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17.15 + * version 2 for more details (a copy is included in the LICENSE file that 17.16 + * accompanied this code). 17.17 + * 17.18 + * You should have received a copy of the GNU General Public License version 17.19 + * 2 along with this work; if not, write to the Free Software Foundation, 17.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17.21 + * 17.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 17.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 17.24 + * have any questions. 17.25 + */ 17.26 + 17.27 +class HelloPathWorld { 17.28 + public static void main(String... args) { 17.29 + System.out.println("Hello World!"); 17.30 + } 17.31 +}
18.1 --- a/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java Thu Dec 17 14:10:44 2009 -0800 18.2 +++ b/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java Sat Dec 19 10:26:47 2009 -0800 18.3 @@ -23,7 +23,7 @@ 18.4 18.5 /* 18.6 * @test 18.7 - * @bug 6397298 6400986 6425592 6449798 6453386 6508401 6498938 18.8 + * @bug 6397298 6400986 6425592 6449798 6453386 6508401 6498938 6911854 18.9 * @summary Tests that getElementsAnnotatedWith works properly. 18.10 * @author Joseph D. Darcy 18.11 * @compile TestElementsAnnotatedWith.java 18.12 @@ -33,8 +33,8 @@ 18.13 * @compile -processor TestElementsAnnotatedWith -proc:only Part1.java Part2.java 18.14 * @compile -processor TestElementsAnnotatedWith -proc:only C2.java 18.15 * @compile -processor TestElementsAnnotatedWith -proc:only Foo.java 18.16 - * @compile -XD-d=. Foo.java 18.17 - * @compile -processor TestElementsAnnotatedWith -proc:only TestElementsAnnotatedWith.java 18.18 + * @compile Foo.java 18.19 + * @compile/process -processor TestElementsAnnotatedWith -proc:only Foo 18.20 */ 18.21 18.22 import java.lang.annotation.Annotation; 18.23 @@ -89,7 +89,7 @@ 18.24 // Verify that the annotation information is as 18.25 // expected. 18.26 18.27 - Set<String> expectedNames = new HashSet<String>(Arrays.asList(annotatedElementInfo.names())); 18.28 + Set<String> expectedNames = new HashSet<>(Arrays.asList(annotatedElementInfo.names())); 18.29 18.30 resultsMeta = 18.31 roundEnvironment. 18.32 @@ -126,9 +126,6 @@ 18.33 System.err.println("AnnotatedElementInfo: " + annotatedElementInfo); 18.34 throw new RuntimeException(); 18.35 } 18.36 - 18.37 - if("TestElementsAnnotatedWith".equals(firstType.getSimpleName().toString())) 18.38 - writeClassFile(); // Start another round to test class file input 18.39 } else { 18.40 // If processing is over without an error, the specified 18.41 // elements should be empty so an empty set should be returned. 18.42 @@ -163,48 +160,14 @@ 18.43 } catch(IllegalArgumentException iae) {} 18.44 18.45 try { 18.46 - Set<? extends Element> elements = roundEnvironment.getElementsAnnotatedWith(processingEnv. 18.47 - getElementUtils(). 18.48 - getTypeElement("java.lang.Object") ); 18.49 + Set<? extends Element> elements = 18.50 + roundEnvironment.getElementsAnnotatedWith(processingEnv. 18.51 + getElementUtils(). 18.52 + getTypeElement("java.lang.Object") ); 18.53 throw new RuntimeException("Illegal argument exception not thrown"); 18.54 } catch(IllegalArgumentException iae) {} 18.55 } 18.56 18.57 - /* 18.58 - * Hack alert! The class file read below is generated by the 18.59 - * "@compile -XD-d=. Foo.java" directive above. This sneakily 18.60 - * overrides the output location to the current directory where a 18.61 - * subsequent @compile can read the file. This could be improved 18.62 - * if either a new directive like @process accepted class file 18.63 - * arguments (the javac command accepts such arguments but 18.64 - * @compile does not) or the test.src and test.classes properties 18.65 - * were set to be read with @compile jobs. 18.66 - */ 18.67 - private void writeClassFile() { 18.68 - try { 18.69 - Filer filer = processingEnv.getFiler(); 18.70 - JavaFileObject jfo = filer.createClassFile("Foo"); 18.71 - OutputStream os = jfo.openOutputStream(); 18.72 - // Copy the bytes over 18.73 - System.out.println((new File(".")).getAbsolutePath()); 18.74 - InputStream io = new BufferedInputStream(new FileInputStream(new File(".", "Foo.class"))); 18.75 - try { 18.76 - int datum = io.read(); 18.77 - while(datum != -1) { 18.78 - os.write(datum); 18.79 - datum = io.read(); 18.80 - } 18.81 - } finally { 18.82 - io.close(); 18.83 - } 18.84 - os.close(); 18.85 - } catch (IOException ioe) { 18.86 - throw new RuntimeException(ioe); 18.87 - } 18.88 - 18.89 - 18.90 - } 18.91 - 18.92 @Override 18.93 public SourceVersion getSupportedSourceVersion() { 18.94 return SourceVersion.latest();
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/test/tools/javap/classfile/deps/GetDeps.java Sat Dec 19 10:26:47 2009 -0800 19.3 @@ -0,0 +1,211 @@ 19.4 +/* 19.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 19.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 19.7 + * 19.8 + * This code is free software; you can redistribute it and/or modify it 19.9 + * under the terms of the GNU General Public License version 2 only, as 19.10 + * published by the Free Software Foundation. Sun designates this 19.11 + * particular file as subject to the "Classpath" exception as provided 19.12 + * by Sun in the LICENSE file that accompanied this code. 19.13 + * 19.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 19.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 19.17 + * version 2 for more details (a copy is included in the LICENSE file that 19.18 + * accompanied this code). 19.19 + * 19.20 + * You should have received a copy of the GNU General Public License version 19.21 + * 2 along with this work; if not, write to the Free Software Foundation, 19.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19.23 + * 19.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 19.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 19.26 + * have any questions. 19.27 + */ 19.28 + 19.29 +import java.io.*; 19.30 +import java.util.*; 19.31 +import java.util.regex.Pattern; 19.32 +import javax.tools.*; 19.33 + 19.34 +import com.sun.tools.classfile.*; 19.35 +import com.sun.tools.classfile.Dependencies.*; 19.36 +import com.sun.tools.classfile.Dependency.Location; 19.37 +import com.sun.tools.javac.file.JavacFileManager; 19.38 +import com.sun.tools.javac.util.Context; 19.39 + 19.40 +/** 19.41 + * Demo utility for using the classfile dependency analysis API framework. 19.42 + * 19.43 + * Usage: 19.44 + * getdeps [options] classes 19.45 + * where options include: 19.46 + * -classpath path where to find classes to analyze 19.47 + * -p package-name restrict analysis to classes in this package 19.48 + * (may be given multiple times) 19.49 + * -r regex restrict analysis to packages matching pattern 19.50 + * (-p and -r are exclusive) 19.51 + * -rev invert the dependencies in the output 19.52 + * -t transitive closure of dependencies 19.53 + */ 19.54 +public class GetDeps { 19.55 + public static void main(String... args) throws Exception { 19.56 + new GetDeps().run(args); 19.57 + } 19.58 + 19.59 + void run(String... args) throws IOException, ClassFileNotFoundException { 19.60 + PrintWriter pw = new PrintWriter(System.out); 19.61 + try { 19.62 + run(pw, args); 19.63 + } finally { 19.64 + pw.flush(); 19.65 + } 19.66 + } 19.67 + 19.68 + void run(PrintWriter out, String... args) throws IOException, ClassFileNotFoundException { 19.69 + decodeArgs(args); 19.70 + 19.71 + final StandardJavaFileManager fm = new JavacFileManager(new Context(), false, null); 19.72 + if (classpath != null) 19.73 + fm.setLocation(StandardLocation.CLASS_PATH, classpath); 19.74 + 19.75 + ClassFileReader reader = new ClassFileReader(fm); 19.76 + 19.77 + Dependencies d = new Dependencies(); 19.78 + 19.79 + if (regex != null) 19.80 + d.setFilter(Dependencies.getRegexFilter(Pattern.compile(regex))); 19.81 + 19.82 + if (packageNames.size() > 0) 19.83 + d.setFilter(Dependencies.getPackageFilter(packageNames, false)); 19.84 + 19.85 + SortedRecorder r = new SortedRecorder(reverse); 19.86 + 19.87 + d.findAllDependencies(reader, rootClassNames, transitiveClosure, r); 19.88 + 19.89 + SortedMap<Location,SortedSet<Dependency>> deps = r.getMap(); 19.90 + for (Map.Entry<Location, SortedSet<Dependency>> e: deps.entrySet()) { 19.91 + out.println(e.getKey()); 19.92 + for (Dependency dep: e.getValue()) { 19.93 + out.println(" " + dep.getTarget()); 19.94 + } 19.95 + } 19.96 + } 19.97 + 19.98 + void decodeArgs(String... args) { 19.99 + rootClassNames = new TreeSet<String>(); 19.100 + packageNames = new TreeSet<String>(); 19.101 + 19.102 + for (int i = 0; i < args.length; i++) { 19.103 + String arg = args[i]; 19.104 + if (arg.equals("-classpath") && (i + 1 < args.length)) 19.105 + classpath = getPathFiles(args[++i]); 19.106 + else if (arg.equals("-p") && (i + 1 < args.length)) 19.107 + packageNames.add(args[++i]); 19.108 + else if (arg.equals("-r") && (i + 1 < args.length)) 19.109 + regex = args[++i]; 19.110 + else if (arg.equals("-rev")) 19.111 + reverse = true; 19.112 + else if (arg.equals("-t")) 19.113 + transitiveClosure = true; 19.114 + else if (arg.startsWith("-")) 19.115 + throw new Error(arg); 19.116 + else { 19.117 + for ( ; i < args.length; i++) 19.118 + rootClassNames.add(args[i]); 19.119 + } 19.120 + } 19.121 + } 19.122 + 19.123 + List<File> getPathFiles(String path) { 19.124 + List<File> files = new ArrayList<File>(); 19.125 + for (String p: path.split(File.pathSeparator)) { 19.126 + if (p.length() > 0) 19.127 + files.add(new File(p)); 19.128 + } 19.129 + return files; 19.130 + } 19.131 + 19.132 + boolean transitiveClosure; 19.133 + List<File> classpath; 19.134 + Set<String> rootClassNames; 19.135 + Set<String> packageNames; 19.136 + String regex; 19.137 + boolean reverse; 19.138 + 19.139 + 19.140 + static class ClassFileReader implements Dependencies.ClassFileReader { 19.141 + private JavaFileManager fm; 19.142 + 19.143 + ClassFileReader(JavaFileManager fm) { 19.144 + this.fm = fm; 19.145 + } 19.146 + 19.147 + @Override 19.148 + public ClassFile getClassFile(String className) throws ClassFileNotFoundException { 19.149 + try { 19.150 + JavaFileObject fo = fm.getJavaFileForInput( 19.151 + StandardLocation.CLASS_PATH, className, JavaFileObject.Kind.CLASS); 19.152 + if (fo == null) 19.153 + fo = fm.getJavaFileForInput( 19.154 + StandardLocation.PLATFORM_CLASS_PATH, className, JavaFileObject.Kind.CLASS); 19.155 + if (fo == null) 19.156 + throw new ClassFileNotFoundException(className); 19.157 + InputStream in = fo.openInputStream(); 19.158 + try { 19.159 + return ClassFile.read(in); 19.160 + } finally { 19.161 + in.close(); 19.162 + } 19.163 + } catch (ConstantPoolException e) { 19.164 + throw new ClassFileNotFoundException(className, e); 19.165 + } catch (IOException e) { 19.166 + throw new ClassFileNotFoundException(className, e); 19.167 + } 19.168 + } 19.169 + }; 19.170 + 19.171 + static class SortedRecorder implements Recorder { 19.172 + public SortedRecorder(boolean reverse) { 19.173 + this.reverse = reverse; 19.174 + } 19.175 + 19.176 + public void addDependency(Dependency d) { 19.177 + Location o = (reverse ? d.getTarget() : d.getOrigin()); 19.178 + SortedSet<Dependency> odeps = map.get(o); 19.179 + if (odeps == null) { 19.180 + Comparator<Dependency> c = (reverse ? originComparator : targetComparator); 19.181 + map.put(o, odeps = new TreeSet<Dependency>(c)); 19.182 + } 19.183 + odeps.add(d); 19.184 + } 19.185 + 19.186 + public SortedMap<Location, SortedSet<Dependency>> getMap() { 19.187 + return map; 19.188 + } 19.189 + 19.190 + private Comparator<Dependency> originComparator = new Comparator<Dependency>() { 19.191 + public int compare(Dependency o1, Dependency o2) { 19.192 + return o1.getOrigin().toString().compareTo(o2.getOrigin().toString()); 19.193 + } 19.194 + }; 19.195 + 19.196 + private Comparator<Dependency> targetComparator = new Comparator<Dependency>() { 19.197 + public int compare(Dependency o1, Dependency o2) { 19.198 + return o1.getTarget().toString().compareTo(o2.getTarget().toString()); 19.199 + } 19.200 + }; 19.201 + 19.202 + private Comparator<Location> locationComparator = new Comparator<Location>() { 19.203 + public int compare(Location o1, Location o2) { 19.204 + return o1.toString().compareTo(o2.toString()); 19.205 + } 19.206 + }; 19.207 + 19.208 + private final SortedMap<Location, SortedSet<Dependency>> map = 19.209 + new TreeMap<Location, SortedSet<Dependency>>(locationComparator); 19.210 + 19.211 + boolean reverse; 19.212 + } 19.213 + 19.214 +}
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/test/tools/javap/classfile/deps/T6907575.java Sat Dec 19 10:26:47 2009 -0800 20.3 @@ -0,0 +1,71 @@ 20.4 +/* 20.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 20.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 20.7 + * 20.8 + * This code is free software; you can redistribute it and/or modify it 20.9 + * under the terms of the GNU General Public License version 2 only, as 20.10 + * published by the Free Software Foundation. Sun designates this 20.11 + * particular file as subject to the "Classpath" exception as provided 20.12 + * by Sun in the LICENSE file that accompanied this code. 20.13 + * 20.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 20.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 20.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20.17 + * version 2 for more details (a copy is included in the LICENSE file that 20.18 + * accompanied this code). 20.19 + * 20.20 + * You should have received a copy of the GNU General Public License version 20.21 + * 2 along with this work; if not, write to the Free Software Foundation, 20.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20.23 + * 20.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 20.26 + * have any questions. 20.27 + */ 20.28 + 20.29 +/* 20.30 + * @test 20.31 + * @bug 6907575 20.32 + * @build GetDeps p.C1 20.33 + * @run main T6907575 20.34 + */ 20.35 + 20.36 +import java.io.*; 20.37 + 20.38 +public class T6907575 { 20.39 + public static void main(String... args) throws Exception { 20.40 + new T6907575().run(); 20.41 + } 20.42 + 20.43 + void run() throws Exception { 20.44 + String testSrc = System.getProperty("test.src"); 20.45 + String testClasses = System.getProperty("test.classes"); 20.46 + 20.47 + StringWriter sw = new StringWriter(); 20.48 + PrintWriter pw = new PrintWriter(sw); 20.49 + GetDeps gd = new GetDeps(); 20.50 + gd.run(pw, "-classpath", testClasses, "-t", "-p", "p", "p/C1"); 20.51 + pw.close(); 20.52 + System.out.println(sw); 20.53 + 20.54 + String ref = readFile(new File(testSrc, "T6907575.out")); 20.55 + diff(sw.toString().replaceAll("[\r\n]+", "\n"), ref); 20.56 + } 20.57 + 20.58 + void diff(String actual, String ref) throws Exception { 20.59 + System.out.println("EXPECT:>>>" + ref + "<<<"); 20.60 + System.out.println("ACTUAL:>>>" + actual + "<<<"); 20.61 + if (!actual.equals(ref)) 20.62 + throw new Exception("output not as expected"); 20.63 + } 20.64 + 20.65 + String readFile(File f) throws IOException { 20.66 + Reader r = new FileReader(f); 20.67 + char[] buf = new char[(int) f.length()]; 20.68 + int offset = 0; 20.69 + int n; 20.70 + while (offset < buf.length && (n = r.read(buf, offset, buf.length - offset)) != -1) 20.71 + offset += n; 20.72 + return new String(buf, 0, offset); 20.73 + } 20.74 +}
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/test/tools/javap/classfile/deps/T6907575.out Sat Dec 19 10:26:47 2009 -0800 21.3 @@ -0,0 +1,8 @@ 21.4 +p/C1 21.5 + java/lang/Object 21.6 + p/C2 21.7 +p/C2 21.8 + java/lang/Object 21.9 + p/C3 21.10 +p/C3 21.11 + java/lang/Object
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/test/tools/javap/classfile/deps/p/C1.java Sat Dec 19 10:26:47 2009 -0800 22.3 @@ -0,0 +1,37 @@ 22.4 +/* 22.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 22.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 22.7 + * 22.8 + * This code is free software; you can redistribute it and/or modify it 22.9 + * under the terms of the GNU General Public License version 2 only, as 22.10 + * published by the Free Software Foundation. Sun designates this 22.11 + * particular file as subject to the "Classpath" exception as provided 22.12 + * by Sun in the LICENSE file that accompanied this code. 22.13 + * 22.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 22.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 22.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 22.17 + * version 2 for more details (a copy is included in the LICENSE file that 22.18 + * accompanied this code). 22.19 + * 22.20 + * You should have received a copy of the GNU General Public License version 22.21 + * 2 along with this work; if not, write to the Free Software Foundation, 22.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 22.23 + * 22.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 22.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 22.26 + * have any questions. 22.27 + */ 22.28 + 22.29 +package p; 22.30 + 22.31 +public class C1 { 22.32 + C2 c2; 22.33 +} 22.34 + 22.35 +class C2 { 22.36 + C3 c3; 22.37 +} 22.38 + 22.39 +class C3 { 22.40 +}