6508981: cleanup file separator handling in JavacFileManager

Tue, 26 Aug 2008 14:52:59 -0700

author
jjg
date
Tue, 26 Aug 2008 14:52:59 -0700
changeset 103
e571266ae14f
parent 100
37551dc0f591
child 104
5e89c4ca637c

6508981: cleanup file separator handling in JavacFileManager
Reviewed-by: mcimadamore

src/share/classes/com/sun/tools/javac/file/JavacFileManager.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/file/RelativePath.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/file/SymbolArchive.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/file/ZipArchive.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javadoc/DocletInvoker.java file | annotate | diff | comparison | revisions
src/share/classes/javax/tools/StandardLocation.java file | annotate | diff | comparison | revisions
test/tools/javac/6508981/TestInferBinaryName.java file | annotate | diff | comparison | revisions
test/tools/javac/6508981/p/A.java file | annotate | diff | comparison | revisions
test/tools/javac/T6725036.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Fri Aug 22 11:46:29 2008 +0100
     1.2 +++ b/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Tue Aug 26 14:52:59 2008 -0700
     1.3 @@ -65,6 +65,8 @@
     1.4  import javax.tools.StandardJavaFileManager;
     1.5  
     1.6  import com.sun.tools.javac.code.Source;
     1.7 +import com.sun.tools.javac.file.RelativePath.RelativeFile;
     1.8 +import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
     1.9  import com.sun.tools.javac.main.JavacOption;
    1.10  import com.sun.tools.javac.main.OptionName;
    1.11  import com.sun.tools.javac.main.RecognizedOptions;
    1.12 @@ -75,8 +77,8 @@
    1.13  import com.sun.tools.javac.util.Log;
    1.14  import com.sun.tools.javac.util.Options;
    1.15  
    1.16 +import static javax.tools.StandardLocation.*;
    1.17  import static com.sun.tools.javac.main.OptionName.*;
    1.18 -import static javax.tools.StandardLocation.*;
    1.19  
    1.20  /**
    1.21   * This class provides access to the source, class and other files
    1.22 @@ -84,9 +86,6 @@
    1.23   */
    1.24  public class JavacFileManager implements StandardJavaFileManager {
    1.25  
    1.26 -    private static final String[] symbolFileLocation = { "lib", "ct.sym" };
    1.27 -    private static final String symbolFilePrefix = "META-INF/sym/rt.jar/";
    1.28 -
    1.29      boolean useZipFileIndex;
    1.30  
    1.31      private static boolean CHECK_ZIP_TIMESTAMP = false;
    1.32 @@ -267,6 +266,7 @@
    1.33              printAscii("Invalid class name: \"%s\"", name);
    1.34          }
    1.35      }
    1.36 +
    1.37      private static void printAscii(String format, Object... args) {
    1.38          String message;
    1.39          try {
    1.40 @@ -278,27 +278,12 @@
    1.41          System.out.println(message);
    1.42      }
    1.43  
    1.44 -    /** Return external representation of name,
    1.45 -     *  converting '.' to File.separatorChar.
    1.46 -     */
    1.47 -    private static String externalizeFileName(CharSequence name) {
    1.48 -        return name.toString().replace('.', File.separatorChar);
    1.49 -    }
    1.50 -
    1.51 -    private static String externalizeFileName(CharSequence n, JavaFileObject.Kind kind) {
    1.52 -        return externalizeFileName(n) + kind.extension;
    1.53 -    }
    1.54 -
    1.55 -    private static String baseName(String fileName) {
    1.56 -        return fileName.substring(fileName.lastIndexOf(File.separatorChar) + 1);
    1.57 -    }
    1.58 -
    1.59      /**
    1.60       * Insert all files in subdirectory `subdirectory' of `directory' which end
    1.61       * in one of the extensions in `extensions' into packageSym.
    1.62       */
    1.63      private void listDirectory(File directory,
    1.64 -                               String subdirectory,
    1.65 +                               RelativeDirectory subdirectory,
    1.66                                 Set<JavaFileObject.Kind> fileKinds,
    1.67                                 boolean recurse,
    1.68                                 ListBuffer<JavaFileObject> l) {
    1.69 @@ -329,22 +314,6 @@
    1.70                      return;
    1.71                  }
    1.72              }
    1.73 -            if (subdirectory.length() != 0) {
    1.74 -                if (!useZipFileIndex) {
    1.75 -                    subdirectory = subdirectory.replace('\\', '/');
    1.76 -                    if (!subdirectory.endsWith("/")) subdirectory = subdirectory + "/";
    1.77 -                }
    1.78 -                else {
    1.79 -                    if (File.separatorChar == '/') {
    1.80 -                        subdirectory = subdirectory.replace('\\', '/');
    1.81 -                    }
    1.82 -                    else {
    1.83 -                        subdirectory = subdirectory.replace('/', '\\');
    1.84 -                    }
    1.85 -
    1.86 -                    if (!subdirectory.endsWith(File.separator)) subdirectory = subdirectory + File.separator;
    1.87 -                }
    1.88 -            }
    1.89  
    1.90              List<String> files = archive.getFiles(subdirectory);
    1.91              if (files != null) {
    1.92 @@ -356,8 +325,8 @@
    1.93                  }
    1.94              }
    1.95              if (recurse) {
    1.96 -                for (String s: archive.getSubdirectories()) {
    1.97 -                    if (s.startsWith(subdirectory) && !s.equals(subdirectory)) {
    1.98 +                for (RelativeDirectory s: archive.getSubdirectories()) {
    1.99 +                    if (subdirectory.contains(s)) {
   1.100                          // Because the archive map is a flat list of directories,
   1.101                          // the enclosing loop will pick up all child subdirectories.
   1.102                          // Therefore, there is no need to recurse deeper.
   1.103 @@ -366,9 +335,7 @@
   1.104                  }
   1.105              }
   1.106          } else {
   1.107 -            File d = subdirectory.length() != 0
   1.108 -                ? new File(directory, subdirectory)
   1.109 -                : directory;
   1.110 +            File d = subdirectory.getFile(directory);
   1.111              if (!caseMapCheck(d, subdirectory))
   1.112                  return;
   1.113  
   1.114 @@ -381,7 +348,7 @@
   1.115                  if (f.isDirectory()) {
   1.116                      if (recurse && SourceVersion.isIdentifier(fname)) {
   1.117                          listDirectory(directory,
   1.118 -                                      subdirectory + File.separator + fname,
   1.119 +                                      new RelativeDirectory(subdirectory, fname),
   1.120                                        fileKinds,
   1.121                                        recurse,
   1.122                                        l);
   1.123 @@ -411,7 +378,7 @@
   1.124       *  ends in a string of characters with the same case as given name.
   1.125       *  Ignore file separators in both path and name.
   1.126       */
   1.127 -    private boolean caseMapCheck(File f, String name) {
   1.128 +    private boolean caseMapCheck(File f, RelativePath name) {
   1.129          if (fileSystemIsCaseSensitive) return true;
   1.130          // Note that getCanonicalPath() returns the case-sensitive
   1.131          // spelled file name.
   1.132 @@ -422,12 +389,12 @@
   1.133              return false;
   1.134          }
   1.135          char[] pcs = path.toCharArray();
   1.136 -        char[] ncs = name.toCharArray();
   1.137 +        char[] ncs = name.path.toCharArray();
   1.138          int i = pcs.length - 1;
   1.139          int j = ncs.length - 1;
   1.140          while (i >= 0 && j >= 0) {
   1.141              while (i >= 0 && pcs[i] == File.separatorChar) i--;
   1.142 -            while (j >= 0 && ncs[j] == File.separatorChar) j--;
   1.143 +            while (j >= 0 && ncs[j] == '/') j--;
   1.144              if (i >= 0 && j >= 0) {
   1.145                  if (pcs[i] != ncs[j]) return false;
   1.146                  i--;
   1.147 @@ -444,13 +411,13 @@
   1.148      public interface Archive {
   1.149          void close() throws IOException;
   1.150  
   1.151 -        boolean contains(String name);
   1.152 +        boolean contains(RelativePath name);
   1.153  
   1.154 -        JavaFileObject getFileObject(String subdirectory, String file);
   1.155 +        JavaFileObject getFileObject(RelativeDirectory subdirectory, String file);
   1.156  
   1.157 -        List<String> getFiles(String subdirectory);
   1.158 +        List<String> getFiles(RelativeDirectory subdirectory);
   1.159  
   1.160 -        Set<String> getSubdirectories();
   1.161 +        Set<RelativeDirectory> getSubdirectories();
   1.162      }
   1.163  
   1.164      public class MissingArchive implements Archive {
   1.165 @@ -458,30 +425,38 @@
   1.166          public MissingArchive(File name) {
   1.167              zipFileName = name;
   1.168          }
   1.169 -        public boolean contains(String name) {
   1.170 +        public boolean contains(RelativePath name) {
   1.171              return false;
   1.172          }
   1.173  
   1.174          public void close() {
   1.175          }
   1.176  
   1.177 -        public JavaFileObject getFileObject(String subdirectory, String file) {
   1.178 +        public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) {
   1.179              return null;
   1.180          }
   1.181  
   1.182 -        public List<String> getFiles(String subdirectory) {
   1.183 +        public List<String> getFiles(RelativeDirectory subdirectory) {
   1.184              return List.nil();
   1.185          }
   1.186  
   1.187 -        public Set<String> getSubdirectories() {
   1.188 +        public Set<RelativeDirectory> getSubdirectories() {
   1.189              return Collections.emptySet();
   1.190          }
   1.191 +
   1.192 +        public String toString() {
   1.193 +            return "MissingArchive[" + zipFileName + "]";
   1.194 +        }
   1.195      }
   1.196  
   1.197      /** A directory of zip files already opened.
   1.198       */
   1.199      Map<File, Archive> archives = new HashMap<File,Archive>();
   1.200  
   1.201 +    private static final String[] symbolFileLocation = { "lib", "ct.sym" };
   1.202 +    private static final RelativeDirectory symbolFilePrefix
   1.203 +            = new RelativeDirectory("META-INF/sym/rt.jar/");
   1.204 +
   1.205      /** Open a new zip file directory.
   1.206       */
   1.207      protected Archive openArchive(File zipFileName) throws IOException {
   1.208 @@ -540,8 +515,12 @@
   1.209                      if (!useZipFileIndex) {
   1.210                          archive = new ZipArchive(this, zdir);
   1.211                      } else {
   1.212 -                        archive = new ZipFileIndexArchive(this, ZipFileIndex.getZipFileIndex(zipFileName, null,
   1.213 -                                usePreindexedCache, preindexCacheLocation, options.get("writezipindexfiles") != null));
   1.214 +                        archive = new ZipFileIndexArchive(this,
   1.215 +                                ZipFileIndex.getZipFileIndex(zipFileName,
   1.216 +                                    null,
   1.217 +                                    usePreindexedCache,
   1.218 +                                    preindexCacheLocation,
   1.219 +                                    options.get("writezipindexfiles") != null));
   1.220                      }
   1.221                  }
   1.222                  else {
   1.223 @@ -551,10 +530,10 @@
   1.224                      else {
   1.225                          archive = new ZipFileIndexArchive(this,
   1.226                                  ZipFileIndex.getZipFileIndex(zipFileName,
   1.227 -                                symbolFilePrefix,
   1.228 -                                usePreindexedCache,
   1.229 -                                preindexCacheLocation,
   1.230 -                                options.get("writezipindexfiles") != null));
   1.231 +                                    symbolFilePrefix,
   1.232 +                                    usePreindexedCache,
   1.233 +                                    preindexCacheLocation,
   1.234 +                                    options.get("writezipindexfiles") != null));
   1.235                      }
   1.236                  }
   1.237              } catch (FileNotFoundException ex) {
   1.238 @@ -796,7 +775,7 @@
   1.239          Iterable<? extends File> path = getLocation(location);
   1.240          if (path == null)
   1.241              return List.nil();
   1.242 -        String subdirectory = externalizeFileName(packageName);
   1.243 +        RelativeDirectory subdirectory = RelativeDirectory.forPackage(packageName);
   1.244          ListBuffer<JavaFileObject> results = new ListBuffer<JavaFileObject>();
   1.245  
   1.246          for (File directory : path)
   1.247 @@ -877,7 +856,7 @@
   1.248          nullCheck(kind);
   1.249          if (!sourceOrClass.contains(kind))
   1.250              throw new IllegalArgumentException("Invalid kind " + kind);
   1.251 -        return getFileForInput(location, externalizeFileName(className, kind));
   1.252 +        return getFileForInput(location, RelativeFile.forClass(className, kind));
   1.253      }
   1.254  
   1.255      public FileObject getFileForInput(Location location,
   1.256 @@ -890,35 +869,32 @@
   1.257          nullCheck(packageName);
   1.258          if (!isRelativeUri(URI.create(relativeName))) // FIXME 6419701
   1.259              throw new IllegalArgumentException("Invalid relative name: " + relativeName);
   1.260 -        String name = packageName.length() == 0
   1.261 -            ? relativeName
   1.262 -            : new File(externalizeFileName(packageName), relativeName).getPath();
   1.263 +        RelativeFile name = packageName.length() == 0
   1.264 +            ? new RelativeFile(relativeName)
   1.265 +            : new RelativeFile(RelativeDirectory.forPackage(packageName), relativeName);
   1.266          return getFileForInput(location, name);
   1.267      }
   1.268  
   1.269 -    private JavaFileObject getFileForInput(Location location, String name) throws IOException {
   1.270 +    private JavaFileObject getFileForInput(Location location, RelativeFile name) throws IOException {
   1.271          Iterable<? extends File> path = getLocation(location);
   1.272          if (path == null)
   1.273              return null;
   1.274  
   1.275          for (File dir: path) {
   1.276              if (dir.isDirectory()) {
   1.277 -                File f = new File(dir, name.replace('/', File.separatorChar));
   1.278 +                File f = name.getFile(dir);
   1.279                  if (f.exists())
   1.280                      return new RegularFileObject(this, f);
   1.281              } else {
   1.282                  Archive a = openArchive(dir);
   1.283                  if (a.contains(name)) {
   1.284 -                    int i = name.lastIndexOf('/');
   1.285 -                    String dirname = name.substring(0, i+1);
   1.286 -                    String basename = name.substring(i+1);
   1.287 -                    return a.getFileObject(dirname, basename);
   1.288 +                    return a.getFileObject(name.dirname(), name.basename());
   1.289                  }
   1.290  
   1.291              }
   1.292          }
   1.293 +
   1.294          return null;
   1.295 -
   1.296      }
   1.297  
   1.298      public JavaFileObject getJavaFileForOutput(Location location,
   1.299 @@ -933,7 +909,7 @@
   1.300          nullCheck(kind);
   1.301          if (!sourceOrClass.contains(kind))
   1.302              throw new IllegalArgumentException("Invalid kind " + kind);
   1.303 -        return getFileForOutput(location, externalizeFileName(className, kind), sibling);
   1.304 +        return getFileForOutput(location, RelativeFile.forClass(className, kind), sibling);
   1.305      }
   1.306  
   1.307      public FileObject getFileForOutput(Location location,
   1.308 @@ -947,14 +923,14 @@
   1.309          nullCheck(packageName);
   1.310          if (!isRelativeUri(URI.create(relativeName))) // FIXME 6419701
   1.311              throw new IllegalArgumentException("relativeName is invalid");
   1.312 -        String name = packageName.length() == 0
   1.313 -            ? relativeName
   1.314 -            : new File(externalizeFileName(packageName), relativeName).getPath();
   1.315 +        RelativeFile name = packageName.length() == 0
   1.316 +            ? new RelativeFile(relativeName)
   1.317 +            : new RelativeFile(RelativeDirectory.forPackage(packageName), relativeName);
   1.318          return getFileForOutput(location, name, sibling);
   1.319      }
   1.320  
   1.321      private JavaFileObject getFileForOutput(Location location,
   1.322 -                                            String fileName,
   1.323 +                                            RelativeFile fileName,
   1.324                                              FileObject sibling)
   1.325          throws IOException
   1.326      {
   1.327 @@ -967,7 +943,7 @@
   1.328                  if (sibling != null && sibling instanceof RegularFileObject) {
   1.329                      siblingDir = ((RegularFileObject)sibling).f.getParentFile();
   1.330                  }
   1.331 -                return new RegularFileObject(this, new File(siblingDir, baseName(fileName)));
   1.332 +                return new RegularFileObject(this, new File(siblingDir, fileName.basename()));
   1.333              }
   1.334          } else if (location == SOURCE_OUTPUT) {
   1.335              dir = (getSourceOutDir() != null ? getSourceOutDir() : getClassOutDir());
   1.336 @@ -980,7 +956,7 @@
   1.337              }
   1.338          }
   1.339  
   1.340 -        File file = (dir == null ? new File(fileName) : new File(dir, fileName));
   1.341 +        File file = fileName.getFile(dir); // null-safe
   1.342          return new RegularFileObject(this, file);
   1.343  
   1.344      }
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/share/classes/com/sun/tools/javac/file/RelativePath.java	Tue Aug 26 14:52:59 2008 -0700
     2.3 @@ -0,0 +1,191 @@
     2.4 +/*
     2.5 + * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
     2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.7 + *
     2.8 + * This code is free software; you can redistribute it and/or modify it
     2.9 + * under the terms of the GNU General Public License version 2 only, as
    2.10 + * published by the Free Software Foundation.  Sun designates this
    2.11 + * particular file as subject to the "Classpath" exception as provided
    2.12 + * by Sun in the LICENSE file that accompanied this code.
    2.13 + *
    2.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    2.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    2.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    2.17 + * version 2 for more details (a copy is included in the LICENSE file that
    2.18 + * accompanied this code).
    2.19 + *
    2.20 + * You should have received a copy of the GNU General Public License version
    2.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    2.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    2.23 + *
    2.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    2.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
    2.26 + * have any questions.
    2.27 + */
    2.28 +
    2.29 +package com.sun.tools.javac.file;
    2.30 +
    2.31 +import java.io.File;
    2.32 +import java.util.zip.ZipEntry;
    2.33 +import java.util.zip.ZipFile;
    2.34 +import javax.tools.JavaFileObject;
    2.35 +
    2.36 +/**
    2.37 + * Used to represent a platform-neutral path within a platform-specific
    2.38 + * container, such as a directory or zip file.
    2.39 + * Internally, the file separator is always '/'.
    2.40 + */
    2.41 +public abstract class RelativePath implements Comparable<RelativePath> {
    2.42 +    /**
    2.43 +     * @param p must use '/' as an internal separator
    2.44 +     */
    2.45 +    protected RelativePath(String p) {
    2.46 +        path = p;
    2.47 +    }
    2.48 +
    2.49 +    public abstract RelativeDirectory dirname();
    2.50 +
    2.51 +    public abstract String basename();
    2.52 +
    2.53 +    public File getFile(File directory) {
    2.54 +        if (path.length() == 0)
    2.55 +            return directory;
    2.56 +        return new File(directory, path.replace('/', File.separatorChar));
    2.57 +    }
    2.58 +
    2.59 +    public int compareTo(RelativePath other) {
    2.60 +        return path.compareTo(other.path);
    2.61 +    }
    2.62 +
    2.63 +    @Override
    2.64 +    public boolean equals(Object other) {
    2.65 +        if (!(other instanceof RelativePath))
    2.66 +            return false;
    2.67 +         return path.equals(((RelativePath) other).path);
    2.68 +    }
    2.69 +
    2.70 +    @Override
    2.71 +    public int hashCode() {
    2.72 +        return path.hashCode();
    2.73 +    }
    2.74 +
    2.75 +    @Override
    2.76 +    public String toString() {
    2.77 +        return "RelPath[" + path + "]";
    2.78 +    }
    2.79 +
    2.80 +    public String getPath() {
    2.81 +        return path;
    2.82 +    }
    2.83 +
    2.84 +    protected final String path;
    2.85 +
    2.86 +    /**
    2.87 +     * Used to represent a platform-neutral subdirectory within a platform-specific
    2.88 +     * container, such as a directory or zip file.
    2.89 +     * Internally, the file separator is always '/', and if the path is not empty,
    2.90 +     * it always ends in a '/' as well.
    2.91 +     */
    2.92 +    public static class RelativeDirectory extends RelativePath {
    2.93 +
    2.94 +        static RelativeDirectory forPackage(CharSequence packageName) {
    2.95 +            return new RelativeDirectory(packageName.toString().replace('.', '/'));
    2.96 +        }
    2.97 +
    2.98 +        /**
    2.99 +         * @param p must use '/' as an internal separator
   2.100 +         */
   2.101 +        public RelativeDirectory(String p) {
   2.102 +            super(p.length() == 0 || p.endsWith("/") ? p : p + "/");
   2.103 +        }
   2.104 +
   2.105 +        /**
   2.106 +         * @param p must use '/' as an internal separator
   2.107 +         */
   2.108 +        public RelativeDirectory(RelativeDirectory d, String p) {
   2.109 +            this(d.path + p);
   2.110 +        }
   2.111 +
   2.112 +        @Override
   2.113 +        public RelativeDirectory dirname() {
   2.114 +            int l = path.length();
   2.115 +            if (l == 0)
   2.116 +                return this;
   2.117 +            int sep = path.lastIndexOf('/', l - 2);
   2.118 +            return new RelativeDirectory(path.substring(0, sep + 1));
   2.119 +        }
   2.120 +
   2.121 +        @Override
   2.122 +        public String basename() {
   2.123 +            int l = path.length();
   2.124 +            if (l == 0)
   2.125 +                return path;
   2.126 +            int sep = path.lastIndexOf('/', l - 2);
   2.127 +            return path.substring(sep + 1, l - 1);
   2.128 +        }
   2.129 +
   2.130 +        /**
   2.131 +         * Return true if this subdirectory "contains" the other path.
   2.132 +         * A subdirectory path does not contain itself.
   2.133 +         **/
   2.134 +        boolean contains(RelativePath other) {
   2.135 +            return other.path.length() > path.length() && other.path.startsWith(path);
   2.136 +        }
   2.137 +
   2.138 +        @Override
   2.139 +        public String toString() {
   2.140 +            return "RelativeDirectory[" + path + "]";
   2.141 +        }
   2.142 +    }
   2.143 +
   2.144 +    /**
   2.145 +     * Used to represent a platform-neutral file within a platform-specific
   2.146 +     * container, such as a directory or zip file.
   2.147 +     * Internally, the file separator is always '/'. It never ends in '/'.
   2.148 +     */
   2.149 +    public static class RelativeFile extends RelativePath {
   2.150 +        static RelativeFile forClass(CharSequence className, JavaFileObject.Kind kind) {
   2.151 +            return new RelativeFile(className.toString().replace('.', '/') + kind.extension);
   2.152 +        }
   2.153 +
   2.154 +        public RelativeFile(String p) {
   2.155 +            super(p);
   2.156 +            if (p.endsWith("/"))
   2.157 +                throw new IllegalArgumentException(p);
   2.158 +        }
   2.159 +
   2.160 +        /**
   2.161 +         * @param p must use '/' as an internal separator
   2.162 +         */
   2.163 +        public RelativeFile(RelativeDirectory d, String p) {
   2.164 +            this(d.path + p);
   2.165 +        }
   2.166 +
   2.167 +        RelativeFile(RelativeDirectory d, RelativePath p) {
   2.168 +            this(d, p.path);
   2.169 +        }
   2.170 +
   2.171 +        @Override
   2.172 +        public RelativeDirectory dirname() {
   2.173 +            int sep = path.lastIndexOf('/');
   2.174 +            return new RelativeDirectory(path.substring(0, sep + 1));
   2.175 +        }
   2.176 +
   2.177 +        @Override
   2.178 +        public String basename() {
   2.179 +            int sep = path.lastIndexOf('/');
   2.180 +            return path.substring(sep + 1);
   2.181 +        }
   2.182 +
   2.183 +        ZipEntry getZipEntry(ZipFile zip) {
   2.184 +            return zip.getEntry(path);
   2.185 +        }
   2.186 +
   2.187 +        @Override
   2.188 +        public String toString() {
   2.189 +            return "RelativeFile[" + path + "]";
   2.190 +        }
   2.191 +
   2.192 +    }
   2.193 +
   2.194 +}
     3.1 --- a/src/share/classes/com/sun/tools/javac/file/SymbolArchive.java	Fri Aug 22 11:46:29 2008 +0100
     3.2 +++ b/src/share/classes/com/sun/tools/javac/file/SymbolArchive.java	Tue Aug 26 14:52:59 2008 -0700
     3.3 @@ -25,47 +25,75 @@
     3.4  
     3.5  package com.sun.tools.javac.file;
     3.6  
     3.7 -import com.sun.tools.javac.util.List;
     3.8  import java.io.File;
     3.9  import java.io.IOException;
    3.10  import java.util.zip.ZipEntry;
    3.11  import java.util.zip.ZipFile;
    3.12  import javax.tools.JavaFileObject;
    3.13  
    3.14 +import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
    3.15 +import com.sun.tools.javac.file.RelativePath.RelativeFile;
    3.16 +import com.sun.tools.javac.util.List;
    3.17 +
    3.18  public class SymbolArchive extends ZipArchive {
    3.19  
    3.20      final File origFile;
    3.21 -    final String prefix;
    3.22 +    final RelativeDirectory prefix;
    3.23  
    3.24 -    public SymbolArchive(JavacFileManager fileManager, File orig, ZipFile zdir, String prefix) throws IOException {
    3.25 -        super(fileManager, zdir);
    3.26 +    public SymbolArchive(JavacFileManager fileManager, File orig, ZipFile zdir, RelativeDirectory prefix) throws IOException {
    3.27 +        super(fileManager, zdir, false);
    3.28          this.origFile = orig;
    3.29          this.prefix = prefix;
    3.30 +        initMap();
    3.31      }
    3.32  
    3.33      @Override
    3.34      void addZipEntry(ZipEntry entry) {
    3.35          String name = entry.getName();
    3.36 -        if (!name.startsWith(prefix)) {
    3.37 +        if (!name.startsWith(prefix.path)) {
    3.38              return;
    3.39          }
    3.40 -        name = name.substring(prefix.length());
    3.41 +        name = name.substring(prefix.path.length());
    3.42          int i = name.lastIndexOf('/');
    3.43 -        String dirname = name.substring(0, i + 1);
    3.44 +        RelativeDirectory dirname = new RelativeDirectory(name.substring(0, i+1));
    3.45          String basename = name.substring(i + 1);
    3.46          if (basename.length() == 0) {
    3.47              return;
    3.48          }
    3.49          List<String> list = map.get(dirname);
    3.50 -        if (list == null) {
    3.51 +        if (list == null)
    3.52              list = List.nil();
    3.53 -        }
    3.54          list = list.prepend(basename);
    3.55          map.put(dirname, list);
    3.56      }
    3.57  
    3.58 -    @Override
    3.59 -    public JavaFileObject getFileObject(String subdirectory, String file) {
    3.60 -        return super.getFileObject(prefix + subdirectory, file);
    3.61 +    public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) {
    3.62 +        RelativeDirectory prefix_subdir = new RelativeDirectory(prefix, subdirectory.path);
    3.63 +        ZipEntry ze = new RelativeFile(prefix_subdir, file).getZipEntry(zdir);
    3.64 +        return new SymbolFileObject(this, file, ze);
    3.65      }
    3.66 +
    3.67 +    public String toString() {
    3.68 +        return "SymbolArchive[" + zdir.getName() + "]";
    3.69 +    }
    3.70 +
    3.71 +    /**
    3.72 +     * A subclass of JavaFileObject representing zip entries in a symbol file.
    3.73 +     */
    3.74 +    public static class SymbolFileObject extends ZipFileObject {
    3.75 +        protected SymbolFileObject(SymbolArchive zarch, String name, ZipEntry entry) {
    3.76 +            super(zarch, name, entry);
    3.77 +        }
    3.78 +
    3.79 +        @Override
    3.80 +        protected String inferBinaryName(Iterable<? extends File> path) {
    3.81 +            String entryName = getZipEntryName();
    3.82 +            String prefix = ((SymbolArchive) zarch).prefix.path;
    3.83 +            if (entryName.startsWith(prefix))
    3.84 +                entryName = entryName.substring(prefix.length());
    3.85 +            return removeExtension(entryName).replace('/', '.');
    3.86 +        }
    3.87 +    }
    3.88 +
    3.89 +
    3.90  }
     4.1 --- a/src/share/classes/com/sun/tools/javac/file/ZipArchive.java	Fri Aug 22 11:46:29 2008 +0100
     4.2 +++ b/src/share/classes/com/sun/tools/javac/file/ZipArchive.java	Tue Aug 26 14:52:59 2008 -0700
     4.3 @@ -25,18 +25,8 @@
     4.4  
     4.5  package com.sun.tools.javac.file;
     4.6  
     4.7 +import java.io.File;
     4.8  import java.io.IOException;
     4.9 -import java.util.Enumeration;
    4.10 -import java.util.HashMap;
    4.11 -import java.util.Map;
    4.12 -import java.util.Set;
    4.13 -import java.util.zip.ZipEntry;
    4.14 -import java.util.zip.ZipFile;
    4.15 -import javax.tools.JavaFileObject;
    4.16 -
    4.17 -import com.sun.tools.javac.file.JavacFileManager.Archive;
    4.18 -import com.sun.tools.javac.util.List;
    4.19 -import java.io.File;
    4.20  import java.io.InputStream;
    4.21  import java.io.OutputStream;
    4.22  import java.io.Writer;
    4.23 @@ -44,13 +34,35 @@
    4.24  import java.nio.ByteBuffer;
    4.25  import java.nio.CharBuffer;
    4.26  import java.nio.charset.CharsetDecoder;
    4.27 +import java.util.Enumeration;
    4.28 +import java.util.HashMap;
    4.29 +import java.util.Map;
    4.30 +import java.util.Set;
    4.31 +import java.util.zip.ZipEntry;
    4.32 +import java.util.zip.ZipFile;
    4.33 +
    4.34 +import javax.tools.JavaFileObject;
    4.35 +
    4.36 +import com.sun.tools.javac.file.JavacFileManager.Archive;
    4.37 +import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
    4.38 +import com.sun.tools.javac.file.RelativePath.RelativeFile;
    4.39 +import com.sun.tools.javac.util.List;
    4.40  
    4.41  public class ZipArchive implements Archive {
    4.42  
    4.43      public ZipArchive(JavacFileManager fm, ZipFile zdir) throws IOException {
    4.44 +        this(fm, zdir, true);
    4.45 +    }
    4.46 +
    4.47 +    protected ZipArchive(JavacFileManager fm, ZipFile zdir, boolean initMap) throws IOException {
    4.48          this.fileManager = fm;
    4.49          this.zdir = zdir;
    4.50 -        this.map = new HashMap<String,List<String>>();
    4.51 +        this.map = new HashMap<RelativeDirectory,List<String>>();
    4.52 +        if (initMap)
    4.53 +            initMap();
    4.54 +    }
    4.55 +
    4.56 +    protected void initMap() throws IOException {
    4.57          for (Enumeration<? extends ZipEntry> e = zdir.entries(); e.hasMoreElements(); ) {
    4.58              ZipEntry entry;
    4.59              try {
    4.60 @@ -67,7 +79,7 @@
    4.61      void addZipEntry(ZipEntry entry) {
    4.62          String name = entry.getName();
    4.63          int i = name.lastIndexOf('/');
    4.64 -        String dirname = name.substring(0, i+1);
    4.65 +        RelativeDirectory dirname = new RelativeDirectory(name.substring(0, i+1));
    4.66          String basename = name.substring(i+1);
    4.67          if (basename.length() == 0)
    4.68              return;
    4.69 @@ -78,26 +90,25 @@
    4.70          map.put(dirname, list);
    4.71      }
    4.72  
    4.73 -    public boolean contains(String name) {
    4.74 -        int i = name.lastIndexOf('/');
    4.75 -        String dirname = name.substring(0, i+1);
    4.76 -        String basename = name.substring(i+1);
    4.77 +    public boolean contains(RelativePath name) {
    4.78 +        RelativeDirectory dirname = name.dirname();
    4.79 +        String basename = name.basename();
    4.80          if (basename.length() == 0)
    4.81              return false;
    4.82          List<String> list = map.get(dirname);
    4.83          return (list != null && list.contains(basename));
    4.84      }
    4.85  
    4.86 -    public List<String> getFiles(String subdirectory) {
    4.87 +    public List<String> getFiles(RelativeDirectory subdirectory) {
    4.88          return map.get(subdirectory);
    4.89      }
    4.90  
    4.91 -    public JavaFileObject getFileObject(String subdirectory, String file) {
    4.92 -        ZipEntry ze = zdir.getEntry(subdirectory + file);
    4.93 +    public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) {
    4.94 +        ZipEntry ze = new RelativeFile(subdirectory, file).getZipEntry(zdir);
    4.95          return new ZipFileObject(this, file, ze);
    4.96      }
    4.97  
    4.98 -    public Set<String> getSubdirectories() {
    4.99 +    public Set<RelativeDirectory> getSubdirectories() {
   4.100          return map.keySet();
   4.101      }
   4.102  
   4.103 @@ -105,8 +116,12 @@
   4.104          zdir.close();
   4.105      }
   4.106  
   4.107 +    public String toString() {
   4.108 +        return "ZipArchive[" + zdir.getName() + "]";
   4.109 +    }
   4.110 +
   4.111      protected JavacFileManager fileManager;
   4.112 -    protected final Map<String,List<String>> map;
   4.113 +    protected final Map<RelativeDirectory,List<String>> map;
   4.114      protected final ZipFile zdir;
   4.115  
   4.116      /**
   4.117 @@ -118,7 +133,7 @@
   4.118          ZipArchive zarch;
   4.119          ZipEntry entry;
   4.120  
   4.121 -        public ZipFileObject(ZipArchive zarch, String name, ZipEntry entry) {
   4.122 +        protected ZipFileObject(ZipArchive zarch, String name, ZipEntry entry) {
   4.123              super(zarch.fileManager);
   4.124              this.zarch = zarch;
   4.125              this.name = name;
   4.126 @@ -222,11 +237,6 @@
   4.127          @Override
   4.128          protected String inferBinaryName(Iterable<? extends File> path) {
   4.129              String entryName = getZipEntryName();
   4.130 -            if (zarch instanceof SymbolArchive) {
   4.131 -                String prefix = ((SymbolArchive) zarch).prefix;
   4.132 -                if (entryName.startsWith(prefix))
   4.133 -                    entryName = entryName.substring(prefix.length());
   4.134 -            }
   4.135              return removeExtension(entryName).replace('/', '.');
   4.136          }
   4.137      }
     5.1 --- a/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java	Fri Aug 22 11:46:29 2008 +0100
     5.2 +++ b/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java	Tue Aug 26 14:52:59 2008 -0700
     5.3 @@ -25,11 +25,12 @@
     5.4  
     5.5  package com.sun.tools.javac.file;
     5.6  
     5.7 +
     5.8  import java.io.File;
     5.9  import java.io.FileNotFoundException;
    5.10  import java.io.IOException;
    5.11  import java.io.RandomAccessFile;
    5.12 -import java.text.MessageFormat;
    5.13 +import java.lang.ref.SoftReference;
    5.14  import java.util.ArrayList;
    5.15  import java.util.Arrays;
    5.16  import java.util.Calendar;
    5.17 @@ -45,6 +46,9 @@
    5.18  import java.util.zip.Inflater;
    5.19  import java.util.zip.ZipException;
    5.20  
    5.21 +import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
    5.22 +import com.sun.tools.javac.file.RelativePath.RelativeFile;
    5.23 +
    5.24  /** This class implements building of index of a zip archive and access to it's context.
    5.25   *  It also uses prebuild index if available. It supports invocations where it will
    5.26   *  serialize an optimized zip index file to disk.
    5.27 @@ -75,8 +79,8 @@
    5.28  
    5.29      private static boolean NON_BATCH_MODE = System.getProperty("nonBatchMode") != null;// TODO: Use -XD compiler switch for this.
    5.30  
    5.31 -    private Map<String, DirectoryEntry> directories = Collections.<String, DirectoryEntry>emptyMap();
    5.32 -    private Set<String> allDirs = Collections.<String>emptySet();
    5.33 +    private Map<RelativeDirectory, DirectoryEntry> directories = Collections.<RelativeDirectory, DirectoryEntry>emptyMap();
    5.34 +    private Set<RelativeDirectory> allDirs = Collections.<RelativeDirectory>emptySet();
    5.35  
    5.36      // ZipFileIndex data entries
    5.37      private File zipFile;
    5.38 @@ -87,7 +91,7 @@
    5.39      private boolean readFromIndex = false;
    5.40      private File zipIndexFile = null;
    5.41      private boolean triedToReadIndex = false;
    5.42 -    final String symbolFilePrefix;
    5.43 +    final RelativeDirectory symbolFilePrefix;
    5.44      private int symbolFilePrefixLength = 0;
    5.45      private boolean hasPopulatedData = false;
    5.46      private long lastReferenceTimeStamp = NOT_MODIFIED;
    5.47 @@ -97,6 +101,9 @@
    5.48  
    5.49      private boolean writeIndex = false;
    5.50  
    5.51 +    private Map <String, SoftReference<RelativeDirectory>> relativeDirectoryCache =
    5.52 +            new HashMap<String, SoftReference<RelativeDirectory>>();
    5.53 +
    5.54      /**
    5.55       * Returns a list of all ZipFileIndex entries
    5.56       *
    5.57 @@ -143,7 +150,10 @@
    5.58          }
    5.59      }
    5.60  
    5.61 -    public static ZipFileIndex getZipFileIndex(File zipFile, String symbolFilePrefix, boolean useCache, String cacheLocation, boolean writeIndex) throws IOException {
    5.62 +    public static ZipFileIndex getZipFileIndex(File zipFile,
    5.63 +            RelativeDirectory symbolFilePrefix,
    5.64 +            boolean useCache, String cacheLocation,
    5.65 +            boolean writeIndex) throws IOException {
    5.66          ZipFileIndex zi = null;
    5.67          lock.lock();
    5.68          try {
    5.69 @@ -231,12 +241,12 @@
    5.70          }
    5.71      }
    5.72  
    5.73 -    private ZipFileIndex(File zipFile, String symbolFilePrefix, boolean writeIndex,
    5.74 +    private ZipFileIndex(File zipFile, RelativeDirectory symbolFilePrefix, boolean writeIndex,
    5.75              boolean useCache, String cacheLocation) throws IOException {
    5.76          this.zipFile = zipFile;
    5.77          this.symbolFilePrefix = symbolFilePrefix;
    5.78          this.symbolFilePrefixLength = (symbolFilePrefix == null ? 0 :
    5.79 -            symbolFilePrefix.getBytes("UTF-8").length);
    5.80 +            symbolFilePrefix.getPath().getBytes("UTF-8").length);
    5.81          this.writeIndex = writeIndex;
    5.82          this.usePreindexedCache = useCache;
    5.83          this.preindexedCacheLocation = cacheLocation;
    5.84 @@ -250,7 +260,7 @@
    5.85      }
    5.86  
    5.87      public String toString() {
    5.88 -        return "ZipFileIndex of file:(" + zipFile + ")";
    5.89 +        return "ZipFileIndex[" + zipFile + "]";
    5.90      }
    5.91  
    5.92      // Just in case...
    5.93 @@ -291,8 +301,8 @@
    5.94              return;
    5.95          }
    5.96  
    5.97 -        directories = Collections.<String, DirectoryEntry>emptyMap();
    5.98 -        allDirs = Collections.<String>emptySet();
    5.99 +        directories = Collections.<RelativeDirectory, DirectoryEntry>emptyMap();
   5.100 +        allDirs = Collections.<RelativeDirectory>emptySet();
   5.101  
   5.102          try {
   5.103              openFile();
   5.104 @@ -317,9 +327,9 @@
   5.105      private void cleanupState() {
   5.106          // Make sure there is a valid but empty index if the file doesn't exist
   5.107          entries = Entry.EMPTY_ARRAY;
   5.108 -        directories = Collections.<String, DirectoryEntry>emptyMap();
   5.109 +        directories = Collections.<RelativeDirectory, DirectoryEntry>emptyMap();
   5.110          zipFileLastModified = NOT_MODIFIED;
   5.111 -        allDirs = Collections.<String>emptySet();
   5.112 +        allDirs = Collections.<RelativeDirectory>emptySet();
   5.113      }
   5.114  
   5.115      public void close() {
   5.116 @@ -346,24 +356,12 @@
   5.117      /**
   5.118       * Returns the ZipFileIndexEntry for an absolute path, if there is one.
   5.119       */
   5.120 -    Entry getZipIndexEntry(String path) {
   5.121 -        if (File.separatorChar != '/') {
   5.122 -            path = path.replace('/', File.separatorChar);
   5.123 -        }
   5.124 +    Entry getZipIndexEntry(RelativePath path) {
   5.125          lock.lock();
   5.126          try {
   5.127              checkIndex();
   5.128 -            String lookFor = "";
   5.129 -            int lastSepIndex = path.lastIndexOf(File.separatorChar);
   5.130 -            boolean noSeparator = false;
   5.131 -            if (lastSepIndex == -1) {
   5.132 -                noSeparator = true;
   5.133 -            }
   5.134 -
   5.135 -            DirectoryEntry de = directories.get(noSeparator ? "" : path.substring(0, lastSepIndex));
   5.136 -
   5.137 -            lookFor = path.substring(noSeparator ? 0 : lastSepIndex + 1);
   5.138 -
   5.139 +            DirectoryEntry de = directories.get(path.dirname());
   5.140 +            String lookFor = path.basename();
   5.141              return de == null ? null : de.getEntry(lookFor);
   5.142          }
   5.143          catch (IOException e) {
   5.144 @@ -377,11 +375,7 @@
   5.145      /**
   5.146       * Returns a javac List of filenames within an absolute path in the ZipFileIndex.
   5.147       */
   5.148 -    public com.sun.tools.javac.util.List<String> getFiles(String path) {
   5.149 -        if (File.separatorChar != '/') {
   5.150 -            path = path.replace('/', File.separatorChar);
   5.151 -        }
   5.152 -
   5.153 +    public com.sun.tools.javac.util.List<String> getFiles(RelativeDirectory path) {
   5.154          lock.lock();
   5.155          try {
   5.156              checkIndex();
   5.157 @@ -402,16 +396,10 @@
   5.158          }
   5.159      }
   5.160  
   5.161 -    public List<String> getAllDirectories(String path) {
   5.162 -
   5.163 -        if (File.separatorChar != '/') {
   5.164 -            path = path.replace('/', File.separatorChar);
   5.165 -        }
   5.166 -
   5.167 +    public List<String> getDirectories(RelativeDirectory path) {
   5.168          lock.lock();
   5.169          try {
   5.170              checkIndex();
   5.171 -            path = path.intern();
   5.172  
   5.173              DirectoryEntry de = directories.get(path);
   5.174              com.sun.tools.javac.util.List<String> ret = de == null ? null : de.getDirectories();
   5.175 @@ -430,24 +418,18 @@
   5.176          }
   5.177      }
   5.178  
   5.179 -    public Set<String> getAllDirectories() {
   5.180 +    public Set<RelativeDirectory> getAllDirectories() {
   5.181          lock.lock();
   5.182          try {
   5.183              checkIndex();
   5.184              if (allDirs == Collections.EMPTY_SET) {
   5.185 -                Set<String> alldirs = new HashSet<String>();
   5.186 -                Iterator<String> dirsIter = directories.keySet().iterator();
   5.187 -                while (dirsIter.hasNext()) {
   5.188 -                    alldirs.add(new String(dirsIter.next()));
   5.189 -                }
   5.190 -
   5.191 -                allDirs = alldirs;
   5.192 +                allDirs = new HashSet<RelativeDirectory>(directories.keySet());
   5.193              }
   5.194  
   5.195              return allDirs;
   5.196          }
   5.197          catch (IOException e) {
   5.198 -            return Collections.<String>emptySet();
   5.199 +            return Collections.<RelativeDirectory>emptySet();
   5.200          }
   5.201          finally {
   5.202              lock.unlock();
   5.203 @@ -461,7 +443,7 @@
   5.204       * @param path A path within the zip.
   5.205       * @return True if the path is a file or dir, false otherwise.
   5.206       */
   5.207 -    public boolean contains(String path) {
   5.208 +    public boolean contains(RelativePath path) {
   5.209          lock.lock();
   5.210          try {
   5.211              checkIndex();
   5.212 @@ -475,17 +457,15 @@
   5.213          }
   5.214      }
   5.215  
   5.216 -    public boolean isDirectory(String path) throws IOException {
   5.217 +    public boolean isDirectory(RelativePath path) throws IOException {
   5.218          lock.lock();
   5.219          try {
   5.220              // The top level in a zip file is always a directory.
   5.221 -            if (path.length() == 0) {
   5.222 +            if (path.getPath().length() == 0) {
   5.223                  lastReferenceTimeStamp = System.currentTimeMillis();
   5.224                  return true;
   5.225              }
   5.226  
   5.227 -            if (File.separatorChar != '/')
   5.228 -                path = path.replace('/', File.separatorChar);
   5.229              checkIndex();
   5.230              return directories.get(path) != null;
   5.231          }
   5.232 @@ -494,7 +474,7 @@
   5.233          }
   5.234      }
   5.235  
   5.236 -    public long getLastModified(String path) throws IOException {
   5.237 +    public long getLastModified(RelativeFile path) throws IOException {
   5.238          lock.lock();
   5.239          try {
   5.240              Entry entry = getZipIndexEntry(path);
   5.241 @@ -507,7 +487,7 @@
   5.242          }
   5.243      }
   5.244  
   5.245 -    public int length(String path) throws IOException {
   5.246 +    public int length(RelativeFile path) throws IOException {
   5.247          lock.lock();
   5.248          try {
   5.249              Entry entry = getZipIndexEntry(path);
   5.250 @@ -531,12 +511,12 @@
   5.251          }
   5.252      }
   5.253  
   5.254 -    public byte[] read(String path) throws IOException {
   5.255 +    public byte[] read(RelativeFile path) throws IOException {
   5.256          lock.lock();
   5.257          try {
   5.258              Entry entry = getZipIndexEntry(path);
   5.259              if (entry == null)
   5.260 -                throw new FileNotFoundException(MessageFormat.format("Path not found in ZIP: {0}", path));
   5.261 +                throw new FileNotFoundException("Path not found in ZIP: " + path.path);
   5.262              return read(entry);
   5.263          }
   5.264          finally {
   5.265 @@ -557,7 +537,7 @@
   5.266          }
   5.267      }
   5.268  
   5.269 -    public int read(String path, byte[] buffer) throws IOException {
   5.270 +    public int read(RelativeFile path, byte[] buffer) throws IOException {
   5.271          lock.lock();
   5.272          try {
   5.273              Entry entry = getZipIndexEntry(path);
   5.274 @@ -690,7 +670,7 @@
   5.275       * ----------------------------------------------------------------------------*/
   5.276  
   5.277      private class ZipDirectory {
   5.278 -        private String lastDir;
   5.279 +        private RelativeDirectory lastDir;
   5.280          private int lastStart;
   5.281          private int lastLen;
   5.282  
   5.283 @@ -747,13 +727,13 @@
   5.284              }
   5.285              throw new ZipException("cannot read zip file");
   5.286          }
   5.287 +
   5.288          private void buildIndex() throws IOException {
   5.289              int entryCount = get2ByteLittleEndian(zipDir, 0);
   5.290  
   5.291 -            entries = new Entry[entryCount];
   5.292              // Add each of the files
   5.293              if (entryCount > 0) {
   5.294 -                directories = new HashMap<String, DirectoryEntry>();
   5.295 +                directories = new HashMap<RelativeDirectory, DirectoryEntry>();
   5.296                  ArrayList<Entry> entryList = new ArrayList<Entry>();
   5.297                  int pos = 2;
   5.298                  for (int i = 0; i < entryCount; i++) {
   5.299 @@ -761,9 +741,11 @@
   5.300                  }
   5.301  
   5.302                  // Add the accumulated dirs into the same list
   5.303 -                Iterator i = directories.keySet().iterator();
   5.304 -                while (i.hasNext()) {
   5.305 -                    Entry zipFileIndexEntry = new Entry( (String) i.next());
   5.306 +                for (RelativeDirectory d: directories.keySet()) {
   5.307 +                    // use shared RelativeDirectory objects for parent dirs
   5.308 +                    RelativeDirectory parent = getRelativeDirectory(d.dirname().getPath());
   5.309 +                    String file = d.basename();
   5.310 +                    Entry zipFileIndexEntry = new Entry(parent, file);
   5.311                      zipFileIndexEntry.isDir = true;
   5.312                      entryList.add(zipFileIndexEntry);
   5.313                  }
   5.314 @@ -776,7 +758,7 @@
   5.315          }
   5.316  
   5.317          private int readEntry(int pos, List<Entry> entryList,
   5.318 -                Map<String, DirectoryEntry> directories) throws IOException {
   5.319 +                Map<RelativeDirectory, DirectoryEntry> directories) throws IOException {
   5.320              if (get4ByteLittleEndian(zipDir, pos) != 0x02014b50) {
   5.321                  throw new ZipException("cannot read zip file entry");
   5.322              }
   5.323 @@ -790,19 +772,20 @@
   5.324                  dirStart += zipFileIndex.symbolFilePrefixLength;
   5.325                 fileStart += zipFileIndex.symbolFilePrefixLength;
   5.326              }
   5.327 -
   5.328 -            // Use the OS's path separator. Keep the position of the last one.
   5.329 +            // Force any '\' to '/'. Keep the position of the last separator.
   5.330              for (int index = fileStart; index < fileEnd; index++) {
   5.331                  byte nextByte = zipDir[index];
   5.332 -                if (nextByte == (byte)'\\' || nextByte == (byte)'/') {
   5.333 -                    zipDir[index] = (byte)File.separatorChar;
   5.334 +                if (nextByte == (byte)'\\') {
   5.335 +                    zipDir[index] = (byte)'/';
   5.336 +                    fileStart = index + 1;
   5.337 +                } else if (nextByte == (byte)'/') {
   5.338                      fileStart = index + 1;
   5.339                  }
   5.340              }
   5.341  
   5.342 -            String directory = null;
   5.343 +            RelativeDirectory directory = null;
   5.344              if (fileStart == dirStart)
   5.345 -                directory = "";
   5.346 +                directory = getRelativeDirectory("");
   5.347              else if (lastDir != null && lastLen == fileStart - dirStart - 1) {
   5.348                  int index = lastLen - 1;
   5.349                  while (zipDir[lastStart + index] == zipDir[dirStart + index]) {
   5.350 @@ -819,22 +802,23 @@
   5.351                  lastStart = dirStart;
   5.352                  lastLen = fileStart - dirStart - 1;
   5.353  
   5.354 -                directory = new String(zipDir, dirStart, lastLen, "UTF-8").intern();
   5.355 +                directory = getRelativeDirectory(new String(zipDir, dirStart, lastLen, "UTF-8"));
   5.356                  lastDir = directory;
   5.357  
   5.358                  // Enter also all the parent directories
   5.359 -                String tempDirectory = directory;
   5.360 +                RelativeDirectory tempDirectory = directory;
   5.361  
   5.362                  while (directories.get(tempDirectory) == null) {
   5.363                      directories.put(tempDirectory, new DirectoryEntry(tempDirectory, zipFileIndex));
   5.364 -                    int separator = tempDirectory.lastIndexOf(File.separatorChar);
   5.365 -                    if (separator == -1)
   5.366 +                    if (tempDirectory.path.indexOf("/") == tempDirectory.path.length() - 1)
   5.367                          break;
   5.368 -                    tempDirectory = tempDirectory.substring(0, separator);
   5.369 +                    else {
   5.370 +                        // use shared RelativeDirectory objects for parent dirs
   5.371 +                        tempDirectory = getRelativeDirectory(tempDirectory.dirname().getPath());
   5.372 +                    }
   5.373                  }
   5.374              }
   5.375              else {
   5.376 -                directory = directory.intern();
   5.377                  if (directories.get(directory) == null) {
   5.378                      directories.put(directory, new DirectoryEntry(directory, zipFileIndex));
   5.379                  }
   5.380 @@ -886,7 +870,7 @@
   5.381  
   5.382          private long writtenOffsetOffset = 0;
   5.383  
   5.384 -        private String dirName;
   5.385 +        private RelativeDirectory dirName;
   5.386  
   5.387          private com.sun.tools.javac.util.List<String> zipFileEntriesFiles = com.sun.tools.javac.util.List.<String>nil();
   5.388          private com.sun.tools.javac.util.List<String> zipFileEntriesDirectories = com.sun.tools.javac.util.List.<String>nil();
   5.389 @@ -898,70 +882,50 @@
   5.390  
   5.391          private int numEntries;
   5.392  
   5.393 -        DirectoryEntry(String dirName, ZipFileIndex index) {
   5.394 -        filesInited = false;
   5.395 +        DirectoryEntry(RelativeDirectory dirName, ZipFileIndex index) {
   5.396 +            filesInited = false;
   5.397              directoriesInited = false;
   5.398              entriesInited = false;
   5.399  
   5.400 -            if (File.separatorChar == '/') {
   5.401 -                dirName.replace('\\', '/');
   5.402 -            }
   5.403 -            else {
   5.404 -                dirName.replace('/', '\\');
   5.405 -            }
   5.406 -
   5.407 -            this.dirName = dirName.intern();
   5.408 +            this.dirName = dirName;
   5.409              this.zipFileIndex = index;
   5.410          }
   5.411  
   5.412          private com.sun.tools.javac.util.List<String> getFiles() {
   5.413 -            if (filesInited) {
   5.414 -                return zipFileEntriesFiles;
   5.415 +            if (!filesInited) {
   5.416 +                initEntries();
   5.417 +                for (Entry e : entries) {
   5.418 +                    if (!e.isDir) {
   5.419 +                        zipFileEntriesFiles = zipFileEntriesFiles.append(e.name);
   5.420 +                    }
   5.421 +                }
   5.422 +                filesInited = true;
   5.423              }
   5.424 -
   5.425 -            initEntries();
   5.426 -
   5.427 -            for (Entry e : entries) {
   5.428 -                if (!e.isDir) {
   5.429 -                    zipFileEntriesFiles = zipFileEntriesFiles.append(e.name);
   5.430 -                }
   5.431 -            }
   5.432 -            filesInited = true;
   5.433              return zipFileEntriesFiles;
   5.434          }
   5.435  
   5.436          private com.sun.tools.javac.util.List<String> getDirectories() {
   5.437 -            if (directoriesInited) {
   5.438 -                return zipFileEntriesFiles;
   5.439 +            if (!directoriesInited) {
   5.440 +                initEntries();
   5.441 +                for (Entry e : entries) {
   5.442 +                    if (e.isDir) {
   5.443 +                        zipFileEntriesDirectories = zipFileEntriesDirectories.append(e.name);
   5.444 +                    }
   5.445 +                }
   5.446 +                directoriesInited = true;
   5.447              }
   5.448 -
   5.449 -            initEntries();
   5.450 -
   5.451 -            for (Entry e : entries) {
   5.452 -                if (e.isDir) {
   5.453 -                    zipFileEntriesDirectories = zipFileEntriesDirectories.append(e.name);
   5.454 -                }
   5.455 -            }
   5.456 -
   5.457 -            directoriesInited = true;
   5.458 -
   5.459              return zipFileEntriesDirectories;
   5.460          }
   5.461  
   5.462          private com.sun.tools.javac.util.List<Entry> getEntries() {
   5.463 -            if (zipFileEntriesInited) {
   5.464 -                return zipFileEntries;
   5.465 +            if (!zipFileEntriesInited) {
   5.466 +                initEntries();
   5.467 +                zipFileEntries = com.sun.tools.javac.util.List.nil();
   5.468 +                for (Entry zfie : entries) {
   5.469 +                    zipFileEntries = zipFileEntries.append(zfie);
   5.470 +                }
   5.471 +                zipFileEntriesInited = true;
   5.472              }
   5.473 -
   5.474 -            initEntries();
   5.475 -
   5.476 -            zipFileEntries = com.sun.tools.javac.util.List.nil();
   5.477 -            for (Entry zfie : entries) {
   5.478 -                zipFileEntries = zipFileEntries.append(zfie);
   5.479 -            }
   5.480 -
   5.481 -            zipFileEntriesInited = true;
   5.482 -
   5.483              return zipFileEntries;
   5.484          }
   5.485  
   5.486 @@ -986,8 +950,6 @@
   5.487                  int to = -Arrays.binarySearch(zipFileIndex.entries,
   5.488                          new Entry(dirName, MAX_CHAR)) - 1;
   5.489  
   5.490 -                boolean emptyList = false;
   5.491 -
   5.492                  for (int i = from; i < to; i++) {
   5.493                      entries.add(zipFileIndex.entries[i]);
   5.494                  }
   5.495 @@ -1071,14 +1033,14 @@
   5.496                  if (zipFile.lastModified() != fileStamp) {
   5.497                      ret = false;
   5.498                  } else {
   5.499 -                    directories = new HashMap<String, DirectoryEntry>();
   5.500 +                    directories = new HashMap<RelativeDirectory, DirectoryEntry>();
   5.501                      int numDirs = raf.readInt();
   5.502                      for (int nDirs = 0; nDirs < numDirs; nDirs++) {
   5.503                          int dirNameBytesLen = raf.readInt();
   5.504                          byte [] dirNameBytes = new byte[dirNameBytesLen];
   5.505                          raf.read(dirNameBytes);
   5.506  
   5.507 -                        String dirNameStr = new String(dirNameBytes, "UTF-8");
   5.508 +                        RelativeDirectory dirNameStr = getRelativeDirectory(new String(dirNameBytes, "UTF-8"));
   5.509                          DirectoryEntry de = new DirectoryEntry(dirNameStr, this);
   5.510                          de.numEntries = raf.readInt();
   5.511                          de.writtenOffsetOffset = raf.readLong();
   5.512 @@ -1132,21 +1094,18 @@
   5.513              raf.writeLong(zipFileLastModified);
   5.514              writtenSoFar += 8;
   5.515  
   5.516 -
   5.517 -            Iterator<String> iterDirName = directories.keySet().iterator();
   5.518              List<DirectoryEntry> directoriesToWrite = new ArrayList<DirectoryEntry>();
   5.519 -            Map<String, Long> offsets = new HashMap<String, Long>();
   5.520 +            Map<RelativeDirectory, Long> offsets = new HashMap<RelativeDirectory, Long>();
   5.521              raf.writeInt(directories.keySet().size());
   5.522              writtenSoFar += 4;
   5.523  
   5.524 -            while(iterDirName.hasNext()) {
   5.525 -                String dirName = iterDirName.next();
   5.526 +            for (RelativeDirectory dirName: directories.keySet()) {
   5.527                  DirectoryEntry dirEntry = directories.get(dirName);
   5.528  
   5.529                  directoriesToWrite.add(dirEntry);
   5.530  
   5.531                  // Write the dir name bytes
   5.532 -                byte [] dirNameBytes = dirName.getBytes("UTF-8");
   5.533 +                byte [] dirNameBytes = dirName.getPath().getBytes("UTF-8");
   5.534                  int dirNameBytesLen = dirNameBytes.length;
   5.535                  raf.writeInt(dirNameBytesLen);
   5.536                  writtenSoFar += 4;
   5.537 @@ -1251,12 +1210,24 @@
   5.538          return zipFile;
   5.539      }
   5.540  
   5.541 +    private RelativeDirectory getRelativeDirectory(String path) {
   5.542 +        RelativeDirectory rd;
   5.543 +        SoftReference<RelativeDirectory> ref = relativeDirectoryCache.get(path);
   5.544 +        if (ref != null) {
   5.545 +            rd = ref.get();
   5.546 +            if (rd != null)
   5.547 +                return rd;
   5.548 +        }
   5.549 +        rd = new RelativeDirectory(path);
   5.550 +        relativeDirectoryCache.put(path, new SoftReference<RelativeDirectory>(rd));
   5.551 +        return rd;
   5.552 +    }
   5.553  
   5.554      static class Entry implements Comparable<Entry> {
   5.555          public static final Entry[] EMPTY_ARRAY = {};
   5.556  
   5.557          // Directory related
   5.558 -        String dir;
   5.559 +        RelativeDirectory dir;
   5.560          boolean isDir;
   5.561  
   5.562          // File related
   5.563 @@ -1269,32 +1240,17 @@
   5.564  
   5.565          private int nativetime;
   5.566  
   5.567 -        public Entry(String path) {
   5.568 -            int separator = path.lastIndexOf(File.separatorChar);
   5.569 -            if (separator == -1) {
   5.570 -                dir = "".intern();
   5.571 -                name = path;
   5.572 -            } else {
   5.573 -                dir = path.substring(0, separator).intern();
   5.574 -                name = path.substring(separator + 1);
   5.575 -            }
   5.576 +        public Entry(RelativePath path) {
   5.577 +            this(path.dirname(), path.basename());
   5.578          }
   5.579  
   5.580 -        public Entry(String directory, String name) {
   5.581 -            this.dir = directory.intern();
   5.582 +        public Entry(RelativeDirectory directory, String name) {
   5.583 +            this.dir = directory;
   5.584              this.name = name;
   5.585          }
   5.586  
   5.587          public String getName() {
   5.588 -            if (dir == null || dir.length() == 0) {
   5.589 -                return name;
   5.590 -            }
   5.591 -
   5.592 -            StringBuilder sb = new StringBuilder();
   5.593 -            sb.append(dir);
   5.594 -            sb.append(File.separatorChar);
   5.595 -            sb.append(name);
   5.596 -            return sb.toString();
   5.597 +            return new RelativeFile(dir, name).getPath();
   5.598          }
   5.599  
   5.600          public String getFileName() {
   5.601 @@ -1331,7 +1287,7 @@
   5.602          }
   5.603  
   5.604          public int compareTo(Entry other) {
   5.605 -            String otherD = other.dir;
   5.606 +            RelativeDirectory otherD = other.dir;
   5.607              if (dir != otherD) {
   5.608                  int c = dir.compareTo(otherD);
   5.609                  if (c != 0)
   5.610 @@ -1340,6 +1296,22 @@
   5.611              return name.compareTo(other.name);
   5.612          }
   5.613  
   5.614 +        @Override
   5.615 +        public boolean equals(Object o) {
   5.616 +            if (!(o instanceof Entry))
   5.617 +                return false;
   5.618 +            Entry other = (Entry) o;
   5.619 +            return dir.equals(other.dir) && name.equals(other.name);
   5.620 +        }
   5.621 +
   5.622 +        @Override
   5.623 +        public int hashCode() {
   5.624 +            int hash = 7;
   5.625 +            hash = 97 * hash + (this.dir != null ? this.dir.hashCode() : 0);
   5.626 +            hash = 97 * hash + (this.name != null ? this.name.hashCode() : 0);
   5.627 +            return hash;
   5.628 +        }
   5.629 +
   5.630  
   5.631          public String toString() {
   5.632              return isDir ? ("Dir:" + dir + " : " + name) :
     6.1 --- a/src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java	Fri Aug 22 11:46:29 2008 +0100
     6.2 +++ b/src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java	Tue Aug 26 14:52:59 2008 -0700
     6.3 @@ -29,11 +29,8 @@
     6.4  import java.util.Set;
     6.5  import javax.tools.JavaFileObject;
     6.6  
     6.7 -import com.sun.tools.javac.file.JavacFileManager.Archive;
     6.8 -import com.sun.tools.javac.util.List;
     6.9  import java.io.ByteArrayInputStream;
    6.10  import java.io.File;
    6.11 -import java.io.FileNotFoundException;
    6.12  import java.io.InputStream;
    6.13  import java.io.OutputStream;
    6.14  import java.io.Writer;
    6.15 @@ -42,6 +39,11 @@
    6.16  import java.nio.CharBuffer;
    6.17  import java.nio.charset.CharsetDecoder;
    6.18  
    6.19 +import com.sun.tools.javac.file.JavacFileManager.Archive;
    6.20 +import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
    6.21 +import com.sun.tools.javac.file.RelativePath.RelativeFile;
    6.22 +import com.sun.tools.javac.util.List;
    6.23 +
    6.24  public class ZipFileIndexArchive implements Archive {
    6.25  
    6.26      private final ZipFileIndex zfIndex;
    6.27 @@ -53,22 +55,22 @@
    6.28          this.zfIndex = zdir;
    6.29      }
    6.30  
    6.31 -    public boolean contains(String name) {
    6.32 +    public boolean contains(RelativePath name) {
    6.33          return zfIndex.contains(name);
    6.34      }
    6.35  
    6.36 -    public List<String> getFiles(String subdirectory) {
    6.37 -        return zfIndex.getFiles((subdirectory.endsWith("/") || subdirectory.endsWith("\\")) ? subdirectory.substring(0, subdirectory.length() - 1) : subdirectory);
    6.38 +    public List<String> getFiles(RelativeDirectory subdirectory) {
    6.39 +        return zfIndex.getFiles(subdirectory);
    6.40      }
    6.41  
    6.42 -    public JavaFileObject getFileObject(String subdirectory, String file) {
    6.43 -        String fullZipFileName = subdirectory + file;
    6.44 +    public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) {
    6.45 +        RelativeFile fullZipFileName = new RelativeFile(subdirectory, file);
    6.46          ZipFileIndex.Entry entry = zfIndex.getZipIndexEntry(fullZipFileName);
    6.47          JavaFileObject ret = new ZipFileIndexFileObject(fileManager, zfIndex, entry, zfIndex.getZipFile().getPath());
    6.48          return ret;
    6.49      }
    6.50  
    6.51 -    public Set<String> getSubdirectories() {
    6.52 +    public Set<RelativeDirectory> getSubdirectories() {
    6.53          return zfIndex.getAllDirectories();
    6.54      }
    6.55  
    6.56 @@ -76,6 +78,10 @@
    6.57          zfIndex.close();
    6.58      }
    6.59  
    6.60 +    public String toString() {
    6.61 +        return "ZipFileIndexArchive[" + zfIndex + "]";
    6.62 +    }
    6.63 +
    6.64      /**
    6.65       * A subclass of JavaFileObject representing zip entries using the com.sun.tools.javac.file.ZipFileIndex implementation.
    6.66       */
    6.67 @@ -181,18 +187,11 @@
    6.68          public URI toUri() {
    6.69              String zipName = new File(getZipName()).toURI().normalize().getPath();
    6.70              String entryName = getZipEntryName();
    6.71 -            if (File.separatorChar != '/') {
    6.72 -                entryName = entryName.replace(File.separatorChar, '/');
    6.73 -            }
    6.74              return URI.create("jar:" + zipName + "!" + entryName);
    6.75          }
    6.76  
    6.77          private byte[] read() throws IOException {
    6.78 -            if (entry == null) {
    6.79 -                entry = zfIndex.getZipIndexEntry(name);
    6.80 -                if (entry == null)
    6.81 -                  throw new FileNotFoundException();
    6.82 -            }
    6.83 +            assert entry != null; // see constructor
    6.84              return zfIndex.read(entry);
    6.85          }
    6.86  
    6.87 @@ -222,11 +221,11 @@
    6.88          protected String inferBinaryName(Iterable<? extends File> path) {
    6.89              String entryName = getZipEntryName();
    6.90              if (zfIndex.symbolFilePrefix != null) {
    6.91 -                String prefix = zfIndex.symbolFilePrefix;
    6.92 +                String prefix = zfIndex.symbolFilePrefix.path;
    6.93                  if (entryName.startsWith(prefix))
    6.94                      entryName = entryName.substring(prefix.length());
    6.95              }
    6.96 -            return removeExtension(entryName).replace(File.separatorChar, '.');
    6.97 +            return removeExtension(entryName).replace('/', '.');
    6.98          }
    6.99      }
   6.100  
     7.1 --- a/src/share/classes/com/sun/tools/javadoc/DocletInvoker.java	Fri Aug 22 11:46:29 2008 +0100
     7.2 +++ b/src/share/classes/com/sun/tools/javadoc/DocletInvoker.java	Tue Aug 26 14:52:59 2008 -0700
     7.3 @@ -82,6 +82,7 @@
     7.4          cpString = appendPath(System.getProperty("java.class.path"), cpString);
     7.5          cpString = appendPath(docletPath, cpString);
     7.6          URL[] urls = pathToURLs(cpString);
     7.7 +        System.err.println("DocletInvoker urls=" + urls);
     7.8          appClassLoader = new URLClassLoader(urls);
     7.9  
    7.10          // attempt to find doclet
     8.1 --- a/src/share/classes/javax/tools/StandardLocation.java	Fri Aug 22 11:46:29 2008 +0100
     8.2 +++ b/src/share/classes/javax/tools/StandardLocation.java	Tue Aug 26 14:52:59 2008 -0700
     8.3 @@ -27,8 +27,6 @@
     8.4  
     8.5  import javax.tools.JavaFileManager.Location;
     8.6  
     8.7 -import java.io.File;
     8.8 -import java.util.*;
     8.9  import java.util.concurrent.*;
    8.10  
    8.11  /**
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/test/tools/javac/6508981/TestInferBinaryName.java	Tue Aug 26 14:52:59 2008 -0700
     9.3 @@ -0,0 +1,177 @@
     9.4 +/*
     9.5 + * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
     9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     9.7 + *
     9.8 + * This code is free software; you can redistribute it and/or modify it
     9.9 + * under the terms of the GNU General Public License version 2 only, as
    9.10 + * published by the Free Software Foundation.
    9.11 + *
    9.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    9.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    9.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    9.15 + * version 2 for more details (a copy is included in the LICENSE file that
    9.16 + * accompanied this code).
    9.17 + *
    9.18 + * You should have received a copy of the GNU General Public License version
    9.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    9.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    9.21 + *
    9.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    9.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
    9.24 + * have any questions.
    9.25 + */
    9.26 +
    9.27 +/*
    9.28 + * @test
    9.29 + * @bug 6508981
    9.30 + * @summary cleanup file separator handling in JavacFileManager
    9.31 + * (This test is specifically to test the new impl of inferBinaryName)
    9.32 + * @build p.A
    9.33 + * @run main TestInferBinaryName
    9.34 + */
    9.35 +
    9.36 +import java.io.*;
    9.37 +import java.util.*;
    9.38 +import javax.tools.*;
    9.39 +
    9.40 +import com.sun.tools.javac.file.JavacFileManager;
    9.41 +import com.sun.tools.javac.util.Context;
    9.42 +import com.sun.tools.javac.util.Options;
    9.43 +
    9.44 +import static javax.tools.JavaFileObject.Kind.*;
    9.45 +import static javax.tools.StandardLocation.*;
    9.46 +
    9.47 +
    9.48 +/**
    9.49 + * Verify the various implementations of inferBinaryName, but configuring
    9.50 + * different instances of a file manager, getting a file object, and checking
    9.51 + * the impl of inferBinaryName for that file object.
    9.52 + */
    9.53 +public class TestInferBinaryName {
    9.54 +    static final boolean IGNORE_SYMBOL_FILE = false;
    9.55 +    static final boolean USE_SYMBOL_FILE = true;
    9.56 +    static final boolean DONT_USE_ZIP_FILE_INDEX = false;
    9.57 +    static final boolean USE_ZIP_FILE_INDEX = true;
    9.58 +
    9.59 +    public static void main(String... args) throws Exception {
    9.60 +        new TestInferBinaryName().run();
    9.61 +    }
    9.62 +
    9.63 +    void run() throws Exception {
    9.64 +        //System.err.println(System.getProperties());
    9.65 +        testDirectory();
    9.66 +        testSymbolArchive();
    9.67 +        testZipArchive();
    9.68 +        testZipFileIndexArchive();
    9.69 +        testZipFileIndexArchive2();
    9.70 +        if (errors > 0)
    9.71 +            throw new Exception(errors + " error found");
    9.72 +    }
    9.73 +
    9.74 +    void testDirectory() throws IOException {
    9.75 +        String testClassName = "p.A";
    9.76 +        JavaFileManager fm =
    9.77 +            getFileManager("test.classes", USE_SYMBOL_FILE, USE_ZIP_FILE_INDEX);
    9.78 +        test("testDirectory",
    9.79 +             fm, testClassName, "com.sun.tools.javac.file.RegularFileObject");
    9.80 +    }
    9.81 +
    9.82 +    void testSymbolArchive() throws IOException {
    9.83 +        String testClassName = "java.lang.String";
    9.84 +        JavaFileManager fm =
    9.85 +            getFileManager("sun.boot.class.path", USE_SYMBOL_FILE, DONT_USE_ZIP_FILE_INDEX);
    9.86 +        test("testSymbolArchive",
    9.87 +             fm, testClassName, "com.sun.tools.javac.file.SymbolArchive$SymbolFileObject");
    9.88 +    }
    9.89 +
    9.90 +    void testZipArchive() throws IOException {
    9.91 +        String testClassName = "java.lang.String";
    9.92 +        JavaFileManager fm =
    9.93 +            getFileManager("sun.boot.class.path", IGNORE_SYMBOL_FILE, DONT_USE_ZIP_FILE_INDEX);
    9.94 +        test("testZipArchive",
    9.95 +             fm, testClassName, "com.sun.tools.javac.file.ZipArchive$ZipFileObject");
    9.96 +    }
    9.97 +
    9.98 +    void testZipFileIndexArchive() throws IOException {
    9.99 +        String testClassName = "java.lang.String";
   9.100 +        JavaFileManager fm =
   9.101 +            getFileManager("sun.boot.class.path", USE_SYMBOL_FILE, USE_ZIP_FILE_INDEX);
   9.102 +        test("testZipFileIndexArchive",
   9.103 +             fm, testClassName, "com.sun.tools.javac.file.ZipFileIndexArchive$ZipFileIndexFileObject");
   9.104 +    }
   9.105 +
   9.106 +    void testZipFileIndexArchive2() throws IOException {
   9.107 +        String testClassName = "java.lang.String";
   9.108 +        JavaFileManager fm =
   9.109 +            getFileManager("sun.boot.class.path", IGNORE_SYMBOL_FILE, USE_ZIP_FILE_INDEX);
   9.110 +        test("testZipFileIndexArchive2",
   9.111 +             fm, testClassName, "com.sun.tools.javac.file.ZipFileIndexArchive$ZipFileIndexFileObject");
   9.112 +    }
   9.113 +
   9.114 +    /**
   9.115 +     * @param testName for debugging
   9.116 +     * @param fm suitably configured file manager
   9.117 +     * @param testClassName the classname to test
   9.118 +     * @param implClassName the expected classname of the JavaFileObject impl,
   9.119 +     *     used for checking that we are checking the expected impl of
   9.120 +     *     inferBinaryName
   9.121 +     */
   9.122 +    void test(String testName,
   9.123 +              JavaFileManager fm, String testClassName, String implClassName) throws IOException {
   9.124 +        JavaFileObject fo = fm.getJavaFileForInput(CLASS_PATH, testClassName, CLASS);
   9.125 +        if (fo == null) {
   9.126 +            System.err.println("Can't find " + testClassName);
   9.127 +            errors++;
   9.128 +            return;
   9.129 +        }
   9.130 +
   9.131 +        String cn = fo.getClass().getName();
   9.132 +        String bn = fm.inferBinaryName(CLASS_PATH, fo);
   9.133 +        System.err.println(testName + " " + cn + " " + bn);
   9.134 +        check(cn, implClassName);
   9.135 +        check(bn, testClassName);
   9.136 +        System.err.println("OK");
   9.137 +    }
   9.138 +
   9.139 +    JavaFileManager getFileManager(String classpathProperty,
   9.140 +                                   boolean symFileKind,
   9.141 +                                   boolean zipFileIndexKind)
   9.142 +            throws IOException {
   9.143 +        Context ctx = new Context();
   9.144 +        // uugh, ugly back door, should be cleaned up, someday
   9.145 +        if (zipFileIndexKind == USE_ZIP_FILE_INDEX)
   9.146 +            System.clearProperty("useJavaUtilZip");
   9.147 +        else
   9.148 +            System.setProperty("useJavaUtilZip", "true");
   9.149 +        Options options = Options.instance(ctx);
   9.150 +        if (symFileKind == IGNORE_SYMBOL_FILE)
   9.151 +            options.put("ignore.symbol.file", "true");
   9.152 +        JavacFileManager fm = new JavacFileManager(ctx, false, null);
   9.153 +        List<File> path = getPath(System.getProperty(classpathProperty));
   9.154 +        fm.setLocation(CLASS_PATH, path);
   9.155 +        return fm;
   9.156 +    }
   9.157 +
   9.158 +    List<File> getPath(String s) {
   9.159 +        List<File> path = new ArrayList<File>();
   9.160 +        for (String f: s.split(File.pathSeparator)) {
   9.161 +            if (f.length() > 0)
   9.162 +                path.add(new File(f));
   9.163 +        }
   9.164 +        //System.err.println("path: " + path);
   9.165 +        return path;
   9.166 +    }
   9.167 +
   9.168 +    void check(String found, String expect) {
   9.169 +        if (!found.equals(expect)) {
   9.170 +            System.err.println("Expected: " + expect);
   9.171 +            System.err.println("   Found: " + found);
   9.172 +            errors++;
   9.173 +        }
   9.174 +    }
   9.175 +
   9.176 +    private int errors;
   9.177 +}
   9.178 +
   9.179 +class A { }
   9.180 +
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/test/tools/javac/6508981/p/A.java	Tue Aug 26 14:52:59 2008 -0700
    10.3 @@ -0,0 +1,24 @@
    10.4 +/*
    10.5 + * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
    10.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    10.7 + *
    10.8 + * This code is free software; you can redistribute it and/or modify it
    10.9 + * under the terms of the GNU General Public License version 2 only, as
   10.10 + * published by the Free Software Foundation.
   10.11 + *
   10.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   10.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   10.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   10.15 + * version 2 for more details (a copy is included in the LICENSE file that
   10.16 + * accompanied this code).
   10.17 + *
   10.18 + * You should have received a copy of the GNU General Public License version
   10.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   10.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   10.21 + *
   10.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   10.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   10.24 + * have any questions.
   10.25 + */
   10.26 +package p;
   10.27 +class A { }
    11.1 --- a/test/tools/javac/T6725036.java	Fri Aug 22 11:46:29 2008 +0100
    11.2 +++ b/test/tools/javac/T6725036.java	Tue Aug 26 14:52:59 2008 -0700
    11.3 @@ -35,6 +35,7 @@
    11.4  import javax.tools.JavaFileObject;
    11.5  
    11.6  import com.sun.tools.javac.file.JavacFileManager;
    11.7 +import com.sun.tools.javac.file.RelativePath.RelativeFile;
    11.8  import com.sun.tools.javac.file.ZipFileIndex;
    11.9  import com.sun.tools.javac.file.ZipFileIndexArchive;
   11.10  import com.sun.tools.javac.util.Context;
   11.11 @@ -45,7 +46,7 @@
   11.12      }
   11.13  
   11.14      void run() throws Exception {
   11.15 -        String TEST_ENTRY_NAME = "java/lang/String.class";
   11.16 +        RelativeFile TEST_ENTRY_NAME = new RelativeFile("java/lang/String.class");
   11.17  
   11.18          File f = new File(System.getProperty("java.home"));
   11.19          if (!f.getName().equals("jre"))
   11.20 @@ -53,22 +54,21 @@
   11.21          File rt_jar = new File(new File(f, "lib"), "rt.jar");
   11.22  
   11.23          JarFile j = new JarFile(rt_jar);
   11.24 -        JarEntry je = j.getJarEntry(TEST_ENTRY_NAME);
   11.25 +        JarEntry je = j.getJarEntry(TEST_ENTRY_NAME.getPath());
   11.26          long jarEntryTime = je.getTime();
   11.27  
   11.28          ZipFileIndex zfi =
   11.29                  ZipFileIndex.getZipFileIndex(rt_jar, null, false, null, false);
   11.30          long zfiTime = zfi.getLastModified(TEST_ENTRY_NAME);
   11.31  
   11.32 -        check(je, jarEntryTime, zfi + ":" + TEST_ENTRY_NAME, zfiTime);
   11.33 +        check(je, jarEntryTime, zfi + ":" + TEST_ENTRY_NAME.getPath(), zfiTime);
   11.34  
   11.35          Context context = new Context();
   11.36          JavacFileManager fm = new JavacFileManager(context, false, null);
   11.37          ZipFileIndexArchive zfia = new ZipFileIndexArchive(fm, zfi);
   11.38 -        int sep = TEST_ENTRY_NAME.lastIndexOf("/");
   11.39          JavaFileObject jfo =
   11.40 -                zfia.getFileObject(TEST_ENTRY_NAME.substring(0, sep + 1),
   11.41 -                    TEST_ENTRY_NAME.substring(sep + 1));
   11.42 +            zfia.getFileObject(TEST_ENTRY_NAME.dirname(),
   11.43 +                                   TEST_ENTRY_NAME.basename());
   11.44          long jfoTime = jfo.getLastModified();
   11.45  
   11.46          check(je, jarEntryTime, jfo, jfoTime);

mercurial