7104039: refactor/cleanup javac Paths class

Tue, 25 Oct 2011 10:48:05 -0700

author
jjg
date
Tue, 25 Oct 2011 10:48:05 -0700
changeset 1116
d830d28fc72e
parent 1115
b73a9be0b993
child 1117
a1eaf78ababb

7104039: refactor/cleanup javac Paths class
Reviewed-by: mcimadamore

src/share/classes/com/sun/tools/apt/main/Main.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/file/JavacFileManager.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/file/Locations.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/file/Paths.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/util/BaseFileManager.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javadoc/DocletInvoker.java file | annotate | diff | comparison | revisions
     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

mercurial