Tue, 25 Oct 2011 10:48:05 -0700
7104039: refactor/cleanup javac Paths class
Reviewed-by: mcimadamore
1.1 --- a/src/share/classes/com/sun/tools/apt/main/Main.java Tue Oct 25 15:40:34 2011 +0100 1.2 +++ b/src/share/classes/com/sun/tools/apt/main/Main.java Tue Oct 25 10:48:05 2011 -0700 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -56,7 +56,7 @@ 1.11 import com.sun.tools.apt.util.Bark; 1.12 import com.sun.mirror.apt.AnnotationProcessorFactory; 1.13 1.14 -import static com.sun.tools.javac.file.Paths.pathToURLs; 1.15 +import static com.sun.tools.javac.file.Locations.pathToURLs; 1.16 1.17 /** This class provides a commandline interface to the apt build-time 1.18 * tool.
2.1 --- a/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Tue Oct 25 15:40:34 2011 +0100 2.2 +++ b/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Tue Oct 25 10:48:05 2011 -0700 2.3 @@ -54,17 +54,14 @@ 2.4 import javax.tools.JavaFileObject; 2.5 import javax.tools.StandardJavaFileManager; 2.6 2.7 -import com.sun.tools.javac.code.Lint; 2.8 import com.sun.tools.javac.file.RelativePath.RelativeFile; 2.9 import com.sun.tools.javac.file.RelativePath.RelativeDirectory; 2.10 -import com.sun.tools.javac.main.OptionName; 2.11 import com.sun.tools.javac.util.BaseFileManager; 2.12 import com.sun.tools.javac.util.Context; 2.13 import com.sun.tools.javac.util.List; 2.14 import com.sun.tools.javac.util.ListBuffer; 2.15 2.16 import static javax.tools.StandardLocation.*; 2.17 -import static com.sun.tools.javac.main.OptionName.*; 2.18 2.19 /** 2.20 * This class provides access to the source, class and other files 2.21 @@ -89,23 +86,9 @@ 2.22 private boolean contextUseOptimizedZip; 2.23 private ZipFileIndexCache zipFileIndexCache; 2.24 2.25 - private final File uninited = new File("U N I N I T E D"); 2.26 - 2.27 private final Set<JavaFileObject.Kind> sourceOrClass = 2.28 EnumSet.of(JavaFileObject.Kind.SOURCE, JavaFileObject.Kind.CLASS); 2.29 2.30 - /** The standard output directory, primarily used for classes. 2.31 - * Initialized by the "-d" option. 2.32 - * If classOutDir = null, files are written into same directory as the sources 2.33 - * they were generated from. 2.34 - */ 2.35 - private File classOutDir = uninited; 2.36 - 2.37 - /** The output directory, used when generating sources while processing annotations. 2.38 - * Initialized by the "-s" option. 2.39 - */ 2.40 - private File sourceOutDir = uninited; 2.41 - 2.42 protected boolean mmappedIO; 2.43 protected boolean ignoreSymbolFile; 2.44 2.45 @@ -169,7 +152,7 @@ 2.46 2.47 @Override 2.48 public boolean isDefaultBootClassPath() { 2.49 - return searchPaths.isDefaultBootClassPath(); 2.50 + return locations.isDefaultBootClassPath(); 2.51 } 2.52 2.53 public JavaFileObject getFileForInput(String name) { 2.54 @@ -483,7 +466,7 @@ 2.55 */ 2.56 private Archive openArchive(File zipFileName, boolean useOptimizedZip) throws IOException { 2.57 File origZipFileName = zipFileName; 2.58 - if (!ignoreSymbolFile && searchPaths.isDefaultBootClassPathRtJar(zipFileName)) { 2.59 + if (!ignoreSymbolFile && locations.isDefaultBootClassPathRtJar(zipFileName)) { 2.60 File file = zipFileName.getParentFile().getParentFile(); // ${java.home} 2.61 if (new File(file.getName()).equals(new File("jre"))) 2.62 file = file.getParentFile(); 2.63 @@ -770,7 +753,7 @@ 2.64 } else if (location == SOURCE_OUTPUT) { 2.65 dir = (getSourceOutDir() != null ? getSourceOutDir() : getClassOutDir()); 2.66 } else { 2.67 - Iterable<? extends File> path = searchPaths.getPathForLocation(location); 2.68 + Iterable<? extends File> path = locations.getLocation(location); 2.69 dir = null; 2.70 for (File f: path) { 2.71 dir = f; 2.72 @@ -805,64 +788,20 @@ 2.73 throws IOException 2.74 { 2.75 nullCheck(location); 2.76 - searchPaths.lazy(); 2.77 - 2.78 - final File dir = location.isOutputLocation() ? getOutputDirectory(path) : null; 2.79 - 2.80 - if (location == CLASS_OUTPUT) 2.81 - classOutDir = getOutputLocation(dir, D); 2.82 - else if (location == SOURCE_OUTPUT) 2.83 - sourceOutDir = getOutputLocation(dir, S); 2.84 - else 2.85 - searchPaths.setPathForLocation(location, path); 2.86 - } 2.87 - // where 2.88 - private File getOutputDirectory(Iterable<? extends File> path) throws IOException { 2.89 - if (path == null) 2.90 - return null; 2.91 - Iterator<? extends File> pathIter = path.iterator(); 2.92 - if (!pathIter.hasNext()) 2.93 - throw new IllegalArgumentException("empty path for directory"); 2.94 - File dir = pathIter.next(); 2.95 - if (pathIter.hasNext()) 2.96 - throw new IllegalArgumentException("path too long for directory"); 2.97 - if (!dir.exists()) 2.98 - throw new FileNotFoundException(dir + ": does not exist"); 2.99 - else if (!dir.isDirectory()) 2.100 - throw new IOException(dir + ": not a directory"); 2.101 - return dir; 2.102 - } 2.103 - 2.104 - private File getOutputLocation(File dir, OptionName defaultOptionName) { 2.105 - if (dir != null) 2.106 - return dir; 2.107 - String arg = options.get(defaultOptionName); 2.108 - if (arg == null) 2.109 - return null; 2.110 - return new File(arg); 2.111 + locations.setLocation(location, path); 2.112 } 2.113 2.114 public Iterable<? extends File> getLocation(Location location) { 2.115 nullCheck(location); 2.116 - searchPaths.lazy(); 2.117 - if (location == CLASS_OUTPUT) { 2.118 - return (getClassOutDir() == null ? null : List.of(getClassOutDir())); 2.119 - } else if (location == SOURCE_OUTPUT) { 2.120 - return (getSourceOutDir() == null ? null : List.of(getSourceOutDir())); 2.121 - } else 2.122 - return searchPaths.getPathForLocation(location); 2.123 + return locations.getLocation(location); 2.124 } 2.125 2.126 private File getClassOutDir() { 2.127 - if (classOutDir == uninited) 2.128 - classOutDir = getOutputLocation(null, D); 2.129 - return classOutDir; 2.130 + return locations.getOutputLocation(CLASS_OUTPUT); 2.131 } 2.132 2.133 private File getSourceOutDir() { 2.134 - if (sourceOutDir == uninited) 2.135 - sourceOutDir = getOutputLocation(null, S); 2.136 - return sourceOutDir; 2.137 + return locations.getOutputLocation(SOURCE_OUTPUT); 2.138 } 2.139 2.140 /**
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/share/classes/com/sun/tools/javac/file/Locations.java Tue Oct 25 10:48:05 2011 -0700 3.3 @@ -0,0 +1,769 @@ 3.4 +/* 3.5 + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. 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. Oracle designates this 3.11 + * particular file as subject to the "Classpath" exception as provided 3.12 + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 3.25 + * or visit www.oracle.com if you need additional information or have any 3.26 + * questions. 3.27 + */ 3.28 + 3.29 +package com.sun.tools.javac.file; 3.30 + 3.31 +import java.io.FileNotFoundException; 3.32 +import java.util.Iterator; 3.33 +import java.io.File; 3.34 +import java.io.IOException; 3.35 +import java.net.MalformedURLException; 3.36 +import java.net.URL; 3.37 +import java.util.Arrays; 3.38 +import java.util.Collection; 3.39 +import java.util.Collections; 3.40 +import java.util.EnumMap; 3.41 +import java.util.EnumSet; 3.42 +import java.util.HashMap; 3.43 +import java.util.HashSet; 3.44 +import java.util.LinkedHashSet; 3.45 +import java.util.Map; 3.46 +import java.util.Set; 3.47 +import java.util.StringTokenizer; 3.48 +import java.util.zip.ZipFile; 3.49 +import javax.tools.JavaFileManager.Location; 3.50 +import javax.tools.StandardLocation; 3.51 + 3.52 +import com.sun.tools.javac.code.Lint; 3.53 +import com.sun.tools.javac.main.OptionName; 3.54 +import com.sun.tools.javac.util.ListBuffer; 3.55 +import com.sun.tools.javac.util.Log; 3.56 +import com.sun.tools.javac.util.Options; 3.57 + 3.58 +import javax.tools.JavaFileManager; 3.59 +import static javax.tools.StandardLocation.*; 3.60 +import static com.sun.tools.javac.main.OptionName.*; 3.61 + 3.62 +/** This class converts command line arguments, environment variables 3.63 + * and system properties (in File.pathSeparator-separated String form) 3.64 + * into a boot class path, user class path, and source path (in 3.65 + * Collection<String> form). 3.66 + * 3.67 + * <p><b>This is NOT part of any supported API. 3.68 + * If you write code that depends on this, you do so at your own risk. 3.69 + * This code and its internal interfaces are subject to change or 3.70 + * deletion without notice.</b> 3.71 + */ 3.72 +public class Locations { 3.73 + 3.74 + /** The log to use for warning output */ 3.75 + private Log log; 3.76 + 3.77 + /** Collection of command-line options */ 3.78 + private Options options; 3.79 + 3.80 + /** Handler for -Xlint options */ 3.81 + private Lint lint; 3.82 + 3.83 + /** Access to (possibly cached) file info */ 3.84 + private FSInfo fsInfo; 3.85 + 3.86 + /** Whether to warn about non-existent path elements */ 3.87 + private boolean warn; 3.88 + 3.89 + // TODO: remove need for this 3.90 + private boolean inited = false; // TODO? caching bad? 3.91 + 3.92 + public Locations() { 3.93 + initHandlers(); 3.94 + } 3.95 + 3.96 + public void update(Log log, Options options, Lint lint, FSInfo fsInfo) { 3.97 + this.log = log; 3.98 + this.options = options; 3.99 + this.lint = lint; 3.100 + this.fsInfo = fsInfo; 3.101 + } 3.102 + 3.103 + public Collection<File> bootClassPath() { 3.104 + return getLocation(PLATFORM_CLASS_PATH); 3.105 + } 3.106 + 3.107 + public boolean isDefaultBootClassPath() { 3.108 + BootClassPathLocationHandler h = 3.109 + (BootClassPathLocationHandler) getHandler(PLATFORM_CLASS_PATH); 3.110 + return h.isDefault(); 3.111 + } 3.112 + 3.113 + boolean isDefaultBootClassPathRtJar(File file) { 3.114 + BootClassPathLocationHandler h = 3.115 + (BootClassPathLocationHandler) getHandler(PLATFORM_CLASS_PATH); 3.116 + return h.isDefaultRtJar(file); 3.117 + } 3.118 + 3.119 + public Collection<File> userClassPath() { 3.120 + return getLocation(CLASS_PATH); 3.121 + } 3.122 + 3.123 + public Collection<File> sourcePath() { 3.124 + Collection<File> p = getLocation(SOURCE_PATH); 3.125 + // TODO: this should be handled by the LocationHandler 3.126 + return p == null || p.isEmpty() ? null : p; 3.127 + } 3.128 + 3.129 + /** 3.130 + * Split a path into its elements. Empty path elements will be ignored. 3.131 + * @param path The path to be split 3.132 + * @return The elements of the path 3.133 + */ 3.134 + private static Iterable<File> getPathEntries(String path) { 3.135 + return getPathEntries(path, null); 3.136 + } 3.137 + 3.138 + /** 3.139 + * Split a path into its elements. If emptyPathDefault is not null, all 3.140 + * empty elements in the path, including empty elements at either end of 3.141 + * the path, will be replaced with the value of emptyPathDefault. 3.142 + * @param path The path to be split 3.143 + * @param emptyPathDefault The value to substitute for empty path elements, 3.144 + * or null, to ignore empty path elements 3.145 + * @return The elements of the path 3.146 + */ 3.147 + private static Iterable<File> getPathEntries(String path, File emptyPathDefault) { 3.148 + ListBuffer<File> entries = new ListBuffer<File>(); 3.149 + int start = 0; 3.150 + while (start <= path.length()) { 3.151 + int sep = path.indexOf(File.pathSeparatorChar, start); 3.152 + if (sep == -1) 3.153 + sep = path.length(); 3.154 + if (start < sep) 3.155 + entries.add(new File(path.substring(start, sep))); 3.156 + else if (emptyPathDefault != null) 3.157 + entries.add(emptyPathDefault); 3.158 + start = sep + 1; 3.159 + } 3.160 + return entries; 3.161 + } 3.162 + 3.163 + /** 3.164 + * Utility class to help evaluate a path option. 3.165 + * Duplicate entries are ignored, jar class paths can be expanded. 3.166 + */ 3.167 + private class Path extends LinkedHashSet<File> { 3.168 + private static final long serialVersionUID = 0; 3.169 + 3.170 + private boolean expandJarClassPaths = false; 3.171 + private Set<File> canonicalValues = new HashSet<File>(); 3.172 + 3.173 + public Path expandJarClassPaths(boolean x) { 3.174 + expandJarClassPaths = x; 3.175 + return this; 3.176 + } 3.177 + 3.178 + /** What to use when path element is the empty string */ 3.179 + private File emptyPathDefault = null; 3.180 + 3.181 + public Path emptyPathDefault(File x) { 3.182 + emptyPathDefault = x; 3.183 + return this; 3.184 + } 3.185 + 3.186 + public Path() { super(); } 3.187 + 3.188 + public Path addDirectories(String dirs, boolean warn) { 3.189 + boolean prev = expandJarClassPaths; 3.190 + expandJarClassPaths = true; 3.191 + try { 3.192 + if (dirs != null) 3.193 + for (File dir : getPathEntries(dirs)) 3.194 + addDirectory(dir, warn); 3.195 + return this; 3.196 + } finally { 3.197 + expandJarClassPaths = prev; 3.198 + } 3.199 + } 3.200 + 3.201 + public Path addDirectories(String dirs) { 3.202 + return addDirectories(dirs, warn); 3.203 + } 3.204 + 3.205 + private void addDirectory(File dir, boolean warn) { 3.206 + if (!dir.isDirectory()) { 3.207 + if (warn) 3.208 + log.warning(Lint.LintCategory.PATH, 3.209 + "dir.path.element.not.found", dir); 3.210 + return; 3.211 + } 3.212 + 3.213 + File[] files = dir.listFiles(); 3.214 + if (files == null) 3.215 + return; 3.216 + 3.217 + for (File direntry : files) { 3.218 + if (isArchive(direntry)) 3.219 + addFile(direntry, warn); 3.220 + } 3.221 + } 3.222 + 3.223 + public Path addFiles(String files, boolean warn) { 3.224 + if (files != null) { 3.225 + addFiles(getPathEntries(files, emptyPathDefault), warn); 3.226 + } 3.227 + return this; 3.228 + } 3.229 + 3.230 + public Path addFiles(String files) { 3.231 + return addFiles(files, warn); 3.232 + } 3.233 + 3.234 + public Path addFiles(Iterable<? extends File> files, boolean warn) { 3.235 + if (files != null) { 3.236 + for (File file: files) 3.237 + addFile(file, warn); 3.238 + } 3.239 + return this; 3.240 + } 3.241 + 3.242 + public Path addFiles(Iterable<? extends File> files) { 3.243 + return addFiles(files, warn); 3.244 + } 3.245 + 3.246 + public void addFile(File file, boolean warn) { 3.247 + if (contains(file)) { 3.248 + // discard duplicates 3.249 + return; 3.250 + } 3.251 + 3.252 + if (! fsInfo.exists(file)) { 3.253 + /* No such file or directory exists */ 3.254 + if (warn) { 3.255 + log.warning(Lint.LintCategory.PATH, 3.256 + "path.element.not.found", file); 3.257 + } 3.258 + super.add(file); 3.259 + return; 3.260 + } 3.261 + 3.262 + File canonFile = fsInfo.getCanonicalFile(file); 3.263 + if (canonicalValues.contains(canonFile)) { 3.264 + /* Discard duplicates and avoid infinite recursion */ 3.265 + return; 3.266 + } 3.267 + 3.268 + if (fsInfo.isFile(file)) { 3.269 + /* File is an ordinary file. */ 3.270 + if (!isArchive(file)) { 3.271 + /* Not a recognized extension; open it to see if 3.272 + it looks like a valid zip file. */ 3.273 + try { 3.274 + ZipFile z = new ZipFile(file); 3.275 + z.close(); 3.276 + if (warn) { 3.277 + log.warning(Lint.LintCategory.PATH, 3.278 + "unexpected.archive.file", file); 3.279 + } 3.280 + } catch (IOException e) { 3.281 + // FIXME: include e.getLocalizedMessage in warning 3.282 + if (warn) { 3.283 + log.warning(Lint.LintCategory.PATH, 3.284 + "invalid.archive.file", file); 3.285 + } 3.286 + return; 3.287 + } 3.288 + } 3.289 + } 3.290 + 3.291 + /* Now what we have left is either a directory or a file name 3.292 + conforming to archive naming convention */ 3.293 + super.add(file); 3.294 + canonicalValues.add(canonFile); 3.295 + 3.296 + if (expandJarClassPaths && fsInfo.isFile(file)) 3.297 + addJarClassPath(file, warn); 3.298 + } 3.299 + 3.300 + // Adds referenced classpath elements from a jar's Class-Path 3.301 + // Manifest entry. In some future release, we may want to 3.302 + // update this code to recognize URLs rather than simple 3.303 + // filenames, but if we do, we should redo all path-related code. 3.304 + private void addJarClassPath(File jarFile, boolean warn) { 3.305 + try { 3.306 + for (File f: fsInfo.getJarClassPath(jarFile)) { 3.307 + addFile(f, warn); 3.308 + } 3.309 + } catch (IOException e) { 3.310 + log.error("error.reading.file", jarFile, JavacFileManager.getMessage(e)); 3.311 + } 3.312 + } 3.313 + } 3.314 + 3.315 + /** 3.316 + * Base class for handling support for the representation of Locations. 3.317 + * Implementations are responsible for handling the interactions between 3.318 + * the command line options for a location, and API access via setLocation. 3.319 + * @see #initHandlers 3.320 + * @see #getHandler 3.321 + */ 3.322 + protected abstract class LocationHandler { 3.323 + final Location location; 3.324 + final Set<OptionName> options; 3.325 + 3.326 + /** 3.327 + * Create a handler. The location and options provide a way to map 3.328 + * from a location or an option to the corresponding handler. 3.329 + * @see #initHandlers 3.330 + */ 3.331 + protected LocationHandler(Location location, OptionName... options) { 3.332 + this.location = location; 3.333 + this.options = EnumSet.copyOf(Arrays.asList(options)); 3.334 + } 3.335 + 3.336 + // TODO: TEMPORARY, while Options still used for command line options 3.337 + void update(Options optionTable) { 3.338 + for (OptionName o: options) { 3.339 + String v = optionTable.get(o); 3.340 + if (v != null) { 3.341 + handleOption(o, v); 3.342 + } 3.343 + } 3.344 + } 3.345 + 3.346 + /** @see JavaFileManager#handleOption. */ 3.347 + abstract boolean handleOption(OptionName option, String value); 3.348 + /** @see JavaFileManager#getLocation. */ 3.349 + abstract Collection<File> getLocation(); 3.350 + /** @see JavaFileManager#setLocation. */ 3.351 + abstract void setLocation(Iterable<? extends File> files) throws IOException; 3.352 + } 3.353 + 3.354 + /** 3.355 + * General purpose implementation for output locations, 3.356 + * such as -d/CLASS_OUTPUT and -s/SOURCE_OUTPUT. 3.357 + * All options are treated as equivalent (i.e. aliases.) 3.358 + * The value is a single file, possibly null. 3.359 + */ 3.360 + private class OutputLocationHandler extends LocationHandler { 3.361 + private File outputDir; 3.362 + 3.363 + OutputLocationHandler(Location location, OptionName... options) { 3.364 + super(location, options); 3.365 + } 3.366 + 3.367 + @Override 3.368 + boolean handleOption(OptionName option, String value) { 3.369 + if (!options.contains(option)) 3.370 + return false; 3.371 + 3.372 + // TODO: could/should validate outputDir exists and is a directory 3.373 + // need to decide how best to report issue for benefit of 3.374 + // direct API call on JavaFileManager.handleOption(specifies IAE) 3.375 + // vs. command line decoding. 3.376 + outputDir = new File(value); 3.377 + return true; 3.378 + } 3.379 + 3.380 + @Override 3.381 + Collection<File> getLocation() { 3.382 + return (outputDir == null) ? null : Collections.singleton(outputDir); 3.383 + } 3.384 + 3.385 + @Override 3.386 + void setLocation(Iterable<? extends File> files) throws IOException { 3.387 + if (files == null) { 3.388 + outputDir = null; 3.389 + } else { 3.390 + Iterator<? extends File> pathIter = files.iterator(); 3.391 + if (!pathIter.hasNext()) 3.392 + throw new IllegalArgumentException("empty path for directory"); 3.393 + File dir = pathIter.next(); 3.394 + if (pathIter.hasNext()) 3.395 + throw new IllegalArgumentException("path too long for directory"); 3.396 + if (!dir.exists()) 3.397 + throw new FileNotFoundException(dir + ": does not exist"); 3.398 + else if (!dir.isDirectory()) 3.399 + throw new IOException(dir + ": not a directory"); 3.400 + outputDir = dir; 3.401 + } 3.402 + } 3.403 + } 3.404 + 3.405 + /** 3.406 + * General purpose implementation for search path locations, 3.407 + * such as -sourcepath/SOURCE_PATH and -processorPath/ANNOTATION_PROCESS_PATH. 3.408 + * All options are treated as equivalent (i.e. aliases.) 3.409 + * The value is an ordered set of files and/or directories. 3.410 + */ 3.411 + private class SimpleLocationHandler extends LocationHandler { 3.412 + protected Collection<File> searchPath; 3.413 + 3.414 + SimpleLocationHandler(Location location, OptionName... options) { 3.415 + super(location, options); 3.416 + } 3.417 + 3.418 + @Override 3.419 + boolean handleOption(OptionName option, String value) { 3.420 + if (!options.contains(option)) 3.421 + return false; 3.422 + searchPath = value == null ? null : 3.423 + Collections.unmodifiableCollection(computePath(value)); 3.424 + return true; 3.425 + } 3.426 + 3.427 + protected Path computePath(String value) { 3.428 + return new Path().addFiles(value); 3.429 + } 3.430 + 3.431 + @Override 3.432 + Collection<File> getLocation() { 3.433 + return searchPath; 3.434 + } 3.435 + 3.436 + @Override 3.437 + void setLocation(Iterable<? extends File> files) { 3.438 + Path p; 3.439 + if (files == null) { 3.440 + p = computePath(null); 3.441 + } else { 3.442 + p = new Path().addFiles(files); 3.443 + } 3.444 + searchPath = Collections.unmodifiableCollection(p); 3.445 + } 3.446 + } 3.447 + 3.448 + /** 3.449 + * Subtype of SimpleLocationHandler for -classpath/CLASS_PATH. 3.450 + * If no value is given, a default is provided, based on system properties 3.451 + * and other values. 3.452 + */ 3.453 + private class ClassPathLocationHandler extends SimpleLocationHandler { 3.454 + ClassPathLocationHandler() { 3.455 + super(StandardLocation.CLASS_PATH, 3.456 + OptionName.CLASSPATH, OptionName.CP); 3.457 + } 3.458 + 3.459 + @Override 3.460 + Collection<File> getLocation() { 3.461 + lazy(); 3.462 + return searchPath; 3.463 + } 3.464 + 3.465 + @Override 3.466 + protected Path computePath(String value) { 3.467 + String cp = value; 3.468 + 3.469 + // CLASSPATH environment variable when run from `javac'. 3.470 + if (cp == null) cp = System.getProperty("env.class.path"); 3.471 + 3.472 + // If invoked via a java VM (not the javac launcher), use the 3.473 + // platform class path 3.474 + if (cp == null && System.getProperty("application.home") == null) 3.475 + cp = System.getProperty("java.class.path"); 3.476 + 3.477 + // Default to current working directory. 3.478 + if (cp == null) cp = "."; 3.479 + 3.480 + return new Path() 3.481 + .expandJarClassPaths(true) // Only search user jars for Class-Paths 3.482 + .emptyPathDefault(new File(".")) // Empty path elt ==> current directory 3.483 + .addFiles(cp); 3.484 + } 3.485 + 3.486 + private void lazy() { 3.487 + if (searchPath == null) 3.488 + setLocation(null); 3.489 + } 3.490 + } 3.491 + 3.492 + /** 3.493 + * Custom subtype of LocationHandler for PLATFORM_CLASS_PATH. 3.494 + * Various options are supported for different components of the 3.495 + * platform class path. 3.496 + * Setting a value with setLocation overrides all existing option values. 3.497 + * Setting any option overrides any value set with setLocation, and reverts 3.498 + * to using default values for options that have not been set. 3.499 + * Setting -bootclasspath or -Xbootclasspath overrides any existing 3.500 + * value for -Xbootclasspath/p: and -Xbootclasspath/a:. 3.501 + */ 3.502 + private class BootClassPathLocationHandler extends LocationHandler { 3.503 + private Collection<File> searchPath; 3.504 + final Map<OptionName, String> optionValues = new EnumMap<OptionName,String>(OptionName.class); 3.505 + 3.506 + /** 3.507 + * rt.jar as found on the default bootclasspath. 3.508 + * If the user specified a bootclasspath, null is used. 3.509 + */ 3.510 + private File defaultBootClassPathRtJar = null; 3.511 + 3.512 + /** 3.513 + * Is bootclasspath the default? 3.514 + */ 3.515 + private boolean isDefaultBootClassPath; 3.516 + 3.517 + BootClassPathLocationHandler() { 3.518 + super(StandardLocation.PLATFORM_CLASS_PATH, 3.519 + OptionName.BOOTCLASSPATH, OptionName.XBOOTCLASSPATH, 3.520 + OptionName.XBOOTCLASSPATH_PREPEND, 3.521 + OptionName.XBOOTCLASSPATH_APPEND, 3.522 + OptionName.ENDORSEDDIRS, OptionName.DJAVA_ENDORSED_DIRS, 3.523 + OptionName.EXTDIRS, OptionName.DJAVA_EXT_DIRS); 3.524 + } 3.525 + 3.526 + boolean isDefault() { 3.527 + lazy(); 3.528 + return isDefaultBootClassPath; 3.529 + } 3.530 + 3.531 + boolean isDefaultRtJar(File file) { 3.532 + lazy(); 3.533 + return file.equals(defaultBootClassPathRtJar); 3.534 + } 3.535 + 3.536 + @Override 3.537 + boolean handleOption(OptionName option, String value) { 3.538 + if (!options.contains(option)) 3.539 + return false; 3.540 + 3.541 + option = canonicalize(option); 3.542 + optionValues.put(option, value); 3.543 + if (option == BOOTCLASSPATH) { 3.544 + optionValues.remove(XBOOTCLASSPATH_PREPEND); 3.545 + optionValues.remove(XBOOTCLASSPATH_APPEND); 3.546 + } 3.547 + searchPath = null; // reset to "uninitialized" 3.548 + return true; 3.549 + } 3.550 + // where 3.551 + // TODO: would be better if option aliasing was handled at a higher 3.552 + // level 3.553 + private OptionName canonicalize(OptionName option) { 3.554 + switch (option) { 3.555 + case XBOOTCLASSPATH: 3.556 + return OptionName.BOOTCLASSPATH; 3.557 + case DJAVA_ENDORSED_DIRS: 3.558 + return OptionName.ENDORSEDDIRS; 3.559 + case DJAVA_EXT_DIRS: 3.560 + return OptionName.EXTDIRS; 3.561 + default: 3.562 + return option; 3.563 + } 3.564 + } 3.565 + 3.566 + @Override 3.567 + Collection<File> getLocation() { 3.568 + lazy(); 3.569 + return searchPath; 3.570 + } 3.571 + 3.572 + @Override 3.573 + void setLocation(Iterable<? extends File> files) { 3.574 + if (files == null) { 3.575 + searchPath = null; // reset to "uninitialized" 3.576 + } else { 3.577 + defaultBootClassPathRtJar = null; 3.578 + isDefaultBootClassPath = false; 3.579 + Path p = new Path().addFiles(files, false); 3.580 + searchPath = Collections.unmodifiableCollection(p); 3.581 + optionValues.clear(); 3.582 + } 3.583 + } 3.584 + 3.585 + Path computePath() { 3.586 + defaultBootClassPathRtJar = null; 3.587 + Path path = new Path(); 3.588 + 3.589 + String bootclasspathOpt = optionValues.get(BOOTCLASSPATH); 3.590 + String endorseddirsOpt = optionValues.get(ENDORSEDDIRS); 3.591 + String extdirsOpt = optionValues.get(EXTDIRS); 3.592 + String xbootclasspathPrependOpt = optionValues.get(XBOOTCLASSPATH_PREPEND); 3.593 + String xbootclasspathAppendOpt = optionValues.get(XBOOTCLASSPATH_APPEND); 3.594 + 3.595 + path.addFiles(xbootclasspathPrependOpt); 3.596 + 3.597 + if (endorseddirsOpt != null) 3.598 + path.addDirectories(endorseddirsOpt); 3.599 + else 3.600 + path.addDirectories(System.getProperty("java.endorsed.dirs"), false); 3.601 + 3.602 + if (bootclasspathOpt != null) { 3.603 + path.addFiles(bootclasspathOpt); 3.604 + } else { 3.605 + // Standard system classes for this compiler's release. 3.606 + String files = System.getProperty("sun.boot.class.path"); 3.607 + path.addFiles(files, false); 3.608 + File rt_jar = new File("rt.jar"); 3.609 + for (File file : getPathEntries(files)) { 3.610 + if (new File(file.getName()).equals(rt_jar)) 3.611 + defaultBootClassPathRtJar = file; 3.612 + } 3.613 + } 3.614 + 3.615 + path.addFiles(xbootclasspathAppendOpt); 3.616 + 3.617 + // Strictly speaking, standard extensions are not bootstrap 3.618 + // classes, but we treat them identically, so we'll pretend 3.619 + // that they are. 3.620 + if (extdirsOpt != null) 3.621 + path.addDirectories(extdirsOpt); 3.622 + else 3.623 + path.addDirectories(System.getProperty("java.ext.dirs"), false); 3.624 + 3.625 + isDefaultBootClassPath = 3.626 + (xbootclasspathPrependOpt == null) && 3.627 + (bootclasspathOpt == null) && 3.628 + (xbootclasspathAppendOpt == null); 3.629 + 3.630 + return path; 3.631 + } 3.632 + 3.633 + private void lazy() { 3.634 + if (searchPath == null) 3.635 + searchPath = Collections.unmodifiableCollection(computePath()); 3.636 + } 3.637 + } 3.638 + 3.639 + Map<Location, LocationHandler> handlersForLocation; 3.640 + Map<OptionName, LocationHandler> handlersForOption; 3.641 + 3.642 + void initHandlers() { 3.643 + handlersForLocation = new HashMap<Location, LocationHandler>(); 3.644 + handlersForOption = new EnumMap<OptionName, LocationHandler>(OptionName.class); 3.645 + 3.646 + LocationHandler[] handlers = { 3.647 + new BootClassPathLocationHandler(), 3.648 + new ClassPathLocationHandler(), 3.649 + new SimpleLocationHandler(StandardLocation.SOURCE_PATH, OptionName.SOURCEPATH), 3.650 + new SimpleLocationHandler(StandardLocation.ANNOTATION_PROCESSOR_PATH, OptionName.PROCESSORPATH), 3.651 + new OutputLocationHandler((StandardLocation.CLASS_OUTPUT), OptionName.D), 3.652 + new OutputLocationHandler((StandardLocation.SOURCE_OUTPUT), OptionName.S) 3.653 + }; 3.654 + 3.655 + for (LocationHandler h: handlers) { 3.656 + handlersForLocation.put(h.location, h); 3.657 + for (OptionName o: h.options) 3.658 + handlersForOption.put(o, h); 3.659 + } 3.660 + } 3.661 + 3.662 + boolean handleOption(OptionName option, String value) { 3.663 + LocationHandler h = handlersForOption.get(option); 3.664 + return (h == null ? false : h.handleOption(option, value)); 3.665 + } 3.666 + 3.667 + Collection<File> getLocation(Location location) { 3.668 + LocationHandler h = getHandler(location); 3.669 + return (h == null ? null : h.getLocation()); 3.670 + } 3.671 + 3.672 + File getOutputLocation(Location location) { 3.673 + if (!location.isOutputLocation()) 3.674 + throw new IllegalArgumentException(); 3.675 + LocationHandler h = getHandler(location); 3.676 + return ((OutputLocationHandler) h).outputDir; 3.677 + } 3.678 + 3.679 + void setLocation(Location location, Iterable<? extends File> files) throws IOException { 3.680 + LocationHandler h = getHandler(location); 3.681 + if (h == null) { 3.682 + if (location.isOutputLocation()) 3.683 + h = new OutputLocationHandler(location); 3.684 + else 3.685 + h = new SimpleLocationHandler(location); 3.686 + handlersForLocation.put(location, h); 3.687 + } 3.688 + h.setLocation(files); 3.689 + } 3.690 + 3.691 + protected LocationHandler getHandler(Location location) { 3.692 + location.getClass(); // null check 3.693 + lazy(); 3.694 + return handlersForLocation.get(location); 3.695 + } 3.696 + 3.697 +// TOGO 3.698 + protected void lazy() { 3.699 + if (!inited) { 3.700 + warn = lint.isEnabled(Lint.LintCategory.PATH); 3.701 + 3.702 + for (LocationHandler h: handlersForLocation.values()) { 3.703 + h.update(options); 3.704 + } 3.705 + 3.706 + inited = true; 3.707 + } 3.708 + } 3.709 + 3.710 + /** Is this the name of an archive file? */ 3.711 + private boolean isArchive(File file) { 3.712 + String n = file.getName().toLowerCase(); 3.713 + return fsInfo.isFile(file) 3.714 + && (n.endsWith(".jar") || n.endsWith(".zip")); 3.715 + } 3.716 + 3.717 + /** 3.718 + * Utility method for converting a search path string to an array 3.719 + * of directory and JAR file URLs. 3.720 + * 3.721 + * Note that this method is called by apt and the DocletInvoker. 3.722 + * 3.723 + * @param path the search path string 3.724 + * @return the resulting array of directory and JAR file URLs 3.725 + */ 3.726 + public static URL[] pathToURLs(String path) { 3.727 + StringTokenizer st = new StringTokenizer(path, File.pathSeparator); 3.728 + URL[] urls = new URL[st.countTokens()]; 3.729 + int count = 0; 3.730 + while (st.hasMoreTokens()) { 3.731 + URL url = fileToURL(new File(st.nextToken())); 3.732 + if (url != null) { 3.733 + urls[count++] = url; 3.734 + } 3.735 + } 3.736 + if (urls.length != count) { 3.737 + URL[] tmp = new URL[count]; 3.738 + System.arraycopy(urls, 0, tmp, 0, count); 3.739 + urls = tmp; 3.740 + } 3.741 + return urls; 3.742 + } 3.743 + 3.744 + /** 3.745 + * Returns the directory or JAR file URL corresponding to the specified 3.746 + * local file name. 3.747 + * 3.748 + * @param file the File object 3.749 + * @return the resulting directory or JAR file URL, or null if unknown 3.750 + */ 3.751 + private static URL fileToURL(File file) { 3.752 + String name; 3.753 + try { 3.754 + name = file.getCanonicalPath(); 3.755 + } catch (IOException e) { 3.756 + name = file.getAbsolutePath(); 3.757 + } 3.758 + name = name.replace(File.separatorChar, '/'); 3.759 + if (!name.startsWith("/")) { 3.760 + name = "/" + name; 3.761 + } 3.762 + // If the file does not exist, then assume that it's a directory 3.763 + if (!file.isFile()) { 3.764 + name = name + "/"; 3.765 + } 3.766 + try { 3.767 + return new URL("file", "", name); 3.768 + } catch (MalformedURLException e) { 3.769 + throw new IllegalArgumentException(file.toString()); 3.770 + } 3.771 + } 3.772 +}
4.1 --- a/src/share/classes/com/sun/tools/javac/file/Paths.java Tue Oct 25 15:40:34 2011 +0100 4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 4.3 @@ -1,540 +0,0 @@ 4.4 -/* 4.5 - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. 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. Oracle designates this 4.11 - * particular file as subject to the "Classpath" exception as provided 4.12 - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 4.25 - * or visit www.oracle.com if you need additional information or have any 4.26 - * questions. 4.27 - */ 4.28 - 4.29 -package com.sun.tools.javac.file; 4.30 - 4.31 -import java.io.File; 4.32 -import java.io.IOException; 4.33 -import java.net.MalformedURLException; 4.34 -import java.net.URL; 4.35 -import java.util.HashMap; 4.36 -import java.util.HashSet; 4.37 -import java.util.Map; 4.38 -import java.util.Set; 4.39 -import java.util.Collection; 4.40 -import java.util.Collections; 4.41 -import java.util.LinkedHashSet; 4.42 -import java.util.StringTokenizer; 4.43 -import java.util.zip.ZipFile; 4.44 -import javax.tools.JavaFileManager.Location; 4.45 - 4.46 -import com.sun.tools.javac.code.Lint; 4.47 -import com.sun.tools.javac.util.ListBuffer; 4.48 -import com.sun.tools.javac.util.Log; 4.49 -import com.sun.tools.javac.util.Options; 4.50 - 4.51 -import static javax.tools.StandardLocation.*; 4.52 -import static com.sun.tools.javac.main.OptionName.*; 4.53 - 4.54 -/** This class converts command line arguments, environment variables 4.55 - * and system properties (in File.pathSeparator-separated String form) 4.56 - * into a boot class path, user class path, and source path (in 4.57 - * Collection<String> form). 4.58 - * 4.59 - * <p><b>This is NOT part of any supported API. 4.60 - * If you write code that depends on this, you do so at your own risk. 4.61 - * This code and its internal interfaces are subject to change or 4.62 - * deletion without notice.</b> 4.63 - */ 4.64 -public class Paths { 4.65 - 4.66 - /** The log to use for warning output */ 4.67 - private Log log; 4.68 - 4.69 - /** Collection of command-line options */ 4.70 - private Options options; 4.71 - 4.72 - /** Handler for -Xlint options */ 4.73 - private Lint lint; 4.74 - 4.75 - /** Access to (possibly cached) file info */ 4.76 - private FSInfo fsInfo; 4.77 - 4.78 - public Paths() { 4.79 - pathsForLocation = new HashMap<Location,Path>(16); 4.80 - } 4.81 - 4.82 - public void update(Log log, Options options, Lint lint, FSInfo fsInfo) { 4.83 - this.log = log; 4.84 - this.options = options; 4.85 - this.lint = lint; 4.86 - this.fsInfo = fsInfo; 4.87 - } 4.88 - 4.89 - /** Whether to warn about non-existent path elements */ 4.90 - private boolean warn; 4.91 - 4.92 - private Map<Location, Path> pathsForLocation; 4.93 - 4.94 - private boolean inited = false; // TODO? caching bad? 4.95 - 4.96 - /** 4.97 - * rt.jar as found on the default bootclass path. If the user specified a 4.98 - * bootclasspath, null is used. 4.99 - */ 4.100 - private File defaultBootClassPathRtJar = null; 4.101 - 4.102 - /** 4.103 - * Is bootclasspath the default? 4.104 - */ 4.105 - private boolean isDefaultBootClassPath; 4.106 - 4.107 - Path getPathForLocation(Location location) { 4.108 - Path path = pathsForLocation.get(location); 4.109 - if (path == null) 4.110 - setPathForLocation(location, null); 4.111 - return pathsForLocation.get(location); 4.112 - } 4.113 - 4.114 - void setPathForLocation(Location location, Iterable<? extends File> path) { 4.115 - // TODO? if (inited) throw new IllegalStateException 4.116 - // TODO: otherwise reset sourceSearchPath, classSearchPath as needed 4.117 - Path p; 4.118 - if (path == null) { 4.119 - if (location == CLASS_PATH) 4.120 - p = computeUserClassPath(); 4.121 - else if (location == PLATFORM_CLASS_PATH) 4.122 - p = computeBootClassPath(); // sets isDefaultBootClassPath 4.123 - else if (location == ANNOTATION_PROCESSOR_PATH) 4.124 - p = computeAnnotationProcessorPath(); 4.125 - else if (location == SOURCE_PATH) 4.126 - p = computeSourcePath(); 4.127 - else 4.128 - // no defaults for other paths 4.129 - p = null; 4.130 - } else { 4.131 - if (location == PLATFORM_CLASS_PATH) { 4.132 - defaultBootClassPathRtJar = null; 4.133 - isDefaultBootClassPath = false; 4.134 - } 4.135 - p = new Path(); 4.136 - for (File f: path) 4.137 - p.addFile(f, warn); // TODO: is use of warn appropriate? 4.138 - } 4.139 - pathsForLocation.put(location, p); 4.140 - } 4.141 - 4.142 - public boolean isDefaultBootClassPath() { 4.143 - lazy(); 4.144 - return isDefaultBootClassPath; 4.145 - } 4.146 - 4.147 - protected void lazy() { 4.148 - if (!inited) { 4.149 - warn = lint.isEnabled(Lint.LintCategory.PATH); 4.150 - 4.151 - pathsForLocation.put(PLATFORM_CLASS_PATH, computeBootClassPath()); 4.152 - pathsForLocation.put(CLASS_PATH, computeUserClassPath()); 4.153 - pathsForLocation.put(SOURCE_PATH, computeSourcePath()); 4.154 - 4.155 - inited = true; 4.156 - } 4.157 - } 4.158 - 4.159 - public Collection<File> bootClassPath() { 4.160 - lazy(); 4.161 - return Collections.unmodifiableCollection(getPathForLocation(PLATFORM_CLASS_PATH)); 4.162 - } 4.163 - public Collection<File> userClassPath() { 4.164 - lazy(); 4.165 - return Collections.unmodifiableCollection(getPathForLocation(CLASS_PATH)); 4.166 - } 4.167 - public Collection<File> sourcePath() { 4.168 - lazy(); 4.169 - Path p = getPathForLocation(SOURCE_PATH); 4.170 - return p == null || p.size() == 0 4.171 - ? null 4.172 - : Collections.unmodifiableCollection(p); 4.173 - } 4.174 - 4.175 - boolean isDefaultBootClassPathRtJar(File file) { 4.176 - return file.equals(defaultBootClassPathRtJar); 4.177 - } 4.178 - 4.179 - /** 4.180 - * Split a path into its elements. Empty path elements will be ignored. 4.181 - * @param path The path to be split 4.182 - * @return The elements of the path 4.183 - */ 4.184 - private static Iterable<File> getPathEntries(String path) { 4.185 - return getPathEntries(path, null); 4.186 - } 4.187 - 4.188 - /** 4.189 - * Split a path into its elements. If emptyPathDefault is not null, all 4.190 - * empty elements in the path, including empty elements at either end of 4.191 - * the path, will be replaced with the value of emptyPathDefault. 4.192 - * @param path The path to be split 4.193 - * @param emptyPathDefault The value to substitute for empty path elements, 4.194 - * or null, to ignore empty path elements 4.195 - * @return The elements of the path 4.196 - */ 4.197 - private static Iterable<File> getPathEntries(String path, File emptyPathDefault) { 4.198 - ListBuffer<File> entries = new ListBuffer<File>(); 4.199 - int start = 0; 4.200 - while (start <= path.length()) { 4.201 - int sep = path.indexOf(File.pathSeparatorChar, start); 4.202 - if (sep == -1) 4.203 - sep = path.length(); 4.204 - if (start < sep) 4.205 - entries.add(new File(path.substring(start, sep))); 4.206 - else if (emptyPathDefault != null) 4.207 - entries.add(emptyPathDefault); 4.208 - start = sep + 1; 4.209 - } 4.210 - return entries; 4.211 - } 4.212 - 4.213 - private class Path extends LinkedHashSet<File> { 4.214 - private static final long serialVersionUID = 0; 4.215 - 4.216 - private boolean expandJarClassPaths = false; 4.217 - private Set<File> canonicalValues = new HashSet<File>(); 4.218 - 4.219 - public Path expandJarClassPaths(boolean x) { 4.220 - expandJarClassPaths = x; 4.221 - return this; 4.222 - } 4.223 - 4.224 - /** What to use when path element is the empty string */ 4.225 - private File emptyPathDefault = null; 4.226 - 4.227 - public Path emptyPathDefault(File x) { 4.228 - emptyPathDefault = x; 4.229 - return this; 4.230 - } 4.231 - 4.232 - public Path() { super(); } 4.233 - 4.234 - public Path addDirectories(String dirs, boolean warn) { 4.235 - boolean prev = expandJarClassPaths; 4.236 - expandJarClassPaths = true; 4.237 - try { 4.238 - if (dirs != null) 4.239 - for (File dir : getPathEntries(dirs)) 4.240 - addDirectory(dir, warn); 4.241 - return this; 4.242 - } finally { 4.243 - expandJarClassPaths = prev; 4.244 - } 4.245 - } 4.246 - 4.247 - public Path addDirectories(String dirs) { 4.248 - return addDirectories(dirs, warn); 4.249 - } 4.250 - 4.251 - private void addDirectory(File dir, boolean warn) { 4.252 - if (!dir.isDirectory()) { 4.253 - if (warn) 4.254 - log.warning(Lint.LintCategory.PATH, 4.255 - "dir.path.element.not.found", dir); 4.256 - return; 4.257 - } 4.258 - 4.259 - File[] files = dir.listFiles(); 4.260 - if (files == null) 4.261 - return; 4.262 - 4.263 - for (File direntry : files) { 4.264 - if (isArchive(direntry)) 4.265 - addFile(direntry, warn); 4.266 - } 4.267 - } 4.268 - 4.269 - public Path addFiles(String files, boolean warn) { 4.270 - if (files != null) { 4.271 - for (File file : getPathEntries(files, emptyPathDefault)) 4.272 - addFile(file, warn); 4.273 - } 4.274 - return this; 4.275 - } 4.276 - 4.277 - public Path addFiles(String files) { 4.278 - return addFiles(files, warn); 4.279 - } 4.280 - 4.281 - public void addFile(File file, boolean warn) { 4.282 - if (contains(file)) { 4.283 - // discard duplicates 4.284 - return; 4.285 - } 4.286 - 4.287 - if (! fsInfo.exists(file)) { 4.288 - /* No such file or directory exists */ 4.289 - if (warn) { 4.290 - log.warning(Lint.LintCategory.PATH, 4.291 - "path.element.not.found", file); 4.292 - } 4.293 - super.add(file); 4.294 - return; 4.295 - } 4.296 - 4.297 - File canonFile = fsInfo.getCanonicalFile(file); 4.298 - if (canonicalValues.contains(canonFile)) { 4.299 - /* Discard duplicates and avoid infinite recursion */ 4.300 - return; 4.301 - } 4.302 - 4.303 - if (fsInfo.isFile(file)) { 4.304 - /* File is an ordinary file. */ 4.305 - if (!isArchive(file)) { 4.306 - /* Not a recognized extension; open it to see if 4.307 - it looks like a valid zip file. */ 4.308 - try { 4.309 - ZipFile z = new ZipFile(file); 4.310 - z.close(); 4.311 - if (warn) { 4.312 - log.warning(Lint.LintCategory.PATH, 4.313 - "unexpected.archive.file", file); 4.314 - } 4.315 - } catch (IOException e) { 4.316 - // FIXME: include e.getLocalizedMessage in warning 4.317 - if (warn) { 4.318 - log.warning(Lint.LintCategory.PATH, 4.319 - "invalid.archive.file", file); 4.320 - } 4.321 - return; 4.322 - } 4.323 - } 4.324 - } 4.325 - 4.326 - /* Now what we have left is either a directory or a file name 4.327 - conforming to archive naming convention */ 4.328 - super.add(file); 4.329 - canonicalValues.add(canonFile); 4.330 - 4.331 - if (expandJarClassPaths && fsInfo.isFile(file)) 4.332 - addJarClassPath(file, warn); 4.333 - } 4.334 - 4.335 - // Adds referenced classpath elements from a jar's Class-Path 4.336 - // Manifest entry. In some future release, we may want to 4.337 - // update this code to recognize URLs rather than simple 4.338 - // filenames, but if we do, we should redo all path-related code. 4.339 - private void addJarClassPath(File jarFile, boolean warn) { 4.340 - try { 4.341 - for (File f: fsInfo.getJarClassPath(jarFile)) { 4.342 - addFile(f, warn); 4.343 - } 4.344 - } catch (IOException e) { 4.345 - log.error("error.reading.file", jarFile, JavacFileManager.getMessage(e)); 4.346 - } 4.347 - } 4.348 - } 4.349 - 4.350 - private Path computeBootClassPath() { 4.351 - defaultBootClassPathRtJar = null; 4.352 - Path path = new Path(); 4.353 - 4.354 - String bootclasspathOpt = options.get(BOOTCLASSPATH); 4.355 - String endorseddirsOpt = options.get(ENDORSEDDIRS); 4.356 - String extdirsOpt = options.get(EXTDIRS); 4.357 - String xbootclasspathPrependOpt = options.get(XBOOTCLASSPATH_PREPEND); 4.358 - String xbootclasspathAppendOpt = options.get(XBOOTCLASSPATH_APPEND); 4.359 - 4.360 - path.addFiles(xbootclasspathPrependOpt); 4.361 - 4.362 - if (endorseddirsOpt != null) 4.363 - path.addDirectories(endorseddirsOpt); 4.364 - else 4.365 - path.addDirectories(System.getProperty("java.endorsed.dirs"), false); 4.366 - 4.367 - if (bootclasspathOpt != null) { 4.368 - path.addFiles(bootclasspathOpt); 4.369 - } else { 4.370 - // Standard system classes for this compiler's release. 4.371 - String files = System.getProperty("sun.boot.class.path"); 4.372 - path.addFiles(files, false); 4.373 - File rt_jar = new File("rt.jar"); 4.374 - for (File file : getPathEntries(files)) { 4.375 - if (new File(file.getName()).equals(rt_jar)) 4.376 - defaultBootClassPathRtJar = file; 4.377 - } 4.378 - } 4.379 - 4.380 - path.addFiles(xbootclasspathAppendOpt); 4.381 - 4.382 - // Strictly speaking, standard extensions are not bootstrap 4.383 - // classes, but we treat them identically, so we'll pretend 4.384 - // that they are. 4.385 - if (extdirsOpt != null) 4.386 - path.addDirectories(extdirsOpt); 4.387 - else 4.388 - path.addDirectories(System.getProperty("java.ext.dirs"), false); 4.389 - 4.390 - isDefaultBootClassPath = 4.391 - (xbootclasspathPrependOpt == null) && 4.392 - (bootclasspathOpt == null) && 4.393 - (xbootclasspathAppendOpt == null); 4.394 - 4.395 - return path; 4.396 - } 4.397 - 4.398 - private Path computeUserClassPath() { 4.399 - String cp = options.get(CLASSPATH); 4.400 - 4.401 - // CLASSPATH environment variable when run from `javac'. 4.402 - if (cp == null) cp = System.getProperty("env.class.path"); 4.403 - 4.404 - // If invoked via a java VM (not the javac launcher), use the 4.405 - // platform class path 4.406 - if (cp == null && System.getProperty("application.home") == null) 4.407 - cp = System.getProperty("java.class.path"); 4.408 - 4.409 - // Default to current working directory. 4.410 - if (cp == null) cp = "."; 4.411 - 4.412 - return new Path() 4.413 - .expandJarClassPaths(true) // Only search user jars for Class-Paths 4.414 - .emptyPathDefault(new File(".")) // Empty path elt ==> current directory 4.415 - .addFiles(cp); 4.416 - } 4.417 - 4.418 - private Path computeSourcePath() { 4.419 - String sourcePathArg = options.get(SOURCEPATH); 4.420 - if (sourcePathArg == null) 4.421 - return null; 4.422 - 4.423 - return new Path().addFiles(sourcePathArg); 4.424 - } 4.425 - 4.426 - private Path computeAnnotationProcessorPath() { 4.427 - String processorPathArg = options.get(PROCESSORPATH); 4.428 - if (processorPathArg == null) 4.429 - return null; 4.430 - 4.431 - return new Path().addFiles(processorPathArg); 4.432 - } 4.433 - 4.434 - /** The actual effective locations searched for sources */ 4.435 - private Path sourceSearchPath; 4.436 - 4.437 - public Collection<File> sourceSearchPath() { 4.438 - if (sourceSearchPath == null) { 4.439 - lazy(); 4.440 - Path sourcePath = getPathForLocation(SOURCE_PATH); 4.441 - Path userClassPath = getPathForLocation(CLASS_PATH); 4.442 - sourceSearchPath = sourcePath != null ? sourcePath : userClassPath; 4.443 - } 4.444 - return Collections.unmodifiableCollection(sourceSearchPath); 4.445 - } 4.446 - 4.447 - /** The actual effective locations searched for classes */ 4.448 - private Path classSearchPath; 4.449 - 4.450 - public Collection<File> classSearchPath() { 4.451 - if (classSearchPath == null) { 4.452 - lazy(); 4.453 - Path bootClassPath = getPathForLocation(PLATFORM_CLASS_PATH); 4.454 - Path userClassPath = getPathForLocation(CLASS_PATH); 4.455 - classSearchPath = new Path(); 4.456 - classSearchPath.addAll(bootClassPath); 4.457 - classSearchPath.addAll(userClassPath); 4.458 - } 4.459 - return Collections.unmodifiableCollection(classSearchPath); 4.460 - } 4.461 - 4.462 - /** The actual effective locations for non-source, non-class files */ 4.463 - private Path otherSearchPath; 4.464 - 4.465 - Collection<File> otherSearchPath() { 4.466 - if (otherSearchPath == null) { 4.467 - lazy(); 4.468 - Path userClassPath = getPathForLocation(CLASS_PATH); 4.469 - Path sourcePath = getPathForLocation(SOURCE_PATH); 4.470 - if (sourcePath == null) 4.471 - otherSearchPath = userClassPath; 4.472 - else { 4.473 - otherSearchPath = new Path(); 4.474 - otherSearchPath.addAll(userClassPath); 4.475 - otherSearchPath.addAll(sourcePath); 4.476 - } 4.477 - } 4.478 - return Collections.unmodifiableCollection(otherSearchPath); 4.479 - } 4.480 - 4.481 - /** Is this the name of an archive file? */ 4.482 - private boolean isArchive(File file) { 4.483 - String n = file.getName().toLowerCase(); 4.484 - return fsInfo.isFile(file) 4.485 - && (n.endsWith(".jar") || n.endsWith(".zip")); 4.486 - } 4.487 - 4.488 - /** 4.489 - * Utility method for converting a search path string to an array 4.490 - * of directory and JAR file URLs. 4.491 - * 4.492 - * Note that this method is called by apt and the DocletInvoker. 4.493 - * 4.494 - * @param path the search path string 4.495 - * @return the resulting array of directory and JAR file URLs 4.496 - */ 4.497 - public static URL[] pathToURLs(String path) { 4.498 - StringTokenizer st = new StringTokenizer(path, File.pathSeparator); 4.499 - URL[] urls = new URL[st.countTokens()]; 4.500 - int count = 0; 4.501 - while (st.hasMoreTokens()) { 4.502 - URL url = fileToURL(new File(st.nextToken())); 4.503 - if (url != null) { 4.504 - urls[count++] = url; 4.505 - } 4.506 - } 4.507 - if (urls.length != count) { 4.508 - URL[] tmp = new URL[count]; 4.509 - System.arraycopy(urls, 0, tmp, 0, count); 4.510 - urls = tmp; 4.511 - } 4.512 - return urls; 4.513 - } 4.514 - 4.515 - /** 4.516 - * Returns the directory or JAR file URL corresponding to the specified 4.517 - * local file name. 4.518 - * 4.519 - * @param file the File object 4.520 - * @return the resulting directory or JAR file URL, or null if unknown 4.521 - */ 4.522 - private static URL fileToURL(File file) { 4.523 - String name; 4.524 - try { 4.525 - name = file.getCanonicalPath(); 4.526 - } catch (IOException e) { 4.527 - name = file.getAbsolutePath(); 4.528 - } 4.529 - name = name.replace(File.separatorChar, '/'); 4.530 - if (!name.startsWith("/")) { 4.531 - name = "/" + name; 4.532 - } 4.533 - // If the file does not exist, then assume that it's a directory 4.534 - if (!file.isFile()) { 4.535 - name = name + "/"; 4.536 - } 4.537 - try { 4.538 - return new URL("file", "", name); 4.539 - } catch (MalformedURLException e) { 4.540 - throw new IllegalArgumentException(file.toString()); 4.541 - } 4.542 - } 4.543 -}
5.1 --- a/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java Tue Oct 25 15:40:34 2011 +0100 5.2 +++ b/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java Tue Oct 25 10:48:05 2011 -0700 5.3 @@ -169,7 +169,7 @@ 5.4 5.5 @Override 5.6 public boolean isDefaultBootClassPath() { 5.7 - return searchPaths.isDefaultBootClassPath(); 5.8 + return locations.isDefaultBootClassPath(); 5.9 } 5.10 5.11 // <editor-fold defaultstate="collapsed" desc="Location handling"> 5.12 @@ -227,13 +227,13 @@ 5.13 if (locn instanceof StandardLocation) { 5.14 switch ((StandardLocation) locn) { 5.15 case CLASS_PATH: 5.16 - files = searchPaths.userClassPath(); 5.17 + files = locations.userClassPath(); 5.18 break; 5.19 case PLATFORM_CLASS_PATH: 5.20 - files = searchPaths.bootClassPath(); 5.21 + files = locations.bootClassPath(); 5.22 break; 5.23 case SOURCE_PATH: 5.24 - files = searchPaths.sourcePath(); 5.25 + files = locations.sourcePath(); 5.26 break; 5.27 case CLASS_OUTPUT: { 5.28 String arg = options.get(D);
6.1 --- a/src/share/classes/com/sun/tools/javac/util/BaseFileManager.java Tue Oct 25 15:40:34 2011 +0100 6.2 +++ b/src/share/classes/com/sun/tools/javac/util/BaseFileManager.java Tue Oct 25 10:48:05 2011 -0700 6.3 @@ -52,7 +52,7 @@ 6.4 import com.sun.tools.javac.code.Lint; 6.5 import com.sun.tools.javac.code.Source; 6.6 import com.sun.tools.javac.file.FSInfo; 6.7 -import com.sun.tools.javac.file.Paths; 6.8 +import com.sun.tools.javac.file.Locations; 6.9 import com.sun.tools.javac.main.JavacOption; 6.10 import com.sun.tools.javac.main.OptionName; 6.11 import com.sun.tools.javac.main.RecognizedOptions; 6.12 @@ -67,7 +67,7 @@ 6.13 protected BaseFileManager(Charset charset) { 6.14 this.charset = charset; 6.15 byteBufferCache = new ByteBufferCache(); 6.16 - searchPaths = createPaths(); 6.17 + locations = createLocations(); 6.18 } 6.19 6.20 /** 6.21 @@ -77,11 +77,11 @@ 6.22 log = Log.instance(context); 6.23 options = Options.instance(context); 6.24 classLoaderClass = options.get("procloader"); 6.25 - searchPaths.update(log, options, Lint.instance(context), FSInfo.instance(context)); 6.26 + locations.update(log, options, Lint.instance(context), FSInfo.instance(context)); 6.27 } 6.28 6.29 - protected Paths createPaths() { 6.30 - return new Paths(); 6.31 + protected Locations createLocations() { 6.32 + return new Locations(); 6.33 } 6.34 6.35 /** 6.36 @@ -98,7 +98,7 @@ 6.37 6.38 protected String classLoaderClass; 6.39 6.40 - protected Paths searchPaths; 6.41 + protected Locations locations; 6.42 6.43 protected Source getSource() { 6.44 String sourceName = options.get(OptionName.SOURCE);
7.1 --- a/src/share/classes/com/sun/tools/javadoc/DocletInvoker.java Tue Oct 25 15:40:34 2011 +0100 7.2 +++ b/src/share/classes/com/sun/tools/javadoc/DocletInvoker.java Tue Oct 25 10:48:05 2011 -0700 7.3 @@ -80,7 +80,7 @@ 7.4 cpString = appendPath(System.getProperty("env.class.path"), cpString); 7.5 cpString = appendPath(System.getProperty("java.class.path"), cpString); 7.6 cpString = appendPath(docletPath, cpString); 7.7 - URL[] urls = com.sun.tools.javac.file.Paths.pathToURLs(cpString); 7.8 + URL[] urls = com.sun.tools.javac.file.Locations.pathToURLs(cpString); 7.9 if (docletParentClassLoader == null) 7.10 appClassLoader = new URLClassLoader(urls, getDelegationClassLoader(docletClassName)); 7.11 else