Mon, 16 Jun 2008 13:28:00 -0700
6714364: refactor javac File handling code into new javac.file package
Reviewed-by: mcimadamore
1.1 --- a/src/share/classes/com/sun/tools/apt/main/JavaCompiler.java Fri Jun 06 15:17:35 2008 -0700 1.2 +++ b/src/share/classes/com/sun/tools/apt/main/JavaCompiler.java Mon Jun 16 13:28:00 2008 -0700 1.3 @@ -26,20 +26,14 @@ 1.4 package com.sun.tools.apt.main; 1.5 1.6 import java.io.*; 1.7 -import java.nio.CharBuffer; 1.8 -import java.util.Set; 1.9 -import java.util.HashSet; 1.10 import java.util.Map; 1.11 -import java.util.HashMap; 1.12 1.13 import javax.tools.JavaFileManager; 1.14 import javax.tools.JavaFileObject; 1.15 1.16 +import com.sun.tools.javac.file.JavacFileManager; 1.17 import com.sun.tools.javac.util.*; 1.18 import com.sun.tools.javac.code.*; 1.19 -import com.sun.tools.javac.tree.*; 1.20 -import com.sun.tools.javac.parser.*; 1.21 -import com.sun.tools.javac.comp.*; 1.22 import com.sun.tools.javac.jvm.*; 1.23 1.24 import com.sun.tools.javac.code.Symbol.*;
2.1 --- a/src/share/classes/com/sun/tools/apt/main/Main.java Fri Jun 06 15:17:35 2008 -0700 2.2 +++ b/src/share/classes/com/sun/tools/apt/main/Main.java Mon Jun 16 13:28:00 2008 -0700 2.3 @@ -44,7 +44,7 @@ 2.4 import java.io.File; 2.5 import java.net.MalformedURLException; 2.6 2.7 -import com.sun.tools.javac.util.Paths; 2.8 +import com.sun.tools.javac.file.Paths; 2.9 import com.sun.tools.javac.code.Source; 2.10 import com.sun.tools.javac.code.Symbol; 2.11 import com.sun.tools.javac.code.Type;
3.1 --- a/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Fri Jun 06 15:17:35 2008 -0700 3.2 +++ b/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Mon Jun 16 13:28:00 2008 -0700 3.3 @@ -36,12 +36,12 @@ 3.4 import javax.lang.model.type.TypeMirror; 3.5 import javax.tools.*; 3.6 3.7 -import com.sun.source.tree.Tree; 3.8 import com.sun.source.tree.*; 3.9 import com.sun.source.util.*; 3.10 import com.sun.tools.javac.code.*; 3.11 import com.sun.tools.javac.code.Symbol.*; 3.12 import com.sun.tools.javac.comp.*; 3.13 +import com.sun.tools.javac.file.JavacFileManager; 3.14 import com.sun.tools.javac.main.*; 3.15 import com.sun.tools.javac.model.*; 3.16 import com.sun.tools.javac.parser.Parser;
4.1 --- a/src/share/classes/com/sun/tools/javac/api/JavacTool.java Fri Jun 06 15:17:35 2008 -0700 4.2 +++ b/src/share/classes/com/sun/tools/javac/api/JavacTool.java Mon Jun 16 13:28:00 2008 -0700 4.3 @@ -31,7 +31,6 @@ 4.4 import java.io.PrintWriter; 4.5 import java.io.Writer; 4.6 import java.util.ArrayList; 4.7 -import java.util.Arrays; 4.8 import java.util.Collections; 4.9 import java.util.EnumSet; 4.10 import java.util.Iterator; 4.11 @@ -42,13 +41,13 @@ 4.12 import javax.tools.*; 4.13 4.14 import com.sun.source.util.JavacTask; 4.15 +import com.sun.tools.javac.file.JavacFileManager; 4.16 import com.sun.tools.javac.main.JavacOption.OptionKind; 4.17 import com.sun.tools.javac.main.JavacOption; 4.18 import com.sun.tools.javac.main.Main; 4.19 import com.sun.tools.javac.main.RecognizedOptions.GrumpyHelper; 4.20 import com.sun.tools.javac.main.RecognizedOptions; 4.21 import com.sun.tools.javac.util.Context; 4.22 -import com.sun.tools.javac.util.JavacFileManager; 4.23 import com.sun.tools.javac.util.Log; 4.24 import com.sun.tools.javac.util.Options; 4.25 import com.sun.tools.javac.util.Pair;
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/src/share/classes/com/sun/tools/javac/file/BaseFileObject.java Mon Jun 16 13:28:00 2008 -0700 5.3 @@ -0,0 +1,79 @@ 5.4 +/* 5.5 + * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. 5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.7 + * 5.8 + * This code is free software; you can redistribute it and/or modify it 5.9 + * under the terms of the GNU General Public License version 2 only, as 5.10 + * published by the Free Software Foundation. Sun designates this 5.11 + * particular file as subject to the "Classpath" exception as provided 5.12 + * by Sun in the LICENSE file that accompanied this code. 5.13 + * 5.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 5.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 5.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 5.17 + * version 2 for more details (a copy is included in the LICENSE file that 5.18 + * accompanied this code). 5.19 + * 5.20 + * You should have received a copy of the GNU General Public License version 5.21 + * 2 along with this work; if not, write to the Free Software Foundation, 5.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 5.23 + * 5.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 5.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 5.26 + * have any questions. 5.27 + */ 5.28 + 5.29 +package com.sun.tools.javac.file; 5.30 + 5.31 +import java.io.IOException; 5.32 +import java.io.InputStreamReader; 5.33 +import java.io.Reader; 5.34 +import java.nio.charset.CharsetDecoder; 5.35 +import javax.lang.model.element.Modifier; 5.36 +import javax.lang.model.element.NestingKind; 5.37 +import javax.tools.JavaFileObject; 5.38 + 5.39 +import static javax.tools.JavaFileObject.Kind.*; 5.40 + 5.41 +public abstract class BaseFileObject implements JavaFileObject { 5.42 + 5.43 + public JavaFileObject.Kind getKind() { 5.44 + String n = getName(); 5.45 + if (n.endsWith(CLASS.extension)) 5.46 + return CLASS; 5.47 + else if (n.endsWith(SOURCE.extension)) 5.48 + return SOURCE; 5.49 + else if (n.endsWith(HTML.extension)) 5.50 + return HTML; 5.51 + else 5.52 + return OTHER; 5.53 + } 5.54 + 5.55 + @Override 5.56 + public String toString() { 5.57 + return getPath(); 5.58 + } 5.59 + 5.60 + /** @deprecated see bug 6410637 */ 5.61 + @Deprecated 5.62 + public String getPath() { 5.63 + return getName(); 5.64 + } 5.65 + 5.66 + /** @deprecated see bug 6410637 */ 5.67 + @Deprecated 5.68 + abstract public String getName(); 5.69 + 5.70 + public NestingKind getNestingKind() { return null; } 5.71 + 5.72 + public Modifier getAccessLevel() { return null; } 5.73 + 5.74 + public Reader openReader(boolean ignoreEncodingErrors) throws IOException { 5.75 + return new InputStreamReader(openInputStream(), getDecoder(ignoreEncodingErrors)); 5.76 + } 5.77 + 5.78 + protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) { 5.79 + throw new UnsupportedOperationException(); 5.80 + } 5.81 + 5.82 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Mon Jun 16 13:28:00 2008 -0700 6.3 @@ -0,0 +1,1718 @@ 6.4 +/* 6.5 + * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. 6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.7 + * 6.8 + * This code is free software; you can redistribute it and/or modify it 6.9 + * under the terms of the GNU General Public License version 2 only, as 6.10 + * published by the Free Software Foundation. Sun designates this 6.11 + * particular file as subject to the "Classpath" exception as provided 6.12 + * by Sun in the LICENSE file that accompanied this code. 6.13 + * 6.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 6.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 6.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 6.17 + * version 2 for more details (a copy is included in the LICENSE file that 6.18 + * accompanied this code). 6.19 + * 6.20 + * You should have received a copy of the GNU General Public License version 6.21 + * 2 along with this work; if not, write to the Free Software Foundation, 6.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 6.23 + * 6.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 6.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 6.26 + * have any questions. 6.27 + */ 6.28 + 6.29 +package com.sun.tools.javac.file; 6.30 + 6.31 +import java.io.ByteArrayInputStream; 6.32 +import java.io.ByteArrayOutputStream; 6.33 +import java.io.File; 6.34 +import java.io.FileInputStream; 6.35 +import java.io.FileNotFoundException; 6.36 +import java.io.FileOutputStream; 6.37 +import java.io.IOException; 6.38 +import java.io.InputStream; 6.39 +import java.io.OutputStream; 6.40 +import java.io.OutputStreamWriter; 6.41 +import java.io.Writer; 6.42 +import java.lang.ref.SoftReference; 6.43 +import java.net.MalformedURLException; 6.44 +import java.net.URI; 6.45 +import java.net.URISyntaxException; 6.46 +import java.net.URL; 6.47 +import java.net.URLClassLoader; 6.48 +import java.nio.ByteBuffer; 6.49 +import java.nio.CharBuffer; 6.50 +import java.nio.channels.FileChannel; 6.51 +import java.nio.charset.Charset; 6.52 +import java.nio.charset.CharsetDecoder; 6.53 +import java.nio.charset.CoderResult; 6.54 +import java.nio.charset.CodingErrorAction; 6.55 +import java.nio.charset.IllegalCharsetNameException; 6.56 +import java.nio.charset.UnsupportedCharsetException; 6.57 +import java.util.ArrayList; 6.58 +import java.util.Arrays; 6.59 +import java.util.Collection; 6.60 +import java.util.Collections; 6.61 +import java.util.EnumSet; 6.62 +import java.util.Enumeration; 6.63 +import java.util.HashMap; 6.64 +import java.util.Iterator; 6.65 +import java.util.Map; 6.66 +import java.util.Set; 6.67 +import java.util.concurrent.ConcurrentHashMap; 6.68 +import java.util.zip.ZipEntry; 6.69 +import java.util.zip.ZipFile; 6.70 + 6.71 +import javax.lang.model.SourceVersion; 6.72 +import javax.tools.FileObject; 6.73 +import javax.tools.JavaFileManager; 6.74 +import javax.tools.JavaFileObject; 6.75 +import javax.tools.StandardJavaFileManager; 6.76 + 6.77 +import com.sun.tools.javac.code.Source; 6.78 +import com.sun.tools.javac.main.JavacOption; 6.79 +import com.sun.tools.javac.main.OptionName; 6.80 +import com.sun.tools.javac.main.RecognizedOptions; 6.81 +import com.sun.tools.javac.util.Context; 6.82 +import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition; 6.83 +import com.sun.tools.javac.util.List; 6.84 +import com.sun.tools.javac.util.ListBuffer; 6.85 +import com.sun.tools.javac.util.Log; 6.86 +import com.sun.tools.javac.util.Options; 6.87 + 6.88 +import static com.sun.tools.javac.main.OptionName.*; 6.89 +import static javax.tools.StandardLocation.*; 6.90 + 6.91 +/** 6.92 + * This class provides access to the source, class and other files 6.93 + * used by the compiler and related tools. 6.94 + */ 6.95 +public class JavacFileManager implements StandardJavaFileManager { 6.96 + 6.97 + private static final String[] symbolFileLocation = { "lib", "ct.sym" }; 6.98 + private static final String symbolFilePrefix = "META-INF/sym/rt.jar/"; 6.99 + 6.100 + boolean useZipFileIndex; 6.101 + 6.102 + private static int symbolFilePrefixLength = 0; 6.103 + static { 6.104 + try { 6.105 + symbolFilePrefixLength = symbolFilePrefix.getBytes("UTF-8").length; 6.106 + } catch (java.io.UnsupportedEncodingException uee) { 6.107 + // Can't happen...UTF-8 is always supported. 6.108 + } 6.109 + } 6.110 + 6.111 + private static boolean CHECK_ZIP_TIMESTAMP = false; 6.112 + private static Map<File, Boolean> isDirectory = new ConcurrentHashMap<File, Boolean>(); 6.113 + 6.114 + 6.115 + public static char[] toArray(CharBuffer buffer) { 6.116 + if (buffer.hasArray()) 6.117 + return ((CharBuffer)buffer.compact().flip()).array(); 6.118 + else 6.119 + return buffer.toString().toCharArray(); 6.120 + } 6.121 + 6.122 + /** 6.123 + * The log to be used for error reporting. 6.124 + */ 6.125 + protected Log log; 6.126 + 6.127 + /** Encapsulates knowledge of paths 6.128 + */ 6.129 + private Paths paths; 6.130 + 6.131 + private Options options; 6.132 + 6.133 + private final File uninited = new File("U N I N I T E D"); 6.134 + 6.135 + private final Set<JavaFileObject.Kind> sourceOrClass = 6.136 + EnumSet.of(JavaFileObject.Kind.SOURCE, JavaFileObject.Kind.CLASS); 6.137 + 6.138 + /** The standard output directory, primarily used for classes. 6.139 + * Initialized by the "-d" option. 6.140 + * If classOutDir = null, files are written into same directory as the sources 6.141 + * they were generated from. 6.142 + */ 6.143 + private File classOutDir = uninited; 6.144 + 6.145 + /** The output directory, used when generating sources while processing annotations. 6.146 + * Initialized by the "-s" option. 6.147 + */ 6.148 + private File sourceOutDir = uninited; 6.149 + 6.150 + protected boolean mmappedIO; 6.151 + protected boolean ignoreSymbolFile; 6.152 + 6.153 + /** 6.154 + * User provided charset (through javax.tools). 6.155 + */ 6.156 + protected Charset charset; 6.157 + 6.158 + /** 6.159 + * Register a Context.Factory to create a JavacFileManager. 6.160 + */ 6.161 + public static void preRegister(final Context context) { 6.162 + context.put(JavaFileManager.class, new Context.Factory<JavaFileManager>() { 6.163 + public JavaFileManager make() { 6.164 + return new JavacFileManager(context, true, null); 6.165 + } 6.166 + }); 6.167 + } 6.168 + 6.169 + /** 6.170 + * Create a JavacFileManager using a given context, optionally registering 6.171 + * it as the JavaFileManager for that context. 6.172 + */ 6.173 + public JavacFileManager(Context context, boolean register, Charset charset) { 6.174 + if (register) 6.175 + context.put(JavaFileManager.class, this); 6.176 + byteBufferCache = new ByteBufferCache(); 6.177 + this.charset = charset; 6.178 + setContext(context); 6.179 + } 6.180 + 6.181 + /** 6.182 + * Set the context for JavacFileManager. 6.183 + */ 6.184 + public void setContext(Context context) { 6.185 + log = Log.instance(context); 6.186 + if (paths == null) { 6.187 + paths = Paths.instance(context); 6.188 + } else { 6.189 + // Reuse the Paths object as it stores the locations that 6.190 + // have been set with setLocation, etc. 6.191 + paths.setContext(context); 6.192 + } 6.193 + 6.194 + options = Options.instance(context); 6.195 + 6.196 + useZipFileIndex = System.getProperty("useJavaUtilZip") == null;// TODO: options.get("useJavaUtilZip") == null; 6.197 + CHECK_ZIP_TIMESTAMP = System.getProperty("checkZipIndexTimestamp") != null;// TODO: options.get("checkZipIndexTimestamp") != null; 6.198 + 6.199 + mmappedIO = options.get("mmappedIO") != null; 6.200 + ignoreSymbolFile = options.get("ignore.symbol.file") != null; 6.201 + } 6.202 + 6.203 + public JavaFileObject getFileForInput(String name) { 6.204 + return getRegularFile(new File(name)); 6.205 + } 6.206 + 6.207 + public JavaFileObject getRegularFile(File file) { 6.208 + return new RegularFileObject(file); 6.209 + } 6.210 + 6.211 + public JavaFileObject getFileForOutput(String classname, 6.212 + JavaFileObject.Kind kind, 6.213 + JavaFileObject sibling) 6.214 + throws IOException 6.215 + { 6.216 + return getJavaFileForOutput(CLASS_OUTPUT, classname, kind, sibling); 6.217 + } 6.218 + 6.219 + public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(Iterable<String> names) { 6.220 + ListBuffer<File> files = new ListBuffer<File>(); 6.221 + for (String name : names) 6.222 + files.append(new File(nullCheck(name))); 6.223 + return getJavaFileObjectsFromFiles(files.toList()); 6.224 + } 6.225 + 6.226 + public Iterable<? extends JavaFileObject> getJavaFileObjects(String... names) { 6.227 + return getJavaFileObjectsFromStrings(Arrays.asList(nullCheck(names))); 6.228 + } 6.229 + 6.230 + protected JavaFileObject.Kind getKind(String extension) { 6.231 + if (extension.equals(JavaFileObject.Kind.CLASS.extension)) 6.232 + return JavaFileObject.Kind.CLASS; 6.233 + else if (extension.equals(JavaFileObject.Kind.SOURCE.extension)) 6.234 + return JavaFileObject.Kind.SOURCE; 6.235 + else if (extension.equals(JavaFileObject.Kind.HTML.extension)) 6.236 + return JavaFileObject.Kind.HTML; 6.237 + else 6.238 + return JavaFileObject.Kind.OTHER; 6.239 + } 6.240 + 6.241 + private static boolean isValidName(String name) { 6.242 + // Arguably, isValidName should reject keywords (such as in SourceVersion.isName() ), 6.243 + // but the set of keywords depends on the source level, and we don't want 6.244 + // impls of JavaFileManager to have to be dependent on the source level. 6.245 + // Therefore we simply check that the argument is a sequence of identifiers 6.246 + // separated by ".". 6.247 + for (String s : name.split("\\.", -1)) { 6.248 + if (!SourceVersion.isIdentifier(s)) 6.249 + return false; 6.250 + } 6.251 + return true; 6.252 + } 6.253 + 6.254 + private static void validateClassName(String className) { 6.255 + if (!isValidName(className)) 6.256 + throw new IllegalArgumentException("Invalid class name: " + className); 6.257 + } 6.258 + 6.259 + private static void validatePackageName(String packageName) { 6.260 + if (packageName.length() > 0 && !isValidName(packageName)) 6.261 + throw new IllegalArgumentException("Invalid packageName name: " + packageName); 6.262 + } 6.263 + 6.264 + public static void testName(String name, 6.265 + boolean isValidPackageName, 6.266 + boolean isValidClassName) 6.267 + { 6.268 + try { 6.269 + validatePackageName(name); 6.270 + if (!isValidPackageName) 6.271 + throw new AssertionError("Invalid package name accepted: " + name); 6.272 + printAscii("Valid package name: \"%s\"", name); 6.273 + } catch (IllegalArgumentException e) { 6.274 + if (isValidPackageName) 6.275 + throw new AssertionError("Valid package name rejected: " + name); 6.276 + printAscii("Invalid package name: \"%s\"", name); 6.277 + } 6.278 + try { 6.279 + validateClassName(name); 6.280 + if (!isValidClassName) 6.281 + throw new AssertionError("Invalid class name accepted: " + name); 6.282 + printAscii("Valid class name: \"%s\"", name); 6.283 + } catch (IllegalArgumentException e) { 6.284 + if (isValidClassName) 6.285 + throw new AssertionError("Valid class name rejected: " + name); 6.286 + printAscii("Invalid class name: \"%s\"", name); 6.287 + } 6.288 + } 6.289 + private static void printAscii(String format, Object... args) { 6.290 + String message; 6.291 + try { 6.292 + final String ascii = "US-ASCII"; 6.293 + message = new String(String.format(null, format, args).getBytes(ascii), ascii); 6.294 + } catch (java.io.UnsupportedEncodingException ex) { 6.295 + throw new AssertionError(ex); 6.296 + } 6.297 + System.out.println(message); 6.298 + } 6.299 + 6.300 + /** Return external representation of name, 6.301 + * converting '.' to File.separatorChar. 6.302 + */ 6.303 + private static String externalizeFileName(CharSequence name) { 6.304 + return name.toString().replace('.', File.separatorChar); 6.305 + } 6.306 + 6.307 + private static String externalizeFileName(CharSequence n, JavaFileObject.Kind kind) { 6.308 + return externalizeFileName(n) + kind.extension; 6.309 + } 6.310 + 6.311 + private static String baseName(String fileName) { 6.312 + return fileName.substring(fileName.lastIndexOf(File.separatorChar) + 1); 6.313 + } 6.314 + 6.315 + /** 6.316 + * Insert all files in subdirectory `subdirectory' of `directory' which end 6.317 + * in one of the extensions in `extensions' into packageSym. 6.318 + */ 6.319 + private void listDirectory(File directory, 6.320 + String subdirectory, 6.321 + Set<JavaFileObject.Kind> fileKinds, 6.322 + boolean recurse, 6.323 + ListBuffer<JavaFileObject> l) { 6.324 + Archive archive = archives.get(directory); 6.325 + 6.326 + boolean isFile = false; 6.327 + if (CHECK_ZIP_TIMESTAMP) { 6.328 + Boolean isf = isDirectory.get(directory); 6.329 + if (isf == null) { 6.330 + isFile = directory.isFile(); 6.331 + isDirectory.put(directory, isFile); 6.332 + } 6.333 + else { 6.334 + isFile = directory.isFile(); 6.335 + } 6.336 + } 6.337 + else { 6.338 + isFile = directory.isFile(); 6.339 + } 6.340 + 6.341 + if (archive != null || isFile) { 6.342 + if (archive == null) { 6.343 + try { 6.344 + archive = openArchive(directory); 6.345 + } catch (IOException ex) { 6.346 + log.error("error.reading.file", 6.347 + directory, ex.getLocalizedMessage()); 6.348 + return; 6.349 + } 6.350 + } 6.351 + if (subdirectory.length() != 0) { 6.352 + if (!useZipFileIndex) { 6.353 + subdirectory = subdirectory.replace('\\', '/'); 6.354 + if (!subdirectory.endsWith("/")) subdirectory = subdirectory + "/"; 6.355 + } 6.356 + else { 6.357 + if (File.separatorChar == '/') { 6.358 + subdirectory = subdirectory.replace('\\', '/'); 6.359 + } 6.360 + else { 6.361 + subdirectory = subdirectory.replace('/', '\\'); 6.362 + } 6.363 + 6.364 + if (!subdirectory.endsWith(File.separator)) subdirectory = subdirectory + File.separator; 6.365 + } 6.366 + } 6.367 + 6.368 + List<String> files = archive.getFiles(subdirectory); 6.369 + if (files != null) { 6.370 + for (String file; !files.isEmpty(); files = files.tail) { 6.371 + file = files.head; 6.372 + if (isValidFile(file, fileKinds)) { 6.373 + l.append(archive.getFileObject(subdirectory, file)); 6.374 + } 6.375 + } 6.376 + } 6.377 + if (recurse) { 6.378 + for (String s: archive.getSubdirectories()) { 6.379 + if (s.startsWith(subdirectory) && !s.equals(subdirectory)) { 6.380 + // Because the archive map is a flat list of directories, 6.381 + // the enclosing loop will pick up all child subdirectories. 6.382 + // Therefore, there is no need to recurse deeper. 6.383 + listDirectory(directory, s, fileKinds, false, l); 6.384 + } 6.385 + } 6.386 + } 6.387 + } else { 6.388 + File d = subdirectory.length() != 0 6.389 + ? new File(directory, subdirectory) 6.390 + : directory; 6.391 + if (!caseMapCheck(d, subdirectory)) 6.392 + return; 6.393 + 6.394 + File[] files = d.listFiles(); 6.395 + if (files == null) 6.396 + return; 6.397 + 6.398 + for (File f: files) { 6.399 + String fname = f.getName(); 6.400 + if (f.isDirectory()) { 6.401 + if (recurse && SourceVersion.isIdentifier(fname)) { 6.402 + listDirectory(directory, 6.403 + subdirectory + File.separator + fname, 6.404 + fileKinds, 6.405 + recurse, 6.406 + l); 6.407 + } 6.408 + } else { 6.409 + if (isValidFile(fname, fileKinds)) { 6.410 + JavaFileObject fe = 6.411 + new RegularFileObject(fname, new File(d, fname)); 6.412 + l.append(fe); 6.413 + } 6.414 + } 6.415 + } 6.416 + } 6.417 + } 6.418 + 6.419 + private boolean isValidFile(String s, Set<JavaFileObject.Kind> fileKinds) { 6.420 + int lastDot = s.lastIndexOf("."); 6.421 + String extn = (lastDot == -1 ? s : s.substring(lastDot)); 6.422 + JavaFileObject.Kind kind = getKind(extn); 6.423 + return fileKinds.contains(kind); 6.424 + } 6.425 + 6.426 + private static final boolean fileSystemIsCaseSensitive = 6.427 + File.separatorChar == '/'; 6.428 + 6.429 + /** Hack to make Windows case sensitive. Test whether given path 6.430 + * ends in a string of characters with the same case as given name. 6.431 + * Ignore file separators in both path and name. 6.432 + */ 6.433 + private boolean caseMapCheck(File f, String name) { 6.434 + if (fileSystemIsCaseSensitive) return true; 6.435 + // Note that getCanonicalPath() returns the case-sensitive 6.436 + // spelled file name. 6.437 + String path; 6.438 + try { 6.439 + path = f.getCanonicalPath(); 6.440 + } catch (IOException ex) { 6.441 + return false; 6.442 + } 6.443 + char[] pcs = path.toCharArray(); 6.444 + char[] ncs = name.toCharArray(); 6.445 + int i = pcs.length - 1; 6.446 + int j = ncs.length - 1; 6.447 + while (i >= 0 && j >= 0) { 6.448 + while (i >= 0 && pcs[i] == File.separatorChar) i--; 6.449 + while (j >= 0 && ncs[j] == File.separatorChar) j--; 6.450 + if (i >= 0 && j >= 0) { 6.451 + if (pcs[i] != ncs[j]) return false; 6.452 + i--; 6.453 + j--; 6.454 + } 6.455 + } 6.456 + return j < 0; 6.457 + } 6.458 + 6.459 + /** 6.460 + * An archive provides a flat directory structure of a ZipFile by 6.461 + * mapping directory names to lists of files (basenames). 6.462 + */ 6.463 + public interface Archive { 6.464 + void close() throws IOException; 6.465 + 6.466 + boolean contains(String name); 6.467 + 6.468 + JavaFileObject getFileObject(String subdirectory, String file); 6.469 + 6.470 + List<String> getFiles(String subdirectory); 6.471 + 6.472 + Set<String> getSubdirectories(); 6.473 + } 6.474 + 6.475 + public class ZipArchive implements Archive { 6.476 + protected final Map<String,List<String>> map; 6.477 + protected final ZipFile zdir; 6.478 + public ZipArchive(ZipFile zdir) throws IOException { 6.479 + this.zdir = zdir; 6.480 + this.map = new HashMap<String,List<String>>(); 6.481 + for (Enumeration<? extends ZipEntry> e = zdir.entries(); e.hasMoreElements(); ) { 6.482 + ZipEntry entry; 6.483 + try { 6.484 + entry = e.nextElement(); 6.485 + } catch (InternalError ex) { 6.486 + IOException io = new IOException(); 6.487 + io.initCause(ex); // convenience constructors added in Mustang :-( 6.488 + throw io; 6.489 + } 6.490 + addZipEntry(entry); 6.491 + } 6.492 + } 6.493 + 6.494 + void addZipEntry(ZipEntry entry) { 6.495 + String name = entry.getName(); 6.496 + int i = name.lastIndexOf('/'); 6.497 + String dirname = name.substring(0, i+1); 6.498 + String basename = name.substring(i+1); 6.499 + if (basename.length() == 0) 6.500 + return; 6.501 + List<String> list = map.get(dirname); 6.502 + if (list == null) 6.503 + list = List.nil(); 6.504 + list = list.prepend(basename); 6.505 + map.put(dirname, list); 6.506 + } 6.507 + 6.508 + public boolean contains(String name) { 6.509 + int i = name.lastIndexOf('/'); 6.510 + String dirname = name.substring(0, i+1); 6.511 + String basename = name.substring(i+1); 6.512 + if (basename.length() == 0) 6.513 + return false; 6.514 + List<String> list = map.get(dirname); 6.515 + return (list != null && list.contains(basename)); 6.516 + } 6.517 + 6.518 + public List<String> getFiles(String subdirectory) { 6.519 + return map.get(subdirectory); 6.520 + } 6.521 + 6.522 + public JavaFileObject getFileObject(String subdirectory, String file) { 6.523 + ZipEntry ze = zdir.getEntry(subdirectory + file); 6.524 + return new ZipFileObject(file, zdir, ze); 6.525 + } 6.526 + 6.527 + public Set<String> getSubdirectories() { 6.528 + return map.keySet(); 6.529 + } 6.530 + 6.531 + public void close() throws IOException { 6.532 + zdir.close(); 6.533 + } 6.534 + } 6.535 + 6.536 + public class SymbolArchive extends ZipArchive { 6.537 + final File origFile; 6.538 + public SymbolArchive(File orig, ZipFile zdir) throws IOException { 6.539 + super(zdir); 6.540 + this.origFile = orig; 6.541 + } 6.542 + 6.543 + @Override 6.544 + void addZipEntry(ZipEntry entry) { 6.545 + // called from super constructor, may not refer to origFile. 6.546 + String name = entry.getName(); 6.547 + if (!name.startsWith(symbolFilePrefix)) 6.548 + return; 6.549 + name = name.substring(symbolFilePrefix.length()); 6.550 + int i = name.lastIndexOf('/'); 6.551 + String dirname = name.substring(0, i+1); 6.552 + String basename = name.substring(i+1); 6.553 + if (basename.length() == 0) 6.554 + return; 6.555 + List<String> list = map.get(dirname); 6.556 + if (list == null) 6.557 + list = List.nil(); 6.558 + list = list.prepend(basename); 6.559 + map.put(dirname, list); 6.560 + } 6.561 + 6.562 + @Override 6.563 + public JavaFileObject getFileObject(String subdirectory, String file) { 6.564 + return super.getFileObject(symbolFilePrefix + subdirectory, file); 6.565 + } 6.566 + } 6.567 + 6.568 + public class MissingArchive implements Archive { 6.569 + final File zipFileName; 6.570 + public MissingArchive(File name) { 6.571 + zipFileName = name; 6.572 + } 6.573 + public boolean contains(String name) { 6.574 + return false; 6.575 + } 6.576 + 6.577 + public void close() { 6.578 + } 6.579 + 6.580 + public JavaFileObject getFileObject(String subdirectory, String file) { 6.581 + return null; 6.582 + } 6.583 + 6.584 + public List<String> getFiles(String subdirectory) { 6.585 + return List.nil(); 6.586 + } 6.587 + 6.588 + public Set<String> getSubdirectories() { 6.589 + return Collections.emptySet(); 6.590 + } 6.591 + } 6.592 + 6.593 + /** A directory of zip files already opened. 6.594 + */ 6.595 + Map<File, Archive> archives = new HashMap<File,Archive>(); 6.596 + 6.597 + /** Open a new zip file directory. 6.598 + */ 6.599 + protected Archive openArchive(File zipFileName) throws IOException { 6.600 + Archive archive = archives.get(zipFileName); 6.601 + if (archive == null) { 6.602 + File origZipFileName = zipFileName; 6.603 + if (!ignoreSymbolFile && paths.isBootClassPathRtJar(zipFileName)) { 6.604 + File file = zipFileName.getParentFile().getParentFile(); // ${java.home} 6.605 + if (new File(file.getName()).equals(new File("jre"))) 6.606 + file = file.getParentFile(); 6.607 + // file == ${jdk.home} 6.608 + for (String name : symbolFileLocation) 6.609 + file = new File(file, name); 6.610 + // file == ${jdk.home}/lib/ct.sym 6.611 + if (file.exists()) 6.612 + zipFileName = file; 6.613 + } 6.614 + 6.615 + try { 6.616 + 6.617 + ZipFile zdir = null; 6.618 + 6.619 + boolean usePreindexedCache = false; 6.620 + String preindexCacheLocation = null; 6.621 + 6.622 + if (!useZipFileIndex) { 6.623 + zdir = new ZipFile(zipFileName); 6.624 + } 6.625 + else { 6.626 + usePreindexedCache = options.get("usezipindex") != null; 6.627 + preindexCacheLocation = options.get("java.io.tmpdir"); 6.628 + String optCacheLoc = options.get("cachezipindexdir"); 6.629 + 6.630 + if (optCacheLoc != null && optCacheLoc.length() != 0) { 6.631 + if (optCacheLoc.startsWith("\"")) { 6.632 + if (optCacheLoc.endsWith("\"")) { 6.633 + optCacheLoc = optCacheLoc.substring(1, optCacheLoc.length() - 1); 6.634 + } 6.635 + else { 6.636 + optCacheLoc = optCacheLoc.substring(1); 6.637 + } 6.638 + } 6.639 + 6.640 + File cacheDir = new File(optCacheLoc); 6.641 + if (cacheDir.exists() && cacheDir.canWrite()) { 6.642 + preindexCacheLocation = optCacheLoc; 6.643 + if (!preindexCacheLocation.endsWith("/") && 6.644 + !preindexCacheLocation.endsWith(File.separator)) { 6.645 + preindexCacheLocation += File.separator; 6.646 + } 6.647 + } 6.648 + } 6.649 + } 6.650 + 6.651 + if (origZipFileName == zipFileName) { 6.652 + if (!useZipFileIndex) { 6.653 + archive = new ZipArchive(zdir); 6.654 + } else { 6.655 + archive = new ZipFileIndexArchive(this, ZipFileIndex.getZipFileIndex(zipFileName, 0, 6.656 + usePreindexedCache, preindexCacheLocation, options.get("writezipindexfiles") != null)); 6.657 + } 6.658 + } 6.659 + else { 6.660 + if (!useZipFileIndex) { 6.661 + archive = new SymbolArchive(origZipFileName, zdir); 6.662 + } 6.663 + else { 6.664 + archive = new ZipFileIndexArchive(this, ZipFileIndex.getZipFileIndex(zipFileName, symbolFilePrefixLength, 6.665 + usePreindexedCache, preindexCacheLocation, options.get("writezipindexfiles") != null)); 6.666 + } 6.667 + } 6.668 + } catch (FileNotFoundException ex) { 6.669 + archive = new MissingArchive(zipFileName); 6.670 + } catch (IOException ex) { 6.671 + log.error("error.reading.file", zipFileName, ex.getLocalizedMessage()); 6.672 + archive = new MissingArchive(zipFileName); 6.673 + } 6.674 + 6.675 + archives.put(origZipFileName, archive); 6.676 + } 6.677 + return archive; 6.678 + } 6.679 + 6.680 + /** Flush any output resources. 6.681 + */ 6.682 + public void flush() { 6.683 + contentCache.clear(); 6.684 + } 6.685 + 6.686 + /** 6.687 + * Close the JavaFileManager, releasing resources. 6.688 + */ 6.689 + public void close() { 6.690 + for (Iterator<Archive> i = archives.values().iterator(); i.hasNext(); ) { 6.691 + Archive a = i.next(); 6.692 + i.remove(); 6.693 + try { 6.694 + a.close(); 6.695 + } catch (IOException e) { 6.696 + } 6.697 + } 6.698 + } 6.699 + 6.700 + private Map<JavaFileObject, SoftReference<CharBuffer>> contentCache = new HashMap<JavaFileObject, SoftReference<CharBuffer>>(); 6.701 + 6.702 + private String defaultEncodingName; 6.703 + private String getDefaultEncodingName() { 6.704 + if (defaultEncodingName == null) { 6.705 + defaultEncodingName = 6.706 + new OutputStreamWriter(new ByteArrayOutputStream()).getEncoding(); 6.707 + } 6.708 + return defaultEncodingName; 6.709 + } 6.710 + 6.711 + protected String getEncodingName() { 6.712 + String encName = options.get(OptionName.ENCODING); 6.713 + if (encName == null) 6.714 + return getDefaultEncodingName(); 6.715 + else 6.716 + return encName; 6.717 + } 6.718 + 6.719 + protected Source getSource() { 6.720 + String sourceName = options.get(OptionName.SOURCE); 6.721 + Source source = null; 6.722 + if (sourceName != null) 6.723 + source = Source.lookup(sourceName); 6.724 + return (source != null ? source : Source.DEFAULT); 6.725 + } 6.726 + 6.727 + /** 6.728 + * Make a byte buffer from an input stream. 6.729 + */ 6.730 + private ByteBuffer makeByteBuffer(InputStream in) 6.731 + throws IOException { 6.732 + int limit = in.available(); 6.733 + if (mmappedIO && in instanceof FileInputStream) { 6.734 + // Experimental memory mapped I/O 6.735 + FileInputStream fin = (FileInputStream)in; 6.736 + return fin.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, limit); 6.737 + } 6.738 + if (limit < 1024) limit = 1024; 6.739 + ByteBuffer result = byteBufferCache.get(limit); 6.740 + int position = 0; 6.741 + while (in.available() != 0) { 6.742 + if (position >= limit) 6.743 + // expand buffer 6.744 + result = ByteBuffer. 6.745 + allocate(limit <<= 1). 6.746 + put((ByteBuffer)result.flip()); 6.747 + int count = in.read(result.array(), 6.748 + position, 6.749 + limit - position); 6.750 + if (count < 0) break; 6.751 + result.position(position += count); 6.752 + } 6.753 + return (ByteBuffer)result.flip(); 6.754 + } 6.755 + 6.756 + /** 6.757 + * A single-element cache of direct byte buffers. 6.758 + */ 6.759 + private static class ByteBufferCache { 6.760 + private ByteBuffer cached; 6.761 + ByteBuffer get(int capacity) { 6.762 + if (capacity < 20480) capacity = 20480; 6.763 + ByteBuffer result = 6.764 + (cached != null && cached.capacity() >= capacity) 6.765 + ? (ByteBuffer)cached.clear() 6.766 + : ByteBuffer.allocate(capacity + capacity>>1); 6.767 + cached = null; 6.768 + return result; 6.769 + } 6.770 + void put(ByteBuffer x) { 6.771 + cached = x; 6.772 + } 6.773 + } 6.774 + private final ByteBufferCache byteBufferCache; 6.775 + 6.776 + private CharsetDecoder getDecoder(String encodingName, boolean ignoreEncodingErrors) { 6.777 + Charset charset = (this.charset == null) 6.778 + ? Charset.forName(encodingName) 6.779 + : this.charset; 6.780 + CharsetDecoder decoder = charset.newDecoder(); 6.781 + 6.782 + CodingErrorAction action; 6.783 + if (ignoreEncodingErrors) 6.784 + action = CodingErrorAction.REPLACE; 6.785 + else 6.786 + action = CodingErrorAction.REPORT; 6.787 + 6.788 + return decoder 6.789 + .onMalformedInput(action) 6.790 + .onUnmappableCharacter(action); 6.791 + } 6.792 + 6.793 + /** 6.794 + * Decode a ByteBuffer into a CharBuffer. 6.795 + */ 6.796 + private CharBuffer decode(ByteBuffer inbuf, boolean ignoreEncodingErrors) { 6.797 + String encodingName = getEncodingName(); 6.798 + CharsetDecoder decoder; 6.799 + try { 6.800 + decoder = getDecoder(encodingName, ignoreEncodingErrors); 6.801 + } catch (IllegalCharsetNameException e) { 6.802 + log.error("unsupported.encoding", encodingName); 6.803 + return (CharBuffer)CharBuffer.allocate(1).flip(); 6.804 + } catch (UnsupportedCharsetException e) { 6.805 + log.error("unsupported.encoding", encodingName); 6.806 + return (CharBuffer)CharBuffer.allocate(1).flip(); 6.807 + } 6.808 + 6.809 + // slightly overestimate the buffer size to avoid reallocation. 6.810 + float factor = 6.811 + decoder.averageCharsPerByte() * 0.8f + 6.812 + decoder.maxCharsPerByte() * 0.2f; 6.813 + CharBuffer dest = CharBuffer. 6.814 + allocate(10 + (int)(inbuf.remaining()*factor)); 6.815 + 6.816 + while (true) { 6.817 + CoderResult result = decoder.decode(inbuf, dest, true); 6.818 + dest.flip(); 6.819 + 6.820 + if (result.isUnderflow()) { // done reading 6.821 + // make sure there is at least one extra character 6.822 + if (dest.limit() == dest.capacity()) { 6.823 + dest = CharBuffer.allocate(dest.capacity()+1).put(dest); 6.824 + dest.flip(); 6.825 + } 6.826 + return dest; 6.827 + } else if (result.isOverflow()) { // buffer too small; expand 6.828 + int newCapacity = 6.829 + 10 + dest.capacity() + 6.830 + (int)(inbuf.remaining()*decoder.maxCharsPerByte()); 6.831 + dest = CharBuffer.allocate(newCapacity).put(dest); 6.832 + } else if (result.isMalformed() || result.isUnmappable()) { 6.833 + // bad character in input 6.834 + 6.835 + // report coding error (warn only pre 1.5) 6.836 + if (!getSource().allowEncodingErrors()) { 6.837 + log.error(new SimpleDiagnosticPosition(dest.limit()), 6.838 + "illegal.char.for.encoding", 6.839 + charset == null ? encodingName : charset.name()); 6.840 + } else { 6.841 + log.warning(new SimpleDiagnosticPosition(dest.limit()), 6.842 + "illegal.char.for.encoding", 6.843 + charset == null ? encodingName : charset.name()); 6.844 + } 6.845 + 6.846 + // skip past the coding error 6.847 + inbuf.position(inbuf.position() + result.length()); 6.848 + 6.849 + // undo the flip() to prepare the output buffer 6.850 + // for more translation 6.851 + dest.position(dest.limit()); 6.852 + dest.limit(dest.capacity()); 6.853 + dest.put((char)0xfffd); // backward compatible 6.854 + } else { 6.855 + throw new AssertionError(result); 6.856 + } 6.857 + } 6.858 + // unreached 6.859 + } 6.860 + 6.861 + public ClassLoader getClassLoader(Location location) { 6.862 + nullCheck(location); 6.863 + Iterable<? extends File> path = getLocation(location); 6.864 + if (path == null) 6.865 + return null; 6.866 + ListBuffer<URL> lb = new ListBuffer<URL>(); 6.867 + for (File f: path) { 6.868 + try { 6.869 + lb.append(f.toURI().toURL()); 6.870 + } catch (MalformedURLException e) { 6.871 + throw new AssertionError(e); 6.872 + } 6.873 + } 6.874 + return new URLClassLoader(lb.toArray(new URL[lb.size()]), 6.875 + getClass().getClassLoader()); 6.876 + } 6.877 + 6.878 + public Iterable<JavaFileObject> list(Location location, 6.879 + String packageName, 6.880 + Set<JavaFileObject.Kind> kinds, 6.881 + boolean recurse) 6.882 + throws IOException 6.883 + { 6.884 + // validatePackageName(packageName); 6.885 + nullCheck(packageName); 6.886 + nullCheck(kinds); 6.887 + 6.888 + Iterable<? extends File> path = getLocation(location); 6.889 + if (path == null) 6.890 + return List.nil(); 6.891 + String subdirectory = externalizeFileName(packageName); 6.892 + ListBuffer<JavaFileObject> results = new ListBuffer<JavaFileObject>(); 6.893 + 6.894 + for (File directory : path) 6.895 + listDirectory(directory, subdirectory, kinds, recurse, results); 6.896 + 6.897 + return results.toList(); 6.898 + } 6.899 + 6.900 + public String inferBinaryName(Location location, JavaFileObject file) { 6.901 + file.getClass(); // null check 6.902 + location.getClass(); // null check 6.903 + // Need to match the path semantics of list(location, ...) 6.904 + Iterable<? extends File> path = getLocation(location); 6.905 + if (path == null) { 6.906 + //System.err.println("Path for " + location + " is null"); 6.907 + return null; 6.908 + } 6.909 + //System.err.println("Path for " + location + " is " + path); 6.910 + 6.911 + if (file instanceof RegularFileObject) { 6.912 + RegularFileObject r = (RegularFileObject) file; 6.913 + String rPath = r.getPath(); 6.914 + //System.err.println("RegularFileObject " + file + " " +r.getPath()); 6.915 + for (File dir: path) { 6.916 + //System.err.println("dir: " + dir); 6.917 + String dPath = dir.getPath(); 6.918 + if (!dPath.endsWith(File.separator)) 6.919 + dPath += File.separator; 6.920 + if (rPath.regionMatches(true, 0, dPath, 0, dPath.length()) 6.921 + && new File(rPath.substring(0, dPath.length())).equals(new File(dPath))) { 6.922 + String relativeName = rPath.substring(dPath.length()); 6.923 + return removeExtension(relativeName).replace(File.separatorChar, '.'); 6.924 + } 6.925 + } 6.926 + } else if (file instanceof ZipFileObject) { 6.927 + ZipFileObject z = (ZipFileObject) file; 6.928 + String entryName = z.getZipEntryName(); 6.929 + if (entryName.startsWith(symbolFilePrefix)) 6.930 + entryName = entryName.substring(symbolFilePrefix.length()); 6.931 + return removeExtension(entryName).replace('/', '.'); 6.932 + } else if (file instanceof ZipFileIndexFileObject) { 6.933 + ZipFileIndexFileObject z = (ZipFileIndexFileObject) file; 6.934 + String entryName = z.getZipEntryName(); 6.935 + if (entryName.startsWith(symbolFilePrefix)) 6.936 + entryName = entryName.substring(symbolFilePrefix.length()); 6.937 + return removeExtension(entryName).replace(File.separatorChar, '.'); 6.938 + } else 6.939 + throw new IllegalArgumentException(file.getClass().getName()); 6.940 + // System.err.println("inferBinaryName failed for " + file); 6.941 + return null; 6.942 + } 6.943 + // where 6.944 + private static String removeExtension(String fileName) { 6.945 + int lastDot = fileName.lastIndexOf("."); 6.946 + return (lastDot == -1 ? fileName : fileName.substring(0, lastDot)); 6.947 + } 6.948 + 6.949 + public boolean isSameFile(FileObject a, FileObject b) { 6.950 + nullCheck(a); 6.951 + nullCheck(b); 6.952 + if (!(a instanceof BaseFileObject)) 6.953 + throw new IllegalArgumentException("Not supported: " + a); 6.954 + if (!(b instanceof BaseFileObject)) 6.955 + throw new IllegalArgumentException("Not supported: " + b); 6.956 + return a.equals(b); 6.957 + } 6.958 + 6.959 + public boolean handleOption(String current, Iterator<String> remaining) { 6.960 + for (JavacOption o: javacFileManagerOptions) { 6.961 + if (o.matches(current)) { 6.962 + if (o.hasArg()) { 6.963 + if (remaining.hasNext()) { 6.964 + if (!o.process(options, current, remaining.next())) 6.965 + return true; 6.966 + } 6.967 + } else { 6.968 + if (!o.process(options, current)) 6.969 + return true; 6.970 + } 6.971 + // operand missing, or process returned false 6.972 + throw new IllegalArgumentException(current); 6.973 + } 6.974 + } 6.975 + 6.976 + return false; 6.977 + } 6.978 + // where 6.979 + private static JavacOption[] javacFileManagerOptions = 6.980 + RecognizedOptions.getJavacFileManagerOptions( 6.981 + new RecognizedOptions.GrumpyHelper()); 6.982 + 6.983 + public int isSupportedOption(String option) { 6.984 + for (JavacOption o : javacFileManagerOptions) { 6.985 + if (o.matches(option)) 6.986 + return o.hasArg() ? 1 : 0; 6.987 + } 6.988 + return -1; 6.989 + } 6.990 + 6.991 + public boolean hasLocation(Location location) { 6.992 + return getLocation(location) != null; 6.993 + } 6.994 + 6.995 + public JavaFileObject getJavaFileForInput(Location location, 6.996 + String className, 6.997 + JavaFileObject.Kind kind) 6.998 + throws IOException 6.999 + { 6.1000 + nullCheck(location); 6.1001 + // validateClassName(className); 6.1002 + nullCheck(className); 6.1003 + nullCheck(kind); 6.1004 + if (!sourceOrClass.contains(kind)) 6.1005 + throw new IllegalArgumentException("Invalid kind " + kind); 6.1006 + return getFileForInput(location, externalizeFileName(className, kind)); 6.1007 + } 6.1008 + 6.1009 + public FileObject getFileForInput(Location location, 6.1010 + String packageName, 6.1011 + String relativeName) 6.1012 + throws IOException 6.1013 + { 6.1014 + nullCheck(location); 6.1015 + // validatePackageName(packageName); 6.1016 + nullCheck(packageName); 6.1017 + if (!isRelativeUri(URI.create(relativeName))) // FIXME 6419701 6.1018 + throw new IllegalArgumentException("Invalid relative name: " + relativeName); 6.1019 + String name = packageName.length() == 0 6.1020 + ? relativeName 6.1021 + : new File(externalizeFileName(packageName), relativeName).getPath(); 6.1022 + return getFileForInput(location, name); 6.1023 + } 6.1024 + 6.1025 + private JavaFileObject getFileForInput(Location location, String name) throws IOException { 6.1026 + Iterable<? extends File> path = getLocation(location); 6.1027 + if (path == null) 6.1028 + return null; 6.1029 + 6.1030 + for (File dir: path) { 6.1031 + if (dir.isDirectory()) { 6.1032 + File f = new File(dir, name.replace('/', File.separatorChar)); 6.1033 + if (f.exists()) 6.1034 + return new RegularFileObject(f); 6.1035 + } else { 6.1036 + Archive a = openArchive(dir); 6.1037 + if (a.contains(name)) { 6.1038 + int i = name.lastIndexOf('/'); 6.1039 + String dirname = name.substring(0, i+1); 6.1040 + String basename = name.substring(i+1); 6.1041 + return a.getFileObject(dirname, basename); 6.1042 + } 6.1043 + 6.1044 + } 6.1045 + } 6.1046 + return null; 6.1047 + 6.1048 + } 6.1049 + 6.1050 + public JavaFileObject getJavaFileForOutput(Location location, 6.1051 + String className, 6.1052 + JavaFileObject.Kind kind, 6.1053 + FileObject sibling) 6.1054 + throws IOException 6.1055 + { 6.1056 + nullCheck(location); 6.1057 + // validateClassName(className); 6.1058 + nullCheck(className); 6.1059 + nullCheck(kind); 6.1060 + if (!sourceOrClass.contains(kind)) 6.1061 + throw new IllegalArgumentException("Invalid kind " + kind); 6.1062 + return getFileForOutput(location, externalizeFileName(className, kind), sibling); 6.1063 + } 6.1064 + 6.1065 + public FileObject getFileForOutput(Location location, 6.1066 + String packageName, 6.1067 + String relativeName, 6.1068 + FileObject sibling) 6.1069 + throws IOException 6.1070 + { 6.1071 + nullCheck(location); 6.1072 + // validatePackageName(packageName); 6.1073 + nullCheck(packageName); 6.1074 + if (!isRelativeUri(URI.create(relativeName))) // FIXME 6419701 6.1075 + throw new IllegalArgumentException("relativeName is invalid"); 6.1076 + String name = packageName.length() == 0 6.1077 + ? relativeName 6.1078 + : new File(externalizeFileName(packageName), relativeName).getPath(); 6.1079 + return getFileForOutput(location, name, sibling); 6.1080 + } 6.1081 + 6.1082 + private JavaFileObject getFileForOutput(Location location, 6.1083 + String fileName, 6.1084 + FileObject sibling) 6.1085 + throws IOException 6.1086 + { 6.1087 + File dir; 6.1088 + if (location == CLASS_OUTPUT) { 6.1089 + if (getClassOutDir() != null) { 6.1090 + dir = getClassOutDir(); 6.1091 + } else { 6.1092 + File siblingDir = null; 6.1093 + if (sibling != null && sibling instanceof RegularFileObject) { 6.1094 + siblingDir = ((RegularFileObject)sibling).f.getParentFile(); 6.1095 + } 6.1096 + return new RegularFileObject(new File(siblingDir, baseName(fileName))); 6.1097 + } 6.1098 + } else if (location == SOURCE_OUTPUT) { 6.1099 + dir = (getSourceOutDir() != null ? getSourceOutDir() : getClassOutDir()); 6.1100 + } else { 6.1101 + Iterable<? extends File> path = paths.getPathForLocation(location); 6.1102 + dir = null; 6.1103 + for (File f: path) { 6.1104 + dir = f; 6.1105 + break; 6.1106 + } 6.1107 + } 6.1108 + 6.1109 + File file = (dir == null ? new File(fileName) : new File(dir, fileName)); 6.1110 + return new RegularFileObject(file); 6.1111 + 6.1112 + } 6.1113 + 6.1114 + public Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles( 6.1115 + Iterable<? extends File> files) 6.1116 + { 6.1117 + ArrayList<RegularFileObject> result; 6.1118 + if (files instanceof Collection) 6.1119 + result = new ArrayList<RegularFileObject>(((Collection)files).size()); 6.1120 + else 6.1121 + result = new ArrayList<RegularFileObject>(); 6.1122 + for (File f: files) 6.1123 + result.add(new RegularFileObject(nullCheck(f))); 6.1124 + return result; 6.1125 + } 6.1126 + 6.1127 + public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files) { 6.1128 + return getJavaFileObjectsFromFiles(Arrays.asList(nullCheck(files))); 6.1129 + } 6.1130 + 6.1131 + public void setLocation(Location location, 6.1132 + Iterable<? extends File> path) 6.1133 + throws IOException 6.1134 + { 6.1135 + nullCheck(location); 6.1136 + paths.lazy(); 6.1137 + 6.1138 + final File dir = location.isOutputLocation() ? getOutputDirectory(path) : null; 6.1139 + 6.1140 + if (location == CLASS_OUTPUT) 6.1141 + classOutDir = getOutputLocation(dir, D); 6.1142 + else if (location == SOURCE_OUTPUT) 6.1143 + sourceOutDir = getOutputLocation(dir, S); 6.1144 + else 6.1145 + paths.setPathForLocation(location, path); 6.1146 + } 6.1147 + // where 6.1148 + private File getOutputDirectory(Iterable<? extends File> path) throws IOException { 6.1149 + if (path == null) 6.1150 + return null; 6.1151 + Iterator<? extends File> pathIter = path.iterator(); 6.1152 + if (!pathIter.hasNext()) 6.1153 + throw new IllegalArgumentException("empty path for directory"); 6.1154 + File dir = pathIter.next(); 6.1155 + if (pathIter.hasNext()) 6.1156 + throw new IllegalArgumentException("path too long for directory"); 6.1157 + if (!dir.exists()) 6.1158 + throw new FileNotFoundException(dir + ": does not exist"); 6.1159 + else if (!dir.isDirectory()) 6.1160 + throw new IOException(dir + ": not a directory"); 6.1161 + return dir; 6.1162 + } 6.1163 + 6.1164 + private File getOutputLocation(File dir, OptionName defaultOptionName) { 6.1165 + if (dir != null) 6.1166 + return dir; 6.1167 + String arg = options.get(defaultOptionName); 6.1168 + if (arg == null) 6.1169 + return null; 6.1170 + return new File(arg); 6.1171 + } 6.1172 + 6.1173 + public Iterable<? extends File> getLocation(Location location) { 6.1174 + nullCheck(location); 6.1175 + paths.lazy(); 6.1176 + if (location == CLASS_OUTPUT) { 6.1177 + return (getClassOutDir() == null ? null : List.of(getClassOutDir())); 6.1178 + } else if (location == SOURCE_OUTPUT) { 6.1179 + return (getSourceOutDir() == null ? null : List.of(getSourceOutDir())); 6.1180 + } else 6.1181 + return paths.getPathForLocation(location); 6.1182 + } 6.1183 + 6.1184 + private File getClassOutDir() { 6.1185 + if (classOutDir == uninited) 6.1186 + classOutDir = getOutputLocation(null, D); 6.1187 + return classOutDir; 6.1188 + } 6.1189 + 6.1190 + private File getSourceOutDir() { 6.1191 + if (sourceOutDir == uninited) 6.1192 + sourceOutDir = getOutputLocation(null, S); 6.1193 + return sourceOutDir; 6.1194 + } 6.1195 + 6.1196 + /** 6.1197 + * Enforces the specification of a "relative" URI as used in 6.1198 + * {@linkplain #getFileForInput(Location,String,URI) 6.1199 + * getFileForInput}. This method must follow the rules defined in 6.1200 + * that method, do not make any changes without consulting the 6.1201 + * specification. 6.1202 + */ 6.1203 + protected static boolean isRelativeUri(URI uri) { 6.1204 + if (uri.isAbsolute()) 6.1205 + return false; 6.1206 + String path = uri.normalize().getPath(); 6.1207 + if (path.length() == 0 /* isEmpty() is mustang API */) 6.1208 + return false; 6.1209 + char first = path.charAt(0); 6.1210 + return first != '.' && first != '/'; 6.1211 + } 6.1212 + 6.1213 + /** 6.1214 + * Converts a relative file name to a relative URI. This is 6.1215 + * different from File.toURI as this method does not canonicalize 6.1216 + * the file before creating the URI. Furthermore, no schema is 6.1217 + * used. 6.1218 + * @param file a relative file name 6.1219 + * @return a relative URI 6.1220 + * @throws IllegalArgumentException if the file name is not 6.1221 + * relative according to the definition given in {@link 6.1222 + * javax.tools.JavaFileManager#getFileForInput} 6.1223 + */ 6.1224 + public static String getRelativeName(File file) { 6.1225 + if (!file.isAbsolute()) { 6.1226 + String result = file.getPath().replace(File.separatorChar, '/'); 6.1227 + if (JavacFileManager.isRelativeUri(URI.create(result))) // FIXME 6419701 6.1228 + return result; 6.1229 + } 6.1230 + throw new IllegalArgumentException("Invalid relative path: " + file); 6.1231 + } 6.1232 + 6.1233 + @SuppressWarnings("deprecation") // bug 6410637 6.1234 + public static String getJavacFileName(FileObject file) { 6.1235 + if (file instanceof BaseFileObject) 6.1236 + return ((BaseFileObject)file).getPath(); 6.1237 + URI uri = file.toUri(); 6.1238 + String scheme = uri.getScheme(); 6.1239 + if (scheme == null || scheme.equals("file") || scheme.equals("jar")) 6.1240 + return uri.getPath(); 6.1241 + else 6.1242 + return uri.toString(); 6.1243 + } 6.1244 + 6.1245 + @SuppressWarnings("deprecation") // bug 6410637 6.1246 + public static String getJavacBaseFileName(FileObject file) { 6.1247 + if (file instanceof BaseFileObject) 6.1248 + return ((BaseFileObject)file).getName(); 6.1249 + URI uri = file.toUri(); 6.1250 + String scheme = uri.getScheme(); 6.1251 + if (scheme == null || scheme.equals("file") || scheme.equals("jar")) { 6.1252 + String path = uri.getPath(); 6.1253 + if (path == null) 6.1254 + return null; 6.1255 + if (scheme != null && scheme.equals("jar")) 6.1256 + path = path.substring(path.lastIndexOf('!') + 1); 6.1257 + return path.substring(path.lastIndexOf('/') + 1); 6.1258 + } else { 6.1259 + return uri.toString(); 6.1260 + } 6.1261 + } 6.1262 + 6.1263 + private static <T> T nullCheck(T o) { 6.1264 + o.getClass(); // null check 6.1265 + return o; 6.1266 + } 6.1267 + 6.1268 + private static <T> Iterable<T> nullCheck(Iterable<T> it) { 6.1269 + for (T t : it) 6.1270 + t.getClass(); // null check 6.1271 + return it; 6.1272 + } 6.1273 + 6.1274 + /** 6.1275 + * A subclass of JavaFileObject representing regular files. 6.1276 + */ 6.1277 + private class RegularFileObject extends BaseFileObject { 6.1278 + /** Have the parent directories been created? 6.1279 + */ 6.1280 + private boolean hasParents=false; 6.1281 + 6.1282 + /** The file's name. 6.1283 + */ 6.1284 + private String name; 6.1285 + 6.1286 + /** The underlying file. 6.1287 + */ 6.1288 + final File f; 6.1289 + 6.1290 + public RegularFileObject(File f) { 6.1291 + this(f.getName(), f); 6.1292 + } 6.1293 + 6.1294 + public RegularFileObject(String name, File f) { 6.1295 + if (f.isDirectory()) 6.1296 + throw new IllegalArgumentException("directories not supported"); 6.1297 + this.name = name; 6.1298 + this.f = f; 6.1299 + } 6.1300 + 6.1301 + public InputStream openInputStream() throws IOException { 6.1302 + return new FileInputStream(f); 6.1303 + } 6.1304 + 6.1305 + protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) { 6.1306 + return JavacFileManager.this.getDecoder(getEncodingName(), ignoreEncodingErrors); 6.1307 + } 6.1308 + 6.1309 + public OutputStream openOutputStream() throws IOException { 6.1310 + ensureParentDirectoriesExist(); 6.1311 + return new FileOutputStream(f); 6.1312 + } 6.1313 + 6.1314 + public Writer openWriter() throws IOException { 6.1315 + ensureParentDirectoriesExist(); 6.1316 + return new OutputStreamWriter(new FileOutputStream(f), getEncodingName()); 6.1317 + } 6.1318 + 6.1319 + private void ensureParentDirectoriesExist() throws IOException { 6.1320 + if (!hasParents) { 6.1321 + File parent = f.getParentFile(); 6.1322 + if (parent != null && !parent.exists()) { 6.1323 + if (!parent.mkdirs()) { 6.1324 + // if the mkdirs failed, it may be because another process concurrently 6.1325 + // created the directory, so check if the directory got created 6.1326 + // anyway before throwing an exception 6.1327 + if (!parent.exists() || !parent.isDirectory()) 6.1328 + throw new IOException("could not create parent directories"); 6.1329 + } 6.1330 + } 6.1331 + hasParents = true; 6.1332 + } 6.1333 + } 6.1334 + 6.1335 + /** @deprecated see bug 6410637 */ 6.1336 + @Deprecated 6.1337 + public String getName() { 6.1338 + return name; 6.1339 + } 6.1340 + 6.1341 + public boolean isNameCompatible(String cn, JavaFileObject.Kind kind) { 6.1342 + cn.getClass(); // null check 6.1343 + if (kind == Kind.OTHER && getKind() != kind) 6.1344 + return false; 6.1345 + String n = cn + kind.extension; 6.1346 + if (name.equals(n)) 6.1347 + return true; 6.1348 + if (name.equalsIgnoreCase(n)) { 6.1349 + try { 6.1350 + // allow for Windows 6.1351 + return (f.getCanonicalFile().getName().equals(n)); 6.1352 + } catch (IOException e) { 6.1353 + } 6.1354 + } 6.1355 + return false; 6.1356 + } 6.1357 + 6.1358 + /** @deprecated see bug 6410637 */ 6.1359 + @Deprecated 6.1360 + public String getPath() { 6.1361 + return f.getPath(); 6.1362 + } 6.1363 + 6.1364 + public long getLastModified() { 6.1365 + return f.lastModified(); 6.1366 + } 6.1367 + 6.1368 + public boolean delete() { 6.1369 + return f.delete(); 6.1370 + } 6.1371 + 6.1372 + public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException { 6.1373 + SoftReference<CharBuffer> r = contentCache.get(this); 6.1374 + CharBuffer cb = (r == null ? null : r.get()); 6.1375 + if (cb == null) { 6.1376 + InputStream in = new FileInputStream(f); 6.1377 + try { 6.1378 + ByteBuffer bb = makeByteBuffer(in); 6.1379 + JavaFileObject prev = log.useSource(this); 6.1380 + try { 6.1381 + cb = decode(bb, ignoreEncodingErrors); 6.1382 + } finally { 6.1383 + log.useSource(prev); 6.1384 + } 6.1385 + byteBufferCache.put(bb); // save for next time 6.1386 + if (!ignoreEncodingErrors) 6.1387 + contentCache.put(this, new SoftReference<CharBuffer>(cb)); 6.1388 + } finally { 6.1389 + in.close(); 6.1390 + } 6.1391 + } 6.1392 + return cb; 6.1393 + } 6.1394 + 6.1395 + @Override 6.1396 + public boolean equals(Object other) { 6.1397 + if (!(other instanceof RegularFileObject)) 6.1398 + return false; 6.1399 + RegularFileObject o = (RegularFileObject) other; 6.1400 + try { 6.1401 + return f.equals(o.f) 6.1402 + || f.getCanonicalFile().equals(o.f.getCanonicalFile()); 6.1403 + } catch (IOException e) { 6.1404 + return false; 6.1405 + } 6.1406 + } 6.1407 + 6.1408 + @Override 6.1409 + public int hashCode() { 6.1410 + return f.hashCode(); 6.1411 + } 6.1412 + 6.1413 + public URI toUri() { 6.1414 + try { 6.1415 + // Do no use File.toURI to avoid file system access 6.1416 + String path = f.getAbsolutePath().replace(File.separatorChar, '/'); 6.1417 + return new URI("file://" + path).normalize(); 6.1418 + } catch (URISyntaxException ex) { 6.1419 + return f.toURI(); 6.1420 + } 6.1421 + } 6.1422 + 6.1423 + } 6.1424 + 6.1425 + /** 6.1426 + * A subclass of JavaFileObject representing zip entries. 6.1427 + */ 6.1428 + public class ZipFileObject extends BaseFileObject { 6.1429 + 6.1430 + /** The entry's name. 6.1431 + */ 6.1432 + private String name; 6.1433 + 6.1434 + /** The zipfile containing the entry. 6.1435 + */ 6.1436 + ZipFile zdir; 6.1437 + 6.1438 + /** The underlying zip entry object. 6.1439 + */ 6.1440 + ZipEntry entry; 6.1441 + 6.1442 + public ZipFileObject(String name, ZipFile zdir, ZipEntry entry) { 6.1443 + this.name = name; 6.1444 + this.zdir = zdir; 6.1445 + this.entry = entry; 6.1446 + } 6.1447 + 6.1448 + public InputStream openInputStream() throws IOException { 6.1449 + return zdir.getInputStream(entry); 6.1450 + } 6.1451 + 6.1452 + public OutputStream openOutputStream() throws IOException { 6.1453 + throw new UnsupportedOperationException(); 6.1454 + } 6.1455 + 6.1456 + protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) { 6.1457 + return JavacFileManager.this.getDecoder(getEncodingName(), ignoreEncodingErrors); 6.1458 + } 6.1459 + 6.1460 + public Writer openWriter() throws IOException { 6.1461 + throw new UnsupportedOperationException(); 6.1462 + } 6.1463 + 6.1464 + /** @deprecated see bug 6410637 */ 6.1465 + @Deprecated 6.1466 + public String getName() { 6.1467 + return name; 6.1468 + } 6.1469 + 6.1470 + public boolean isNameCompatible(String cn, JavaFileObject.Kind k) { 6.1471 + cn.getClass(); // null check 6.1472 + if (k == Kind.OTHER && getKind() != k) 6.1473 + return false; 6.1474 + return name.equals(cn + k.extension); 6.1475 + } 6.1476 + 6.1477 + /** @deprecated see bug 6410637 */ 6.1478 + @Deprecated 6.1479 + public String getPath() { 6.1480 + return zdir.getName() + "(" + entry + ")"; 6.1481 + } 6.1482 + 6.1483 + public long getLastModified() { 6.1484 + return entry.getTime(); 6.1485 + } 6.1486 + 6.1487 + public boolean delete() { 6.1488 + throw new UnsupportedOperationException(); 6.1489 + } 6.1490 + 6.1491 + public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException { 6.1492 + SoftReference<CharBuffer> r = contentCache.get(this); 6.1493 + CharBuffer cb = (r == null ? null : r.get()); 6.1494 + if (cb == null) { 6.1495 + InputStream in = zdir.getInputStream(entry); 6.1496 + try { 6.1497 + ByteBuffer bb = makeByteBuffer(in); 6.1498 + JavaFileObject prev = log.useSource(this); 6.1499 + try { 6.1500 + cb = decode(bb, ignoreEncodingErrors); 6.1501 + } finally { 6.1502 + log.useSource(prev); 6.1503 + } 6.1504 + byteBufferCache.put(bb); // save for next time 6.1505 + if (!ignoreEncodingErrors) 6.1506 + contentCache.put(this, new SoftReference<CharBuffer>(cb)); 6.1507 + } finally { 6.1508 + in.close(); 6.1509 + } 6.1510 + } 6.1511 + return cb; 6.1512 + } 6.1513 + 6.1514 + @Override 6.1515 + public boolean equals(Object other) { 6.1516 + if (!(other instanceof ZipFileObject)) 6.1517 + return false; 6.1518 + ZipFileObject o = (ZipFileObject) other; 6.1519 + return zdir.equals(o.zdir) || name.equals(o.name); 6.1520 + } 6.1521 + 6.1522 + @Override 6.1523 + public int hashCode() { 6.1524 + return zdir.hashCode() + name.hashCode(); 6.1525 + } 6.1526 + 6.1527 + public String getZipName() { 6.1528 + return zdir.getName(); 6.1529 + } 6.1530 + 6.1531 + public String getZipEntryName() { 6.1532 + return entry.getName(); 6.1533 + } 6.1534 + 6.1535 + public URI toUri() { 6.1536 + String zipName = new File(getZipName()).toURI().normalize().getPath(); 6.1537 + String entryName = getZipEntryName(); 6.1538 + return URI.create("jar:" + zipName + "!" + entryName); 6.1539 + } 6.1540 + 6.1541 + } 6.1542 + 6.1543 + /** 6.1544 + * A subclass of JavaFileObject representing zip entries using the com.sun.tools.javac.zip.ZipFileIndex implementation. 6.1545 + */ 6.1546 + public class ZipFileIndexFileObject extends BaseFileObject { 6.1547 + 6.1548 + /** The entry's name. 6.1549 + */ 6.1550 + private String name; 6.1551 + 6.1552 + /** The zipfile containing the entry. 6.1553 + */ 6.1554 + ZipFileIndex zfIndex; 6.1555 + 6.1556 + /** The underlying zip entry object. 6.1557 + */ 6.1558 + ZipFileIndexEntry entry; 6.1559 + 6.1560 + /** The InputStream for this zip entry (file.) 6.1561 + */ 6.1562 + InputStream inputStream = null; 6.1563 + 6.1564 + /** The name of the zip file where this entry resides. 6.1565 + */ 6.1566 + String zipName; 6.1567 + 6.1568 + JavacFileManager defFileManager = null; 6.1569 + 6.1570 + public ZipFileIndexFileObject(JavacFileManager fileManager, ZipFileIndex zfIndex, ZipFileIndexEntry entry, String zipFileName) { 6.1571 + super(); 6.1572 + this.name = entry.getFileName(); 6.1573 + this.zfIndex = zfIndex; 6.1574 + this.entry = entry; 6.1575 + this.zipName = zipFileName; 6.1576 + defFileManager = fileManager; 6.1577 + } 6.1578 + 6.1579 + public InputStream openInputStream() throws IOException { 6.1580 + 6.1581 + if (inputStream == null) { 6.1582 + inputStream = new ByteArrayInputStream(read()); 6.1583 + } 6.1584 + return inputStream; 6.1585 + } 6.1586 + 6.1587 + protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) { 6.1588 + return JavacFileManager.this.getDecoder(getEncodingName(), ignoreEncodingErrors); 6.1589 + } 6.1590 + 6.1591 + public OutputStream openOutputStream() throws IOException { 6.1592 + throw new UnsupportedOperationException(); 6.1593 + } 6.1594 + 6.1595 + public Writer openWriter() throws IOException { 6.1596 + throw new UnsupportedOperationException(); 6.1597 + } 6.1598 + 6.1599 + /** @deprecated see bug 6410637 */ 6.1600 + @Deprecated 6.1601 + public String getName() { 6.1602 + return name; 6.1603 + } 6.1604 + 6.1605 + public boolean isNameCompatible(String cn, JavaFileObject.Kind k) { 6.1606 + cn.getClass(); // null check 6.1607 + if (k == Kind.OTHER && getKind() != k) 6.1608 + return false; 6.1609 + return name.equals(cn + k.extension); 6.1610 + } 6.1611 + 6.1612 + /** @deprecated see bug 6410637 */ 6.1613 + @Deprecated 6.1614 + public String getPath() { 6.1615 + return zipName + "(" + entry.getName() + ")"; 6.1616 + } 6.1617 + 6.1618 + public long getLastModified() { 6.1619 + return entry.getLastModified(); 6.1620 + } 6.1621 + 6.1622 + public boolean delete() { 6.1623 + throw new UnsupportedOperationException(); 6.1624 + } 6.1625 + 6.1626 + @Override 6.1627 + public boolean equals(Object other) { 6.1628 + if (!(other instanceof ZipFileIndexFileObject)) 6.1629 + return false; 6.1630 + ZipFileIndexFileObject o = (ZipFileIndexFileObject) other; 6.1631 + return entry.equals(o.entry); 6.1632 + } 6.1633 + 6.1634 + @Override 6.1635 + public int hashCode() { 6.1636 + return zipName.hashCode() + (name.hashCode() << 10); 6.1637 + } 6.1638 + 6.1639 + public String getZipName() { 6.1640 + return zipName; 6.1641 + } 6.1642 + 6.1643 + public String getZipEntryName() { 6.1644 + return entry.getName(); 6.1645 + } 6.1646 + 6.1647 + public URI toUri() { 6.1648 + String zipName = new File(getZipName()).toURI().normalize().getPath(); 6.1649 + String entryName = getZipEntryName(); 6.1650 + if (File.separatorChar != '/') { 6.1651 + entryName = entryName.replace(File.separatorChar, '/'); 6.1652 + } 6.1653 + return URI.create("jar:" + zipName + "!" + entryName); 6.1654 + } 6.1655 + 6.1656 + private byte[] read() throws IOException { 6.1657 + if (entry == null) { 6.1658 + entry = zfIndex.getZipIndexEntry(name); 6.1659 + if (entry == null) 6.1660 + throw new FileNotFoundException(); 6.1661 + } 6.1662 + return zfIndex.read(entry); 6.1663 + } 6.1664 + 6.1665 + public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException { 6.1666 + SoftReference<CharBuffer> r = defFileManager.contentCache.get(this); 6.1667 + CharBuffer cb = (r == null ? null : r.get()); 6.1668 + if (cb == null) { 6.1669 + InputStream in = new ByteArrayInputStream(zfIndex.read(entry)); 6.1670 + try { 6.1671 + ByteBuffer bb = makeByteBuffer(in); 6.1672 + JavaFileObject prev = log.useSource(this); 6.1673 + try { 6.1674 + cb = decode(bb, ignoreEncodingErrors); 6.1675 + } finally { 6.1676 + log.useSource(prev); 6.1677 + } 6.1678 + byteBufferCache.put(bb); // save for next time 6.1679 + if (!ignoreEncodingErrors) 6.1680 + defFileManager.contentCache.put(this, new SoftReference<CharBuffer>(cb)); 6.1681 + } finally { 6.1682 + in.close(); 6.1683 + } 6.1684 + } 6.1685 + return cb; 6.1686 + } 6.1687 + } 6.1688 + 6.1689 + public class ZipFileIndexArchive implements Archive { 6.1690 + private final ZipFileIndex zfIndex; 6.1691 + private JavacFileManager fileManager; 6.1692 + 6.1693 + public ZipFileIndexArchive(JavacFileManager fileManager, ZipFileIndex zdir) throws IOException { 6.1694 + this.fileManager = fileManager; 6.1695 + this.zfIndex = zdir; 6.1696 + } 6.1697 + 6.1698 + public boolean contains(String name) { 6.1699 + return zfIndex.contains(name); 6.1700 + } 6.1701 + 6.1702 + public com.sun.tools.javac.util.List<String> getFiles(String subdirectory) { 6.1703 + return zfIndex.getFiles(((subdirectory.endsWith("/") || subdirectory.endsWith("\\"))? subdirectory.substring(0, subdirectory.length() - 1) : subdirectory)); 6.1704 + } 6.1705 + 6.1706 + public JavaFileObject getFileObject(String subdirectory, String file) { 6.1707 + String fullZipFileName = subdirectory + file; 6.1708 + ZipFileIndexEntry entry = zfIndex.getZipIndexEntry(fullZipFileName); 6.1709 + JavaFileObject ret = new ZipFileIndexFileObject(fileManager, zfIndex, entry, zfIndex.getZipFile().getPath()); 6.1710 + return ret; 6.1711 + } 6.1712 + 6.1713 + public Set<String> getSubdirectories() { 6.1714 + return zfIndex.getAllDirectories(); 6.1715 + } 6.1716 + 6.1717 + public void close() throws IOException { 6.1718 + zfIndex.close(); 6.1719 + } 6.1720 + } 6.1721 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/src/share/classes/com/sun/tools/javac/file/Old199.java Mon Jun 16 13:28:00 2008 -0700 7.3 @@ -0,0 +1,54 @@ 7.4 +/* 7.5 + * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. 7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.7 + * 7.8 + * This code is free software; you can redistribute it and/or modify it 7.9 + * under the terms of the GNU General Public License version 2 only, as 7.10 + * published by the Free Software Foundation. Sun designates this 7.11 + * particular file as subject to the "Classpath" exception as provided 7.12 + * by Sun in the LICENSE file that accompanied this code. 7.13 + * 7.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 7.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 7.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 7.17 + * version 2 for more details (a copy is included in the LICENSE file that 7.18 + * accompanied this code). 7.19 + * 7.20 + * You should have received a copy of the GNU General Public License version 7.21 + * 2 along with this work; if not, write to the Free Software Foundation, 7.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 7.23 + * 7.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 7.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 7.26 + * have any questions. 7.27 + */ 7.28 + 7.29 +package com.sun.tools.javac.file; 7.30 + 7.31 +import javax.tools.FileObject; 7.32 + 7.33 +/** 7.34 + * Provides an easy migration to JSR 199 v3.3. The class is 7.35 + * deprecated as we should remove it as soon as possible. 7.36 + * 7.37 + * <p><b>This is NOT part of any API supported by Sun Microsystems. 7.38 + * If you write code that depends on this, you do so at your own 7.39 + * risk. This code and its internal interfaces are subject to change 7.40 + * or deletion without notice.</b></p> 7.41 + * 7.42 + * @author Peter von der Ah\u00e9 7.43 + */ 7.44 +@Deprecated 7.45 +public class Old199 { 7.46 + 7.47 + private Old199() {} 7.48 + 7.49 + public static String getPath(FileObject jfo) { 7.50 + return JavacFileManager.getJavacFileName(jfo); 7.51 + } 7.52 + 7.53 + public static String getName(FileObject jfo) { 7.54 + return JavacFileManager.getJavacBaseFileName(jfo); 7.55 + } 7.56 + 7.57 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/share/classes/com/sun/tools/javac/file/Paths.java Mon Jun 16 13:28:00 2008 -0700 8.3 @@ -0,0 +1,577 @@ 8.4 +/* 8.5 + * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. 8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.7 + * 8.8 + * This code is free software; you can redistribute it and/or modify it 8.9 + * under the terms of the GNU General Public License version 2 only, as 8.10 + * published by the Free Software Foundation. Sun designates this 8.11 + * particular file as subject to the "Classpath" exception as provided 8.12 + * by Sun in the LICENSE file that accompanied this code. 8.13 + * 8.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 8.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 8.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 8.17 + * version 2 for more details (a copy is included in the LICENSE file that 8.18 + * accompanied this code). 8.19 + * 8.20 + * You should have received a copy of the GNU General Public License version 8.21 + * 2 along with this work; if not, write to the Free Software Foundation, 8.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 8.23 + * 8.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 8.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 8.26 + * have any questions. 8.27 + */ 8.28 + 8.29 +package com.sun.tools.javac.file; 8.30 + 8.31 +import java.io.File; 8.32 +import java.io.IOException; 8.33 +import java.util.HashMap; 8.34 +import java.util.HashSet; 8.35 +import java.util.Map; 8.36 +import java.util.Set; 8.37 +import java.util.jar.JarFile; 8.38 +import java.util.jar.Manifest; 8.39 +import java.util.jar.Attributes; 8.40 +import java.util.Collection; 8.41 +import java.util.Collections; 8.42 +import java.util.LinkedHashSet; 8.43 +import java.util.Iterator; 8.44 +import java.util.StringTokenizer; 8.45 +import java.util.zip.ZipFile; 8.46 +import java.util.ArrayList; 8.47 +import java.util.concurrent.ConcurrentHashMap; 8.48 +import java.util.concurrent.locks.Lock; 8.49 +import java.util.concurrent.locks.ReentrantLock; 8.50 +import javax.tools.JavaFileManager.Location; 8.51 + 8.52 +import com.sun.tools.javac.code.Lint; 8.53 +import com.sun.tools.javac.util.Context; 8.54 +import com.sun.tools.javac.util.Log; 8.55 +import com.sun.tools.javac.util.Options; 8.56 + 8.57 +import static javax.tools.StandardLocation.*; 8.58 +import static com.sun.tools.javac.main.OptionName.*; 8.59 + 8.60 +/** This class converts command line arguments, environment variables 8.61 + * and system properties (in File.pathSeparator-separated String form) 8.62 + * into a boot class path, user class path, and source path (in 8.63 + * Collection<String> form). 8.64 + * 8.65 + * <p><b>This is NOT part of any API supported by Sun Microsystems. If 8.66 + * you write code that depends on this, you do so at your own risk. 8.67 + * This code and its internal interfaces are subject to change or 8.68 + * deletion without notice.</b> 8.69 + */ 8.70 +public class Paths { 8.71 + 8.72 + /** The context key for the todo list */ 8.73 + protected static final Context.Key<Paths> pathsKey = 8.74 + new Context.Key<Paths>(); 8.75 + 8.76 + /** Get the Paths instance for this context. 8.77 + * @param context the context 8.78 + * @return the Paths instance for this context 8.79 + */ 8.80 + public static Paths instance(Context context) { 8.81 + Paths instance = context.get(pathsKey); 8.82 + if (instance == null) 8.83 + instance = new Paths(context); 8.84 + return instance; 8.85 + } 8.86 + 8.87 + /** The log to use for warning output */ 8.88 + private Log log; 8.89 + 8.90 + /** Collection of command-line options */ 8.91 + private Options options; 8.92 + 8.93 + /** Handler for -Xlint options */ 8.94 + private Lint lint; 8.95 + 8.96 + private static boolean NON_BATCH_MODE = System.getProperty("nonBatchMode") != null;// TODO: Use -XD compiler switch for this. 8.97 + private static Map<File, PathEntry> pathExistanceCache = new ConcurrentHashMap<File, PathEntry>(); 8.98 + private static Map<File, java.util.List<File>> manifestEntries = new ConcurrentHashMap<File, java.util.List<File>>(); 8.99 + private static Map<File, Boolean> isDirectory = new ConcurrentHashMap<File, Boolean>(); 8.100 + private static Lock lock = new ReentrantLock(); 8.101 + 8.102 + public static void clearPathExistanceCache() { 8.103 + pathExistanceCache.clear(); 8.104 + } 8.105 + 8.106 + static class PathEntry { 8.107 + boolean exists = false; 8.108 + boolean isFile = false; 8.109 + File cannonicalPath = null; 8.110 + } 8.111 + 8.112 + protected Paths(Context context) { 8.113 + context.put(pathsKey, this); 8.114 + pathsForLocation = new HashMap<Location,Path>(16); 8.115 + setContext(context); 8.116 + } 8.117 + 8.118 + void setContext(Context context) { 8.119 + log = Log.instance(context); 8.120 + options = Options.instance(context); 8.121 + lint = Lint.instance(context); 8.122 + } 8.123 + 8.124 + /** Whether to warn about non-existent path elements */ 8.125 + private boolean warn; 8.126 + 8.127 + private Map<Location, Path> pathsForLocation; 8.128 + 8.129 + private boolean inited = false; // TODO? caching bad? 8.130 + 8.131 + /** 8.132 + * rt.jar as found on the default bootclass path. If the user specified a 8.133 + * bootclasspath, null is used. 8.134 + */ 8.135 + private File bootClassPathRtJar = null; 8.136 + 8.137 + Path getPathForLocation(Location location) { 8.138 + Path path = pathsForLocation.get(location); 8.139 + if (path == null) 8.140 + setPathForLocation(location, null); 8.141 + return pathsForLocation.get(location); 8.142 + } 8.143 + 8.144 + void setPathForLocation(Location location, Iterable<? extends File> path) { 8.145 + // TODO? if (inited) throw new IllegalStateException 8.146 + // TODO: otherwise reset sourceSearchPath, classSearchPath as needed 8.147 + Path p; 8.148 + if (path == null) { 8.149 + if (location == CLASS_PATH) 8.150 + p = computeUserClassPath(); 8.151 + else if (location == PLATFORM_CLASS_PATH) 8.152 + p = computeBootClassPath(); 8.153 + else if (location == ANNOTATION_PROCESSOR_PATH) 8.154 + p = computeAnnotationProcessorPath(); 8.155 + else if (location == SOURCE_PATH) 8.156 + p = computeSourcePath(); 8.157 + else 8.158 + // no defaults for other paths 8.159 + p = null; 8.160 + } else { 8.161 + p = new Path(); 8.162 + for (File f: path) 8.163 + p.addFile(f, warn); // TODO: is use of warn appropriate? 8.164 + } 8.165 + pathsForLocation.put(location, p); 8.166 + } 8.167 + 8.168 + protected void lazy() { 8.169 + if (!inited) { 8.170 + warn = lint.isEnabled(Lint.LintCategory.PATH); 8.171 + 8.172 + pathsForLocation.put(PLATFORM_CLASS_PATH, computeBootClassPath()); 8.173 + pathsForLocation.put(CLASS_PATH, computeUserClassPath()); 8.174 + pathsForLocation.put(SOURCE_PATH, computeSourcePath()); 8.175 + 8.176 + inited = true; 8.177 + } 8.178 + } 8.179 + 8.180 + public Collection<File> bootClassPath() { 8.181 + lazy(); 8.182 + return Collections.unmodifiableCollection(getPathForLocation(PLATFORM_CLASS_PATH)); 8.183 + } 8.184 + public Collection<File> userClassPath() { 8.185 + lazy(); 8.186 + return Collections.unmodifiableCollection(getPathForLocation(CLASS_PATH)); 8.187 + } 8.188 + public Collection<File> sourcePath() { 8.189 + lazy(); 8.190 + Path p = getPathForLocation(SOURCE_PATH); 8.191 + return p == null || p.size() == 0 8.192 + ? null 8.193 + : Collections.unmodifiableCollection(p); 8.194 + } 8.195 + 8.196 + boolean isBootClassPathRtJar(File file) { 8.197 + return file.equals(bootClassPathRtJar); 8.198 + } 8.199 + 8.200 + private static class PathIterator implements Iterable<String> { 8.201 + private int pos = 0; 8.202 + private final String path; 8.203 + private final String emptyPathDefault; 8.204 + 8.205 + public PathIterator(String path, String emptyPathDefault) { 8.206 + this.path = path; 8.207 + this.emptyPathDefault = emptyPathDefault; 8.208 + } 8.209 + public PathIterator(String path) { this(path, null); } 8.210 + public Iterator<String> iterator() { 8.211 + return new Iterator<String>() { 8.212 + public boolean hasNext() { 8.213 + return pos <= path.length(); 8.214 + } 8.215 + public String next() { 8.216 + int beg = pos; 8.217 + int end = path.indexOf(File.pathSeparator, beg); 8.218 + if (end == -1) 8.219 + end = path.length(); 8.220 + pos = end + 1; 8.221 + 8.222 + if (beg == end && emptyPathDefault != null) 8.223 + return emptyPathDefault; 8.224 + else 8.225 + return path.substring(beg, end); 8.226 + } 8.227 + public void remove() { 8.228 + throw new UnsupportedOperationException(); 8.229 + } 8.230 + }; 8.231 + } 8.232 + } 8.233 + 8.234 + private class Path extends LinkedHashSet<File> { 8.235 + private static final long serialVersionUID = 0; 8.236 + 8.237 + private boolean expandJarClassPaths = false; 8.238 + private Set<File> canonicalValues = new HashSet<File>(); 8.239 + 8.240 + public Path expandJarClassPaths(boolean x) { 8.241 + expandJarClassPaths = x; 8.242 + return this; 8.243 + } 8.244 + 8.245 + /** What to use when path element is the empty string */ 8.246 + private String emptyPathDefault = null; 8.247 + 8.248 + public Path emptyPathDefault(String x) { 8.249 + emptyPathDefault = x; 8.250 + return this; 8.251 + } 8.252 + 8.253 + public Path() { super(); } 8.254 + 8.255 + public Path addDirectories(String dirs, boolean warn) { 8.256 + if (dirs != null) 8.257 + for (String dir : new PathIterator(dirs)) 8.258 + addDirectory(dir, warn); 8.259 + return this; 8.260 + } 8.261 + 8.262 + public Path addDirectories(String dirs) { 8.263 + return addDirectories(dirs, warn); 8.264 + } 8.265 + 8.266 + private void addDirectory(String dir, boolean warn) { 8.267 + if (! new File(dir).isDirectory()) { 8.268 + if (warn) 8.269 + log.warning("dir.path.element.not.found", dir); 8.270 + return; 8.271 + } 8.272 + 8.273 + File[] files = new File(dir).listFiles(); 8.274 + if (files == null) 8.275 + return; 8.276 + 8.277 + for (File direntry : files) { 8.278 + if (isArchive(direntry)) 8.279 + addFile(direntry, warn); 8.280 + } 8.281 + } 8.282 + 8.283 + public Path addFiles(String files, boolean warn) { 8.284 + if (files != null) 8.285 + for (String file : new PathIterator(files, emptyPathDefault)) 8.286 + addFile(file, warn); 8.287 + return this; 8.288 + } 8.289 + 8.290 + public Path addFiles(String files) { 8.291 + return addFiles(files, warn); 8.292 + } 8.293 + 8.294 + public Path addFile(String file, boolean warn) { 8.295 + addFile(new File(file), warn); 8.296 + return this; 8.297 + } 8.298 + 8.299 + public void addFile(File file, boolean warn) { 8.300 + boolean foundInCache = false; 8.301 + PathEntry pe = null; 8.302 + if (!NON_BATCH_MODE) { 8.303 + pe = pathExistanceCache.get(file); 8.304 + if (pe != null) { 8.305 + foundInCache = true; 8.306 + } 8.307 + else { 8.308 + pe = new PathEntry(); 8.309 + } 8.310 + } 8.311 + else { 8.312 + pe = new PathEntry(); 8.313 + } 8.314 + 8.315 + File canonFile; 8.316 + try { 8.317 + if (!foundInCache) { 8.318 + pe.cannonicalPath = file.getCanonicalFile(); 8.319 + } 8.320 + else { 8.321 + canonFile = pe.cannonicalPath; 8.322 + } 8.323 + } catch (IOException e) { 8.324 + pe.cannonicalPath = canonFile = file; 8.325 + } 8.326 + 8.327 + if (contains(file) || canonicalValues.contains(pe.cannonicalPath)) { 8.328 + /* Discard duplicates and avoid infinite recursion */ 8.329 + return; 8.330 + } 8.331 + 8.332 + if (!foundInCache) { 8.333 + pe.exists = file.exists(); 8.334 + pe.isFile = file.isFile(); 8.335 + if (!NON_BATCH_MODE) { 8.336 + pathExistanceCache.put(file, pe); 8.337 + } 8.338 + } 8.339 + 8.340 + if (! pe.exists) { 8.341 + /* No such file or directory exists */ 8.342 + if (warn) 8.343 + log.warning("path.element.not.found", file); 8.344 + } else if (pe.isFile) { 8.345 + /* File is an ordinary file. */ 8.346 + if (!isArchive(file)) { 8.347 + /* Not a recognized extension; open it to see if 8.348 + it looks like a valid zip file. */ 8.349 + try { 8.350 + ZipFile z = new ZipFile(file); 8.351 + z.close(); 8.352 + if (warn) 8.353 + log.warning("unexpected.archive.file", file); 8.354 + } catch (IOException e) { 8.355 + // FIXME: include e.getLocalizedMessage in warning 8.356 + if (warn) 8.357 + log.warning("invalid.archive.file", file); 8.358 + return; 8.359 + } 8.360 + } 8.361 + } 8.362 + 8.363 + /* Now what we have left is either a directory or a file name 8.364 + confirming to archive naming convention */ 8.365 + super.add(file); 8.366 + canonicalValues.add(pe.cannonicalPath); 8.367 + 8.368 + if (expandJarClassPaths && file.exists() && file.isFile()) 8.369 + addJarClassPath(file, warn); 8.370 + } 8.371 + 8.372 + // Adds referenced classpath elements from a jar's Class-Path 8.373 + // Manifest entry. In some future release, we may want to 8.374 + // update this code to recognize URLs rather than simple 8.375 + // filenames, but if we do, we should redo all path-related code. 8.376 + private void addJarClassPath(File jarFile, boolean warn) { 8.377 + try { 8.378 + java.util.List<File> manifestsList = manifestEntries.get(jarFile); 8.379 + if (!NON_BATCH_MODE) { 8.380 + lock.lock(); 8.381 + try { 8.382 + if (manifestsList != null) { 8.383 + for (File entr : manifestsList) { 8.384 + addFile(entr, warn); 8.385 + } 8.386 + return; 8.387 + } 8.388 + } 8.389 + finally { 8.390 + lock.unlock(); 8.391 + } 8.392 + } 8.393 + 8.394 + if (!NON_BATCH_MODE) { 8.395 + manifestsList = new ArrayList<File>(); 8.396 + manifestEntries.put(jarFile, manifestsList); 8.397 + } 8.398 + 8.399 + String jarParent = jarFile.getParent(); 8.400 + JarFile jar = new JarFile(jarFile); 8.401 + 8.402 + try { 8.403 + Manifest man = jar.getManifest(); 8.404 + if (man == null) return; 8.405 + 8.406 + Attributes attr = man.getMainAttributes(); 8.407 + if (attr == null) return; 8.408 + 8.409 + String path = attr.getValue(Attributes.Name.CLASS_PATH); 8.410 + if (path == null) return; 8.411 + 8.412 + for (StringTokenizer st = new StringTokenizer(path); 8.413 + st.hasMoreTokens();) { 8.414 + String elt = st.nextToken(); 8.415 + File f = (jarParent == null ? new File(elt) : new File(jarParent, elt)); 8.416 + addFile(f, warn); 8.417 + 8.418 + if (!NON_BATCH_MODE) { 8.419 + lock.lock(); 8.420 + try { 8.421 + manifestsList.add(f); 8.422 + } 8.423 + finally { 8.424 + lock.unlock(); 8.425 + } 8.426 + } 8.427 + } 8.428 + } finally { 8.429 + jar.close(); 8.430 + } 8.431 + } catch (IOException e) { 8.432 + log.error("error.reading.file", jarFile, e.getLocalizedMessage()); 8.433 + } 8.434 + } 8.435 + } 8.436 + 8.437 + private Path computeBootClassPath() { 8.438 + bootClassPathRtJar = null; 8.439 + String optionValue; 8.440 + Path path = new Path(); 8.441 + 8.442 + path.addFiles(options.get(XBOOTCLASSPATH_PREPEND)); 8.443 + 8.444 + if ((optionValue = options.get(ENDORSEDDIRS)) != null) 8.445 + path.addDirectories(optionValue); 8.446 + else 8.447 + path.addDirectories(System.getProperty("java.endorsed.dirs"), false); 8.448 + 8.449 + if ((optionValue = options.get(BOOTCLASSPATH)) != null) { 8.450 + path.addFiles(optionValue); 8.451 + } else { 8.452 + // Standard system classes for this compiler's release. 8.453 + String files = System.getProperty("sun.boot.class.path"); 8.454 + path.addFiles(files, false); 8.455 + File rt_jar = new File("rt.jar"); 8.456 + for (String file : new PathIterator(files, null)) { 8.457 + File f = new File(file); 8.458 + if (new File(f.getName()).equals(rt_jar)) 8.459 + bootClassPathRtJar = f; 8.460 + } 8.461 + } 8.462 + 8.463 + path.addFiles(options.get(XBOOTCLASSPATH_APPEND)); 8.464 + 8.465 + // Strictly speaking, standard extensions are not bootstrap 8.466 + // classes, but we treat them identically, so we'll pretend 8.467 + // that they are. 8.468 + if ((optionValue = options.get(EXTDIRS)) != null) 8.469 + path.addDirectories(optionValue); 8.470 + else 8.471 + path.addDirectories(System.getProperty("java.ext.dirs"), false); 8.472 + 8.473 + return path; 8.474 + } 8.475 + 8.476 + private Path computeUserClassPath() { 8.477 + String cp = options.get(CLASSPATH); 8.478 + 8.479 + // CLASSPATH environment variable when run from `javac'. 8.480 + if (cp == null) cp = System.getProperty("env.class.path"); 8.481 + 8.482 + // If invoked via a java VM (not the javac launcher), use the 8.483 + // platform class path 8.484 + if (cp == null && System.getProperty("application.home") == null) 8.485 + cp = System.getProperty("java.class.path"); 8.486 + 8.487 + // Default to current working directory. 8.488 + if (cp == null) cp = "."; 8.489 + 8.490 + return new Path() 8.491 + .expandJarClassPaths(true) // Only search user jars for Class-Paths 8.492 + .emptyPathDefault(".") // Empty path elt ==> current directory 8.493 + .addFiles(cp); 8.494 + } 8.495 + 8.496 + private Path computeSourcePath() { 8.497 + String sourcePathArg = options.get(SOURCEPATH); 8.498 + if (sourcePathArg == null) 8.499 + return null; 8.500 + 8.501 + return new Path().addFiles(sourcePathArg); 8.502 + } 8.503 + 8.504 + private Path computeAnnotationProcessorPath() { 8.505 + String processorPathArg = options.get(PROCESSORPATH); 8.506 + if (processorPathArg == null) 8.507 + return null; 8.508 + 8.509 + return new Path().addFiles(processorPathArg); 8.510 + } 8.511 + 8.512 + /** The actual effective locations searched for sources */ 8.513 + private Path sourceSearchPath; 8.514 + 8.515 + public Collection<File> sourceSearchPath() { 8.516 + if (sourceSearchPath == null) { 8.517 + lazy(); 8.518 + Path sourcePath = getPathForLocation(SOURCE_PATH); 8.519 + Path userClassPath = getPathForLocation(CLASS_PATH); 8.520 + sourceSearchPath = sourcePath != null ? sourcePath : userClassPath; 8.521 + } 8.522 + return Collections.unmodifiableCollection(sourceSearchPath); 8.523 + } 8.524 + 8.525 + /** The actual effective locations searched for classes */ 8.526 + private Path classSearchPath; 8.527 + 8.528 + public Collection<File> classSearchPath() { 8.529 + if (classSearchPath == null) { 8.530 + lazy(); 8.531 + Path bootClassPath = getPathForLocation(PLATFORM_CLASS_PATH); 8.532 + Path userClassPath = getPathForLocation(CLASS_PATH); 8.533 + classSearchPath = new Path(); 8.534 + classSearchPath.addAll(bootClassPath); 8.535 + classSearchPath.addAll(userClassPath); 8.536 + } 8.537 + return Collections.unmodifiableCollection(classSearchPath); 8.538 + } 8.539 + 8.540 + /** The actual effective locations for non-source, non-class files */ 8.541 + private Path otherSearchPath; 8.542 + 8.543 + Collection<File> otherSearchPath() { 8.544 + if (otherSearchPath == null) { 8.545 + lazy(); 8.546 + Path userClassPath = getPathForLocation(CLASS_PATH); 8.547 + Path sourcePath = getPathForLocation(SOURCE_PATH); 8.548 + if (sourcePath == null) 8.549 + otherSearchPath = userClassPath; 8.550 + else { 8.551 + otherSearchPath = new Path(); 8.552 + otherSearchPath.addAll(userClassPath); 8.553 + otherSearchPath.addAll(sourcePath); 8.554 + } 8.555 + } 8.556 + return Collections.unmodifiableCollection(otherSearchPath); 8.557 + } 8.558 + 8.559 + /** Is this the name of an archive file? */ 8.560 + private static boolean isArchive(File file) { 8.561 + String n = file.getName().toLowerCase(); 8.562 + boolean isFile = false; 8.563 + if (!NON_BATCH_MODE) { 8.564 + Boolean isf = isDirectory.get(file); 8.565 + if (isf == null) { 8.566 + isFile = file.isFile(); 8.567 + isDirectory.put(file, isFile); 8.568 + } 8.569 + else { 8.570 + isFile = isf; 8.571 + } 8.572 + } 8.573 + else { 8.574 + isFile = file.isFile(); 8.575 + } 8.576 + 8.577 + return isFile 8.578 + && (n.endsWith(".jar") || n.endsWith(".zip")); 8.579 + } 8.580 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java Mon Jun 16 13:28:00 2008 -0700 9.3 @@ -0,0 +1,1248 @@ 9.4 +/* 9.5 + * Copyright 2007-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. Sun designates this 9.11 + * particular file as subject to the "Classpath" exception as provided 9.12 + * by Sun in the LICENSE file that accompanied this code. 9.13 + * 9.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 9.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 9.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 9.17 + * version 2 for more details (a copy is included in the LICENSE file that 9.18 + * accompanied this code). 9.19 + * 9.20 + * You should have received a copy of the GNU General Public License version 9.21 + * 2 along with this work; if not, write to the Free Software Foundation, 9.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 9.23 + * 9.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 9.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 9.26 + * have any questions. 9.27 + */ 9.28 + 9.29 +package com.sun.tools.javac.file; 9.30 + 9.31 +import java.io.File; 9.32 +import java.io.FileNotFoundException; 9.33 +import java.io.IOException; 9.34 +import java.io.RandomAccessFile; 9.35 +import java.text.MessageFormat; 9.36 +import java.util.ArrayList; 9.37 +import java.util.Arrays; 9.38 +import java.util.Collections; 9.39 +import java.util.HashMap; 9.40 +import java.util.HashSet; 9.41 +import java.util.Iterator; 9.42 +import java.util.List; 9.43 +import java.util.Map; 9.44 +import java.util.Set; 9.45 +import java.util.concurrent.locks.ReentrantLock; 9.46 +import java.util.zip.DataFormatException; 9.47 +import java.util.zip.Inflater; 9.48 +import java.util.zip.ZipException; 9.49 + 9.50 +/** This class implements building of index of a zip archive and access to it's context. 9.51 + * It also uses prebuild index if available. It supports invocations where it will 9.52 + * serialize an optimized zip index file to disk. 9.53 + * 9.54 + * In oreder to use secondary index file make sure the option "usezipindex" is in the Options object, 9.55 + * when JavacFileManager is invoked. (You can pass "-XDusezipindex" on the command line. 9.56 + * 9.57 + * Location where to look for/generate optimized zip index files can be provided using 9.58 + * "-XDcachezipindexdir=<directory>". If this flag is not provided, the dfault location is 9.59 + * the value of the "java.io.tmpdir" system property. 9.60 + * 9.61 + * If key "-XDwritezipindexfiles" is specified, there will be new optimized index file 9.62 + * created for each archive, used by the compiler for compilation, at location, 9.63 + * specified by "cachezipindexdir" option. 9.64 + * 9.65 + * If nonBatchMode option is specified (-XDnonBatchMode) the compiler will use timestamp 9.66 + * checking to reindex the zip files if it is needed. In batch mode the timestamps are not checked 9.67 + * and the compiler uses the cached indexes. 9.68 + */ 9.69 +public class ZipFileIndex { 9.70 + private static final String MIN_CHAR = String.valueOf(Character.MIN_VALUE); 9.71 + private static final String MAX_CHAR = String.valueOf(Character.MAX_VALUE); 9.72 + 9.73 + public final static long NOT_MODIFIED = Long.MIN_VALUE; 9.74 + 9.75 + private static Map<File, ZipFileIndex> zipFileIndexCache = new HashMap<File, ZipFileIndex>(); 9.76 + private static ReentrantLock lock = new ReentrantLock(); 9.77 + 9.78 + private static boolean NON_BATCH_MODE = System.getProperty("nonBatchMode") != null;// TODO: Use -XD compiler switch for this. 9.79 + 9.80 + private Map<String, DirectoryEntry> directories = Collections.<String, DirectoryEntry>emptyMap(); 9.81 + private Set<String> allDirs = Collections.<String>emptySet(); 9.82 + 9.83 + // ZipFileIndex data entries 9.84 + private File zipFile; 9.85 + private long zipFileLastModified = NOT_MODIFIED; 9.86 + private RandomAccessFile zipRandomFile; 9.87 + private ZipFileIndexEntry[] entries; 9.88 + 9.89 + private boolean readFromIndex = false; 9.90 + private File zipIndexFile = null; 9.91 + private boolean triedToReadIndex = false; 9.92 + private int symbolFilePrefixLength = 0; 9.93 + private boolean hasPopulatedData = false; 9.94 + private long lastReferenceTimeStamp = NOT_MODIFIED; 9.95 + 9.96 + private boolean usePreindexedCache = false; 9.97 + private String preindexedCacheLocation = null; 9.98 + 9.99 + private boolean writeIndex = false; 9.100 + 9.101 + /** 9.102 + * Returns a list of all ZipFileIndex entries 9.103 + * 9.104 + * @return A list of ZipFileIndex entries, or an empty list 9.105 + */ 9.106 + public static List<ZipFileIndex> getZipFileIndexes() { 9.107 + return getZipFileIndexes(false); 9.108 + } 9.109 + 9.110 + /** 9.111 + * Returns a list of all ZipFileIndex entries 9.112 + * 9.113 + * @param openedOnly If true it returns a list of only opened ZipFileIndex entries, otherwise 9.114 + * all ZipFileEntry(s) are included into the list. 9.115 + * @return A list of ZipFileIndex entries, or an empty list 9.116 + */ 9.117 + public static List<ZipFileIndex> getZipFileIndexes(boolean openedOnly) { 9.118 + List<ZipFileIndex> zipFileIndexes = new ArrayList<ZipFileIndex>(); 9.119 + lock.lock(); 9.120 + try { 9.121 + zipFileIndexes.addAll(zipFileIndexCache.values()); 9.122 + 9.123 + if (openedOnly) { 9.124 + for(ZipFileIndex elem : zipFileIndexes) { 9.125 + if (!elem.isOpen()) { 9.126 + zipFileIndexes.remove(elem); 9.127 + } 9.128 + } 9.129 + } 9.130 + } 9.131 + finally { 9.132 + lock.unlock(); 9.133 + } 9.134 + return zipFileIndexes; 9.135 + } 9.136 + 9.137 + public boolean isOpen() { 9.138 + lock.lock(); 9.139 + try { 9.140 + return zipRandomFile != null; 9.141 + } 9.142 + finally { 9.143 + lock.unlock(); 9.144 + } 9.145 + } 9.146 + 9.147 + public static ZipFileIndex getZipFileIndex(File zipFile, int symbolFilePrefixLen, boolean useCache, String cacheLocation, boolean writeIndex) throws IOException { 9.148 + ZipFileIndex zi = null; 9.149 + lock.lock(); 9.150 + try { 9.151 + zi = getExistingZipIndex(zipFile); 9.152 + 9.153 + if (zi == null || (zi != null && zipFile.lastModified() != zi.zipFileLastModified)) { 9.154 + zi = new ZipFileIndex(zipFile, symbolFilePrefixLen, writeIndex, 9.155 + useCache, cacheLocation); 9.156 + zipFileIndexCache.put(zipFile, zi); 9.157 + } 9.158 + } 9.159 + finally { 9.160 + lock.unlock(); 9.161 + } 9.162 + return zi; 9.163 + } 9.164 + 9.165 + public static ZipFileIndex getExistingZipIndex(File zipFile) { 9.166 + lock.lock(); 9.167 + try { 9.168 + return zipFileIndexCache.get(zipFile); 9.169 + } 9.170 + finally { 9.171 + lock.unlock(); 9.172 + } 9.173 + } 9.174 + 9.175 + public static void clearCache() { 9.176 + lock.lock(); 9.177 + try { 9.178 + zipFileIndexCache.clear(); 9.179 + } 9.180 + finally { 9.181 + lock.unlock(); 9.182 + } 9.183 + } 9.184 + 9.185 + public static void clearCache(long timeNotUsed) { 9.186 + lock.lock(); 9.187 + try { 9.188 + Iterator<File> cachedFileIterator = zipFileIndexCache.keySet().iterator(); 9.189 + while (cachedFileIterator.hasNext()) { 9.190 + File cachedFile = cachedFileIterator.next(); 9.191 + ZipFileIndex cachedZipIndex = zipFileIndexCache.get(cachedFile); 9.192 + if (cachedZipIndex != null) { 9.193 + long timeToTest = cachedZipIndex.lastReferenceTimeStamp + timeNotUsed; 9.194 + if (timeToTest < cachedZipIndex.lastReferenceTimeStamp || // Overflow... 9.195 + System.currentTimeMillis() > timeToTest) { 9.196 + zipFileIndexCache.remove(cachedFile); 9.197 + } 9.198 + } 9.199 + } 9.200 + } 9.201 + finally { 9.202 + lock.unlock(); 9.203 + } 9.204 + } 9.205 + 9.206 + public static void removeFromCache(File file) { 9.207 + lock.lock(); 9.208 + try { 9.209 + zipFileIndexCache.remove(file); 9.210 + } 9.211 + finally { 9.212 + lock.unlock(); 9.213 + } 9.214 + } 9.215 + 9.216 + /** Sets already opened list of ZipFileIndexes from an outside client 9.217 + * of the compiler. This functionality should be used in a non-batch clients of the compiler. 9.218 + */ 9.219 + public static void setOpenedIndexes(List<ZipFileIndex>indexes) throws IllegalStateException { 9.220 + lock.lock(); 9.221 + try { 9.222 + if (zipFileIndexCache.isEmpty()) { 9.223 + throw new IllegalStateException("Setting opened indexes should be called only when the ZipFileCache is empty. Call JavacFileManager.flush() before calling this method."); 9.224 + } 9.225 + 9.226 + for (ZipFileIndex zfi : indexes) { 9.227 + zipFileIndexCache.put(zfi.zipFile, zfi); 9.228 + } 9.229 + } 9.230 + finally { 9.231 + lock.unlock(); 9.232 + } 9.233 + } 9.234 + 9.235 + private ZipFileIndex(File zipFile, int symbolFilePrefixLen, boolean writeIndex, 9.236 + boolean useCache, String cacheLocation) throws IOException { 9.237 + this.zipFile = zipFile; 9.238 + this.symbolFilePrefixLength = symbolFilePrefixLen; 9.239 + this.writeIndex = writeIndex; 9.240 + this.usePreindexedCache = useCache; 9.241 + this.preindexedCacheLocation = cacheLocation; 9.242 + 9.243 + if (zipFile != null) { 9.244 + this.zipFileLastModified = zipFile.lastModified(); 9.245 + } 9.246 + 9.247 + // Validate integrity of the zip file 9.248 + checkIndex(); 9.249 + } 9.250 + 9.251 + public String toString() { 9.252 + return "ZipFileIndex of file:(" + zipFile + ")"; 9.253 + } 9.254 + 9.255 + // Just in case... 9.256 + protected void finalize() { 9.257 + closeFile(); 9.258 + } 9.259 + 9.260 + private boolean isUpToDate() { 9.261 + if (zipFile != null && 9.262 + ((!NON_BATCH_MODE) || zipFileLastModified == zipFile.lastModified()) && 9.263 + hasPopulatedData) { 9.264 + return true; 9.265 + } 9.266 + 9.267 + return false; 9.268 + } 9.269 + 9.270 + /** 9.271 + * Here we need to make sure that the ZipFileIndex is valid. Check the timestamp of the file and 9.272 + * if its the same as the one at the time the index was build we don't need to reopen anything. 9.273 + */ 9.274 + private void checkIndex() throws IOException { 9.275 + boolean isUpToDate = true; 9.276 + if (!isUpToDate()) { 9.277 + closeFile(); 9.278 + isUpToDate = false; 9.279 + } 9.280 + 9.281 + if (zipRandomFile != null || isUpToDate) { 9.282 + lastReferenceTimeStamp = System.currentTimeMillis(); 9.283 + return; 9.284 + } 9.285 + 9.286 + hasPopulatedData = true; 9.287 + 9.288 + if (readIndex()) { 9.289 + lastReferenceTimeStamp = System.currentTimeMillis(); 9.290 + return; 9.291 + } 9.292 + 9.293 + directories = Collections.<String, DirectoryEntry>emptyMap(); 9.294 + allDirs = Collections.<String>emptySet(); 9.295 + 9.296 + try { 9.297 + openFile(); 9.298 + long totalLength = zipRandomFile.length(); 9.299 + ZipDirectory directory = new ZipDirectory(zipRandomFile, 0L, totalLength, this); 9.300 + directory.buildIndex(); 9.301 + } finally { 9.302 + if (zipRandomFile != null) { 9.303 + closeFile(); 9.304 + } 9.305 + } 9.306 + 9.307 + lastReferenceTimeStamp = System.currentTimeMillis(); 9.308 + } 9.309 + 9.310 + private void openFile() throws FileNotFoundException { 9.311 + if (zipRandomFile == null && zipFile != null) { 9.312 + zipRandomFile = new RandomAccessFile(zipFile, "r"); 9.313 + } 9.314 + } 9.315 + 9.316 + private void cleanupState() { 9.317 + // Make sure there is a valid but empty index if the file doesn't exist 9.318 + entries = ZipFileIndexEntry.EMPTY_ARRAY; 9.319 + directories = Collections.<String, DirectoryEntry>emptyMap(); 9.320 + zipFileLastModified = NOT_MODIFIED; 9.321 + allDirs = Collections.<String>emptySet(); 9.322 + } 9.323 + 9.324 + public void close() { 9.325 + lock.lock(); 9.326 + try { 9.327 + writeIndex(); 9.328 + closeFile(); 9.329 + } 9.330 + finally { 9.331 + lock.unlock(); 9.332 + } 9.333 + } 9.334 + 9.335 + private void closeFile() { 9.336 + if (zipRandomFile != null) { 9.337 + try { 9.338 + zipRandomFile.close(); 9.339 + } catch (IOException ex) { 9.340 + } 9.341 + zipRandomFile = null; 9.342 + } 9.343 + } 9.344 + 9.345 + /** 9.346 + * Returns the ZipFileIndexEntry for an absolute path, if there is one. 9.347 + */ 9.348 + public ZipFileIndexEntry getZipIndexEntry(String path) { 9.349 + if (File.separatorChar != '/') { 9.350 + path = path.replace('/', File.separatorChar); 9.351 + } 9.352 + lock.lock(); 9.353 + try { 9.354 + checkIndex(); 9.355 + String lookFor = ""; 9.356 + int lastSepIndex = path.lastIndexOf(File.separatorChar); 9.357 + boolean noSeparator = false; 9.358 + if (lastSepIndex == -1) { 9.359 + noSeparator = true; 9.360 + } 9.361 + 9.362 + DirectoryEntry de = directories.get(noSeparator ? "" : path.substring(0, lastSepIndex)); 9.363 + 9.364 + lookFor = path.substring(noSeparator ? 0 : lastSepIndex + 1); 9.365 + 9.366 + return de == null ? null : de.getEntry(lookFor); 9.367 + } 9.368 + catch (IOException e) { 9.369 + return null; 9.370 + } 9.371 + finally { 9.372 + lock.unlock(); 9.373 + } 9.374 + } 9.375 + 9.376 + /** 9.377 + * Returns a javac List of filenames within an absolute path in the ZipFileIndex. 9.378 + */ 9.379 + public com.sun.tools.javac.util.List<String> getFiles(String path) { 9.380 + if (File.separatorChar != '/') { 9.381 + path = path.replace('/', File.separatorChar); 9.382 + } 9.383 + 9.384 + lock.lock(); 9.385 + try { 9.386 + checkIndex(); 9.387 + 9.388 + DirectoryEntry de = directories.get(path); 9.389 + com.sun.tools.javac.util.List<String> ret = de == null ? null : de.getFiles(); 9.390 + 9.391 + if (ret == null) { 9.392 + return com.sun.tools.javac.util.List.<String>nil(); 9.393 + } 9.394 + return ret; 9.395 + } 9.396 + catch (IOException e) { 9.397 + return com.sun.tools.javac.util.List.<String>nil(); 9.398 + } 9.399 + finally { 9.400 + lock.unlock(); 9.401 + } 9.402 + } 9.403 + 9.404 + public List<String> getAllDirectories(String path) { 9.405 + 9.406 + if (File.separatorChar != '/') { 9.407 + path = path.replace('/', File.separatorChar); 9.408 + } 9.409 + 9.410 + lock.lock(); 9.411 + try { 9.412 + checkIndex(); 9.413 + path = path.intern(); 9.414 + 9.415 + DirectoryEntry de = directories.get(path); 9.416 + com.sun.tools.javac.util.List<String> ret = de == null ? null : de.getDirectories(); 9.417 + 9.418 + if (ret == null) { 9.419 + return com.sun.tools.javac.util.List.<String>nil(); 9.420 + } 9.421 + 9.422 + return ret; 9.423 + } 9.424 + catch (IOException e) { 9.425 + return com.sun.tools.javac.util.List.<String>nil(); 9.426 + } 9.427 + finally { 9.428 + lock.unlock(); 9.429 + } 9.430 + } 9.431 + 9.432 + public Set<String> getAllDirectories() { 9.433 + lock.lock(); 9.434 + try { 9.435 + checkIndex(); 9.436 + if (allDirs == Collections.EMPTY_SET) { 9.437 + Set<String> alldirs = new HashSet<String>(); 9.438 + Iterator<String> dirsIter = directories.keySet().iterator(); 9.439 + while (dirsIter.hasNext()) { 9.440 + alldirs.add(new String(dirsIter.next())); 9.441 + } 9.442 + 9.443 + allDirs = alldirs; 9.444 + } 9.445 + 9.446 + return allDirs; 9.447 + } 9.448 + catch (IOException e) { 9.449 + return Collections.<String>emptySet(); 9.450 + } 9.451 + finally { 9.452 + lock.unlock(); 9.453 + } 9.454 + } 9.455 + 9.456 + /** 9.457 + * Tests if a specific path exists in the zip. This method will return true 9.458 + * for file entries and directories. 9.459 + * 9.460 + * @param path A path within the zip. 9.461 + * @return True if the path is a file or dir, false otherwise. 9.462 + */ 9.463 + public boolean contains(String path) { 9.464 + lock.lock(); 9.465 + try { 9.466 + checkIndex(); 9.467 + return getZipIndexEntry(path) != null; 9.468 + } 9.469 + catch (IOException e) { 9.470 + return false; 9.471 + } 9.472 + finally { 9.473 + lock.unlock(); 9.474 + } 9.475 + } 9.476 + 9.477 + public boolean isDirectory(String path) throws IOException { 9.478 + lock.lock(); 9.479 + try { 9.480 + // The top level in a zip file is always a directory. 9.481 + if (path.length() == 0) { 9.482 + lastReferenceTimeStamp = System.currentTimeMillis(); 9.483 + return true; 9.484 + } 9.485 + 9.486 + if (File.separatorChar != '/') 9.487 + path = path.replace('/', File.separatorChar); 9.488 + checkIndex(); 9.489 + return directories.get(path) != null; 9.490 + } 9.491 + finally { 9.492 + lock.unlock(); 9.493 + } 9.494 + } 9.495 + 9.496 + public long getLastModified(String path) throws IOException { 9.497 + lock.lock(); 9.498 + try { 9.499 + ZipFileIndexEntry entry = getZipIndexEntry(path); 9.500 + if (entry == null) 9.501 + throw new FileNotFoundException(); 9.502 + return entry.getLastModified(); 9.503 + } 9.504 + finally { 9.505 + lock.unlock(); 9.506 + } 9.507 + } 9.508 + 9.509 + public int length(String path) throws IOException { 9.510 + lock.lock(); 9.511 + try { 9.512 + ZipFileIndexEntry entry = getZipIndexEntry(path); 9.513 + if (entry == null) 9.514 + throw new FileNotFoundException(); 9.515 + 9.516 + if (entry.isDir) { 9.517 + return 0; 9.518 + } 9.519 + 9.520 + byte[] header = getHeader(entry); 9.521 + // entry is not compressed? 9.522 + if (get2ByteLittleEndian(header, 8) == 0) { 9.523 + return entry.compressedSize; 9.524 + } else { 9.525 + return entry.size; 9.526 + } 9.527 + } 9.528 + finally { 9.529 + lock.unlock(); 9.530 + } 9.531 + } 9.532 + 9.533 + public byte[] read(String path) throws IOException { 9.534 + lock.lock(); 9.535 + try { 9.536 + ZipFileIndexEntry entry = getZipIndexEntry(path); 9.537 + if (entry == null) 9.538 + throw new FileNotFoundException(MessageFormat.format("Path not found in ZIP: {0}", path)); 9.539 + return read(entry); 9.540 + } 9.541 + finally { 9.542 + lock.unlock(); 9.543 + } 9.544 + } 9.545 + 9.546 + public byte[] read(ZipFileIndexEntry entry) throws IOException { 9.547 + lock.lock(); 9.548 + try { 9.549 + openFile(); 9.550 + byte[] result = readBytes(entry); 9.551 + closeFile(); 9.552 + return result; 9.553 + } 9.554 + finally { 9.555 + lock.unlock(); 9.556 + } 9.557 + } 9.558 + 9.559 + public int read(String path, byte[] buffer) throws IOException { 9.560 + lock.lock(); 9.561 + try { 9.562 + ZipFileIndexEntry entry = getZipIndexEntry(path); 9.563 + if (entry == null) 9.564 + throw new FileNotFoundException(); 9.565 + return read(entry, buffer); 9.566 + } 9.567 + finally { 9.568 + lock.unlock(); 9.569 + } 9.570 + } 9.571 + 9.572 + public int read(ZipFileIndexEntry entry, byte[] buffer) 9.573 + throws IOException { 9.574 + lock.lock(); 9.575 + try { 9.576 + int result = readBytes(entry, buffer); 9.577 + return result; 9.578 + } 9.579 + finally { 9.580 + lock.unlock(); 9.581 + } 9.582 + } 9.583 + 9.584 + private byte[] readBytes(ZipFileIndexEntry entry) throws IOException { 9.585 + byte[] header = getHeader(entry); 9.586 + int csize = entry.compressedSize; 9.587 + byte[] cbuf = new byte[csize]; 9.588 + zipRandomFile.skipBytes(get2ByteLittleEndian(header, 26) + get2ByteLittleEndian(header, 28)); 9.589 + zipRandomFile.readFully(cbuf, 0, csize); 9.590 + 9.591 + // is this compressed - offset 8 in the ZipEntry header 9.592 + if (get2ByteLittleEndian(header, 8) == 0) 9.593 + return cbuf; 9.594 + 9.595 + int size = entry.size; 9.596 + byte[] buf = new byte[size]; 9.597 + if (inflate(cbuf, buf) != size) 9.598 + throw new ZipException("corrupted zip file"); 9.599 + 9.600 + return buf; 9.601 + } 9.602 + 9.603 + /** 9.604 + * 9.605 + */ 9.606 + private int readBytes(ZipFileIndexEntry entry, byte[] buffer) throws IOException { 9.607 + byte[] header = getHeader(entry); 9.608 + 9.609 + // entry is not compressed? 9.610 + if (get2ByteLittleEndian(header, 8) == 0) { 9.611 + zipRandomFile.skipBytes(get2ByteLittleEndian(header, 26) + get2ByteLittleEndian(header, 28)); 9.612 + int offset = 0; 9.613 + int size = buffer.length; 9.614 + while (offset < size) { 9.615 + int count = zipRandomFile.read(buffer, offset, size - offset); 9.616 + if (count == -1) 9.617 + break; 9.618 + offset += count; 9.619 + } 9.620 + return entry.size; 9.621 + } 9.622 + 9.623 + int csize = entry.compressedSize; 9.624 + byte[] cbuf = new byte[csize]; 9.625 + zipRandomFile.skipBytes(get2ByteLittleEndian(header, 26) + get2ByteLittleEndian(header, 28)); 9.626 + zipRandomFile.readFully(cbuf, 0, csize); 9.627 + 9.628 + int count = inflate(cbuf, buffer); 9.629 + if (count == -1) 9.630 + throw new ZipException("corrupted zip file"); 9.631 + 9.632 + return entry.size; 9.633 + } 9.634 + 9.635 + //---------------------------------------------------------------------------- 9.636 + // Zip utilities 9.637 + //---------------------------------------------------------------------------- 9.638 + 9.639 + private byte[] getHeader(ZipFileIndexEntry entry) throws IOException { 9.640 + zipRandomFile.seek(entry.offset); 9.641 + byte[] header = new byte[30]; 9.642 + zipRandomFile.readFully(header); 9.643 + if (get4ByteLittleEndian(header, 0) != 0x04034b50) 9.644 + throw new ZipException("corrupted zip file"); 9.645 + if ((get2ByteLittleEndian(header, 6) & 1) != 0) 9.646 + throw new ZipException("encrypted zip file"); // offset 6 in the header of the ZipFileEntry 9.647 + return header; 9.648 + } 9.649 + 9.650 + /* 9.651 + * Inflate using the java.util.zip.Inflater class 9.652 + */ 9.653 + private static Inflater inflater; 9.654 + private int inflate(byte[] src, byte[] dest) { 9.655 + 9.656 + // construct the inflater object or reuse an existing one 9.657 + if (inflater == null) 9.658 + inflater = new Inflater(true); 9.659 + 9.660 + synchronized (inflater) { 9.661 + inflater.reset(); 9.662 + inflater.setInput(src); 9.663 + try { 9.664 + return inflater.inflate(dest); 9.665 + } catch (DataFormatException ex) { 9.666 + return -1; 9.667 + } 9.668 + } 9.669 + } 9.670 + 9.671 + /** 9.672 + * return the two bytes buf[pos], buf[pos+1] as an unsigned integer in little 9.673 + * endian format. 9.674 + */ 9.675 + private static int get2ByteLittleEndian(byte[] buf, int pos) { 9.676 + return (buf[pos] & 0xFF) + ((buf[pos+1] & 0xFF) << 8); 9.677 + } 9.678 + 9.679 + /** 9.680 + * return the 4 bytes buf[i..i+3] as an integer in little endian format. 9.681 + */ 9.682 + private static int get4ByteLittleEndian(byte[] buf, int pos) { 9.683 + return (buf[pos] & 0xFF) + ((buf[pos + 1] & 0xFF) << 8) + 9.684 + ((buf[pos + 2] & 0xFF) << 16) + ((buf[pos + 3] & 0xFF) << 24); 9.685 + } 9.686 + 9.687 + /* ---------------------------------------------------------------------------- 9.688 + * ZipDirectory 9.689 + * ----------------------------------------------------------------------------*/ 9.690 + 9.691 + private class ZipDirectory { 9.692 + private String lastDir; 9.693 + private int lastStart; 9.694 + private int lastLen; 9.695 + 9.696 + byte[] zipDir; 9.697 + RandomAccessFile zipRandomFile = null; 9.698 + ZipFileIndex zipFileIndex = null; 9.699 + 9.700 + public ZipDirectory(RandomAccessFile zipRandomFile, long start, long end, ZipFileIndex index) throws IOException { 9.701 + this.zipRandomFile = zipRandomFile; 9.702 + this.zipFileIndex = index; 9.703 + 9.704 + findCENRecord(start, end); 9.705 + } 9.706 + 9.707 + /* 9.708 + * Reads zip file central directory. 9.709 + * For more details see readCEN in zip_util.c from the JDK sources. 9.710 + * This is a Java port of that function. 9.711 + */ 9.712 + private void findCENRecord(long start, long end) throws IOException { 9.713 + long totalLength = end - start; 9.714 + int endbuflen = 1024; 9.715 + byte[] endbuf = new byte[endbuflen]; 9.716 + long endbufend = end - start; 9.717 + 9.718 + // There is a variable-length field after the dir offset record. We need to do consequential search. 9.719 + while (endbufend >= 22) { 9.720 + if (endbufend < endbuflen) 9.721 + endbuflen = (int)endbufend; 9.722 + long endbufpos = endbufend - endbuflen; 9.723 + zipRandomFile.seek(start + endbufpos); 9.724 + zipRandomFile.readFully(endbuf, 0, endbuflen); 9.725 + int i = endbuflen - 22; 9.726 + while (i >= 0 && 9.727 + !(endbuf[i] == 0x50 && 9.728 + endbuf[i + 1] == 0x4b && 9.729 + endbuf[i + 2] == 0x05 && 9.730 + endbuf[i + 3] == 0x06 && 9.731 + endbufpos + i + 22 + 9.732 + get2ByteLittleEndian(endbuf, i + 20) == totalLength)) { 9.733 + i--; 9.734 + } 9.735 + 9.736 + if (i >= 0) { 9.737 + zipDir = new byte[get4ByteLittleEndian(endbuf, i + 12) + 2]; 9.738 + zipDir[0] = endbuf[i + 10]; 9.739 + zipDir[1] = endbuf[i + 11]; 9.740 + zipRandomFile.seek(start + get4ByteLittleEndian(endbuf, i + 16)); 9.741 + zipRandomFile.readFully(zipDir, 2, zipDir.length - 2); 9.742 + return; 9.743 + } else { 9.744 + endbufend = endbufpos + 21; 9.745 + } 9.746 + } 9.747 + throw new ZipException("cannot read zip file"); 9.748 + } 9.749 + private void buildIndex() throws IOException { 9.750 + int entryCount = get2ByteLittleEndian(zipDir, 0); 9.751 + 9.752 + entries = new ZipFileIndexEntry[entryCount]; 9.753 + // Add each of the files 9.754 + if (entryCount > 0) { 9.755 + directories = new HashMap<String, DirectoryEntry>(); 9.756 + ArrayList<ZipFileIndexEntry> entryList = new ArrayList<ZipFileIndexEntry>(); 9.757 + int pos = 2; 9.758 + for (int i = 0; i < entryCount; i++) { 9.759 + pos = readEntry(pos, entryList, directories); 9.760 + } 9.761 + 9.762 + // Add the accumulated dirs into the same list 9.763 + Iterator i = directories.keySet().iterator(); 9.764 + while (i.hasNext()) { 9.765 + ZipFileIndexEntry zipFileIndexEntry = new ZipFileIndexEntry( (String) i.next()); 9.766 + zipFileIndexEntry.isDir = true; 9.767 + entryList.add(zipFileIndexEntry); 9.768 + } 9.769 + 9.770 + entries = entryList.toArray(new ZipFileIndexEntry[entryList.size()]); 9.771 + Arrays.sort(entries); 9.772 + } else { 9.773 + cleanupState(); 9.774 + } 9.775 + } 9.776 + 9.777 + private int readEntry(int pos, List<ZipFileIndexEntry> entryList, 9.778 + Map<String, DirectoryEntry> directories) throws IOException { 9.779 + if (get4ByteLittleEndian(zipDir, pos) != 0x02014b50) { 9.780 + throw new ZipException("cannot read zip file entry"); 9.781 + } 9.782 + 9.783 + int dirStart = pos + 46; 9.784 + int fileStart = dirStart; 9.785 + int fileEnd = fileStart + get2ByteLittleEndian(zipDir, pos + 28); 9.786 + 9.787 + if (zipFileIndex.symbolFilePrefixLength != 0 && 9.788 + ((fileEnd - fileStart) >= symbolFilePrefixLength)) { 9.789 + dirStart += zipFileIndex.symbolFilePrefixLength; 9.790 + fileStart += zipFileIndex.symbolFilePrefixLength; 9.791 + } 9.792 + 9.793 + // Use the OS's path separator. Keep the position of the last one. 9.794 + for (int index = fileStart; index < fileEnd; index++) { 9.795 + byte nextByte = zipDir[index]; 9.796 + if (nextByte == (byte)'\\' || nextByte == (byte)'/') { 9.797 + zipDir[index] = (byte)File.separatorChar; 9.798 + fileStart = index + 1; 9.799 + } 9.800 + } 9.801 + 9.802 + String directory = null; 9.803 + if (fileStart == dirStart) 9.804 + directory = ""; 9.805 + else if (lastDir != null && lastLen == fileStart - dirStart - 1) { 9.806 + int index = lastLen - 1; 9.807 + while (zipDir[lastStart + index] == zipDir[dirStart + index]) { 9.808 + if (index == 0) { 9.809 + directory = lastDir; 9.810 + break; 9.811 + } 9.812 + index--; 9.813 + } 9.814 + } 9.815 + 9.816 + // Sub directories 9.817 + if (directory == null) { 9.818 + lastStart = dirStart; 9.819 + lastLen = fileStart - dirStart - 1; 9.820 + 9.821 + directory = new String(zipDir, dirStart, lastLen, "UTF-8").intern(); 9.822 + lastDir = directory; 9.823 + 9.824 + // Enter also all the parent directories 9.825 + String tempDirectory = directory; 9.826 + 9.827 + while (directories.get(tempDirectory) == null) { 9.828 + directories.put(tempDirectory, new DirectoryEntry(tempDirectory, zipFileIndex)); 9.829 + int separator = tempDirectory.lastIndexOf(File.separatorChar); 9.830 + if (separator == -1) 9.831 + break; 9.832 + tempDirectory = tempDirectory.substring(0, separator); 9.833 + } 9.834 + } 9.835 + else { 9.836 + directory = directory.intern(); 9.837 + if (directories.get(directory) == null) { 9.838 + directories.put(directory, new DirectoryEntry(directory, zipFileIndex)); 9.839 + } 9.840 + } 9.841 + 9.842 + // For each dir create also a file 9.843 + if (fileStart != fileEnd) { 9.844 + ZipFileIndexEntry entry = new ZipFileIndexEntry(directory, 9.845 + new String(zipDir, fileStart, fileEnd - fileStart, "UTF-8")); 9.846 + 9.847 + entry.setNativeTime(get4ByteLittleEndian(zipDir, pos + 12)); 9.848 + entry.compressedSize = get4ByteLittleEndian(zipDir, pos + 20); 9.849 + entry.size = get4ByteLittleEndian(zipDir, pos + 24); 9.850 + entry.offset = get4ByteLittleEndian(zipDir, pos + 42); 9.851 + entryList.add(entry); 9.852 + } 9.853 + 9.854 + return pos + 46 + 9.855 + get2ByteLittleEndian(zipDir, pos + 28) + 9.856 + get2ByteLittleEndian(zipDir, pos + 30) + 9.857 + get2ByteLittleEndian(zipDir, pos + 32); 9.858 + } 9.859 + } 9.860 + 9.861 + /** 9.862 + * Returns the last modified timestamp of a zip file. 9.863 + * @return long 9.864 + */ 9.865 + public long getZipFileLastModified() throws IOException { 9.866 + lock.lock(); 9.867 + try { 9.868 + checkIndex(); 9.869 + return zipFileLastModified; 9.870 + } 9.871 + finally { 9.872 + lock.unlock(); 9.873 + } 9.874 + } 9.875 + 9.876 + /** ------------------------------------------------------------------------ 9.877 + * DirectoryEntry class 9.878 + * -------------------------------------------------------------------------*/ 9.879 + static class DirectoryEntry { 9.880 + private boolean filesInited; 9.881 + private boolean directoriesInited; 9.882 + private boolean zipFileEntriesInited; 9.883 + private boolean entriesInited; 9.884 + 9.885 + private long writtenOffsetOffset = 0; 9.886 + 9.887 + private String dirName; 9.888 + 9.889 + private com.sun.tools.javac.util.List<String> zipFileEntriesFiles = com.sun.tools.javac.util.List.<String>nil(); 9.890 + private com.sun.tools.javac.util.List<String> zipFileEntriesDirectories = com.sun.tools.javac.util.List.<String>nil(); 9.891 + private com.sun.tools.javac.util.List<ZipFileIndexEntry> zipFileEntries = com.sun.tools.javac.util.List.<ZipFileIndexEntry>nil(); 9.892 + 9.893 + private List<ZipFileIndexEntry> entries = new ArrayList<ZipFileIndexEntry>(); 9.894 + 9.895 + private ZipFileIndex zipFileIndex; 9.896 + 9.897 + private int numEntries; 9.898 + 9.899 + DirectoryEntry(String dirName, ZipFileIndex index) { 9.900 + filesInited = false; 9.901 + directoriesInited = false; 9.902 + entriesInited = false; 9.903 + 9.904 + if (File.separatorChar == '/') { 9.905 + dirName.replace('\\', '/'); 9.906 + } 9.907 + else { 9.908 + dirName.replace('/', '\\'); 9.909 + } 9.910 + 9.911 + this.dirName = dirName.intern(); 9.912 + this.zipFileIndex = index; 9.913 + } 9.914 + 9.915 + private com.sun.tools.javac.util.List<String> getFiles() { 9.916 + if (filesInited) { 9.917 + return zipFileEntriesFiles; 9.918 + } 9.919 + 9.920 + initEntries(); 9.921 + 9.922 + for (ZipFileIndexEntry e : entries) { 9.923 + if (!e.isDir) { 9.924 + zipFileEntriesFiles = zipFileEntriesFiles.append(e.name); 9.925 + } 9.926 + } 9.927 + filesInited = true; 9.928 + return zipFileEntriesFiles; 9.929 + } 9.930 + 9.931 + private com.sun.tools.javac.util.List<String> getDirectories() { 9.932 + if (directoriesInited) { 9.933 + return zipFileEntriesFiles; 9.934 + } 9.935 + 9.936 + initEntries(); 9.937 + 9.938 + for (ZipFileIndexEntry e : entries) { 9.939 + if (e.isDir) { 9.940 + zipFileEntriesDirectories = zipFileEntriesDirectories.append(e.name); 9.941 + } 9.942 + } 9.943 + 9.944 + directoriesInited = true; 9.945 + 9.946 + return zipFileEntriesDirectories; 9.947 + } 9.948 + 9.949 + private com.sun.tools.javac.util.List<ZipFileIndexEntry> getEntries() { 9.950 + if (zipFileEntriesInited) { 9.951 + return zipFileEntries; 9.952 + } 9.953 + 9.954 + initEntries(); 9.955 + 9.956 + zipFileEntries = com.sun.tools.javac.util.List.nil(); 9.957 + for (ZipFileIndexEntry zfie : entries) { 9.958 + zipFileEntries = zipFileEntries.append(zfie); 9.959 + } 9.960 + 9.961 + zipFileEntriesInited = true; 9.962 + 9.963 + return zipFileEntries; 9.964 + } 9.965 + 9.966 + private ZipFileIndexEntry getEntry(String rootName) { 9.967 + initEntries(); 9.968 + int index = Collections.binarySearch(entries, new ZipFileIndexEntry(dirName, rootName)); 9.969 + if (index < 0) { 9.970 + return null; 9.971 + } 9.972 + 9.973 + return entries.get(index); 9.974 + } 9.975 + 9.976 + private void initEntries() { 9.977 + if (entriesInited) { 9.978 + return; 9.979 + } 9.980 + 9.981 + if (!zipFileIndex.readFromIndex) { 9.982 + int from = -Arrays.binarySearch(zipFileIndex.entries, 9.983 + new ZipFileIndexEntry(dirName, ZipFileIndex.MIN_CHAR)) - 1; 9.984 + int to = -Arrays.binarySearch(zipFileIndex.entries, 9.985 + new ZipFileIndexEntry(dirName, MAX_CHAR)) - 1; 9.986 + 9.987 + boolean emptyList = false; 9.988 + 9.989 + for (int i = from; i < to; i++) { 9.990 + entries.add(zipFileIndex.entries[i]); 9.991 + } 9.992 + } else { 9.993 + File indexFile = zipFileIndex.getIndexFile(); 9.994 + if (indexFile != null) { 9.995 + RandomAccessFile raf = null; 9.996 + try { 9.997 + raf = new RandomAccessFile(indexFile, "r"); 9.998 + raf.seek(writtenOffsetOffset); 9.999 + 9.1000 + for (int nFiles = 0; nFiles < numEntries; nFiles++) { 9.1001 + // Read the name bytes 9.1002 + int zfieNameBytesLen = raf.readInt(); 9.1003 + byte [] zfieNameBytes = new byte[zfieNameBytesLen]; 9.1004 + raf.read(zfieNameBytes); 9.1005 + String eName = new String(zfieNameBytes, "UTF-8"); 9.1006 + 9.1007 + // Read isDir 9.1008 + boolean eIsDir = raf.readByte() == (byte)0 ? false : true; 9.1009 + 9.1010 + // Read offset of bytes in the real Jar/Zip file 9.1011 + int eOffset = raf.readInt(); 9.1012 + 9.1013 + // Read size of the file in the real Jar/Zip file 9.1014 + int eSize = raf.readInt(); 9.1015 + 9.1016 + // Read compressed size of the file in the real Jar/Zip file 9.1017 + int eCsize = raf.readInt(); 9.1018 + 9.1019 + // Read java time stamp of the file in the real Jar/Zip file 9.1020 + long eJavaTimestamp = raf.readLong(); 9.1021 + 9.1022 + ZipFileIndexEntry rfie = new ZipFileIndexEntry(dirName, eName); 9.1023 + rfie.isDir = eIsDir; 9.1024 + rfie.offset = eOffset; 9.1025 + rfie.size = eSize; 9.1026 + rfie.compressedSize = eCsize; 9.1027 + rfie.javatime = eJavaTimestamp; 9.1028 + entries.add(rfie); 9.1029 + } 9.1030 + } catch (Throwable t) { 9.1031 + // Do nothing 9.1032 + } finally { 9.1033 + try { 9.1034 + if (raf == null) { 9.1035 + raf.close(); 9.1036 + } 9.1037 + } catch (Throwable t) { 9.1038 + // Do nothing 9.1039 + } 9.1040 + } 9.1041 + } 9.1042 + } 9.1043 + 9.1044 + entriesInited = true; 9.1045 + } 9.1046 + 9.1047 + List<ZipFileIndexEntry> getEntriesAsCollection() { 9.1048 + initEntries(); 9.1049 + 9.1050 + return entries; 9.1051 + } 9.1052 + } 9.1053 + 9.1054 + private boolean readIndex() { 9.1055 + if (triedToReadIndex || !usePreindexedCache) { 9.1056 + return false; 9.1057 + } 9.1058 + 9.1059 + boolean ret = false; 9.1060 + lock.lock(); 9.1061 + try { 9.1062 + triedToReadIndex = true; 9.1063 + RandomAccessFile raf = null; 9.1064 + try { 9.1065 + File indexFileName = getIndexFile(); 9.1066 + raf = new RandomAccessFile(indexFileName, "r"); 9.1067 + 9.1068 + long fileStamp = raf.readLong(); 9.1069 + if (zipFile.lastModified() != fileStamp) { 9.1070 + ret = false; 9.1071 + } else { 9.1072 + directories = new HashMap<String, DirectoryEntry>(); 9.1073 + int numDirs = raf.readInt(); 9.1074 + for (int nDirs = 0; nDirs < numDirs; nDirs++) { 9.1075 + int dirNameBytesLen = raf.readInt(); 9.1076 + byte [] dirNameBytes = new byte[dirNameBytesLen]; 9.1077 + raf.read(dirNameBytes); 9.1078 + 9.1079 + String dirNameStr = new String(dirNameBytes, "UTF-8"); 9.1080 + DirectoryEntry de = new DirectoryEntry(dirNameStr, this); 9.1081 + de.numEntries = raf.readInt(); 9.1082 + de.writtenOffsetOffset = raf.readLong(); 9.1083 + directories.put(dirNameStr, de); 9.1084 + } 9.1085 + ret = true; 9.1086 + zipFileLastModified = fileStamp; 9.1087 + } 9.1088 + } catch (Throwable t) { 9.1089 + // Do nothing 9.1090 + } finally { 9.1091 + if (raf != null) { 9.1092 + try { 9.1093 + raf.close(); 9.1094 + } catch (Throwable tt) { 9.1095 + // Do nothing 9.1096 + } 9.1097 + } 9.1098 + } 9.1099 + if (ret == true) { 9.1100 + readFromIndex = true; 9.1101 + } 9.1102 + } 9.1103 + finally { 9.1104 + lock.unlock(); 9.1105 + } 9.1106 + 9.1107 + return ret; 9.1108 + } 9.1109 + 9.1110 + private boolean writeIndex() { 9.1111 + boolean ret = false; 9.1112 + if (readFromIndex || !usePreindexedCache) { 9.1113 + return true; 9.1114 + } 9.1115 + 9.1116 + if (!writeIndex) { 9.1117 + return true; 9.1118 + } 9.1119 + 9.1120 + File indexFile = getIndexFile(); 9.1121 + if (indexFile == null) { 9.1122 + return false; 9.1123 + } 9.1124 + 9.1125 + RandomAccessFile raf = null; 9.1126 + long writtenSoFar = 0; 9.1127 + try { 9.1128 + raf = new RandomAccessFile(indexFile, "rw"); 9.1129 + 9.1130 + raf.writeLong(zipFileLastModified); 9.1131 + writtenSoFar += 8; 9.1132 + 9.1133 + 9.1134 + Iterator<String> iterDirName = directories.keySet().iterator(); 9.1135 + List<DirectoryEntry> directoriesToWrite = new ArrayList<DirectoryEntry>(); 9.1136 + Map<String, Long> offsets = new HashMap<String, Long>(); 9.1137 + raf.writeInt(directories.keySet().size()); 9.1138 + writtenSoFar += 4; 9.1139 + 9.1140 + while(iterDirName.hasNext()) { 9.1141 + String dirName = iterDirName.next(); 9.1142 + DirectoryEntry dirEntry = directories.get(dirName); 9.1143 + 9.1144 + directoriesToWrite.add(dirEntry); 9.1145 + 9.1146 + // Write the dir name bytes 9.1147 + byte [] dirNameBytes = dirName.getBytes("UTF-8"); 9.1148 + int dirNameBytesLen = dirNameBytes.length; 9.1149 + raf.writeInt(dirNameBytesLen); 9.1150 + writtenSoFar += 4; 9.1151 + 9.1152 + raf.write(dirNameBytes); 9.1153 + writtenSoFar += dirNameBytesLen; 9.1154 + 9.1155 + // Write the number of files in the dir 9.1156 + List dirEntries = dirEntry.getEntriesAsCollection(); 9.1157 + raf.writeInt(dirEntries.size()); 9.1158 + writtenSoFar += 4; 9.1159 + 9.1160 + offsets.put(dirName, new Long(writtenSoFar)); 9.1161 + 9.1162 + // Write the offset of the file's data in the dir 9.1163 + dirEntry.writtenOffsetOffset = 0L; 9.1164 + raf.writeLong(0L); 9.1165 + writtenSoFar += 8; 9.1166 + } 9.1167 + 9.1168 + for (DirectoryEntry de : directoriesToWrite) { 9.1169 + // Fix up the offset in the directory table 9.1170 + long currFP = raf.getFilePointer(); 9.1171 + 9.1172 + long offsetOffset = offsets.get(de.dirName).longValue(); 9.1173 + raf.seek(offsetOffset); 9.1174 + raf.writeLong(writtenSoFar); 9.1175 + 9.1176 + raf.seek(currFP); 9.1177 + 9.1178 + // Now write each of the files in the DirectoryEntry 9.1179 + List<ZipFileIndexEntry> entries = de.getEntriesAsCollection(); 9.1180 + for (ZipFileIndexEntry zfie : entries) { 9.1181 + // Write the name bytes 9.1182 + byte [] zfieNameBytes = zfie.name.getBytes("UTF-8"); 9.1183 + int zfieNameBytesLen = zfieNameBytes.length; 9.1184 + raf.writeInt(zfieNameBytesLen); 9.1185 + writtenSoFar += 4; 9.1186 + raf.write(zfieNameBytes); 9.1187 + writtenSoFar += zfieNameBytesLen; 9.1188 + 9.1189 + // Write isDir 9.1190 + raf.writeByte(zfie.isDir ? (byte)1 : (byte)0); 9.1191 + writtenSoFar += 1; 9.1192 + 9.1193 + // Write offset of bytes in the real Jar/Zip file 9.1194 + raf.writeInt(zfie.offset); 9.1195 + writtenSoFar += 4; 9.1196 + 9.1197 + // Write size of the file in the real Jar/Zip file 9.1198 + raf.writeInt(zfie.size); 9.1199 + writtenSoFar += 4; 9.1200 + 9.1201 + // Write compressed size of the file in the real Jar/Zip file 9.1202 + raf.writeInt(zfie.compressedSize); 9.1203 + writtenSoFar += 4; 9.1204 + 9.1205 + // Write java time stamp of the file in the real Jar/Zip file 9.1206 + raf.writeLong(zfie.getLastModified()); 9.1207 + writtenSoFar += 8; 9.1208 + } 9.1209 + } 9.1210 + } catch (Throwable t) { 9.1211 + // Do nothing 9.1212 + } finally { 9.1213 + try { 9.1214 + if (raf != null) { 9.1215 + raf.close(); 9.1216 + } 9.1217 + } catch(IOException ioe) { 9.1218 + // Do nothing 9.1219 + } 9.1220 + } 9.1221 + 9.1222 + return ret; 9.1223 + } 9.1224 + 9.1225 + public boolean writeZipIndex() { 9.1226 + lock.lock(); 9.1227 + try { 9.1228 + return writeIndex(); 9.1229 + } 9.1230 + finally { 9.1231 + lock.unlock(); 9.1232 + } 9.1233 + } 9.1234 + 9.1235 + private File getIndexFile() { 9.1236 + if (zipIndexFile == null) { 9.1237 + if (zipFile == null) { 9.1238 + return null; 9.1239 + } 9.1240 + 9.1241 + zipIndexFile = new File((preindexedCacheLocation == null ? "" : preindexedCacheLocation) + 9.1242 + zipFile.getName() + ".index"); 9.1243 + } 9.1244 + 9.1245 + return zipIndexFile; 9.1246 + } 9.1247 + 9.1248 + public File getZipFile() { 9.1249 + return zipFile; 9.1250 + } 9.1251 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/src/share/classes/com/sun/tools/javac/file/ZipFileIndexEntry.java Mon Jun 16 13:28:00 2008 -0700 10.3 @@ -0,0 +1,116 @@ 10.4 +/* 10.5 + * Copyright 2007-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. Sun designates this 10.11 + * particular file as subject to the "Classpath" exception as provided 10.12 + * by Sun in the LICENSE file that accompanied this code. 10.13 + * 10.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 10.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 10.17 + * version 2 for more details (a copy is included in the LICENSE file that 10.18 + * accompanied this code). 10.19 + * 10.20 + * You should have received a copy of the GNU General Public License version 10.21 + * 2 along with this work; if not, write to the Free Software Foundation, 10.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 10.23 + * 10.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 10.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 10.26 + * have any questions. 10.27 + */ 10.28 + 10.29 +package com.sun.tools.javac.file; 10.30 + 10.31 +import java.io.File; 10.32 + 10.33 +public final class ZipFileIndexEntry implements Comparable<ZipFileIndexEntry> { 10.34 + public static final ZipFileIndexEntry[] EMPTY_ARRAY = {}; 10.35 + 10.36 + // Directory related 10.37 + String dir; 10.38 + boolean isDir; 10.39 + 10.40 + // File related 10.41 + String name; 10.42 + 10.43 + int offset; 10.44 + int size; 10.45 + int compressedSize; 10.46 + long javatime; 10.47 + 10.48 + private int nativetime; 10.49 + 10.50 + public ZipFileIndexEntry(String path) { 10.51 + int separator = path.lastIndexOf(File.separatorChar); 10.52 + if (separator == -1) { 10.53 + dir = "".intern(); 10.54 + name = path; 10.55 + } else { 10.56 + dir = path.substring(0, separator).intern(); 10.57 + name = path.substring(separator + 1); 10.58 + } 10.59 + } 10.60 + 10.61 + public ZipFileIndexEntry(String directory, String name) { 10.62 + this.dir = directory.intern(); 10.63 + this.name = name; 10.64 + } 10.65 + 10.66 + public String getName() { 10.67 + if (dir == null || dir.length() == 0) { 10.68 + return name; 10.69 + } 10.70 + 10.71 + StringBuilder sb = new StringBuilder(); 10.72 + sb.append(dir); 10.73 + sb.append(File.separatorChar); 10.74 + sb.append(name); 10.75 + return sb.toString(); 10.76 + } 10.77 + 10.78 + public String getFileName() { 10.79 + return name; 10.80 + } 10.81 + 10.82 + public long getLastModified() { 10.83 + if (javatime == 0) { 10.84 + javatime = dosToJavaTime(nativetime); 10.85 + } 10.86 + return javatime; 10.87 + } 10.88 + 10.89 + // From java.util.zip 10.90 + private static long dosToJavaTime(int nativetime) { 10.91 + // Bootstrap build problems prevent me from using the code directly 10.92 + // Convert the raw/native time to a long for now 10.93 + return (long)nativetime; 10.94 + } 10.95 + 10.96 + void setNativeTime(int natTime) { 10.97 + nativetime = natTime; 10.98 + } 10.99 + 10.100 + public boolean isDirectory() { 10.101 + return isDir; 10.102 + } 10.103 + 10.104 + public int compareTo(ZipFileIndexEntry other) { 10.105 + String otherD = other.dir; 10.106 + if (dir != otherD) { 10.107 + int c = dir.compareTo(otherD); 10.108 + if (c != 0) 10.109 + return c; 10.110 + } 10.111 + return name.compareTo(other.name); 10.112 + } 10.113 + 10.114 + 10.115 + public String toString() { 10.116 + return isDir ? ("Dir:" + dir + " : " + name) : 10.117 + (dir + ":" + name); 10.118 + } 10.119 +}
11.1 --- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Fri Jun 06 15:17:35 2008 -0700 11.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Mon Jun 16 13:28:00 2008 -0700 11.3 @@ -42,6 +42,7 @@ 11.4 import com.sun.tools.javac.code.Type.*; 11.5 import com.sun.tools.javac.code.Symbol.*; 11.6 import com.sun.tools.javac.code.Symtab; 11.7 +import com.sun.tools.javac.file.BaseFileObject; 11.8 import com.sun.tools.javac.util.*; 11.9 import com.sun.tools.javac.util.List; 11.10
12.1 --- a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Fri Jun 06 15:17:35 2008 -0700 12.2 +++ b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Mon Jun 16 13:28:00 2008 -0700 12.3 @@ -40,6 +40,7 @@ 12.4 import javax.tools.JavaFileObject; 12.5 import javax.tools.DiagnosticListener; 12.6 12.7 +import com.sun.tools.javac.file.JavacFileManager; 12.8 import com.sun.source.util.TaskEvent; 12.9 import com.sun.source.util.TaskListener; 12.10
13.1 --- a/src/share/classes/com/sun/tools/javac/main/Main.java Fri Jun 06 15:17:35 2008 -0700 13.2 +++ b/src/share/classes/com/sun/tools/javac/main/Main.java Mon Jun 16 13:28:00 2008 -0700 13.3 @@ -25,13 +25,13 @@ 13.4 13.5 package com.sun.tools.javac.main; 13.6 13.7 -import com.sun.tools.javac.util.Options; 13.8 import java.io.File; 13.9 import java.io.IOException; 13.10 import java.io.PrintWriter; 13.11 import java.util.MissingResourceException; 13.12 13.13 import com.sun.tools.javac.code.Source; 13.14 +import com.sun.tools.javac.file.JavacFileManager; 13.15 import com.sun.tools.javac.jvm.Target; 13.16 import com.sun.tools.javac.main.JavacOption.Option; 13.17 import com.sun.tools.javac.main.RecognizedOptions.OptionHelper;
14.1 --- a/src/share/classes/com/sun/tools/javac/parser/Scanner.java Fri Jun 06 15:17:35 2008 -0700 14.2 +++ b/src/share/classes/com/sun/tools/javac/parser/Scanner.java Mon Jun 16 13:28:00 2008 -0700 14.3 @@ -25,16 +25,12 @@ 14.4 14.5 package com.sun.tools.javac.parser; 14.6 14.7 -import java.io.*; 14.8 import java.nio.*; 14.9 -import java.nio.ByteBuffer; 14.10 -import java.nio.charset.*; 14.11 -import java.nio.channels.*; 14.12 -import java.util.regex.*; 14.13 14.14 +import com.sun.tools.javac.code.Source; 14.15 +import com.sun.tools.javac.file.JavacFileManager; 14.16 import com.sun.tools.javac.util.*; 14.17 14.18 -import com.sun.tools.javac.code.Source; 14.19 14.20 import static com.sun.tools.javac.parser.Token.*; 14.21 import static com.sun.tools.javac.util.LayoutCharacters.*;
15.1 --- a/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Fri Jun 06 15:17:35 2008 -0700 15.2 +++ b/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Mon Jun 16 13:28:00 2008 -0700 15.3 @@ -25,22 +25,17 @@ 15.4 15.5 package com.sun.tools.javac.processing; 15.6 15.7 -import com.sun.source.util.TaskEvent; 15.8 -import com.sun.source.util.TaskListener; 15.9 -import com.sun.tools.javac.api.JavacTaskImpl; 15.10 -import com.sun.tools.javac.util.List; 15.11 -import com.sun.tools.javac.util.*; 15.12 -import com.sun.tools.javac.code.*; 15.13 -import com.sun.tools.javac.code.Symbol.*; 15.14 -import com.sun.tools.javac.comp.*; 15.15 -import com.sun.tools.javac.jvm.*; 15.16 -import com.sun.tools.javac.tree.*; 15.17 -import com.sun.tools.javac.parser.*; 15.18 -import com.sun.tools.javac.code.Symbol.*; 15.19 -import com.sun.tools.javac.model.JavacElements; 15.20 -import com.sun.tools.javac.model.JavacTypes; 15.21 -import com.sun.tools.javac.tree.JCTree.*; 15.22 -import com.sun.tools.javac.main.JavaCompiler; 15.23 + 15.24 +import java.lang.reflect.*; 15.25 +import java.util.*; 15.26 +import java.util.regex.*; 15.27 + 15.28 +import java.net.URL; 15.29 +import java.io.Closeable; 15.30 +import java.io.File; 15.31 +import java.io.PrintWriter; 15.32 +import java.io.IOException; 15.33 +import java.net.MalformedURLException; 15.34 import java.io.StringWriter; 15.35 15.36 import javax.annotation.processing.*; 15.37 @@ -50,25 +45,35 @@ 15.38 import javax.lang.model.element.TypeElement; 15.39 import javax.lang.model.element.PackageElement; 15.40 import javax.lang.model.util.*; 15.41 - 15.42 import javax.tools.JavaFileManager; 15.43 import javax.tools.StandardJavaFileManager; 15.44 import javax.tools.JavaFileObject; 15.45 import javax.tools.DiagnosticListener; 15.46 + 15.47 +import com.sun.source.util.TaskEvent; 15.48 +import com.sun.source.util.TaskListener; 15.49 +import com.sun.tools.javac.api.JavacTaskImpl; 15.50 +import com.sun.tools.javac.code.*; 15.51 +import com.sun.tools.javac.code.Symbol.*; 15.52 +import com.sun.tools.javac.file.Paths; 15.53 +import com.sun.tools.javac.file.JavacFileManager; 15.54 +import com.sun.tools.javac.jvm.*; 15.55 +import com.sun.tools.javac.main.JavaCompiler; 15.56 +import com.sun.tools.javac.model.JavacElements; 15.57 +import com.sun.tools.javac.model.JavacTypes; 15.58 +import com.sun.tools.javac.parser.*; 15.59 +import com.sun.tools.javac.tree.*; 15.60 +import com.sun.tools.javac.tree.JCTree.*; 15.61 +import com.sun.tools.javac.util.Abort; 15.62 +import com.sun.tools.javac.util.Context; 15.63 +import com.sun.tools.javac.util.List; 15.64 +import com.sun.tools.javac.util.ListBuffer; 15.65 +import com.sun.tools.javac.util.Log; 15.66 +import com.sun.tools.javac.util.Name; 15.67 +import com.sun.tools.javac.util.Options; 15.68 + 15.69 import static javax.tools.StandardLocation.*; 15.70 15.71 -import java.lang.reflect.*; 15.72 -import java.util.*; 15.73 -import java.util.regex.*; 15.74 - 15.75 -import java.net.URLClassLoader; 15.76 -import java.net.URL; 15.77 -import java.io.Closeable; 15.78 -import java.io.File; 15.79 -import java.io.PrintWriter; 15.80 -import java.io.IOException; 15.81 -import java.net.MalformedURLException; 15.82 - 15.83 /** 15.84 * Objects of this class hold and manage the state needed to support 15.85 * annotation processing.
16.1 --- a/src/share/classes/com/sun/tools/javac/util/BaseFileObject.java Fri Jun 06 15:17:35 2008 -0700 16.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 16.3 @@ -1,79 +0,0 @@ 16.4 -/* 16.5 - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. 16.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 16.7 - * 16.8 - * This code is free software; you can redistribute it and/or modify it 16.9 - * under the terms of the GNU General Public License version 2 only, as 16.10 - * published by the Free Software Foundation. Sun designates this 16.11 - * particular file as subject to the "Classpath" exception as provided 16.12 - * by Sun in the LICENSE file that accompanied this code. 16.13 - * 16.14 - * This code is distributed in the hope that it will be useful, but WITHOUT 16.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16.17 - * version 2 for more details (a copy is included in the LICENSE file that 16.18 - * accompanied this code). 16.19 - * 16.20 - * You should have received a copy of the GNU General Public License version 16.21 - * 2 along with this work; if not, write to the Free Software Foundation, 16.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 16.23 - * 16.24 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 16.25 - * CA 95054 USA or visit www.sun.com if you need additional information or 16.26 - * have any questions. 16.27 - */ 16.28 - 16.29 -package com.sun.tools.javac.util; 16.30 - 16.31 -import java.io.IOException; 16.32 -import java.io.InputStreamReader; 16.33 -import java.io.Reader; 16.34 -import java.nio.charset.CharsetDecoder; 16.35 -import javax.lang.model.element.Modifier; 16.36 -import javax.lang.model.element.NestingKind; 16.37 -import javax.tools.JavaFileObject; 16.38 - 16.39 -import static javax.tools.JavaFileObject.Kind.*; 16.40 - 16.41 -public abstract class BaseFileObject implements JavaFileObject { 16.42 - 16.43 - public JavaFileObject.Kind getKind() { 16.44 - String n = getName(); 16.45 - if (n.endsWith(CLASS.extension)) 16.46 - return CLASS; 16.47 - else if (n.endsWith(SOURCE.extension)) 16.48 - return SOURCE; 16.49 - else if (n.endsWith(HTML.extension)) 16.50 - return HTML; 16.51 - else 16.52 - return OTHER; 16.53 - } 16.54 - 16.55 - @Override 16.56 - public String toString() { 16.57 - return getPath(); 16.58 - } 16.59 - 16.60 - /** @deprecated see bug 6410637 */ 16.61 - @Deprecated 16.62 - public String getPath() { 16.63 - return getName(); 16.64 - } 16.65 - 16.66 - /** @deprecated see bug 6410637 */ 16.67 - @Deprecated 16.68 - abstract public String getName(); 16.69 - 16.70 - public NestingKind getNestingKind() { return null; } 16.71 - 16.72 - public Modifier getAccessLevel() { return null; } 16.73 - 16.74 - public Reader openReader(boolean ignoreEncodingErrors) throws IOException { 16.75 - return new InputStreamReader(openInputStream(), getDecoder(ignoreEncodingErrors)); 16.76 - } 16.77 - 16.78 - protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) { 16.79 - throw new UnsupportedOperationException(); 16.80 - } 16.81 - 16.82 -}
17.1 --- a/src/share/classes/com/sun/tools/javac/util/DiagnosticFormatter.java Fri Jun 06 15:17:35 2008 -0700 17.2 +++ b/src/share/classes/com/sun/tools/javac/util/DiagnosticFormatter.java Mon Jun 16 13:28:00 2008 -0700 17.3 @@ -27,6 +27,7 @@ 17.4 17.5 import javax.tools.JavaFileObject; 17.6 17.7 +import com.sun.tools.javac.file.JavacFileManager; 17.8 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticSource; 17.9 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType; 17.10
18.1 --- a/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java Fri Jun 06 15:17:35 2008 -0700 18.2 +++ b/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java Mon Jun 16 13:28:00 2008 -0700 18.3 @@ -25,17 +25,13 @@ 18.4 18.5 package com.sun.tools.javac.util; 18.6 18.7 -import java.net.URI; 18.8 -import java.text.MessageFormat; 18.9 import java.util.Locale; 18.10 import java.util.Map; 18.11 -import java.util.MissingResourceException; 18.12 -import java.util.ResourceBundle; 18.13 18.14 import javax.tools.Diagnostic; 18.15 -import javax.tools.FileObject; 18.16 import javax.tools.JavaFileObject; 18.17 18.18 +import com.sun.tools.javac.file.JavacFileManager; 18.19 import com.sun.tools.javac.tree.JCTree; 18.20 18.21 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticType.*;
19.1 --- a/src/share/classes/com/sun/tools/javac/util/JavacFileManager.java Fri Jun 06 15:17:35 2008 -0700 19.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 19.3 @@ -1,1715 +0,0 @@ 19.4 -/* 19.5 - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. 19.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 19.7 - * 19.8 - * This code is free software; you can redistribute it and/or modify it 19.9 - * under the terms of the GNU General Public License version 2 only, as 19.10 - * published by the Free Software Foundation. Sun designates this 19.11 - * particular file as subject to the "Classpath" exception as provided 19.12 - * by Sun in the LICENSE file that accompanied this code. 19.13 - * 19.14 - * This code is distributed in the hope that it will be useful, but WITHOUT 19.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 19.17 - * version 2 for more details (a copy is included in the LICENSE file that 19.18 - * accompanied this code). 19.19 - * 19.20 - * You should have received a copy of the GNU General Public License version 19.21 - * 2 along with this work; if not, write to the Free Software Foundation, 19.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19.23 - * 19.24 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 19.25 - * CA 95054 USA or visit www.sun.com if you need additional information or 19.26 - * have any questions. 19.27 - */ 19.28 - 19.29 -package com.sun.tools.javac.util; 19.30 - 19.31 -import com.sun.tools.javac.main.JavacOption; 19.32 -import com.sun.tools.javac.main.OptionName; 19.33 -import com.sun.tools.javac.main.RecognizedOptions; 19.34 -import java.io.ByteArrayOutputStream; 19.35 -import java.io.File; 19.36 -import java.io.FileInputStream; 19.37 -import java.io.FileNotFoundException; 19.38 -import java.io.FileOutputStream; 19.39 -import java.io.IOException; 19.40 -import java.io.InputStream; 19.41 -import java.io.OutputStream; 19.42 -import java.io.OutputStreamWriter; 19.43 -import java.io.Writer; 19.44 -import java.lang.ref.SoftReference; 19.45 -import java.net.MalformedURLException; 19.46 -import java.net.URI; 19.47 -import java.net.URISyntaxException; 19.48 -import java.net.URL; 19.49 -import java.net.URLClassLoader; 19.50 -import java.nio.ByteBuffer; 19.51 -import java.nio.CharBuffer; 19.52 -import java.nio.channels.FileChannel; 19.53 -import java.nio.charset.Charset; 19.54 -import java.nio.charset.CharsetDecoder; 19.55 -import java.nio.charset.CoderResult; 19.56 -import java.nio.charset.CodingErrorAction; 19.57 -import java.nio.charset.IllegalCharsetNameException; 19.58 -import java.nio.charset.UnsupportedCharsetException; 19.59 -import java.util.ArrayList; 19.60 -import java.util.Arrays; 19.61 -import java.util.Collection; 19.62 -import java.util.Collections; 19.63 -import java.util.EnumSet; 19.64 -import java.util.Enumeration; 19.65 -import java.util.HashMap; 19.66 -import java.util.Iterator; 19.67 -import java.util.Map; 19.68 -import java.util.Set; 19.69 -import java.util.zip.ZipEntry; 19.70 -import java.util.zip.ZipFile; 19.71 - 19.72 -import javax.lang.model.SourceVersion; 19.73 -import javax.tools.FileObject; 19.74 -import javax.tools.JavaFileManager; 19.75 -import javax.tools.JavaFileObject; 19.76 - 19.77 -import com.sun.tools.javac.code.Source; 19.78 -import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition; 19.79 -import java.util.concurrent.ConcurrentHashMap; 19.80 -import javax.tools.StandardJavaFileManager; 19.81 - 19.82 -import com.sun.tools.javac.zip.*; 19.83 -import java.io.ByteArrayInputStream; 19.84 - 19.85 -import static com.sun.tools.javac.main.OptionName.*; 19.86 -import static javax.tools.StandardLocation.*; 19.87 - 19.88 -/** 19.89 - * This class provides access to the source, class and other files 19.90 - * used by the compiler and related tools. 19.91 - */ 19.92 -public class JavacFileManager implements StandardJavaFileManager { 19.93 - 19.94 - private static final String[] symbolFileLocation = { "lib", "ct.sym" }; 19.95 - private static final String symbolFilePrefix = "META-INF/sym/rt.jar/"; 19.96 - 19.97 - boolean useZipFileIndex; 19.98 - 19.99 - private static int symbolFilePrefixLength = 0; 19.100 - static { 19.101 - try { 19.102 - symbolFilePrefixLength = symbolFilePrefix.getBytes("UTF-8").length; 19.103 - } catch (java.io.UnsupportedEncodingException uee) { 19.104 - // Can't happen...UTF-8 is always supported. 19.105 - } 19.106 - } 19.107 - 19.108 - private static boolean CHECK_ZIP_TIMESTAMP = false; 19.109 - private static Map<File, Boolean> isDirectory = new ConcurrentHashMap<File, Boolean>(); 19.110 - 19.111 - 19.112 - public static char[] toArray(CharBuffer buffer) { 19.113 - if (buffer.hasArray()) 19.114 - return ((CharBuffer)buffer.compact().flip()).array(); 19.115 - else 19.116 - return buffer.toString().toCharArray(); 19.117 - } 19.118 - 19.119 - /** 19.120 - * The log to be used for error reporting. 19.121 - */ 19.122 - protected Log log; 19.123 - 19.124 - /** Encapsulates knowledge of paths 19.125 - */ 19.126 - private Paths paths; 19.127 - 19.128 - private Options options; 19.129 - 19.130 - private final File uninited = new File("U N I N I T E D"); 19.131 - 19.132 - private final Set<JavaFileObject.Kind> sourceOrClass = 19.133 - EnumSet.of(JavaFileObject.Kind.SOURCE, JavaFileObject.Kind.CLASS); 19.134 - 19.135 - /** The standard output directory, primarily used for classes. 19.136 - * Initialized by the "-d" option. 19.137 - * If classOutDir = null, files are written into same directory as the sources 19.138 - * they were generated from. 19.139 - */ 19.140 - private File classOutDir = uninited; 19.141 - 19.142 - /** The output directory, used when generating sources while processing annotations. 19.143 - * Initialized by the "-s" option. 19.144 - */ 19.145 - private File sourceOutDir = uninited; 19.146 - 19.147 - protected boolean mmappedIO; 19.148 - protected boolean ignoreSymbolFile; 19.149 - 19.150 - /** 19.151 - * User provided charset (through javax.tools). 19.152 - */ 19.153 - protected Charset charset; 19.154 - 19.155 - /** 19.156 - * Register a Context.Factory to create a JavacFileManager. 19.157 - */ 19.158 - public static void preRegister(final Context context) { 19.159 - context.put(JavaFileManager.class, new Context.Factory<JavaFileManager>() { 19.160 - public JavaFileManager make() { 19.161 - return new JavacFileManager(context, true, null); 19.162 - } 19.163 - }); 19.164 - } 19.165 - 19.166 - /** 19.167 - * Create a JavacFileManager using a given context, optionally registering 19.168 - * it as the JavaFileManager for that context. 19.169 - */ 19.170 - public JavacFileManager(Context context, boolean register, Charset charset) { 19.171 - if (register) 19.172 - context.put(JavaFileManager.class, this); 19.173 - byteBufferCache = new ByteBufferCache(); 19.174 - this.charset = charset; 19.175 - setContext(context); 19.176 - } 19.177 - 19.178 - /** 19.179 - * Set the context for JavacFileManager. 19.180 - */ 19.181 - public void setContext(Context context) { 19.182 - log = Log.instance(context); 19.183 - if (paths == null) { 19.184 - paths = Paths.instance(context); 19.185 - } else { 19.186 - // Reuse the Paths object as it stores the locations that 19.187 - // have been set with setLocation, etc. 19.188 - paths.setContext(context); 19.189 - } 19.190 - 19.191 - options = Options.instance(context); 19.192 - 19.193 - useZipFileIndex = System.getProperty("useJavaUtilZip") == null;// TODO: options.get("useJavaUtilZip") == null; 19.194 - CHECK_ZIP_TIMESTAMP = System.getProperty("checkZipIndexTimestamp") != null;// TODO: options.get("checkZipIndexTimestamp") != null; 19.195 - 19.196 - mmappedIO = options.get("mmappedIO") != null; 19.197 - ignoreSymbolFile = options.get("ignore.symbol.file") != null; 19.198 - } 19.199 - 19.200 - public JavaFileObject getFileForInput(String name) { 19.201 - return getRegularFile(new File(name)); 19.202 - } 19.203 - 19.204 - public JavaFileObject getRegularFile(File file) { 19.205 - return new RegularFileObject(file); 19.206 - } 19.207 - 19.208 - public JavaFileObject getFileForOutput(String classname, 19.209 - JavaFileObject.Kind kind, 19.210 - JavaFileObject sibling) 19.211 - throws IOException 19.212 - { 19.213 - return getJavaFileForOutput(CLASS_OUTPUT, classname, kind, sibling); 19.214 - } 19.215 - 19.216 - public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(Iterable<String> names) { 19.217 - ListBuffer<File> files = new ListBuffer<File>(); 19.218 - for (String name : names) 19.219 - files.append(new File(nullCheck(name))); 19.220 - return getJavaFileObjectsFromFiles(files.toList()); 19.221 - } 19.222 - 19.223 - public Iterable<? extends JavaFileObject> getJavaFileObjects(String... names) { 19.224 - return getJavaFileObjectsFromStrings(Arrays.asList(nullCheck(names))); 19.225 - } 19.226 - 19.227 - protected JavaFileObject.Kind getKind(String extension) { 19.228 - if (extension.equals(JavaFileObject.Kind.CLASS.extension)) 19.229 - return JavaFileObject.Kind.CLASS; 19.230 - else if (extension.equals(JavaFileObject.Kind.SOURCE.extension)) 19.231 - return JavaFileObject.Kind.SOURCE; 19.232 - else if (extension.equals(JavaFileObject.Kind.HTML.extension)) 19.233 - return JavaFileObject.Kind.HTML; 19.234 - else 19.235 - return JavaFileObject.Kind.OTHER; 19.236 - } 19.237 - 19.238 - private static boolean isValidName(String name) { 19.239 - // Arguably, isValidName should reject keywords (such as in SourceVersion.isName() ), 19.240 - // but the set of keywords depends on the source level, and we don't want 19.241 - // impls of JavaFileManager to have to be dependent on the source level. 19.242 - // Therefore we simply check that the argument is a sequence of identifiers 19.243 - // separated by ".". 19.244 - for (String s : name.split("\\.", -1)) { 19.245 - if (!SourceVersion.isIdentifier(s)) 19.246 - return false; 19.247 - } 19.248 - return true; 19.249 - } 19.250 - 19.251 - private static void validateClassName(String className) { 19.252 - if (!isValidName(className)) 19.253 - throw new IllegalArgumentException("Invalid class name: " + className); 19.254 - } 19.255 - 19.256 - private static void validatePackageName(String packageName) { 19.257 - if (packageName.length() > 0 && !isValidName(packageName)) 19.258 - throw new IllegalArgumentException("Invalid packageName name: " + packageName); 19.259 - } 19.260 - 19.261 - public static void testName(String name, 19.262 - boolean isValidPackageName, 19.263 - boolean isValidClassName) 19.264 - { 19.265 - try { 19.266 - validatePackageName(name); 19.267 - if (!isValidPackageName) 19.268 - throw new AssertionError("Invalid package name accepted: " + name); 19.269 - printAscii("Valid package name: \"%s\"", name); 19.270 - } catch (IllegalArgumentException e) { 19.271 - if (isValidPackageName) 19.272 - throw new AssertionError("Valid package name rejected: " + name); 19.273 - printAscii("Invalid package name: \"%s\"", name); 19.274 - } 19.275 - try { 19.276 - validateClassName(name); 19.277 - if (!isValidClassName) 19.278 - throw new AssertionError("Invalid class name accepted: " + name); 19.279 - printAscii("Valid class name: \"%s\"", name); 19.280 - } catch (IllegalArgumentException e) { 19.281 - if (isValidClassName) 19.282 - throw new AssertionError("Valid class name rejected: " + name); 19.283 - printAscii("Invalid class name: \"%s\"", name); 19.284 - } 19.285 - } 19.286 - private static void printAscii(String format, Object... args) { 19.287 - String message; 19.288 - try { 19.289 - final String ascii = "US-ASCII"; 19.290 - message = new String(String.format(null, format, args).getBytes(ascii), ascii); 19.291 - } catch (java.io.UnsupportedEncodingException ex) { 19.292 - throw new AssertionError(ex); 19.293 - } 19.294 - System.out.println(message); 19.295 - } 19.296 - 19.297 - /** Return external representation of name, 19.298 - * converting '.' to File.separatorChar. 19.299 - */ 19.300 - private static String externalizeFileName(CharSequence name) { 19.301 - return name.toString().replace('.', File.separatorChar); 19.302 - } 19.303 - 19.304 - private static String externalizeFileName(CharSequence n, JavaFileObject.Kind kind) { 19.305 - return externalizeFileName(n) + kind.extension; 19.306 - } 19.307 - 19.308 - private static String baseName(String fileName) { 19.309 - return fileName.substring(fileName.lastIndexOf(File.separatorChar) + 1); 19.310 - } 19.311 - 19.312 - /** 19.313 - * Insert all files in subdirectory `subdirectory' of `directory' which end 19.314 - * in one of the extensions in `extensions' into packageSym. 19.315 - */ 19.316 - private void listDirectory(File directory, 19.317 - String subdirectory, 19.318 - Set<JavaFileObject.Kind> fileKinds, 19.319 - boolean recurse, 19.320 - ListBuffer<JavaFileObject> l) { 19.321 - Archive archive = archives.get(directory); 19.322 - 19.323 - boolean isFile = false; 19.324 - if (CHECK_ZIP_TIMESTAMP) { 19.325 - Boolean isf = isDirectory.get(directory); 19.326 - if (isf == null) { 19.327 - isFile = directory.isFile(); 19.328 - isDirectory.put(directory, isFile); 19.329 - } 19.330 - else { 19.331 - isFile = directory.isFile(); 19.332 - } 19.333 - } 19.334 - else { 19.335 - isFile = directory.isFile(); 19.336 - } 19.337 - 19.338 - if (archive != null || isFile) { 19.339 - if (archive == null) { 19.340 - try { 19.341 - archive = openArchive(directory); 19.342 - } catch (IOException ex) { 19.343 - log.error("error.reading.file", 19.344 - directory, ex.getLocalizedMessage()); 19.345 - return; 19.346 - } 19.347 - } 19.348 - if (subdirectory.length() != 0) { 19.349 - if (!useZipFileIndex) { 19.350 - subdirectory = subdirectory.replace('\\', '/'); 19.351 - if (!subdirectory.endsWith("/")) subdirectory = subdirectory + "/"; 19.352 - } 19.353 - else { 19.354 - if (File.separatorChar == '/') { 19.355 - subdirectory = subdirectory.replace('\\', '/'); 19.356 - } 19.357 - else { 19.358 - subdirectory = subdirectory.replace('/', '\\'); 19.359 - } 19.360 - 19.361 - if (!subdirectory.endsWith(File.separator)) subdirectory = subdirectory + File.separator; 19.362 - } 19.363 - } 19.364 - 19.365 - List<String> files = archive.getFiles(subdirectory); 19.366 - if (files != null) { 19.367 - for (String file; !files.isEmpty(); files = files.tail) { 19.368 - file = files.head; 19.369 - if (isValidFile(file, fileKinds)) { 19.370 - l.append(archive.getFileObject(subdirectory, file)); 19.371 - } 19.372 - } 19.373 - } 19.374 - if (recurse) { 19.375 - for (String s: archive.getSubdirectories()) { 19.376 - if (s.startsWith(subdirectory) && !s.equals(subdirectory)) { 19.377 - // Because the archive map is a flat list of directories, 19.378 - // the enclosing loop will pick up all child subdirectories. 19.379 - // Therefore, there is no need to recurse deeper. 19.380 - listDirectory(directory, s, fileKinds, false, l); 19.381 - } 19.382 - } 19.383 - } 19.384 - } else { 19.385 - File d = subdirectory.length() != 0 19.386 - ? new File(directory, subdirectory) 19.387 - : directory; 19.388 - if (!caseMapCheck(d, subdirectory)) 19.389 - return; 19.390 - 19.391 - File[] files = d.listFiles(); 19.392 - if (files == null) 19.393 - return; 19.394 - 19.395 - for (File f: files) { 19.396 - String fname = f.getName(); 19.397 - if (f.isDirectory()) { 19.398 - if (recurse && SourceVersion.isIdentifier(fname)) { 19.399 - listDirectory(directory, 19.400 - subdirectory + File.separator + fname, 19.401 - fileKinds, 19.402 - recurse, 19.403 - l); 19.404 - } 19.405 - } else { 19.406 - if (isValidFile(fname, fileKinds)) { 19.407 - JavaFileObject fe = 19.408 - new RegularFileObject(fname, new File(d, fname)); 19.409 - l.append(fe); 19.410 - } 19.411 - } 19.412 - } 19.413 - } 19.414 - } 19.415 - 19.416 - private boolean isValidFile(String s, Set<JavaFileObject.Kind> fileKinds) { 19.417 - int lastDot = s.lastIndexOf("."); 19.418 - String extn = (lastDot == -1 ? s : s.substring(lastDot)); 19.419 - JavaFileObject.Kind kind = getKind(extn); 19.420 - return fileKinds.contains(kind); 19.421 - } 19.422 - 19.423 - private static final boolean fileSystemIsCaseSensitive = 19.424 - File.separatorChar == '/'; 19.425 - 19.426 - /** Hack to make Windows case sensitive. Test whether given path 19.427 - * ends in a string of characters with the same case as given name. 19.428 - * Ignore file separators in both path and name. 19.429 - */ 19.430 - private boolean caseMapCheck(File f, String name) { 19.431 - if (fileSystemIsCaseSensitive) return true; 19.432 - // Note that getCanonicalPath() returns the case-sensitive 19.433 - // spelled file name. 19.434 - String path; 19.435 - try { 19.436 - path = f.getCanonicalPath(); 19.437 - } catch (IOException ex) { 19.438 - return false; 19.439 - } 19.440 - char[] pcs = path.toCharArray(); 19.441 - char[] ncs = name.toCharArray(); 19.442 - int i = pcs.length - 1; 19.443 - int j = ncs.length - 1; 19.444 - while (i >= 0 && j >= 0) { 19.445 - while (i >= 0 && pcs[i] == File.separatorChar) i--; 19.446 - while (j >= 0 && ncs[j] == File.separatorChar) j--; 19.447 - if (i >= 0 && j >= 0) { 19.448 - if (pcs[i] != ncs[j]) return false; 19.449 - i--; 19.450 - j--; 19.451 - } 19.452 - } 19.453 - return j < 0; 19.454 - } 19.455 - 19.456 - /** 19.457 - * An archive provides a flat directory structure of a ZipFile by 19.458 - * mapping directory names to lists of files (basenames). 19.459 - */ 19.460 - public interface Archive { 19.461 - void close() throws IOException; 19.462 - 19.463 - boolean contains(String name); 19.464 - 19.465 - JavaFileObject getFileObject(String subdirectory, String file); 19.466 - 19.467 - List<String> getFiles(String subdirectory); 19.468 - 19.469 - Set<String> getSubdirectories(); 19.470 - } 19.471 - 19.472 - public class ZipArchive implements Archive { 19.473 - protected final Map<String,List<String>> map; 19.474 - protected final ZipFile zdir; 19.475 - public ZipArchive(ZipFile zdir) throws IOException { 19.476 - this.zdir = zdir; 19.477 - this.map = new HashMap<String,List<String>>(); 19.478 - for (Enumeration<? extends ZipEntry> e = zdir.entries(); e.hasMoreElements(); ) { 19.479 - ZipEntry entry; 19.480 - try { 19.481 - entry = e.nextElement(); 19.482 - } catch (InternalError ex) { 19.483 - IOException io = new IOException(); 19.484 - io.initCause(ex); // convenience constructors added in Mustang :-( 19.485 - throw io; 19.486 - } 19.487 - addZipEntry(entry); 19.488 - } 19.489 - } 19.490 - 19.491 - void addZipEntry(ZipEntry entry) { 19.492 - String name = entry.getName(); 19.493 - int i = name.lastIndexOf('/'); 19.494 - String dirname = name.substring(0, i+1); 19.495 - String basename = name.substring(i+1); 19.496 - if (basename.length() == 0) 19.497 - return; 19.498 - List<String> list = map.get(dirname); 19.499 - if (list == null) 19.500 - list = List.nil(); 19.501 - list = list.prepend(basename); 19.502 - map.put(dirname, list); 19.503 - } 19.504 - 19.505 - public boolean contains(String name) { 19.506 - int i = name.lastIndexOf('/'); 19.507 - String dirname = name.substring(0, i+1); 19.508 - String basename = name.substring(i+1); 19.509 - if (basename.length() == 0) 19.510 - return false; 19.511 - List<String> list = map.get(dirname); 19.512 - return (list != null && list.contains(basename)); 19.513 - } 19.514 - 19.515 - public List<String> getFiles(String subdirectory) { 19.516 - return map.get(subdirectory); 19.517 - } 19.518 - 19.519 - public JavaFileObject getFileObject(String subdirectory, String file) { 19.520 - ZipEntry ze = zdir.getEntry(subdirectory + file); 19.521 - return new ZipFileObject(file, zdir, ze); 19.522 - } 19.523 - 19.524 - public Set<String> getSubdirectories() { 19.525 - return map.keySet(); 19.526 - } 19.527 - 19.528 - public void close() throws IOException { 19.529 - zdir.close(); 19.530 - } 19.531 - } 19.532 - 19.533 - public class SymbolArchive extends ZipArchive { 19.534 - final File origFile; 19.535 - public SymbolArchive(File orig, ZipFile zdir) throws IOException { 19.536 - super(zdir); 19.537 - this.origFile = orig; 19.538 - } 19.539 - 19.540 - @Override 19.541 - void addZipEntry(ZipEntry entry) { 19.542 - // called from super constructor, may not refer to origFile. 19.543 - String name = entry.getName(); 19.544 - if (!name.startsWith(symbolFilePrefix)) 19.545 - return; 19.546 - name = name.substring(symbolFilePrefix.length()); 19.547 - int i = name.lastIndexOf('/'); 19.548 - String dirname = name.substring(0, i+1); 19.549 - String basename = name.substring(i+1); 19.550 - if (basename.length() == 0) 19.551 - return; 19.552 - List<String> list = map.get(dirname); 19.553 - if (list == null) 19.554 - list = List.nil(); 19.555 - list = list.prepend(basename); 19.556 - map.put(dirname, list); 19.557 - } 19.558 - 19.559 - @Override 19.560 - public JavaFileObject getFileObject(String subdirectory, String file) { 19.561 - return super.getFileObject(symbolFilePrefix + subdirectory, file); 19.562 - } 19.563 - } 19.564 - 19.565 - public class MissingArchive implements Archive { 19.566 - final File zipFileName; 19.567 - public MissingArchive(File name) { 19.568 - zipFileName = name; 19.569 - } 19.570 - public boolean contains(String name) { 19.571 - return false; 19.572 - } 19.573 - 19.574 - public void close() { 19.575 - } 19.576 - 19.577 - public JavaFileObject getFileObject(String subdirectory, String file) { 19.578 - return null; 19.579 - } 19.580 - 19.581 - public List<String> getFiles(String subdirectory) { 19.582 - return List.nil(); 19.583 - } 19.584 - 19.585 - public Set<String> getSubdirectories() { 19.586 - return Collections.emptySet(); 19.587 - } 19.588 - } 19.589 - 19.590 - /** A directory of zip files already opened. 19.591 - */ 19.592 - Map<File, Archive> archives = new HashMap<File,Archive>(); 19.593 - 19.594 - /** Open a new zip file directory. 19.595 - */ 19.596 - protected Archive openArchive(File zipFileName) throws IOException { 19.597 - Archive archive = archives.get(zipFileName); 19.598 - if (archive == null) { 19.599 - File origZipFileName = zipFileName; 19.600 - if (!ignoreSymbolFile && paths.isBootClassPathRtJar(zipFileName)) { 19.601 - File file = zipFileName.getParentFile().getParentFile(); // ${java.home} 19.602 - if (new File(file.getName()).equals(new File("jre"))) 19.603 - file = file.getParentFile(); 19.604 - // file == ${jdk.home} 19.605 - for (String name : symbolFileLocation) 19.606 - file = new File(file, name); 19.607 - // file == ${jdk.home}/lib/ct.sym 19.608 - if (file.exists()) 19.609 - zipFileName = file; 19.610 - } 19.611 - 19.612 - try { 19.613 - 19.614 - ZipFile zdir = null; 19.615 - 19.616 - boolean usePreindexedCache = false; 19.617 - String preindexCacheLocation = null; 19.618 - 19.619 - if (!useZipFileIndex) { 19.620 - zdir = new ZipFile(zipFileName); 19.621 - } 19.622 - else { 19.623 - usePreindexedCache = options.get("usezipindex") != null; 19.624 - preindexCacheLocation = options.get("java.io.tmpdir"); 19.625 - String optCacheLoc = options.get("cachezipindexdir"); 19.626 - 19.627 - if (optCacheLoc != null && optCacheLoc.length() != 0) { 19.628 - if (optCacheLoc.startsWith("\"")) { 19.629 - if (optCacheLoc.endsWith("\"")) { 19.630 - optCacheLoc = optCacheLoc.substring(1, optCacheLoc.length() - 1); 19.631 - } 19.632 - else { 19.633 - optCacheLoc = optCacheLoc.substring(1); 19.634 - } 19.635 - } 19.636 - 19.637 - File cacheDir = new File(optCacheLoc); 19.638 - if (cacheDir.exists() && cacheDir.canWrite()) { 19.639 - preindexCacheLocation = optCacheLoc; 19.640 - if (!preindexCacheLocation.endsWith("/") && 19.641 - !preindexCacheLocation.endsWith(File.separator)) { 19.642 - preindexCacheLocation += File.separator; 19.643 - } 19.644 - } 19.645 - } 19.646 - } 19.647 - 19.648 - if (origZipFileName == zipFileName) { 19.649 - if (!useZipFileIndex) { 19.650 - archive = new ZipArchive(zdir); 19.651 - } else { 19.652 - archive = new ZipFileIndexArchive(this, ZipFileIndex.getZipFileIndex(zipFileName, 0, 19.653 - usePreindexedCache, preindexCacheLocation, options.get("writezipindexfiles") != null)); 19.654 - } 19.655 - } 19.656 - else { 19.657 - if (!useZipFileIndex) { 19.658 - archive = new SymbolArchive(origZipFileName, zdir); 19.659 - } 19.660 - else { 19.661 - archive = new ZipFileIndexArchive(this, ZipFileIndex.getZipFileIndex(zipFileName, symbolFilePrefixLength, 19.662 - usePreindexedCache, preindexCacheLocation, options.get("writezipindexfiles") != null)); 19.663 - } 19.664 - } 19.665 - } catch (FileNotFoundException ex) { 19.666 - archive = new MissingArchive(zipFileName); 19.667 - } catch (IOException ex) { 19.668 - log.error("error.reading.file", zipFileName, ex.getLocalizedMessage()); 19.669 - archive = new MissingArchive(zipFileName); 19.670 - } 19.671 - 19.672 - archives.put(origZipFileName, archive); 19.673 - } 19.674 - return archive; 19.675 - } 19.676 - 19.677 - /** Flush any output resources. 19.678 - */ 19.679 - public void flush() { 19.680 - contentCache.clear(); 19.681 - } 19.682 - 19.683 - /** 19.684 - * Close the JavaFileManager, releasing resources. 19.685 - */ 19.686 - public void close() { 19.687 - for (Iterator<Archive> i = archives.values().iterator(); i.hasNext(); ) { 19.688 - Archive a = i.next(); 19.689 - i.remove(); 19.690 - try { 19.691 - a.close(); 19.692 - } catch (IOException e) { 19.693 - } 19.694 - } 19.695 - } 19.696 - 19.697 - private Map<JavaFileObject, SoftReference<CharBuffer>> contentCache = new HashMap<JavaFileObject, SoftReference<CharBuffer>>(); 19.698 - 19.699 - private String defaultEncodingName; 19.700 - private String getDefaultEncodingName() { 19.701 - if (defaultEncodingName == null) { 19.702 - defaultEncodingName = 19.703 - new OutputStreamWriter(new ByteArrayOutputStream()).getEncoding(); 19.704 - } 19.705 - return defaultEncodingName; 19.706 - } 19.707 - 19.708 - protected String getEncodingName() { 19.709 - String encName = options.get(OptionName.ENCODING); 19.710 - if (encName == null) 19.711 - return getDefaultEncodingName(); 19.712 - else 19.713 - return encName; 19.714 - } 19.715 - 19.716 - protected Source getSource() { 19.717 - String sourceName = options.get(OptionName.SOURCE); 19.718 - Source source = null; 19.719 - if (sourceName != null) 19.720 - source = Source.lookup(sourceName); 19.721 - return (source != null ? source : Source.DEFAULT); 19.722 - } 19.723 - 19.724 - /** 19.725 - * Make a byte buffer from an input stream. 19.726 - */ 19.727 - private ByteBuffer makeByteBuffer(InputStream in) 19.728 - throws IOException { 19.729 - int limit = in.available(); 19.730 - if (mmappedIO && in instanceof FileInputStream) { 19.731 - // Experimental memory mapped I/O 19.732 - FileInputStream fin = (FileInputStream)in; 19.733 - return fin.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, limit); 19.734 - } 19.735 - if (limit < 1024) limit = 1024; 19.736 - ByteBuffer result = byteBufferCache.get(limit); 19.737 - int position = 0; 19.738 - while (in.available() != 0) { 19.739 - if (position >= limit) 19.740 - // expand buffer 19.741 - result = ByteBuffer. 19.742 - allocate(limit <<= 1). 19.743 - put((ByteBuffer)result.flip()); 19.744 - int count = in.read(result.array(), 19.745 - position, 19.746 - limit - position); 19.747 - if (count < 0) break; 19.748 - result.position(position += count); 19.749 - } 19.750 - return (ByteBuffer)result.flip(); 19.751 - } 19.752 - 19.753 - /** 19.754 - * A single-element cache of direct byte buffers. 19.755 - */ 19.756 - private static class ByteBufferCache { 19.757 - private ByteBuffer cached; 19.758 - ByteBuffer get(int capacity) { 19.759 - if (capacity < 20480) capacity = 20480; 19.760 - ByteBuffer result = 19.761 - (cached != null && cached.capacity() >= capacity) 19.762 - ? (ByteBuffer)cached.clear() 19.763 - : ByteBuffer.allocate(capacity + capacity>>1); 19.764 - cached = null; 19.765 - return result; 19.766 - } 19.767 - void put(ByteBuffer x) { 19.768 - cached = x; 19.769 - } 19.770 - } 19.771 - private final ByteBufferCache byteBufferCache; 19.772 - 19.773 - private CharsetDecoder getDecoder(String encodingName, boolean ignoreEncodingErrors) { 19.774 - Charset charset = (this.charset == null) 19.775 - ? Charset.forName(encodingName) 19.776 - : this.charset; 19.777 - CharsetDecoder decoder = charset.newDecoder(); 19.778 - 19.779 - CodingErrorAction action; 19.780 - if (ignoreEncodingErrors) 19.781 - action = CodingErrorAction.REPLACE; 19.782 - else 19.783 - action = CodingErrorAction.REPORT; 19.784 - 19.785 - return decoder 19.786 - .onMalformedInput(action) 19.787 - .onUnmappableCharacter(action); 19.788 - } 19.789 - 19.790 - /** 19.791 - * Decode a ByteBuffer into a CharBuffer. 19.792 - */ 19.793 - private CharBuffer decode(ByteBuffer inbuf, boolean ignoreEncodingErrors) { 19.794 - String encodingName = getEncodingName(); 19.795 - CharsetDecoder decoder; 19.796 - try { 19.797 - decoder = getDecoder(encodingName, ignoreEncodingErrors); 19.798 - } catch (IllegalCharsetNameException e) { 19.799 - log.error("unsupported.encoding", encodingName); 19.800 - return (CharBuffer)CharBuffer.allocate(1).flip(); 19.801 - } catch (UnsupportedCharsetException e) { 19.802 - log.error("unsupported.encoding", encodingName); 19.803 - return (CharBuffer)CharBuffer.allocate(1).flip(); 19.804 - } 19.805 - 19.806 - // slightly overestimate the buffer size to avoid reallocation. 19.807 - float factor = 19.808 - decoder.averageCharsPerByte() * 0.8f + 19.809 - decoder.maxCharsPerByte() * 0.2f; 19.810 - CharBuffer dest = CharBuffer. 19.811 - allocate(10 + (int)(inbuf.remaining()*factor)); 19.812 - 19.813 - while (true) { 19.814 - CoderResult result = decoder.decode(inbuf, dest, true); 19.815 - dest.flip(); 19.816 - 19.817 - if (result.isUnderflow()) { // done reading 19.818 - // make sure there is at least one extra character 19.819 - if (dest.limit() == dest.capacity()) { 19.820 - dest = CharBuffer.allocate(dest.capacity()+1).put(dest); 19.821 - dest.flip(); 19.822 - } 19.823 - return dest; 19.824 - } else if (result.isOverflow()) { // buffer too small; expand 19.825 - int newCapacity = 19.826 - 10 + dest.capacity() + 19.827 - (int)(inbuf.remaining()*decoder.maxCharsPerByte()); 19.828 - dest = CharBuffer.allocate(newCapacity).put(dest); 19.829 - } else if (result.isMalformed() || result.isUnmappable()) { 19.830 - // bad character in input 19.831 - 19.832 - // report coding error (warn only pre 1.5) 19.833 - if (!getSource().allowEncodingErrors()) { 19.834 - log.error(new SimpleDiagnosticPosition(dest.limit()), 19.835 - "illegal.char.for.encoding", 19.836 - charset == null ? encodingName : charset.name()); 19.837 - } else { 19.838 - log.warning(new SimpleDiagnosticPosition(dest.limit()), 19.839 - "illegal.char.for.encoding", 19.840 - charset == null ? encodingName : charset.name()); 19.841 - } 19.842 - 19.843 - // skip past the coding error 19.844 - inbuf.position(inbuf.position() + result.length()); 19.845 - 19.846 - // undo the flip() to prepare the output buffer 19.847 - // for more translation 19.848 - dest.position(dest.limit()); 19.849 - dest.limit(dest.capacity()); 19.850 - dest.put((char)0xfffd); // backward compatible 19.851 - } else { 19.852 - throw new AssertionError(result); 19.853 - } 19.854 - } 19.855 - // unreached 19.856 - } 19.857 - 19.858 - public ClassLoader getClassLoader(Location location) { 19.859 - nullCheck(location); 19.860 - Iterable<? extends File> path = getLocation(location); 19.861 - if (path == null) 19.862 - return null; 19.863 - ListBuffer<URL> lb = new ListBuffer<URL>(); 19.864 - for (File f: path) { 19.865 - try { 19.866 - lb.append(f.toURI().toURL()); 19.867 - } catch (MalformedURLException e) { 19.868 - throw new AssertionError(e); 19.869 - } 19.870 - } 19.871 - return new URLClassLoader(lb.toArray(new URL[lb.size()]), 19.872 - getClass().getClassLoader()); 19.873 - } 19.874 - 19.875 - public Iterable<JavaFileObject> list(Location location, 19.876 - String packageName, 19.877 - Set<JavaFileObject.Kind> kinds, 19.878 - boolean recurse) 19.879 - throws IOException 19.880 - { 19.881 - // validatePackageName(packageName); 19.882 - nullCheck(packageName); 19.883 - nullCheck(kinds); 19.884 - 19.885 - Iterable<? extends File> path = getLocation(location); 19.886 - if (path == null) 19.887 - return List.nil(); 19.888 - String subdirectory = externalizeFileName(packageName); 19.889 - ListBuffer<JavaFileObject> results = new ListBuffer<JavaFileObject>(); 19.890 - 19.891 - for (File directory : path) 19.892 - listDirectory(directory, subdirectory, kinds, recurse, results); 19.893 - 19.894 - return results.toList(); 19.895 - } 19.896 - 19.897 - public String inferBinaryName(Location location, JavaFileObject file) { 19.898 - file.getClass(); // null check 19.899 - location.getClass(); // null check 19.900 - // Need to match the path semantics of list(location, ...) 19.901 - Iterable<? extends File> path = getLocation(location); 19.902 - if (path == null) { 19.903 - //System.err.println("Path for " + location + " is null"); 19.904 - return null; 19.905 - } 19.906 - //System.err.println("Path for " + location + " is " + path); 19.907 - 19.908 - if (file instanceof RegularFileObject) { 19.909 - RegularFileObject r = (RegularFileObject) file; 19.910 - String rPath = r.getPath(); 19.911 - //System.err.println("RegularFileObject " + file + " " +r.getPath()); 19.912 - for (File dir: path) { 19.913 - //System.err.println("dir: " + dir); 19.914 - String dPath = dir.getPath(); 19.915 - if (!dPath.endsWith(File.separator)) 19.916 - dPath += File.separator; 19.917 - if (rPath.regionMatches(true, 0, dPath, 0, dPath.length()) 19.918 - && new File(rPath.substring(0, dPath.length())).equals(new File(dPath))) { 19.919 - String relativeName = rPath.substring(dPath.length()); 19.920 - return removeExtension(relativeName).replace(File.separatorChar, '.'); 19.921 - } 19.922 - } 19.923 - } else if (file instanceof ZipFileObject) { 19.924 - ZipFileObject z = (ZipFileObject) file; 19.925 - String entryName = z.getZipEntryName(); 19.926 - if (entryName.startsWith(symbolFilePrefix)) 19.927 - entryName = entryName.substring(symbolFilePrefix.length()); 19.928 - return removeExtension(entryName).replace('/', '.'); 19.929 - } else if (file instanceof ZipFileIndexFileObject) { 19.930 - ZipFileIndexFileObject z = (ZipFileIndexFileObject) file; 19.931 - String entryName = z.getZipEntryName(); 19.932 - if (entryName.startsWith(symbolFilePrefix)) 19.933 - entryName = entryName.substring(symbolFilePrefix.length()); 19.934 - return removeExtension(entryName).replace(File.separatorChar, '.'); 19.935 - } else 19.936 - throw new IllegalArgumentException(file.getClass().getName()); 19.937 - // System.err.println("inferBinaryName failed for " + file); 19.938 - return null; 19.939 - } 19.940 - // where 19.941 - private static String removeExtension(String fileName) { 19.942 - int lastDot = fileName.lastIndexOf("."); 19.943 - return (lastDot == -1 ? fileName : fileName.substring(0, lastDot)); 19.944 - } 19.945 - 19.946 - public boolean isSameFile(FileObject a, FileObject b) { 19.947 - nullCheck(a); 19.948 - nullCheck(b); 19.949 - if (!(a instanceof BaseFileObject)) 19.950 - throw new IllegalArgumentException("Not supported: " + a); 19.951 - if (!(b instanceof BaseFileObject)) 19.952 - throw new IllegalArgumentException("Not supported: " + b); 19.953 - return a.equals(b); 19.954 - } 19.955 - 19.956 - public boolean handleOption(String current, Iterator<String> remaining) { 19.957 - for (JavacOption o: javacFileManagerOptions) { 19.958 - if (o.matches(current)) { 19.959 - if (o.hasArg()) { 19.960 - if (remaining.hasNext()) { 19.961 - if (!o.process(options, current, remaining.next())) 19.962 - return true; 19.963 - } 19.964 - } else { 19.965 - if (!o.process(options, current)) 19.966 - return true; 19.967 - } 19.968 - // operand missing, or process returned false 19.969 - throw new IllegalArgumentException(current); 19.970 - } 19.971 - } 19.972 - 19.973 - return false; 19.974 - } 19.975 - // where 19.976 - private static JavacOption[] javacFileManagerOptions = 19.977 - RecognizedOptions.getJavacFileManagerOptions( 19.978 - new RecognizedOptions.GrumpyHelper()); 19.979 - 19.980 - public int isSupportedOption(String option) { 19.981 - for (JavacOption o : javacFileManagerOptions) { 19.982 - if (o.matches(option)) 19.983 - return o.hasArg() ? 1 : 0; 19.984 - } 19.985 - return -1; 19.986 - } 19.987 - 19.988 - public boolean hasLocation(Location location) { 19.989 - return getLocation(location) != null; 19.990 - } 19.991 - 19.992 - public JavaFileObject getJavaFileForInput(Location location, 19.993 - String className, 19.994 - JavaFileObject.Kind kind) 19.995 - throws IOException 19.996 - { 19.997 - nullCheck(location); 19.998 - // validateClassName(className); 19.999 - nullCheck(className); 19.1000 - nullCheck(kind); 19.1001 - if (!sourceOrClass.contains(kind)) 19.1002 - throw new IllegalArgumentException("Invalid kind " + kind); 19.1003 - return getFileForInput(location, externalizeFileName(className, kind)); 19.1004 - } 19.1005 - 19.1006 - public FileObject getFileForInput(Location location, 19.1007 - String packageName, 19.1008 - String relativeName) 19.1009 - throws IOException 19.1010 - { 19.1011 - nullCheck(location); 19.1012 - // validatePackageName(packageName); 19.1013 - nullCheck(packageName); 19.1014 - if (!isRelativeUri(URI.create(relativeName))) // FIXME 6419701 19.1015 - throw new IllegalArgumentException("Invalid relative name: " + relativeName); 19.1016 - String name = packageName.length() == 0 19.1017 - ? relativeName 19.1018 - : new File(externalizeFileName(packageName), relativeName).getPath(); 19.1019 - return getFileForInput(location, name); 19.1020 - } 19.1021 - 19.1022 - private JavaFileObject getFileForInput(Location location, String name) throws IOException { 19.1023 - Iterable<? extends File> path = getLocation(location); 19.1024 - if (path == null) 19.1025 - return null; 19.1026 - 19.1027 - for (File dir: path) { 19.1028 - if (dir.isDirectory()) { 19.1029 - File f = new File(dir, name.replace('/', File.separatorChar)); 19.1030 - if (f.exists()) 19.1031 - return new RegularFileObject(f); 19.1032 - } else { 19.1033 - Archive a = openArchive(dir); 19.1034 - if (a.contains(name)) { 19.1035 - int i = name.lastIndexOf('/'); 19.1036 - String dirname = name.substring(0, i+1); 19.1037 - String basename = name.substring(i+1); 19.1038 - return a.getFileObject(dirname, basename); 19.1039 - } 19.1040 - 19.1041 - } 19.1042 - } 19.1043 - return null; 19.1044 - 19.1045 - } 19.1046 - 19.1047 - public JavaFileObject getJavaFileForOutput(Location location, 19.1048 - String className, 19.1049 - JavaFileObject.Kind kind, 19.1050 - FileObject sibling) 19.1051 - throws IOException 19.1052 - { 19.1053 - nullCheck(location); 19.1054 - // validateClassName(className); 19.1055 - nullCheck(className); 19.1056 - nullCheck(kind); 19.1057 - if (!sourceOrClass.contains(kind)) 19.1058 - throw new IllegalArgumentException("Invalid kind " + kind); 19.1059 - return getFileForOutput(location, externalizeFileName(className, kind), sibling); 19.1060 - } 19.1061 - 19.1062 - public FileObject getFileForOutput(Location location, 19.1063 - String packageName, 19.1064 - String relativeName, 19.1065 - FileObject sibling) 19.1066 - throws IOException 19.1067 - { 19.1068 - nullCheck(location); 19.1069 - // validatePackageName(packageName); 19.1070 - nullCheck(packageName); 19.1071 - if (!isRelativeUri(URI.create(relativeName))) // FIXME 6419701 19.1072 - throw new IllegalArgumentException("relativeName is invalid"); 19.1073 - String name = packageName.length() == 0 19.1074 - ? relativeName 19.1075 - : new File(externalizeFileName(packageName), relativeName).getPath(); 19.1076 - return getFileForOutput(location, name, sibling); 19.1077 - } 19.1078 - 19.1079 - private JavaFileObject getFileForOutput(Location location, 19.1080 - String fileName, 19.1081 - FileObject sibling) 19.1082 - throws IOException 19.1083 - { 19.1084 - File dir; 19.1085 - if (location == CLASS_OUTPUT) { 19.1086 - if (getClassOutDir() != null) { 19.1087 - dir = getClassOutDir(); 19.1088 - } else { 19.1089 - File siblingDir = null; 19.1090 - if (sibling != null && sibling instanceof RegularFileObject) { 19.1091 - siblingDir = ((RegularFileObject)sibling).f.getParentFile(); 19.1092 - } 19.1093 - return new RegularFileObject(new File(siblingDir, baseName(fileName))); 19.1094 - } 19.1095 - } else if (location == SOURCE_OUTPUT) { 19.1096 - dir = (getSourceOutDir() != null ? getSourceOutDir() : getClassOutDir()); 19.1097 - } else { 19.1098 - Iterable<? extends File> path = paths.getPathForLocation(location); 19.1099 - dir = null; 19.1100 - for (File f: path) { 19.1101 - dir = f; 19.1102 - break; 19.1103 - } 19.1104 - } 19.1105 - 19.1106 - File file = (dir == null ? new File(fileName) : new File(dir, fileName)); 19.1107 - return new RegularFileObject(file); 19.1108 - 19.1109 - } 19.1110 - 19.1111 - public Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles( 19.1112 - Iterable<? extends File> files) 19.1113 - { 19.1114 - ArrayList<RegularFileObject> result; 19.1115 - if (files instanceof Collection) 19.1116 - result = new ArrayList<RegularFileObject>(((Collection)files).size()); 19.1117 - else 19.1118 - result = new ArrayList<RegularFileObject>(); 19.1119 - for (File f: files) 19.1120 - result.add(new RegularFileObject(nullCheck(f))); 19.1121 - return result; 19.1122 - } 19.1123 - 19.1124 - public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files) { 19.1125 - return getJavaFileObjectsFromFiles(Arrays.asList(nullCheck(files))); 19.1126 - } 19.1127 - 19.1128 - public void setLocation(Location location, 19.1129 - Iterable<? extends File> path) 19.1130 - throws IOException 19.1131 - { 19.1132 - nullCheck(location); 19.1133 - paths.lazy(); 19.1134 - 19.1135 - final File dir = location.isOutputLocation() ? getOutputDirectory(path) : null; 19.1136 - 19.1137 - if (location == CLASS_OUTPUT) 19.1138 - classOutDir = getOutputLocation(dir, D); 19.1139 - else if (location == SOURCE_OUTPUT) 19.1140 - sourceOutDir = getOutputLocation(dir, S); 19.1141 - else 19.1142 - paths.setPathForLocation(location, path); 19.1143 - } 19.1144 - // where 19.1145 - private File getOutputDirectory(Iterable<? extends File> path) throws IOException { 19.1146 - if (path == null) 19.1147 - return null; 19.1148 - Iterator<? extends File> pathIter = path.iterator(); 19.1149 - if (!pathIter.hasNext()) 19.1150 - throw new IllegalArgumentException("empty path for directory"); 19.1151 - File dir = pathIter.next(); 19.1152 - if (pathIter.hasNext()) 19.1153 - throw new IllegalArgumentException("path too long for directory"); 19.1154 - if (!dir.exists()) 19.1155 - throw new FileNotFoundException(dir + ": does not exist"); 19.1156 - else if (!dir.isDirectory()) 19.1157 - throw new IOException(dir + ": not a directory"); 19.1158 - return dir; 19.1159 - } 19.1160 - 19.1161 - private File getOutputLocation(File dir, OptionName defaultOptionName) { 19.1162 - if (dir != null) 19.1163 - return dir; 19.1164 - String arg = options.get(defaultOptionName); 19.1165 - if (arg == null) 19.1166 - return null; 19.1167 - return new File(arg); 19.1168 - } 19.1169 - 19.1170 - public Iterable<? extends File> getLocation(Location location) { 19.1171 - nullCheck(location); 19.1172 - paths.lazy(); 19.1173 - if (location == CLASS_OUTPUT) { 19.1174 - return (getClassOutDir() == null ? null : List.of(getClassOutDir())); 19.1175 - } else if (location == SOURCE_OUTPUT) { 19.1176 - return (getSourceOutDir() == null ? null : List.of(getSourceOutDir())); 19.1177 - } else 19.1178 - return paths.getPathForLocation(location); 19.1179 - } 19.1180 - 19.1181 - private File getClassOutDir() { 19.1182 - if (classOutDir == uninited) 19.1183 - classOutDir = getOutputLocation(null, D); 19.1184 - return classOutDir; 19.1185 - } 19.1186 - 19.1187 - private File getSourceOutDir() { 19.1188 - if (sourceOutDir == uninited) 19.1189 - sourceOutDir = getOutputLocation(null, S); 19.1190 - return sourceOutDir; 19.1191 - } 19.1192 - 19.1193 - /** 19.1194 - * Enforces the specification of a "relative" URI as used in 19.1195 - * {@linkplain #getFileForInput(Location,String,URI) 19.1196 - * getFileForInput}. This method must follow the rules defined in 19.1197 - * that method, do not make any changes without consulting the 19.1198 - * specification. 19.1199 - */ 19.1200 - protected static boolean isRelativeUri(URI uri) { 19.1201 - if (uri.isAbsolute()) 19.1202 - return false; 19.1203 - String path = uri.normalize().getPath(); 19.1204 - if (path.length() == 0 /* isEmpty() is mustang API */) 19.1205 - return false; 19.1206 - char first = path.charAt(0); 19.1207 - return first != '.' && first != '/'; 19.1208 - } 19.1209 - 19.1210 - /** 19.1211 - * Converts a relative file name to a relative URI. This is 19.1212 - * different from File.toURI as this method does not canonicalize 19.1213 - * the file before creating the URI. Furthermore, no schema is 19.1214 - * used. 19.1215 - * @param file a relative file name 19.1216 - * @return a relative URI 19.1217 - * @throws IllegalArgumentException if the file name is not 19.1218 - * relative according to the definition given in {@link 19.1219 - * javax.tools.JavaFileManager#getFileForInput} 19.1220 - */ 19.1221 - public static String getRelativeName(File file) { 19.1222 - if (!file.isAbsolute()) { 19.1223 - String result = file.getPath().replace(File.separatorChar, '/'); 19.1224 - if (JavacFileManager.isRelativeUri(URI.create(result))) // FIXME 6419701 19.1225 - return result; 19.1226 - } 19.1227 - throw new IllegalArgumentException("Invalid relative path: " + file); 19.1228 - } 19.1229 - 19.1230 - @SuppressWarnings("deprecation") // bug 6410637 19.1231 - protected static String getJavacFileName(FileObject file) { 19.1232 - if (file instanceof BaseFileObject) 19.1233 - return ((BaseFileObject)file).getPath(); 19.1234 - URI uri = file.toUri(); 19.1235 - String scheme = uri.getScheme(); 19.1236 - if (scheme == null || scheme.equals("file") || scheme.equals("jar")) 19.1237 - return uri.getPath(); 19.1238 - else 19.1239 - return uri.toString(); 19.1240 - } 19.1241 - 19.1242 - @SuppressWarnings("deprecation") // bug 6410637 19.1243 - protected static String getJavacBaseFileName(FileObject file) { 19.1244 - if (file instanceof BaseFileObject) 19.1245 - return ((BaseFileObject)file).getName(); 19.1246 - URI uri = file.toUri(); 19.1247 - String scheme = uri.getScheme(); 19.1248 - if (scheme == null || scheme.equals("file") || scheme.equals("jar")) { 19.1249 - String path = uri.getPath(); 19.1250 - if (path == null) 19.1251 - return null; 19.1252 - if (scheme != null && scheme.equals("jar")) 19.1253 - path = path.substring(path.lastIndexOf('!') + 1); 19.1254 - return path.substring(path.lastIndexOf('/') + 1); 19.1255 - } else { 19.1256 - return uri.toString(); 19.1257 - } 19.1258 - } 19.1259 - 19.1260 - private static <T> T nullCheck(T o) { 19.1261 - o.getClass(); // null check 19.1262 - return o; 19.1263 - } 19.1264 - 19.1265 - private static <T> Iterable<T> nullCheck(Iterable<T> it) { 19.1266 - for (T t : it) 19.1267 - t.getClass(); // null check 19.1268 - return it; 19.1269 - } 19.1270 - 19.1271 - /** 19.1272 - * A subclass of JavaFileObject representing regular files. 19.1273 - */ 19.1274 - private class RegularFileObject extends BaseFileObject { 19.1275 - /** Have the parent directories been created? 19.1276 - */ 19.1277 - private boolean hasParents=false; 19.1278 - 19.1279 - /** The file's name. 19.1280 - */ 19.1281 - private String name; 19.1282 - 19.1283 - /** The underlying file. 19.1284 - */ 19.1285 - final File f; 19.1286 - 19.1287 - public RegularFileObject(File f) { 19.1288 - this(f.getName(), f); 19.1289 - } 19.1290 - 19.1291 - public RegularFileObject(String name, File f) { 19.1292 - if (f.isDirectory()) 19.1293 - throw new IllegalArgumentException("directories not supported"); 19.1294 - this.name = name; 19.1295 - this.f = f; 19.1296 - } 19.1297 - 19.1298 - public InputStream openInputStream() throws IOException { 19.1299 - return new FileInputStream(f); 19.1300 - } 19.1301 - 19.1302 - protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) { 19.1303 - return JavacFileManager.this.getDecoder(getEncodingName(), ignoreEncodingErrors); 19.1304 - } 19.1305 - 19.1306 - public OutputStream openOutputStream() throws IOException { 19.1307 - ensureParentDirectoriesExist(); 19.1308 - return new FileOutputStream(f); 19.1309 - } 19.1310 - 19.1311 - public Writer openWriter() throws IOException { 19.1312 - ensureParentDirectoriesExist(); 19.1313 - return new OutputStreamWriter(new FileOutputStream(f), getEncodingName()); 19.1314 - } 19.1315 - 19.1316 - private void ensureParentDirectoriesExist() throws IOException { 19.1317 - if (!hasParents) { 19.1318 - File parent = f.getParentFile(); 19.1319 - if (parent != null && !parent.exists()) { 19.1320 - if (!parent.mkdirs()) { 19.1321 - // if the mkdirs failed, it may be because another process concurrently 19.1322 - // created the directory, so check if the directory got created 19.1323 - // anyway before throwing an exception 19.1324 - if (!parent.exists() || !parent.isDirectory()) 19.1325 - throw new IOException("could not create parent directories"); 19.1326 - } 19.1327 - } 19.1328 - hasParents = true; 19.1329 - } 19.1330 - } 19.1331 - 19.1332 - /** @deprecated see bug 6410637 */ 19.1333 - @Deprecated 19.1334 - public String getName() { 19.1335 - return name; 19.1336 - } 19.1337 - 19.1338 - public boolean isNameCompatible(String cn, JavaFileObject.Kind kind) { 19.1339 - cn.getClass(); // null check 19.1340 - if (kind == Kind.OTHER && getKind() != kind) 19.1341 - return false; 19.1342 - String n = cn + kind.extension; 19.1343 - if (name.equals(n)) 19.1344 - return true; 19.1345 - if (name.equalsIgnoreCase(n)) { 19.1346 - try { 19.1347 - // allow for Windows 19.1348 - return (f.getCanonicalFile().getName().equals(n)); 19.1349 - } catch (IOException e) { 19.1350 - } 19.1351 - } 19.1352 - return false; 19.1353 - } 19.1354 - 19.1355 - /** @deprecated see bug 6410637 */ 19.1356 - @Deprecated 19.1357 - public String getPath() { 19.1358 - return f.getPath(); 19.1359 - } 19.1360 - 19.1361 - public long getLastModified() { 19.1362 - return f.lastModified(); 19.1363 - } 19.1364 - 19.1365 - public boolean delete() { 19.1366 - return f.delete(); 19.1367 - } 19.1368 - 19.1369 - public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException { 19.1370 - SoftReference<CharBuffer> r = contentCache.get(this); 19.1371 - CharBuffer cb = (r == null ? null : r.get()); 19.1372 - if (cb == null) { 19.1373 - InputStream in = new FileInputStream(f); 19.1374 - try { 19.1375 - ByteBuffer bb = makeByteBuffer(in); 19.1376 - JavaFileObject prev = log.useSource(this); 19.1377 - try { 19.1378 - cb = decode(bb, ignoreEncodingErrors); 19.1379 - } finally { 19.1380 - log.useSource(prev); 19.1381 - } 19.1382 - byteBufferCache.put(bb); // save for next time 19.1383 - if (!ignoreEncodingErrors) 19.1384 - contentCache.put(this, new SoftReference<CharBuffer>(cb)); 19.1385 - } finally { 19.1386 - in.close(); 19.1387 - } 19.1388 - } 19.1389 - return cb; 19.1390 - } 19.1391 - 19.1392 - @Override 19.1393 - public boolean equals(Object other) { 19.1394 - if (!(other instanceof RegularFileObject)) 19.1395 - return false; 19.1396 - RegularFileObject o = (RegularFileObject) other; 19.1397 - try { 19.1398 - return f.equals(o.f) 19.1399 - || f.getCanonicalFile().equals(o.f.getCanonicalFile()); 19.1400 - } catch (IOException e) { 19.1401 - return false; 19.1402 - } 19.1403 - } 19.1404 - 19.1405 - @Override 19.1406 - public int hashCode() { 19.1407 - return f.hashCode(); 19.1408 - } 19.1409 - 19.1410 - public URI toUri() { 19.1411 - try { 19.1412 - // Do no use File.toURI to avoid file system access 19.1413 - String path = f.getAbsolutePath().replace(File.separatorChar, '/'); 19.1414 - return new URI("file://" + path).normalize(); 19.1415 - } catch (URISyntaxException ex) { 19.1416 - return f.toURI(); 19.1417 - } 19.1418 - } 19.1419 - 19.1420 - } 19.1421 - 19.1422 - /** 19.1423 - * A subclass of JavaFileObject representing zip entries. 19.1424 - */ 19.1425 - public class ZipFileObject extends BaseFileObject { 19.1426 - 19.1427 - /** The entry's name. 19.1428 - */ 19.1429 - private String name; 19.1430 - 19.1431 - /** The zipfile containing the entry. 19.1432 - */ 19.1433 - ZipFile zdir; 19.1434 - 19.1435 - /** The underlying zip entry object. 19.1436 - */ 19.1437 - ZipEntry entry; 19.1438 - 19.1439 - public ZipFileObject(String name, ZipFile zdir, ZipEntry entry) { 19.1440 - this.name = name; 19.1441 - this.zdir = zdir; 19.1442 - this.entry = entry; 19.1443 - } 19.1444 - 19.1445 - public InputStream openInputStream() throws IOException { 19.1446 - return zdir.getInputStream(entry); 19.1447 - } 19.1448 - 19.1449 - public OutputStream openOutputStream() throws IOException { 19.1450 - throw new UnsupportedOperationException(); 19.1451 - } 19.1452 - 19.1453 - protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) { 19.1454 - return JavacFileManager.this.getDecoder(getEncodingName(), ignoreEncodingErrors); 19.1455 - } 19.1456 - 19.1457 - public Writer openWriter() throws IOException { 19.1458 - throw new UnsupportedOperationException(); 19.1459 - } 19.1460 - 19.1461 - /** @deprecated see bug 6410637 */ 19.1462 - @Deprecated 19.1463 - public String getName() { 19.1464 - return name; 19.1465 - } 19.1466 - 19.1467 - public boolean isNameCompatible(String cn, JavaFileObject.Kind k) { 19.1468 - cn.getClass(); // null check 19.1469 - if (k == Kind.OTHER && getKind() != k) 19.1470 - return false; 19.1471 - return name.equals(cn + k.extension); 19.1472 - } 19.1473 - 19.1474 - /** @deprecated see bug 6410637 */ 19.1475 - @Deprecated 19.1476 - public String getPath() { 19.1477 - return zdir.getName() + "(" + entry + ")"; 19.1478 - } 19.1479 - 19.1480 - public long getLastModified() { 19.1481 - return entry.getTime(); 19.1482 - } 19.1483 - 19.1484 - public boolean delete() { 19.1485 - throw new UnsupportedOperationException(); 19.1486 - } 19.1487 - 19.1488 - public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException { 19.1489 - SoftReference<CharBuffer> r = contentCache.get(this); 19.1490 - CharBuffer cb = (r == null ? null : r.get()); 19.1491 - if (cb == null) { 19.1492 - InputStream in = zdir.getInputStream(entry); 19.1493 - try { 19.1494 - ByteBuffer bb = makeByteBuffer(in); 19.1495 - JavaFileObject prev = log.useSource(this); 19.1496 - try { 19.1497 - cb = decode(bb, ignoreEncodingErrors); 19.1498 - } finally { 19.1499 - log.useSource(prev); 19.1500 - } 19.1501 - byteBufferCache.put(bb); // save for next time 19.1502 - if (!ignoreEncodingErrors) 19.1503 - contentCache.put(this, new SoftReference<CharBuffer>(cb)); 19.1504 - } finally { 19.1505 - in.close(); 19.1506 - } 19.1507 - } 19.1508 - return cb; 19.1509 - } 19.1510 - 19.1511 - @Override 19.1512 - public boolean equals(Object other) { 19.1513 - if (!(other instanceof ZipFileObject)) 19.1514 - return false; 19.1515 - ZipFileObject o = (ZipFileObject) other; 19.1516 - return zdir.equals(o.zdir) || name.equals(o.name); 19.1517 - } 19.1518 - 19.1519 - @Override 19.1520 - public int hashCode() { 19.1521 - return zdir.hashCode() + name.hashCode(); 19.1522 - } 19.1523 - 19.1524 - public String getZipName() { 19.1525 - return zdir.getName(); 19.1526 - } 19.1527 - 19.1528 - public String getZipEntryName() { 19.1529 - return entry.getName(); 19.1530 - } 19.1531 - 19.1532 - public URI toUri() { 19.1533 - String zipName = new File(getZipName()).toURI().normalize().getPath(); 19.1534 - String entryName = getZipEntryName(); 19.1535 - return URI.create("jar:" + zipName + "!" + entryName); 19.1536 - } 19.1537 - 19.1538 - } 19.1539 - 19.1540 - /** 19.1541 - * A subclass of JavaFileObject representing zip entries using the com.sun.tools.javac.zip.ZipFileIndex implementation. 19.1542 - */ 19.1543 - public class ZipFileIndexFileObject extends BaseFileObject { 19.1544 - 19.1545 - /** The entry's name. 19.1546 - */ 19.1547 - private String name; 19.1548 - 19.1549 - /** The zipfile containing the entry. 19.1550 - */ 19.1551 - ZipFileIndex zfIndex; 19.1552 - 19.1553 - /** The underlying zip entry object. 19.1554 - */ 19.1555 - ZipFileIndexEntry entry; 19.1556 - 19.1557 - /** The InputStream for this zip entry (file.) 19.1558 - */ 19.1559 - InputStream inputStream = null; 19.1560 - 19.1561 - /** The name of the zip file where this entry resides. 19.1562 - */ 19.1563 - String zipName; 19.1564 - 19.1565 - JavacFileManager defFileManager = null; 19.1566 - 19.1567 - public ZipFileIndexFileObject(JavacFileManager fileManager, ZipFileIndex zfIndex, ZipFileIndexEntry entry, String zipFileName) { 19.1568 - super(); 19.1569 - this.name = entry.getFileName(); 19.1570 - this.zfIndex = zfIndex; 19.1571 - this.entry = entry; 19.1572 - this.zipName = zipFileName; 19.1573 - defFileManager = fileManager; 19.1574 - } 19.1575 - 19.1576 - public InputStream openInputStream() throws IOException { 19.1577 - 19.1578 - if (inputStream == null) { 19.1579 - inputStream = new ByteArrayInputStream(read()); 19.1580 - } 19.1581 - return inputStream; 19.1582 - } 19.1583 - 19.1584 - protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) { 19.1585 - return JavacFileManager.this.getDecoder(getEncodingName(), ignoreEncodingErrors); 19.1586 - } 19.1587 - 19.1588 - public OutputStream openOutputStream() throws IOException { 19.1589 - throw new UnsupportedOperationException(); 19.1590 - } 19.1591 - 19.1592 - public Writer openWriter() throws IOException { 19.1593 - throw new UnsupportedOperationException(); 19.1594 - } 19.1595 - 19.1596 - /** @deprecated see bug 6410637 */ 19.1597 - @Deprecated 19.1598 - public String getName() { 19.1599 - return name; 19.1600 - } 19.1601 - 19.1602 - public boolean isNameCompatible(String cn, JavaFileObject.Kind k) { 19.1603 - cn.getClass(); // null check 19.1604 - if (k == Kind.OTHER && getKind() != k) 19.1605 - return false; 19.1606 - return name.equals(cn + k.extension); 19.1607 - } 19.1608 - 19.1609 - /** @deprecated see bug 6410637 */ 19.1610 - @Deprecated 19.1611 - public String getPath() { 19.1612 - return zipName + "(" + entry.getName() + ")"; 19.1613 - } 19.1614 - 19.1615 - public long getLastModified() { 19.1616 - return entry.getLastModified(); 19.1617 - } 19.1618 - 19.1619 - public boolean delete() { 19.1620 - throw new UnsupportedOperationException(); 19.1621 - } 19.1622 - 19.1623 - @Override 19.1624 - public boolean equals(Object other) { 19.1625 - if (!(other instanceof ZipFileIndexFileObject)) 19.1626 - return false; 19.1627 - ZipFileIndexFileObject o = (ZipFileIndexFileObject) other; 19.1628 - return entry.equals(o.entry); 19.1629 - } 19.1630 - 19.1631 - @Override 19.1632 - public int hashCode() { 19.1633 - return zipName.hashCode() + (name.hashCode() << 10); 19.1634 - } 19.1635 - 19.1636 - public String getZipName() { 19.1637 - return zipName; 19.1638 - } 19.1639 - 19.1640 - public String getZipEntryName() { 19.1641 - return entry.getName(); 19.1642 - } 19.1643 - 19.1644 - public URI toUri() { 19.1645 - String zipName = new File(getZipName()).toURI().normalize().getPath(); 19.1646 - String entryName = getZipEntryName(); 19.1647 - if (File.separatorChar != '/') { 19.1648 - entryName = entryName.replace(File.separatorChar, '/'); 19.1649 - } 19.1650 - return URI.create("jar:" + zipName + "!" + entryName); 19.1651 - } 19.1652 - 19.1653 - private byte[] read() throws IOException { 19.1654 - if (entry == null) { 19.1655 - entry = zfIndex.getZipIndexEntry(name); 19.1656 - if (entry == null) 19.1657 - throw new FileNotFoundException(); 19.1658 - } 19.1659 - return zfIndex.read(entry); 19.1660 - } 19.1661 - 19.1662 - public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException { 19.1663 - SoftReference<CharBuffer> r = defFileManager.contentCache.get(this); 19.1664 - CharBuffer cb = (r == null ? null : r.get()); 19.1665 - if (cb == null) { 19.1666 - InputStream in = new ByteArrayInputStream(zfIndex.read(entry)); 19.1667 - try { 19.1668 - ByteBuffer bb = makeByteBuffer(in); 19.1669 - JavaFileObject prev = log.useSource(this); 19.1670 - try { 19.1671 - cb = decode(bb, ignoreEncodingErrors); 19.1672 - } finally { 19.1673 - log.useSource(prev); 19.1674 - } 19.1675 - byteBufferCache.put(bb); // save for next time 19.1676 - if (!ignoreEncodingErrors) 19.1677 - defFileManager.contentCache.put(this, new SoftReference<CharBuffer>(cb)); 19.1678 - } finally { 19.1679 - in.close(); 19.1680 - } 19.1681 - } 19.1682 - return cb; 19.1683 - } 19.1684 - } 19.1685 - 19.1686 - public class ZipFileIndexArchive implements Archive { 19.1687 - private final ZipFileIndex zfIndex; 19.1688 - private JavacFileManager fileManager; 19.1689 - 19.1690 - public ZipFileIndexArchive(JavacFileManager fileManager, ZipFileIndex zdir) throws IOException { 19.1691 - this.fileManager = fileManager; 19.1692 - this.zfIndex = zdir; 19.1693 - } 19.1694 - 19.1695 - public boolean contains(String name) { 19.1696 - return zfIndex.contains(name); 19.1697 - } 19.1698 - 19.1699 - public com.sun.tools.javac.util.List<String> getFiles(String subdirectory) { 19.1700 - return zfIndex.getFiles(((subdirectory.endsWith("/") || subdirectory.endsWith("\\"))? subdirectory.substring(0, subdirectory.length() - 1) : subdirectory)); 19.1701 - } 19.1702 - 19.1703 - public JavaFileObject getFileObject(String subdirectory, String file) { 19.1704 - String fullZipFileName = subdirectory + file; 19.1705 - ZipFileIndexEntry entry = zfIndex.getZipIndexEntry(fullZipFileName); 19.1706 - JavaFileObject ret = new ZipFileIndexFileObject(fileManager, zfIndex, entry, zfIndex.getZipFile().getPath()); 19.1707 - return ret; 19.1708 - } 19.1709 - 19.1710 - public Set<String> getSubdirectories() { 19.1711 - return zfIndex.getAllDirectories(); 19.1712 - } 19.1713 - 19.1714 - public void close() throws IOException { 19.1715 - zfIndex.close(); 19.1716 - } 19.1717 - } 19.1718 -}
20.1 --- a/src/share/classes/com/sun/tools/javac/util/Log.java Fri Jun 06 15:17:35 2008 -0700 20.2 +++ b/src/share/classes/com/sun/tools/javac/util/Log.java Mon Jun 16 13:28:00 2008 -0700 20.3 @@ -33,11 +33,14 @@ 20.4 import java.util.Set; 20.5 import javax.tools.DiagnosticListener; 20.6 import javax.tools.JavaFileObject; 20.7 + 20.8 import com.sun.tools.javac.code.Source; 20.9 +import com.sun.tools.javac.file.JavacFileManager; 20.10 import com.sun.tools.javac.tree.JCTree; 20.11 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 20.12 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType; 20.13 import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition; 20.14 + 20.15 import static com.sun.tools.javac.util.LayoutCharacters.*; 20.16 20.17 /** A class for error logs. Reports errors and warnings, and
21.1 --- a/src/share/classes/com/sun/tools/javac/util/Old199.java Fri Jun 06 15:17:35 2008 -0700 21.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 21.3 @@ -1,60 +0,0 @@ 21.4 -/* 21.5 - * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. 21.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 21.7 - * 21.8 - * This code is free software; you can redistribute it and/or modify it 21.9 - * under the terms of the GNU General Public License version 2 only, as 21.10 - * published by the Free Software Foundation. Sun designates this 21.11 - * particular file as subject to the "Classpath" exception as provided 21.12 - * by Sun in the LICENSE file that accompanied this code. 21.13 - * 21.14 - * This code is distributed in the hope that it will be useful, but WITHOUT 21.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 21.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 21.17 - * version 2 for more details (a copy is included in the LICENSE file that 21.18 - * accompanied this code). 21.19 - * 21.20 - * You should have received a copy of the GNU General Public License version 21.21 - * 2 along with this work; if not, write to the Free Software Foundation, 21.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21.23 - * 21.24 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 21.25 - * CA 95054 USA or visit www.sun.com if you need additional information or 21.26 - * have any questions. 21.27 - */ 21.28 - 21.29 -package com.sun.tools.javac.util; 21.30 - 21.31 -import java.io.File; 21.32 -import java.io.IOException; 21.33 -import java.net.URI; 21.34 -import java.net.URISyntaxException; 21.35 -import javax.tools.*; 21.36 - 21.37 -import static javax.tools.StandardLocation.SOURCE_PATH; 21.38 - 21.39 -/** 21.40 - * Provides an easy migration to JSR 199 v3.3. The class is 21.41 - * deprecated as we should remove it as soon as possible. 21.42 - * 21.43 - * <p><b>This is NOT part of any API supported by Sun Microsystems. 21.44 - * If you write code that depends on this, you do so at your own 21.45 - * risk. This code and its internal interfaces are subject to change 21.46 - * or deletion without notice.</b></p> 21.47 - * 21.48 - * @author Peter von der Ah\u00e9 21.49 - */ 21.50 -@Deprecated 21.51 -public class Old199 { 21.52 - 21.53 - private Old199() {} 21.54 - 21.55 - public static String getPath(FileObject jfo) { 21.56 - return JavacFileManager.getJavacFileName(jfo); 21.57 - } 21.58 - 21.59 - public static String getName(FileObject jfo) { 21.60 - return JavacFileManager.getJavacBaseFileName(jfo); 21.61 - } 21.62 - 21.63 -}
22.1 --- a/src/share/classes/com/sun/tools/javac/util/Paths.java Fri Jun 06 15:17:35 2008 -0700 22.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 22.3 @@ -1,572 +0,0 @@ 22.4 -/* 22.5 - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. 22.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 22.7 - * 22.8 - * This code is free software; you can redistribute it and/or modify it 22.9 - * under the terms of the GNU General Public License version 2 only, as 22.10 - * published by the Free Software Foundation. Sun designates this 22.11 - * particular file as subject to the "Classpath" exception as provided 22.12 - * by Sun in the LICENSE file that accompanied this code. 22.13 - * 22.14 - * This code is distributed in the hope that it will be useful, but WITHOUT 22.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 22.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 22.17 - * version 2 for more details (a copy is included in the LICENSE file that 22.18 - * accompanied this code). 22.19 - * 22.20 - * You should have received a copy of the GNU General Public License version 22.21 - * 2 along with this work; if not, write to the Free Software Foundation, 22.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 22.23 - * 22.24 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 22.25 - * CA 95054 USA or visit www.sun.com if you need additional information or 22.26 - * have any questions. 22.27 - */ 22.28 - 22.29 -package com.sun.tools.javac.util; 22.30 -import java.io.File; 22.31 -import java.io.IOException; 22.32 -import java.util.HashMap; 22.33 -import java.util.HashSet; 22.34 -import java.util.Map; 22.35 -import java.util.Set; 22.36 -import java.util.jar.JarFile; 22.37 -import java.util.jar.Manifest; 22.38 -import java.util.jar.Attributes; 22.39 -import java.util.Collection; 22.40 -import java.util.Collections; 22.41 -import java.util.LinkedHashSet; 22.42 -import java.util.Iterator; 22.43 -import java.util.StringTokenizer; 22.44 -import java.util.zip.ZipFile; 22.45 -import com.sun.tools.javac.code.Lint; 22.46 -import java.util.ArrayList; 22.47 -import java.util.concurrent.ConcurrentHashMap; 22.48 -import java.util.concurrent.locks.Lock; 22.49 -import java.util.concurrent.locks.ReentrantLock; 22.50 -import javax.tools.JavaFileManager.Location; 22.51 - 22.52 -import static com.sun.tools.javac.main.OptionName.*; 22.53 -import static javax.tools.StandardLocation.*; 22.54 - 22.55 -/** This class converts command line arguments, environment variables 22.56 - * and system properties (in File.pathSeparator-separated String form) 22.57 - * into a boot class path, user class path, and source path (in 22.58 - * Collection<String> form). 22.59 - * 22.60 - * <p><b>This is NOT part of any API supported by Sun Microsystems. If 22.61 - * you write code that depends on this, you do so at your own risk. 22.62 - * This code and its internal interfaces are subject to change or 22.63 - * deletion without notice.</b> 22.64 - */ 22.65 -public class Paths { 22.66 - 22.67 - /** The context key for the todo list */ 22.68 - protected static final Context.Key<Paths> pathsKey = 22.69 - new Context.Key<Paths>(); 22.70 - 22.71 - /** Get the Paths instance for this context. 22.72 - * @param context the context 22.73 - * @return the Paths instance for this context 22.74 - */ 22.75 - public static Paths instance(Context context) { 22.76 - Paths instance = context.get(pathsKey); 22.77 - if (instance == null) 22.78 - instance = new Paths(context); 22.79 - return instance; 22.80 - } 22.81 - 22.82 - /** The log to use for warning output */ 22.83 - private Log log; 22.84 - 22.85 - /** Collection of command-line options */ 22.86 - private Options options; 22.87 - 22.88 - /** Handler for -Xlint options */ 22.89 - private Lint lint; 22.90 - 22.91 - private static boolean NON_BATCH_MODE = System.getProperty("nonBatchMode") != null;// TODO: Use -XD compiler switch for this. 22.92 - private static Map<File, PathEntry> pathExistanceCache = new ConcurrentHashMap<File, PathEntry>(); 22.93 - private static Map<File, java.util.List<File>> manifestEntries = new ConcurrentHashMap<File, java.util.List<File>>(); 22.94 - private static Map<File, Boolean> isDirectory = new ConcurrentHashMap<File, Boolean>(); 22.95 - private static Lock lock = new ReentrantLock(); 22.96 - 22.97 - public static void clearPathExistanceCache() { 22.98 - pathExistanceCache.clear(); 22.99 - } 22.100 - 22.101 - static class PathEntry { 22.102 - boolean exists = false; 22.103 - boolean isFile = false; 22.104 - File cannonicalPath = null; 22.105 - } 22.106 - 22.107 - protected Paths(Context context) { 22.108 - context.put(pathsKey, this); 22.109 - pathsForLocation = new HashMap<Location,Path>(16); 22.110 - setContext(context); 22.111 - } 22.112 - 22.113 - void setContext(Context context) { 22.114 - log = Log.instance(context); 22.115 - options = Options.instance(context); 22.116 - lint = Lint.instance(context); 22.117 - } 22.118 - 22.119 - /** Whether to warn about non-existent path elements */ 22.120 - private boolean warn; 22.121 - 22.122 - private Map<Location, Path> pathsForLocation; 22.123 - 22.124 - private boolean inited = false; // TODO? caching bad? 22.125 - 22.126 - /** 22.127 - * rt.jar as found on the default bootclass path. If the user specified a 22.128 - * bootclasspath, null is used. 22.129 - */ 22.130 - private File bootClassPathRtJar = null; 22.131 - 22.132 - Path getPathForLocation(Location location) { 22.133 - Path path = pathsForLocation.get(location); 22.134 - if (path == null) 22.135 - setPathForLocation(location, null); 22.136 - return pathsForLocation.get(location); 22.137 - } 22.138 - 22.139 - void setPathForLocation(Location location, Iterable<? extends File> path) { 22.140 - // TODO? if (inited) throw new IllegalStateException 22.141 - // TODO: otherwise reset sourceSearchPath, classSearchPath as needed 22.142 - Path p; 22.143 - if (path == null) { 22.144 - if (location == CLASS_PATH) 22.145 - p = computeUserClassPath(); 22.146 - else if (location == PLATFORM_CLASS_PATH) 22.147 - p = computeBootClassPath(); 22.148 - else if (location == ANNOTATION_PROCESSOR_PATH) 22.149 - p = computeAnnotationProcessorPath(); 22.150 - else if (location == SOURCE_PATH) 22.151 - p = computeSourcePath(); 22.152 - else 22.153 - // no defaults for other paths 22.154 - p = null; 22.155 - } else { 22.156 - p = new Path(); 22.157 - for (File f: path) 22.158 - p.addFile(f, warn); // TODO: is use of warn appropriate? 22.159 - } 22.160 - pathsForLocation.put(location, p); 22.161 - } 22.162 - 22.163 - protected void lazy() { 22.164 - if (!inited) { 22.165 - warn = lint.isEnabled(Lint.LintCategory.PATH); 22.166 - 22.167 - pathsForLocation.put(PLATFORM_CLASS_PATH, computeBootClassPath()); 22.168 - pathsForLocation.put(CLASS_PATH, computeUserClassPath()); 22.169 - pathsForLocation.put(SOURCE_PATH, computeSourcePath()); 22.170 - 22.171 - inited = true; 22.172 - } 22.173 - } 22.174 - 22.175 - public Collection<File> bootClassPath() { 22.176 - lazy(); 22.177 - return Collections.unmodifiableCollection(getPathForLocation(PLATFORM_CLASS_PATH)); 22.178 - } 22.179 - public Collection<File> userClassPath() { 22.180 - lazy(); 22.181 - return Collections.unmodifiableCollection(getPathForLocation(CLASS_PATH)); 22.182 - } 22.183 - public Collection<File> sourcePath() { 22.184 - lazy(); 22.185 - Path p = getPathForLocation(SOURCE_PATH); 22.186 - return p == null || p.size() == 0 22.187 - ? null 22.188 - : Collections.unmodifiableCollection(p); 22.189 - } 22.190 - 22.191 - boolean isBootClassPathRtJar(File file) { 22.192 - return file.equals(bootClassPathRtJar); 22.193 - } 22.194 - 22.195 - private static class PathIterator implements Iterable<String> { 22.196 - private int pos = 0; 22.197 - private final String path; 22.198 - private final String emptyPathDefault; 22.199 - 22.200 - public PathIterator(String path, String emptyPathDefault) { 22.201 - this.path = path; 22.202 - this.emptyPathDefault = emptyPathDefault; 22.203 - } 22.204 - public PathIterator(String path) { this(path, null); } 22.205 - public Iterator<String> iterator() { 22.206 - return new Iterator<String>() { 22.207 - public boolean hasNext() { 22.208 - return pos <= path.length(); 22.209 - } 22.210 - public String next() { 22.211 - int beg = pos; 22.212 - int end = path.indexOf(File.pathSeparator, beg); 22.213 - if (end == -1) 22.214 - end = path.length(); 22.215 - pos = end + 1; 22.216 - 22.217 - if (beg == end && emptyPathDefault != null) 22.218 - return emptyPathDefault; 22.219 - else 22.220 - return path.substring(beg, end); 22.221 - } 22.222 - public void remove() { 22.223 - throw new UnsupportedOperationException(); 22.224 - } 22.225 - }; 22.226 - } 22.227 - } 22.228 - 22.229 - private class Path extends LinkedHashSet<File> { 22.230 - private static final long serialVersionUID = 0; 22.231 - 22.232 - private boolean expandJarClassPaths = false; 22.233 - private Set<File> canonicalValues = new HashSet<File>(); 22.234 - 22.235 - public Path expandJarClassPaths(boolean x) { 22.236 - expandJarClassPaths = x; 22.237 - return this; 22.238 - } 22.239 - 22.240 - /** What to use when path element is the empty string */ 22.241 - private String emptyPathDefault = null; 22.242 - 22.243 - public Path emptyPathDefault(String x) { 22.244 - emptyPathDefault = x; 22.245 - return this; 22.246 - } 22.247 - 22.248 - public Path() { super(); } 22.249 - 22.250 - public Path addDirectories(String dirs, boolean warn) { 22.251 - if (dirs != null) 22.252 - for (String dir : new PathIterator(dirs)) 22.253 - addDirectory(dir, warn); 22.254 - return this; 22.255 - } 22.256 - 22.257 - public Path addDirectories(String dirs) { 22.258 - return addDirectories(dirs, warn); 22.259 - } 22.260 - 22.261 - private void addDirectory(String dir, boolean warn) { 22.262 - if (! new File(dir).isDirectory()) { 22.263 - if (warn) 22.264 - log.warning("dir.path.element.not.found", dir); 22.265 - return; 22.266 - } 22.267 - 22.268 - File[] files = new File(dir).listFiles(); 22.269 - if (files == null) 22.270 - return; 22.271 - 22.272 - for (File direntry : files) { 22.273 - if (isArchive(direntry)) 22.274 - addFile(direntry, warn); 22.275 - } 22.276 - } 22.277 - 22.278 - public Path addFiles(String files, boolean warn) { 22.279 - if (files != null) 22.280 - for (String file : new PathIterator(files, emptyPathDefault)) 22.281 - addFile(file, warn); 22.282 - return this; 22.283 - } 22.284 - 22.285 - public Path addFiles(String files) { 22.286 - return addFiles(files, warn); 22.287 - } 22.288 - 22.289 - public Path addFile(String file, boolean warn) { 22.290 - addFile(new File(file), warn); 22.291 - return this; 22.292 - } 22.293 - 22.294 - public void addFile(File file, boolean warn) { 22.295 - boolean foundInCache = false; 22.296 - PathEntry pe = null; 22.297 - if (!NON_BATCH_MODE) { 22.298 - pe = pathExistanceCache.get(file); 22.299 - if (pe != null) { 22.300 - foundInCache = true; 22.301 - } 22.302 - else { 22.303 - pe = new PathEntry(); 22.304 - } 22.305 - } 22.306 - else { 22.307 - pe = new PathEntry(); 22.308 - } 22.309 - 22.310 - File canonFile; 22.311 - try { 22.312 - if (!foundInCache) { 22.313 - pe.cannonicalPath = file.getCanonicalFile(); 22.314 - } 22.315 - else { 22.316 - canonFile = pe.cannonicalPath; 22.317 - } 22.318 - } catch (IOException e) { 22.319 - pe.cannonicalPath = canonFile = file; 22.320 - } 22.321 - 22.322 - if (contains(file) || canonicalValues.contains(pe.cannonicalPath)) { 22.323 - /* Discard duplicates and avoid infinite recursion */ 22.324 - return; 22.325 - } 22.326 - 22.327 - if (!foundInCache) { 22.328 - pe.exists = file.exists(); 22.329 - pe.isFile = file.isFile(); 22.330 - if (!NON_BATCH_MODE) { 22.331 - pathExistanceCache.put(file, pe); 22.332 - } 22.333 - } 22.334 - 22.335 - if (! pe.exists) { 22.336 - /* No such file or directory exists */ 22.337 - if (warn) 22.338 - log.warning("path.element.not.found", file); 22.339 - } else if (pe.isFile) { 22.340 - /* File is an ordinary file. */ 22.341 - if (!isArchive(file)) { 22.342 - /* Not a recognized extension; open it to see if 22.343 - it looks like a valid zip file. */ 22.344 - try { 22.345 - ZipFile z = new ZipFile(file); 22.346 - z.close(); 22.347 - if (warn) 22.348 - log.warning("unexpected.archive.file", file); 22.349 - } catch (IOException e) { 22.350 - // FIXME: include e.getLocalizedMessage in warning 22.351 - if (warn) 22.352 - log.warning("invalid.archive.file", file); 22.353 - return; 22.354 - } 22.355 - } 22.356 - } 22.357 - 22.358 - /* Now what we have left is either a directory or a file name 22.359 - confirming to archive naming convention */ 22.360 - super.add(file); 22.361 - canonicalValues.add(pe.cannonicalPath); 22.362 - 22.363 - if (expandJarClassPaths && file.exists() && file.isFile()) 22.364 - addJarClassPath(file, warn); 22.365 - } 22.366 - 22.367 - // Adds referenced classpath elements from a jar's Class-Path 22.368 - // Manifest entry. In some future release, we may want to 22.369 - // update this code to recognize URLs rather than simple 22.370 - // filenames, but if we do, we should redo all path-related code. 22.371 - private void addJarClassPath(File jarFile, boolean warn) { 22.372 - try { 22.373 - java.util.List<File> manifestsList = manifestEntries.get(jarFile); 22.374 - if (!NON_BATCH_MODE) { 22.375 - lock.lock(); 22.376 - try { 22.377 - if (manifestsList != null) { 22.378 - for (File entr : manifestsList) { 22.379 - addFile(entr, warn); 22.380 - } 22.381 - return; 22.382 - } 22.383 - } 22.384 - finally { 22.385 - lock.unlock(); 22.386 - } 22.387 - } 22.388 - 22.389 - if (!NON_BATCH_MODE) { 22.390 - manifestsList = new ArrayList<File>(); 22.391 - manifestEntries.put(jarFile, manifestsList); 22.392 - } 22.393 - 22.394 - String jarParent = jarFile.getParent(); 22.395 - JarFile jar = new JarFile(jarFile); 22.396 - 22.397 - try { 22.398 - Manifest man = jar.getManifest(); 22.399 - if (man == null) return; 22.400 - 22.401 - Attributes attr = man.getMainAttributes(); 22.402 - if (attr == null) return; 22.403 - 22.404 - String path = attr.getValue(Attributes.Name.CLASS_PATH); 22.405 - if (path == null) return; 22.406 - 22.407 - for (StringTokenizer st = new StringTokenizer(path); 22.408 - st.hasMoreTokens();) { 22.409 - String elt = st.nextToken(); 22.410 - File f = (jarParent == null ? new File(elt) : new File(jarParent, elt)); 22.411 - addFile(f, warn); 22.412 - 22.413 - if (!NON_BATCH_MODE) { 22.414 - lock.lock(); 22.415 - try { 22.416 - manifestsList.add(f); 22.417 - } 22.418 - finally { 22.419 - lock.unlock(); 22.420 - } 22.421 - } 22.422 - } 22.423 - } finally { 22.424 - jar.close(); 22.425 - } 22.426 - } catch (IOException e) { 22.427 - log.error("error.reading.file", jarFile, e.getLocalizedMessage()); 22.428 - } 22.429 - } 22.430 - } 22.431 - 22.432 - private Path computeBootClassPath() { 22.433 - bootClassPathRtJar = null; 22.434 - String optionValue; 22.435 - Path path = new Path(); 22.436 - 22.437 - path.addFiles(options.get(XBOOTCLASSPATH_PREPEND)); 22.438 - 22.439 - if ((optionValue = options.get(ENDORSEDDIRS)) != null) 22.440 - path.addDirectories(optionValue); 22.441 - else 22.442 - path.addDirectories(System.getProperty("java.endorsed.dirs"), false); 22.443 - 22.444 - if ((optionValue = options.get(BOOTCLASSPATH)) != null) { 22.445 - path.addFiles(optionValue); 22.446 - } else { 22.447 - // Standard system classes for this compiler's release. 22.448 - String files = System.getProperty("sun.boot.class.path"); 22.449 - path.addFiles(files, false); 22.450 - File rt_jar = new File("rt.jar"); 22.451 - for (String file : new PathIterator(files, null)) { 22.452 - File f = new File(file); 22.453 - if (new File(f.getName()).equals(rt_jar)) 22.454 - bootClassPathRtJar = f; 22.455 - } 22.456 - } 22.457 - 22.458 - path.addFiles(options.get(XBOOTCLASSPATH_APPEND)); 22.459 - 22.460 - // Strictly speaking, standard extensions are not bootstrap 22.461 - // classes, but we treat them identically, so we'll pretend 22.462 - // that they are. 22.463 - if ((optionValue = options.get(EXTDIRS)) != null) 22.464 - path.addDirectories(optionValue); 22.465 - else 22.466 - path.addDirectories(System.getProperty("java.ext.dirs"), false); 22.467 - 22.468 - return path; 22.469 - } 22.470 - 22.471 - private Path computeUserClassPath() { 22.472 - String cp = options.get(CLASSPATH); 22.473 - 22.474 - // CLASSPATH environment variable when run from `javac'. 22.475 - if (cp == null) cp = System.getProperty("env.class.path"); 22.476 - 22.477 - // If invoked via a java VM (not the javac launcher), use the 22.478 - // platform class path 22.479 - if (cp == null && System.getProperty("application.home") == null) 22.480 - cp = System.getProperty("java.class.path"); 22.481 - 22.482 - // Default to current working directory. 22.483 - if (cp == null) cp = "."; 22.484 - 22.485 - return new Path() 22.486 - .expandJarClassPaths(true) // Only search user jars for Class-Paths 22.487 - .emptyPathDefault(".") // Empty path elt ==> current directory 22.488 - .addFiles(cp); 22.489 - } 22.490 - 22.491 - private Path computeSourcePath() { 22.492 - String sourcePathArg = options.get(SOURCEPATH); 22.493 - if (sourcePathArg == null) 22.494 - return null; 22.495 - 22.496 - return new Path().addFiles(sourcePathArg); 22.497 - } 22.498 - 22.499 - private Path computeAnnotationProcessorPath() { 22.500 - String processorPathArg = options.get(PROCESSORPATH); 22.501 - if (processorPathArg == null) 22.502 - return null; 22.503 - 22.504 - return new Path().addFiles(processorPathArg); 22.505 - } 22.506 - 22.507 - /** The actual effective locations searched for sources */ 22.508 - private Path sourceSearchPath; 22.509 - 22.510 - public Collection<File> sourceSearchPath() { 22.511 - if (sourceSearchPath == null) { 22.512 - lazy(); 22.513 - Path sourcePath = getPathForLocation(SOURCE_PATH); 22.514 - Path userClassPath = getPathForLocation(CLASS_PATH); 22.515 - sourceSearchPath = sourcePath != null ? sourcePath : userClassPath; 22.516 - } 22.517 - return Collections.unmodifiableCollection(sourceSearchPath); 22.518 - } 22.519 - 22.520 - /** The actual effective locations searched for classes */ 22.521 - private Path classSearchPath; 22.522 - 22.523 - public Collection<File> classSearchPath() { 22.524 - if (classSearchPath == null) { 22.525 - lazy(); 22.526 - Path bootClassPath = getPathForLocation(PLATFORM_CLASS_PATH); 22.527 - Path userClassPath = getPathForLocation(CLASS_PATH); 22.528 - classSearchPath = new Path(); 22.529 - classSearchPath.addAll(bootClassPath); 22.530 - classSearchPath.addAll(userClassPath); 22.531 - } 22.532 - return Collections.unmodifiableCollection(classSearchPath); 22.533 - } 22.534 - 22.535 - /** The actual effective locations for non-source, non-class files */ 22.536 - private Path otherSearchPath; 22.537 - 22.538 - Collection<File> otherSearchPath() { 22.539 - if (otherSearchPath == null) { 22.540 - lazy(); 22.541 - Path userClassPath = getPathForLocation(CLASS_PATH); 22.542 - Path sourcePath = getPathForLocation(SOURCE_PATH); 22.543 - if (sourcePath == null) 22.544 - otherSearchPath = userClassPath; 22.545 - else { 22.546 - otherSearchPath = new Path(); 22.547 - otherSearchPath.addAll(userClassPath); 22.548 - otherSearchPath.addAll(sourcePath); 22.549 - } 22.550 - } 22.551 - return Collections.unmodifiableCollection(otherSearchPath); 22.552 - } 22.553 - 22.554 - /** Is this the name of an archive file? */ 22.555 - private static boolean isArchive(File file) { 22.556 - String n = file.getName().toLowerCase(); 22.557 - boolean isFile = false; 22.558 - if (!NON_BATCH_MODE) { 22.559 - Boolean isf = isDirectory.get(file); 22.560 - if (isf == null) { 22.561 - isFile = file.isFile(); 22.562 - isDirectory.put(file, isFile); 22.563 - } 22.564 - else { 22.565 - isFile = isf; 22.566 - } 22.567 - } 22.568 - else { 22.569 - isFile = file.isFile(); 22.570 - } 22.571 - 22.572 - return isFile 22.573 - && (n.endsWith(".jar") || n.endsWith(".zip")); 22.574 - } 22.575 -}
23.1 --- a/src/share/classes/com/sun/tools/javac/zip/ZipFileIndex.java Fri Jun 06 15:17:35 2008 -0700 23.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 23.3 @@ -1,1236 +0,0 @@ 23.4 -/* 23.5 - * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. 23.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 23.7 - * 23.8 - * This code is free software; you can redistribute it and/or modify it 23.9 - * under the terms of the GNU General Public License version 2 only, as 23.10 - * published by the Free Software Foundation. Sun designates this 23.11 - * particular file as subject to the "Classpath" exception as provided 23.12 - * by Sun in the LICENSE file that accompanied this code. 23.13 - * 23.14 - * This code is distributed in the hope that it will be useful, but WITHOUT 23.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 23.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 23.17 - * version 2 for more details (a copy is included in the LICENSE file that 23.18 - * accompanied this code). 23.19 - * 23.20 - * You should have received a copy of the GNU General Public License version 23.21 - * 2 along with this work; if not, write to the Free Software Foundation, 23.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 23.23 - * 23.24 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 23.25 - * CA 95054 USA or visit www.sun.com if you need additional information or 23.26 - * have any questions. 23.27 - */ 23.28 - 23.29 -package com.sun.tools.javac.zip; 23.30 - 23.31 -import java.io.*; 23.32 -import java.text.MessageFormat; 23.33 -import java.util.*; 23.34 -import java.util.List; 23.35 -import java.util.concurrent.locks.ReentrantLock; 23.36 -import java.util.zip.*; 23.37 - 23.38 -/** This class implements building of index of a zip archive and access to it's context. 23.39 - * It also uses prebuild index if available. It supports invocations where it will 23.40 - * serialize an optimized zip index file to disk. 23.41 - * 23.42 - * In oreder to use secondary index file make sure the option "usezipindex" is in the Options object, 23.43 - * when JavacFileManager is invoked. (You can pass "-XDusezipindex" on the command line. 23.44 - * 23.45 - * Location where to look for/generate optimized zip index files can be provided using 23.46 - * "-XDcachezipindexdir=<directory>". If this flag is not provided, the dfault location is 23.47 - * the value of the "java.io.tmpdir" system property. 23.48 - * 23.49 - * If key "-XDwritezipindexfiles" is specified, there will be new optimized index file 23.50 - * created for each archive, used by the compiler for compilation, at location, 23.51 - * specified by "cachezipindexdir" option. 23.52 - * 23.53 - * If nonBatchMode option is specified (-XDnonBatchMode) the compiler will use timestamp 23.54 - * checking to reindex the zip files if it is needed. In batch mode the timestamps are not checked 23.55 - * and the compiler uses the cached indexes. 23.56 - */ 23.57 -public class ZipFileIndex { 23.58 - private static final String MIN_CHAR = String.valueOf(Character.MIN_VALUE); 23.59 - private static final String MAX_CHAR = String.valueOf(Character.MAX_VALUE); 23.60 - 23.61 - public final static long NOT_MODIFIED = Long.MIN_VALUE; 23.62 - 23.63 - private static Map<File, ZipFileIndex> zipFileIndexCache = new HashMap<File, ZipFileIndex>(); 23.64 - private static ReentrantLock lock = new ReentrantLock(); 23.65 - 23.66 - private static boolean NON_BATCH_MODE = System.getProperty("nonBatchMode") != null;// TODO: Use -XD compiler switch for this. 23.67 - 23.68 - private Map<String, DirectoryEntry> directories = Collections.<String, DirectoryEntry>emptyMap(); 23.69 - private Set<String> allDirs = Collections.<String>emptySet(); 23.70 - 23.71 - // ZipFileIndex data entries 23.72 - private File zipFile; 23.73 - private long zipFileLastModified = NOT_MODIFIED; 23.74 - private RandomAccessFile zipRandomFile; 23.75 - private ZipFileIndexEntry[] entries; 23.76 - 23.77 - private boolean readFromIndex = false; 23.78 - private File zipIndexFile = null; 23.79 - private boolean triedToReadIndex = false; 23.80 - private int symbolFilePrefixLength = 0; 23.81 - private boolean hasPopulatedData = false; 23.82 - private long lastReferenceTimeStamp = NOT_MODIFIED; 23.83 - 23.84 - private boolean usePreindexedCache = false; 23.85 - private String preindexedCacheLocation = null; 23.86 - 23.87 - private boolean writeIndex = false; 23.88 - 23.89 - /** 23.90 - * Returns a list of all ZipFileIndex entries 23.91 - * 23.92 - * @return A list of ZipFileIndex entries, or an empty list 23.93 - */ 23.94 - public static List<ZipFileIndex> getZipFileIndexes() { 23.95 - return getZipFileIndexes(false); 23.96 - } 23.97 - 23.98 - /** 23.99 - * Returns a list of all ZipFileIndex entries 23.100 - * 23.101 - * @param openedOnly If true it returns a list of only opened ZipFileIndex entries, otherwise 23.102 - * all ZipFileEntry(s) are included into the list. 23.103 - * @return A list of ZipFileIndex entries, or an empty list 23.104 - */ 23.105 - public static List<ZipFileIndex> getZipFileIndexes(boolean openedOnly) { 23.106 - List<ZipFileIndex> zipFileIndexes = new ArrayList<ZipFileIndex>(); 23.107 - lock.lock(); 23.108 - try { 23.109 - zipFileIndexes.addAll(zipFileIndexCache.values()); 23.110 - 23.111 - if (openedOnly) { 23.112 - for(ZipFileIndex elem : zipFileIndexes) { 23.113 - if (!elem.isOpen()) { 23.114 - zipFileIndexes.remove(elem); 23.115 - } 23.116 - } 23.117 - } 23.118 - } 23.119 - finally { 23.120 - lock.unlock(); 23.121 - } 23.122 - return zipFileIndexes; 23.123 - } 23.124 - 23.125 - public boolean isOpen() { 23.126 - lock.lock(); 23.127 - try { 23.128 - return zipRandomFile != null; 23.129 - } 23.130 - finally { 23.131 - lock.unlock(); 23.132 - } 23.133 - } 23.134 - 23.135 - public static ZipFileIndex getZipFileIndex(File zipFile, int symbolFilePrefixLen, boolean useCache, String cacheLocation, boolean writeIndex) throws IOException { 23.136 - ZipFileIndex zi = null; 23.137 - lock.lock(); 23.138 - try { 23.139 - zi = getExistingZipIndex(zipFile); 23.140 - 23.141 - if (zi == null || (zi != null && zipFile.lastModified() != zi.zipFileLastModified)) { 23.142 - zi = new ZipFileIndex(zipFile, symbolFilePrefixLen, writeIndex, 23.143 - useCache, cacheLocation); 23.144 - zipFileIndexCache.put(zipFile, zi); 23.145 - } 23.146 - } 23.147 - finally { 23.148 - lock.unlock(); 23.149 - } 23.150 - return zi; 23.151 - } 23.152 - 23.153 - public static ZipFileIndex getExistingZipIndex(File zipFile) { 23.154 - lock.lock(); 23.155 - try { 23.156 - return zipFileIndexCache.get(zipFile); 23.157 - } 23.158 - finally { 23.159 - lock.unlock(); 23.160 - } 23.161 - } 23.162 - 23.163 - public static void clearCache() { 23.164 - lock.lock(); 23.165 - try { 23.166 - zipFileIndexCache.clear(); 23.167 - } 23.168 - finally { 23.169 - lock.unlock(); 23.170 - } 23.171 - } 23.172 - 23.173 - public static void clearCache(long timeNotUsed) { 23.174 - lock.lock(); 23.175 - try { 23.176 - Iterator<File> cachedFileIterator = zipFileIndexCache.keySet().iterator(); 23.177 - while (cachedFileIterator.hasNext()) { 23.178 - File cachedFile = cachedFileIterator.next(); 23.179 - ZipFileIndex cachedZipIndex = zipFileIndexCache.get(cachedFile); 23.180 - if (cachedZipIndex != null) { 23.181 - long timeToTest = cachedZipIndex.lastReferenceTimeStamp + timeNotUsed; 23.182 - if (timeToTest < cachedZipIndex.lastReferenceTimeStamp || // Overflow... 23.183 - System.currentTimeMillis() > timeToTest) { 23.184 - zipFileIndexCache.remove(cachedFile); 23.185 - } 23.186 - } 23.187 - } 23.188 - } 23.189 - finally { 23.190 - lock.unlock(); 23.191 - } 23.192 - } 23.193 - 23.194 - public static void removeFromCache(File file) { 23.195 - lock.lock(); 23.196 - try { 23.197 - zipFileIndexCache.remove(file); 23.198 - } 23.199 - finally { 23.200 - lock.unlock(); 23.201 - } 23.202 - } 23.203 - 23.204 - /** Sets already opened list of ZipFileIndexes from an outside client 23.205 - * of the compiler. This functionality should be used in a non-batch clients of the compiler. 23.206 - */ 23.207 - public static void setOpenedIndexes(List<ZipFileIndex>indexes) throws IllegalStateException { 23.208 - lock.lock(); 23.209 - try { 23.210 - if (zipFileIndexCache.isEmpty()) { 23.211 - throw new IllegalStateException("Setting opened indexes should be called only when the ZipFileCache is empty. Call JavacFileManager.flush() before calling this method."); 23.212 - } 23.213 - 23.214 - for (ZipFileIndex zfi : indexes) { 23.215 - zipFileIndexCache.put(zfi.zipFile, zfi); 23.216 - } 23.217 - } 23.218 - finally { 23.219 - lock.unlock(); 23.220 - } 23.221 - } 23.222 - 23.223 - private ZipFileIndex(File zipFile, int symbolFilePrefixLen, boolean writeIndex, 23.224 - boolean useCache, String cacheLocation) throws IOException { 23.225 - this.zipFile = zipFile; 23.226 - this.symbolFilePrefixLength = symbolFilePrefixLen; 23.227 - this.writeIndex = writeIndex; 23.228 - this.usePreindexedCache = useCache; 23.229 - this.preindexedCacheLocation = cacheLocation; 23.230 - 23.231 - if (zipFile != null) { 23.232 - this.zipFileLastModified = zipFile.lastModified(); 23.233 - } 23.234 - 23.235 - // Validate integrity of the zip file 23.236 - checkIndex(); 23.237 - } 23.238 - 23.239 - public String toString() { 23.240 - return "ZipFileIndex of file:(" + zipFile + ")"; 23.241 - } 23.242 - 23.243 - // Just in case... 23.244 - protected void finalize() { 23.245 - closeFile(); 23.246 - } 23.247 - 23.248 - private boolean isUpToDate() { 23.249 - if (zipFile != null && 23.250 - ((!NON_BATCH_MODE) || zipFileLastModified == zipFile.lastModified()) && 23.251 - hasPopulatedData) { 23.252 - return true; 23.253 - } 23.254 - 23.255 - return false; 23.256 - } 23.257 - 23.258 - /** 23.259 - * Here we need to make sure that the ZipFileIndex is valid. Check the timestamp of the file and 23.260 - * if its the same as the one at the time the index was build we don't need to reopen anything. 23.261 - */ 23.262 - private void checkIndex() throws IOException { 23.263 - boolean isUpToDate = true; 23.264 - if (!isUpToDate()) { 23.265 - closeFile(); 23.266 - isUpToDate = false; 23.267 - } 23.268 - 23.269 - if (zipRandomFile != null || isUpToDate) { 23.270 - lastReferenceTimeStamp = System.currentTimeMillis(); 23.271 - return; 23.272 - } 23.273 - 23.274 - hasPopulatedData = true; 23.275 - 23.276 - if (readIndex()) { 23.277 - lastReferenceTimeStamp = System.currentTimeMillis(); 23.278 - return; 23.279 - } 23.280 - 23.281 - directories = Collections.<String, DirectoryEntry>emptyMap(); 23.282 - allDirs = Collections.<String>emptySet(); 23.283 - 23.284 - try { 23.285 - openFile(); 23.286 - long totalLength = zipRandomFile.length(); 23.287 - ZipDirectory directory = new ZipDirectory(zipRandomFile, 0L, totalLength, this); 23.288 - directory.buildIndex(); 23.289 - } finally { 23.290 - if (zipRandomFile != null) { 23.291 - closeFile(); 23.292 - } 23.293 - } 23.294 - 23.295 - lastReferenceTimeStamp = System.currentTimeMillis(); 23.296 - } 23.297 - 23.298 - private void openFile() throws FileNotFoundException { 23.299 - if (zipRandomFile == null && zipFile != null) { 23.300 - zipRandomFile = new RandomAccessFile(zipFile, "r"); 23.301 - } 23.302 - } 23.303 - 23.304 - private void cleanupState() { 23.305 - // Make sure there is a valid but empty index if the file doesn't exist 23.306 - entries = ZipFileIndexEntry.EMPTY_ARRAY; 23.307 - directories = Collections.<String, DirectoryEntry>emptyMap(); 23.308 - zipFileLastModified = NOT_MODIFIED; 23.309 - allDirs = Collections.<String>emptySet(); 23.310 - } 23.311 - 23.312 - public void close() { 23.313 - lock.lock(); 23.314 - try { 23.315 - writeIndex(); 23.316 - closeFile(); 23.317 - } 23.318 - finally { 23.319 - lock.unlock(); 23.320 - } 23.321 - } 23.322 - 23.323 - private void closeFile() { 23.324 - if (zipRandomFile != null) { 23.325 - try { 23.326 - zipRandomFile.close(); 23.327 - } catch (IOException ex) { 23.328 - } 23.329 - zipRandomFile = null; 23.330 - } 23.331 - } 23.332 - 23.333 - /** 23.334 - * Returns the ZipFileIndexEntry for an absolute path, if there is one. 23.335 - */ 23.336 - public ZipFileIndexEntry getZipIndexEntry(String path) { 23.337 - if (File.separatorChar != '/') { 23.338 - path = path.replace('/', File.separatorChar); 23.339 - } 23.340 - lock.lock(); 23.341 - try { 23.342 - checkIndex(); 23.343 - String lookFor = ""; 23.344 - int lastSepIndex = path.lastIndexOf(File.separatorChar); 23.345 - boolean noSeparator = false; 23.346 - if (lastSepIndex == -1) { 23.347 - noSeparator = true; 23.348 - } 23.349 - 23.350 - DirectoryEntry de = directories.get(noSeparator ? "" : path.substring(0, lastSepIndex)); 23.351 - 23.352 - lookFor = path.substring(noSeparator ? 0 : lastSepIndex + 1); 23.353 - 23.354 - return de == null ? null : de.getEntry(lookFor); 23.355 - } 23.356 - catch (IOException e) { 23.357 - return null; 23.358 - } 23.359 - finally { 23.360 - lock.unlock(); 23.361 - } 23.362 - } 23.363 - 23.364 - /** 23.365 - * Returns a javac List of filenames within an absolute path in the ZipFileIndex. 23.366 - */ 23.367 - public com.sun.tools.javac.util.List<String> getFiles(String path) { 23.368 - if (File.separatorChar != '/') { 23.369 - path = path.replace('/', File.separatorChar); 23.370 - } 23.371 - 23.372 - lock.lock(); 23.373 - try { 23.374 - checkIndex(); 23.375 - 23.376 - DirectoryEntry de = directories.get(path); 23.377 - com.sun.tools.javac.util.List<String> ret = de == null ? null : de.getFiles(); 23.378 - 23.379 - if (ret == null) { 23.380 - return com.sun.tools.javac.util.List.<String>nil(); 23.381 - } 23.382 - return ret; 23.383 - } 23.384 - catch (IOException e) { 23.385 - return com.sun.tools.javac.util.List.<String>nil(); 23.386 - } 23.387 - finally { 23.388 - lock.unlock(); 23.389 - } 23.390 - } 23.391 - 23.392 - public List<String> getAllDirectories(String path) { 23.393 - 23.394 - if (File.separatorChar != '/') { 23.395 - path = path.replace('/', File.separatorChar); 23.396 - } 23.397 - 23.398 - lock.lock(); 23.399 - try { 23.400 - checkIndex(); 23.401 - path = path.intern(); 23.402 - 23.403 - DirectoryEntry de = directories.get(path); 23.404 - com.sun.tools.javac.util.List<String> ret = de == null ? null : de.getDirectories(); 23.405 - 23.406 - if (ret == null) { 23.407 - return com.sun.tools.javac.util.List.<String>nil(); 23.408 - } 23.409 - 23.410 - return ret; 23.411 - } 23.412 - catch (IOException e) { 23.413 - return com.sun.tools.javac.util.List.<String>nil(); 23.414 - } 23.415 - finally { 23.416 - lock.unlock(); 23.417 - } 23.418 - } 23.419 - 23.420 - public Set<String> getAllDirectories() { 23.421 - lock.lock(); 23.422 - try { 23.423 - checkIndex(); 23.424 - if (allDirs == Collections.EMPTY_SET) { 23.425 - Set<String> alldirs = new HashSet<String>(); 23.426 - Iterator<String> dirsIter = directories.keySet().iterator(); 23.427 - while (dirsIter.hasNext()) { 23.428 - alldirs.add(new String(dirsIter.next())); 23.429 - } 23.430 - 23.431 - allDirs = alldirs; 23.432 - } 23.433 - 23.434 - return allDirs; 23.435 - } 23.436 - catch (IOException e) { 23.437 - return Collections.<String>emptySet(); 23.438 - } 23.439 - finally { 23.440 - lock.unlock(); 23.441 - } 23.442 - } 23.443 - 23.444 - /** 23.445 - * Tests if a specific path exists in the zip. This method will return true 23.446 - * for file entries and directories. 23.447 - * 23.448 - * @param path A path within the zip. 23.449 - * @return True if the path is a file or dir, false otherwise. 23.450 - */ 23.451 - public boolean contains(String path) { 23.452 - lock.lock(); 23.453 - try { 23.454 - checkIndex(); 23.455 - return getZipIndexEntry(path) != null; 23.456 - } 23.457 - catch (IOException e) { 23.458 - return false; 23.459 - } 23.460 - finally { 23.461 - lock.unlock(); 23.462 - } 23.463 - } 23.464 - 23.465 - public boolean isDirectory(String path) throws IOException { 23.466 - lock.lock(); 23.467 - try { 23.468 - // The top level in a zip file is always a directory. 23.469 - if (path.length() == 0) { 23.470 - lastReferenceTimeStamp = System.currentTimeMillis(); 23.471 - return true; 23.472 - } 23.473 - 23.474 - if (File.separatorChar != '/') 23.475 - path = path.replace('/', File.separatorChar); 23.476 - checkIndex(); 23.477 - return directories.get(path) != null; 23.478 - } 23.479 - finally { 23.480 - lock.unlock(); 23.481 - } 23.482 - } 23.483 - 23.484 - public long getLastModified(String path) throws IOException { 23.485 - lock.lock(); 23.486 - try { 23.487 - ZipFileIndexEntry entry = getZipIndexEntry(path); 23.488 - if (entry == null) 23.489 - throw new FileNotFoundException(); 23.490 - return entry.getLastModified(); 23.491 - } 23.492 - finally { 23.493 - lock.unlock(); 23.494 - } 23.495 - } 23.496 - 23.497 - public int length(String path) throws IOException { 23.498 - lock.lock(); 23.499 - try { 23.500 - ZipFileIndexEntry entry = getZipIndexEntry(path); 23.501 - if (entry == null) 23.502 - throw new FileNotFoundException(); 23.503 - 23.504 - if (entry.isDir) { 23.505 - return 0; 23.506 - } 23.507 - 23.508 - byte[] header = getHeader(entry); 23.509 - // entry is not compressed? 23.510 - if (get2ByteLittleEndian(header, 8) == 0) { 23.511 - return entry.compressedSize; 23.512 - } else { 23.513 - return entry.size; 23.514 - } 23.515 - } 23.516 - finally { 23.517 - lock.unlock(); 23.518 - } 23.519 - } 23.520 - 23.521 - public byte[] read(String path) throws IOException { 23.522 - lock.lock(); 23.523 - try { 23.524 - ZipFileIndexEntry entry = getZipIndexEntry(path); 23.525 - if (entry == null) 23.526 - throw new FileNotFoundException(MessageFormat.format("Path not found in ZIP: {0}", path)); 23.527 - return read(entry); 23.528 - } 23.529 - finally { 23.530 - lock.unlock(); 23.531 - } 23.532 - } 23.533 - 23.534 - public byte[] read(ZipFileIndexEntry entry) throws IOException { 23.535 - lock.lock(); 23.536 - try { 23.537 - openFile(); 23.538 - byte[] result = readBytes(entry); 23.539 - closeFile(); 23.540 - return result; 23.541 - } 23.542 - finally { 23.543 - lock.unlock(); 23.544 - } 23.545 - } 23.546 - 23.547 - public int read(String path, byte[] buffer) throws IOException { 23.548 - lock.lock(); 23.549 - try { 23.550 - ZipFileIndexEntry entry = getZipIndexEntry(path); 23.551 - if (entry == null) 23.552 - throw new FileNotFoundException(); 23.553 - return read(entry, buffer); 23.554 - } 23.555 - finally { 23.556 - lock.unlock(); 23.557 - } 23.558 - } 23.559 - 23.560 - public int read(ZipFileIndexEntry entry, byte[] buffer) 23.561 - throws IOException { 23.562 - lock.lock(); 23.563 - try { 23.564 - int result = readBytes(entry, buffer); 23.565 - return result; 23.566 - } 23.567 - finally { 23.568 - lock.unlock(); 23.569 - } 23.570 - } 23.571 - 23.572 - private byte[] readBytes(ZipFileIndexEntry entry) throws IOException { 23.573 - byte[] header = getHeader(entry); 23.574 - int csize = entry.compressedSize; 23.575 - byte[] cbuf = new byte[csize]; 23.576 - zipRandomFile.skipBytes(get2ByteLittleEndian(header, 26) + get2ByteLittleEndian(header, 28)); 23.577 - zipRandomFile.readFully(cbuf, 0, csize); 23.578 - 23.579 - // is this compressed - offset 8 in the ZipEntry header 23.580 - if (get2ByteLittleEndian(header, 8) == 0) 23.581 - return cbuf; 23.582 - 23.583 - int size = entry.size; 23.584 - byte[] buf = new byte[size]; 23.585 - if (inflate(cbuf, buf) != size) 23.586 - throw new ZipException("corrupted zip file"); 23.587 - 23.588 - return buf; 23.589 - } 23.590 - 23.591 - /** 23.592 - * 23.593 - */ 23.594 - private int readBytes(ZipFileIndexEntry entry, byte[] buffer) throws IOException { 23.595 - byte[] header = getHeader(entry); 23.596 - 23.597 - // entry is not compressed? 23.598 - if (get2ByteLittleEndian(header, 8) == 0) { 23.599 - zipRandomFile.skipBytes(get2ByteLittleEndian(header, 26) + get2ByteLittleEndian(header, 28)); 23.600 - int offset = 0; 23.601 - int size = buffer.length; 23.602 - while (offset < size) { 23.603 - int count = zipRandomFile.read(buffer, offset, size - offset); 23.604 - if (count == -1) 23.605 - break; 23.606 - offset += count; 23.607 - } 23.608 - return entry.size; 23.609 - } 23.610 - 23.611 - int csize = entry.compressedSize; 23.612 - byte[] cbuf = new byte[csize]; 23.613 - zipRandomFile.skipBytes(get2ByteLittleEndian(header, 26) + get2ByteLittleEndian(header, 28)); 23.614 - zipRandomFile.readFully(cbuf, 0, csize); 23.615 - 23.616 - int count = inflate(cbuf, buffer); 23.617 - if (count == -1) 23.618 - throw new ZipException("corrupted zip file"); 23.619 - 23.620 - return entry.size; 23.621 - } 23.622 - 23.623 - //---------------------------------------------------------------------------- 23.624 - // Zip utilities 23.625 - //---------------------------------------------------------------------------- 23.626 - 23.627 - private byte[] getHeader(ZipFileIndexEntry entry) throws IOException { 23.628 - zipRandomFile.seek(entry.offset); 23.629 - byte[] header = new byte[30]; 23.630 - zipRandomFile.readFully(header); 23.631 - if (get4ByteLittleEndian(header, 0) != 0x04034b50) 23.632 - throw new ZipException("corrupted zip file"); 23.633 - if ((get2ByteLittleEndian(header, 6) & 1) != 0) 23.634 - throw new ZipException("encrypted zip file"); // offset 6 in the header of the ZipFileEntry 23.635 - return header; 23.636 - } 23.637 - 23.638 - /* 23.639 - * Inflate using the java.util.zip.Inflater class 23.640 - */ 23.641 - private static Inflater inflater; 23.642 - private int inflate(byte[] src, byte[] dest) { 23.643 - 23.644 - // construct the inflater object or reuse an existing one 23.645 - if (inflater == null) 23.646 - inflater = new Inflater(true); 23.647 - 23.648 - synchronized (inflater) { 23.649 - inflater.reset(); 23.650 - inflater.setInput(src); 23.651 - try { 23.652 - return inflater.inflate(dest); 23.653 - } catch (DataFormatException ex) { 23.654 - return -1; 23.655 - } 23.656 - } 23.657 - } 23.658 - 23.659 - /** 23.660 - * return the two bytes buf[pos], buf[pos+1] as an unsigned integer in little 23.661 - * endian format. 23.662 - */ 23.663 - private static int get2ByteLittleEndian(byte[] buf, int pos) { 23.664 - return (buf[pos] & 0xFF) + ((buf[pos+1] & 0xFF) << 8); 23.665 - } 23.666 - 23.667 - /** 23.668 - * return the 4 bytes buf[i..i+3] as an integer in little endian format. 23.669 - */ 23.670 - private static int get4ByteLittleEndian(byte[] buf, int pos) { 23.671 - return (buf[pos] & 0xFF) + ((buf[pos + 1] & 0xFF) << 8) + 23.672 - ((buf[pos + 2] & 0xFF) << 16) + ((buf[pos + 3] & 0xFF) << 24); 23.673 - } 23.674 - 23.675 - /* ---------------------------------------------------------------------------- 23.676 - * ZipDirectory 23.677 - * ----------------------------------------------------------------------------*/ 23.678 - 23.679 - private class ZipDirectory { 23.680 - private String lastDir; 23.681 - private int lastStart; 23.682 - private int lastLen; 23.683 - 23.684 - byte[] zipDir; 23.685 - RandomAccessFile zipRandomFile = null; 23.686 - ZipFileIndex zipFileIndex = null; 23.687 - 23.688 - public ZipDirectory(RandomAccessFile zipRandomFile, long start, long end, ZipFileIndex index) throws IOException { 23.689 - this.zipRandomFile = zipRandomFile; 23.690 - this.zipFileIndex = index; 23.691 - 23.692 - findCENRecord(start, end); 23.693 - } 23.694 - 23.695 - /* 23.696 - * Reads zip file central directory. 23.697 - * For more details see readCEN in zip_util.c from the JDK sources. 23.698 - * This is a Java port of that function. 23.699 - */ 23.700 - private void findCENRecord(long start, long end) throws IOException { 23.701 - long totalLength = end - start; 23.702 - int endbuflen = 1024; 23.703 - byte[] endbuf = new byte[endbuflen]; 23.704 - long endbufend = end - start; 23.705 - 23.706 - // There is a variable-length field after the dir offset record. We need to do consequential search. 23.707 - while (endbufend >= 22) { 23.708 - if (endbufend < endbuflen) 23.709 - endbuflen = (int)endbufend; 23.710 - long endbufpos = endbufend - endbuflen; 23.711 - zipRandomFile.seek(start + endbufpos); 23.712 - zipRandomFile.readFully(endbuf, 0, endbuflen); 23.713 - int i = endbuflen - 22; 23.714 - while (i >= 0 && 23.715 - !(endbuf[i] == 0x50 && 23.716 - endbuf[i + 1] == 0x4b && 23.717 - endbuf[i + 2] == 0x05 && 23.718 - endbuf[i + 3] == 0x06 && 23.719 - endbufpos + i + 22 + 23.720 - get2ByteLittleEndian(endbuf, i + 20) == totalLength)) { 23.721 - i--; 23.722 - } 23.723 - 23.724 - if (i >= 0) { 23.725 - zipDir = new byte[get4ByteLittleEndian(endbuf, i + 12) + 2]; 23.726 - zipDir[0] = endbuf[i + 10]; 23.727 - zipDir[1] = endbuf[i + 11]; 23.728 - zipRandomFile.seek(start + get4ByteLittleEndian(endbuf, i + 16)); 23.729 - zipRandomFile.readFully(zipDir, 2, zipDir.length - 2); 23.730 - return; 23.731 - } else { 23.732 - endbufend = endbufpos + 21; 23.733 - } 23.734 - } 23.735 - throw new ZipException("cannot read zip file"); 23.736 - } 23.737 - private void buildIndex() throws IOException { 23.738 - int entryCount = get2ByteLittleEndian(zipDir, 0); 23.739 - 23.740 - entries = new ZipFileIndexEntry[entryCount]; 23.741 - // Add each of the files 23.742 - if (entryCount > 0) { 23.743 - directories = new HashMap<String, DirectoryEntry>(); 23.744 - ArrayList<ZipFileIndexEntry> entryList = new ArrayList<ZipFileIndexEntry>(); 23.745 - int pos = 2; 23.746 - for (int i = 0; i < entryCount; i++) { 23.747 - pos = readEntry(pos, entryList, directories); 23.748 - } 23.749 - 23.750 - // Add the accumulated dirs into the same list 23.751 - Iterator i = directories.keySet().iterator(); 23.752 - while (i.hasNext()) { 23.753 - ZipFileIndexEntry zipFileIndexEntry = new ZipFileIndexEntry( (String) i.next()); 23.754 - zipFileIndexEntry.isDir = true; 23.755 - entryList.add(zipFileIndexEntry); 23.756 - } 23.757 - 23.758 - entries = entryList.toArray(new ZipFileIndexEntry[entryList.size()]); 23.759 - Arrays.sort(entries); 23.760 - } else { 23.761 - cleanupState(); 23.762 - } 23.763 - } 23.764 - 23.765 - private int readEntry(int pos, List<ZipFileIndexEntry> entryList, 23.766 - Map<String, DirectoryEntry> directories) throws IOException { 23.767 - if (get4ByteLittleEndian(zipDir, pos) != 0x02014b50) { 23.768 - throw new ZipException("cannot read zip file entry"); 23.769 - } 23.770 - 23.771 - int dirStart = pos + 46; 23.772 - int fileStart = dirStart; 23.773 - int fileEnd = fileStart + get2ByteLittleEndian(zipDir, pos + 28); 23.774 - 23.775 - if (zipFileIndex.symbolFilePrefixLength != 0 && 23.776 - ((fileEnd - fileStart) >= symbolFilePrefixLength)) { 23.777 - dirStart += zipFileIndex.symbolFilePrefixLength; 23.778 - fileStart += zipFileIndex.symbolFilePrefixLength; 23.779 - } 23.780 - 23.781 - // Use the OS's path separator. Keep the position of the last one. 23.782 - for (int index = fileStart; index < fileEnd; index++) { 23.783 - byte nextByte = zipDir[index]; 23.784 - if (nextByte == (byte)'\\' || nextByte == (byte)'/') { 23.785 - zipDir[index] = (byte)File.separatorChar; 23.786 - fileStart = index + 1; 23.787 - } 23.788 - } 23.789 - 23.790 - String directory = null; 23.791 - if (fileStart == dirStart) 23.792 - directory = ""; 23.793 - else if (lastDir != null && lastLen == fileStart - dirStart - 1) { 23.794 - int index = lastLen - 1; 23.795 - while (zipDir[lastStart + index] == zipDir[dirStart + index]) { 23.796 - if (index == 0) { 23.797 - directory = lastDir; 23.798 - break; 23.799 - } 23.800 - index--; 23.801 - } 23.802 - } 23.803 - 23.804 - // Sub directories 23.805 - if (directory == null) { 23.806 - lastStart = dirStart; 23.807 - lastLen = fileStart - dirStart - 1; 23.808 - 23.809 - directory = new String(zipDir, dirStart, lastLen, "UTF-8").intern(); 23.810 - lastDir = directory; 23.811 - 23.812 - // Enter also all the parent directories 23.813 - String tempDirectory = directory; 23.814 - 23.815 - while (directories.get(tempDirectory) == null) { 23.816 - directories.put(tempDirectory, new DirectoryEntry(tempDirectory, zipFileIndex)); 23.817 - int separator = tempDirectory.lastIndexOf(File.separatorChar); 23.818 - if (separator == -1) 23.819 - break; 23.820 - tempDirectory = tempDirectory.substring(0, separator); 23.821 - } 23.822 - } 23.823 - else { 23.824 - directory = directory.intern(); 23.825 - if (directories.get(directory) == null) { 23.826 - directories.put(directory, new DirectoryEntry(directory, zipFileIndex)); 23.827 - } 23.828 - } 23.829 - 23.830 - // For each dir create also a file 23.831 - if (fileStart != fileEnd) { 23.832 - ZipFileIndexEntry entry = new ZipFileIndexEntry(directory, 23.833 - new String(zipDir, fileStart, fileEnd - fileStart, "UTF-8")); 23.834 - 23.835 - entry.setNativeTime(get4ByteLittleEndian(zipDir, pos + 12)); 23.836 - entry.compressedSize = get4ByteLittleEndian(zipDir, pos + 20); 23.837 - entry.size = get4ByteLittleEndian(zipDir, pos + 24); 23.838 - entry.offset = get4ByteLittleEndian(zipDir, pos + 42); 23.839 - entryList.add(entry); 23.840 - } 23.841 - 23.842 - return pos + 46 + 23.843 - get2ByteLittleEndian(zipDir, pos + 28) + 23.844 - get2ByteLittleEndian(zipDir, pos + 30) + 23.845 - get2ByteLittleEndian(zipDir, pos + 32); 23.846 - } 23.847 - } 23.848 - 23.849 - /** 23.850 - * Returns the last modified timestamp of a zip file. 23.851 - * @return long 23.852 - */ 23.853 - public long getZipFileLastModified() throws IOException { 23.854 - lock.lock(); 23.855 - try { 23.856 - checkIndex(); 23.857 - return zipFileLastModified; 23.858 - } 23.859 - finally { 23.860 - lock.unlock(); 23.861 - } 23.862 - } 23.863 - 23.864 - /** ------------------------------------------------------------------------ 23.865 - * DirectoryEntry class 23.866 - * -------------------------------------------------------------------------*/ 23.867 - static class DirectoryEntry { 23.868 - private boolean filesInited; 23.869 - private boolean directoriesInited; 23.870 - private boolean zipFileEntriesInited; 23.871 - private boolean entriesInited; 23.872 - 23.873 - private long writtenOffsetOffset = 0; 23.874 - 23.875 - private String dirName; 23.876 - 23.877 - private com.sun.tools.javac.util.List<String> zipFileEntriesFiles = com.sun.tools.javac.util.List.<String>nil(); 23.878 - private com.sun.tools.javac.util.List<String> zipFileEntriesDirectories = com.sun.tools.javac.util.List.<String>nil(); 23.879 - private com.sun.tools.javac.util.List<ZipFileIndexEntry> zipFileEntries = com.sun.tools.javac.util.List.<ZipFileIndexEntry>nil(); 23.880 - 23.881 - private List<ZipFileIndexEntry> entries = new ArrayList<ZipFileIndexEntry>(); 23.882 - 23.883 - private ZipFileIndex zipFileIndex; 23.884 - 23.885 - private int numEntries; 23.886 - 23.887 - DirectoryEntry(String dirName, ZipFileIndex index) { 23.888 - filesInited = false; 23.889 - directoriesInited = false; 23.890 - entriesInited = false; 23.891 - 23.892 - if (File.separatorChar == '/') { 23.893 - dirName.replace('\\', '/'); 23.894 - } 23.895 - else { 23.896 - dirName.replace('/', '\\'); 23.897 - } 23.898 - 23.899 - this.dirName = dirName.intern(); 23.900 - this.zipFileIndex = index; 23.901 - } 23.902 - 23.903 - private com.sun.tools.javac.util.List<String> getFiles() { 23.904 - if (filesInited) { 23.905 - return zipFileEntriesFiles; 23.906 - } 23.907 - 23.908 - initEntries(); 23.909 - 23.910 - for (ZipFileIndexEntry e : entries) { 23.911 - if (!e.isDir) { 23.912 - zipFileEntriesFiles = zipFileEntriesFiles.append(e.name); 23.913 - } 23.914 - } 23.915 - filesInited = true; 23.916 - return zipFileEntriesFiles; 23.917 - } 23.918 - 23.919 - private com.sun.tools.javac.util.List<String> getDirectories() { 23.920 - if (directoriesInited) { 23.921 - return zipFileEntriesFiles; 23.922 - } 23.923 - 23.924 - initEntries(); 23.925 - 23.926 - for (ZipFileIndexEntry e : entries) { 23.927 - if (e.isDir) { 23.928 - zipFileEntriesDirectories = zipFileEntriesDirectories.append(e.name); 23.929 - } 23.930 - } 23.931 - 23.932 - directoriesInited = true; 23.933 - 23.934 - return zipFileEntriesDirectories; 23.935 - } 23.936 - 23.937 - private com.sun.tools.javac.util.List<ZipFileIndexEntry> getEntries() { 23.938 - if (zipFileEntriesInited) { 23.939 - return zipFileEntries; 23.940 - } 23.941 - 23.942 - initEntries(); 23.943 - 23.944 - zipFileEntries = com.sun.tools.javac.util.List.nil(); 23.945 - for (ZipFileIndexEntry zfie : entries) { 23.946 - zipFileEntries = zipFileEntries.append(zfie); 23.947 - } 23.948 - 23.949 - zipFileEntriesInited = true; 23.950 - 23.951 - return zipFileEntries; 23.952 - } 23.953 - 23.954 - private ZipFileIndexEntry getEntry(String rootName) { 23.955 - initEntries(); 23.956 - int index = Collections.binarySearch(entries, new ZipFileIndexEntry(dirName, rootName)); 23.957 - if (index < 0) { 23.958 - return null; 23.959 - } 23.960 - 23.961 - return entries.get(index); 23.962 - } 23.963 - 23.964 - private void initEntries() { 23.965 - if (entriesInited) { 23.966 - return; 23.967 - } 23.968 - 23.969 - if (!zipFileIndex.readFromIndex) { 23.970 - int from = -Arrays.binarySearch(zipFileIndex.entries, 23.971 - new ZipFileIndexEntry(dirName, ZipFileIndex.MIN_CHAR)) - 1; 23.972 - int to = -Arrays.binarySearch(zipFileIndex.entries, 23.973 - new ZipFileIndexEntry(dirName, MAX_CHAR)) - 1; 23.974 - 23.975 - boolean emptyList = false; 23.976 - 23.977 - for (int i = from; i < to; i++) { 23.978 - entries.add(zipFileIndex.entries[i]); 23.979 - } 23.980 - } else { 23.981 - File indexFile = zipFileIndex.getIndexFile(); 23.982 - if (indexFile != null) { 23.983 - RandomAccessFile raf = null; 23.984 - try { 23.985 - raf = new RandomAccessFile(indexFile, "r"); 23.986 - raf.seek(writtenOffsetOffset); 23.987 - 23.988 - for (int nFiles = 0; nFiles < numEntries; nFiles++) { 23.989 - // Read the name bytes 23.990 - int zfieNameBytesLen = raf.readInt(); 23.991 - byte [] zfieNameBytes = new byte[zfieNameBytesLen]; 23.992 - raf.read(zfieNameBytes); 23.993 - String eName = new String(zfieNameBytes, "UTF-8"); 23.994 - 23.995 - // Read isDir 23.996 - boolean eIsDir = raf.readByte() == (byte)0 ? false : true; 23.997 - 23.998 - // Read offset of bytes in the real Jar/Zip file 23.999 - int eOffset = raf.readInt(); 23.1000 - 23.1001 - // Read size of the file in the real Jar/Zip file 23.1002 - int eSize = raf.readInt(); 23.1003 - 23.1004 - // Read compressed size of the file in the real Jar/Zip file 23.1005 - int eCsize = raf.readInt(); 23.1006 - 23.1007 - // Read java time stamp of the file in the real Jar/Zip file 23.1008 - long eJavaTimestamp = raf.readLong(); 23.1009 - 23.1010 - ZipFileIndexEntry rfie = new ZipFileIndexEntry(dirName, eName); 23.1011 - rfie.isDir = eIsDir; 23.1012 - rfie.offset = eOffset; 23.1013 - rfie.size = eSize; 23.1014 - rfie.compressedSize = eCsize; 23.1015 - rfie.javatime = eJavaTimestamp; 23.1016 - entries.add(rfie); 23.1017 - } 23.1018 - } catch (Throwable t) { 23.1019 - // Do nothing 23.1020 - } finally { 23.1021 - try { 23.1022 - if (raf == null) { 23.1023 - raf.close(); 23.1024 - } 23.1025 - } catch (Throwable t) { 23.1026 - // Do nothing 23.1027 - } 23.1028 - } 23.1029 - } 23.1030 - } 23.1031 - 23.1032 - entriesInited = true; 23.1033 - } 23.1034 - 23.1035 - List<ZipFileIndexEntry> getEntriesAsCollection() { 23.1036 - initEntries(); 23.1037 - 23.1038 - return entries; 23.1039 - } 23.1040 - } 23.1041 - 23.1042 - private boolean readIndex() { 23.1043 - if (triedToReadIndex || !usePreindexedCache) { 23.1044 - return false; 23.1045 - } 23.1046 - 23.1047 - boolean ret = false; 23.1048 - lock.lock(); 23.1049 - try { 23.1050 - triedToReadIndex = true; 23.1051 - RandomAccessFile raf = null; 23.1052 - try { 23.1053 - File indexFileName = getIndexFile(); 23.1054 - raf = new RandomAccessFile(indexFileName, "r"); 23.1055 - 23.1056 - long fileStamp = raf.readLong(); 23.1057 - if (zipFile.lastModified() != fileStamp) { 23.1058 - ret = false; 23.1059 - } else { 23.1060 - directories = new HashMap<String, DirectoryEntry>(); 23.1061 - int numDirs = raf.readInt(); 23.1062 - for (int nDirs = 0; nDirs < numDirs; nDirs++) { 23.1063 - int dirNameBytesLen = raf.readInt(); 23.1064 - byte [] dirNameBytes = new byte[dirNameBytesLen]; 23.1065 - raf.read(dirNameBytes); 23.1066 - 23.1067 - String dirNameStr = new String(dirNameBytes, "UTF-8"); 23.1068 - DirectoryEntry de = new DirectoryEntry(dirNameStr, this); 23.1069 - de.numEntries = raf.readInt(); 23.1070 - de.writtenOffsetOffset = raf.readLong(); 23.1071 - directories.put(dirNameStr, de); 23.1072 - } 23.1073 - ret = true; 23.1074 - zipFileLastModified = fileStamp; 23.1075 - } 23.1076 - } catch (Throwable t) { 23.1077 - // Do nothing 23.1078 - } finally { 23.1079 - if (raf != null) { 23.1080 - try { 23.1081 - raf.close(); 23.1082 - } catch (Throwable tt) { 23.1083 - // Do nothing 23.1084 - } 23.1085 - } 23.1086 - } 23.1087 - if (ret == true) { 23.1088 - readFromIndex = true; 23.1089 - } 23.1090 - } 23.1091 - finally { 23.1092 - lock.unlock(); 23.1093 - } 23.1094 - 23.1095 - return ret; 23.1096 - } 23.1097 - 23.1098 - private boolean writeIndex() { 23.1099 - boolean ret = false; 23.1100 - if (readFromIndex || !usePreindexedCache) { 23.1101 - return true; 23.1102 - } 23.1103 - 23.1104 - if (!writeIndex) { 23.1105 - return true; 23.1106 - } 23.1107 - 23.1108 - File indexFile = getIndexFile(); 23.1109 - if (indexFile == null) { 23.1110 - return false; 23.1111 - } 23.1112 - 23.1113 - RandomAccessFile raf = null; 23.1114 - long writtenSoFar = 0; 23.1115 - try { 23.1116 - raf = new RandomAccessFile(indexFile, "rw"); 23.1117 - 23.1118 - raf.writeLong(zipFileLastModified); 23.1119 - writtenSoFar += 8; 23.1120 - 23.1121 - 23.1122 - Iterator<String> iterDirName = directories.keySet().iterator(); 23.1123 - List<DirectoryEntry> directoriesToWrite = new ArrayList<DirectoryEntry>(); 23.1124 - Map<String, Long> offsets = new HashMap<String, Long>(); 23.1125 - raf.writeInt(directories.keySet().size()); 23.1126 - writtenSoFar += 4; 23.1127 - 23.1128 - while(iterDirName.hasNext()) { 23.1129 - String dirName = iterDirName.next(); 23.1130 - DirectoryEntry dirEntry = directories.get(dirName); 23.1131 - 23.1132 - directoriesToWrite.add(dirEntry); 23.1133 - 23.1134 - // Write the dir name bytes 23.1135 - byte [] dirNameBytes = dirName.getBytes("UTF-8"); 23.1136 - int dirNameBytesLen = dirNameBytes.length; 23.1137 - raf.writeInt(dirNameBytesLen); 23.1138 - writtenSoFar += 4; 23.1139 - 23.1140 - raf.write(dirNameBytes); 23.1141 - writtenSoFar += dirNameBytesLen; 23.1142 - 23.1143 - // Write the number of files in the dir 23.1144 - List dirEntries = dirEntry.getEntriesAsCollection(); 23.1145 - raf.writeInt(dirEntries.size()); 23.1146 - writtenSoFar += 4; 23.1147 - 23.1148 - offsets.put(dirName, new Long(writtenSoFar)); 23.1149 - 23.1150 - // Write the offset of the file's data in the dir 23.1151 - dirEntry.writtenOffsetOffset = 0L; 23.1152 - raf.writeLong(0L); 23.1153 - writtenSoFar += 8; 23.1154 - } 23.1155 - 23.1156 - for (DirectoryEntry de : directoriesToWrite) { 23.1157 - // Fix up the offset in the directory table 23.1158 - long currFP = raf.getFilePointer(); 23.1159 - 23.1160 - long offsetOffset = offsets.get(de.dirName).longValue(); 23.1161 - raf.seek(offsetOffset); 23.1162 - raf.writeLong(writtenSoFar); 23.1163 - 23.1164 - raf.seek(currFP); 23.1165 - 23.1166 - // Now write each of the files in the DirectoryEntry 23.1167 - List<ZipFileIndexEntry> entries = de.getEntriesAsCollection(); 23.1168 - for (ZipFileIndexEntry zfie : entries) { 23.1169 - // Write the name bytes 23.1170 - byte [] zfieNameBytes = zfie.name.getBytes("UTF-8"); 23.1171 - int zfieNameBytesLen = zfieNameBytes.length; 23.1172 - raf.writeInt(zfieNameBytesLen); 23.1173 - writtenSoFar += 4; 23.1174 - raf.write(zfieNameBytes); 23.1175 - writtenSoFar += zfieNameBytesLen; 23.1176 - 23.1177 - // Write isDir 23.1178 - raf.writeByte(zfie.isDir ? (byte)1 : (byte)0); 23.1179 - writtenSoFar += 1; 23.1180 - 23.1181 - // Write offset of bytes in the real Jar/Zip file 23.1182 - raf.writeInt(zfie.offset); 23.1183 - writtenSoFar += 4; 23.1184 - 23.1185 - // Write size of the file in the real Jar/Zip file 23.1186 - raf.writeInt(zfie.size); 23.1187 - writtenSoFar += 4; 23.1188 - 23.1189 - // Write compressed size of the file in the real Jar/Zip file 23.1190 - raf.writeInt(zfie.compressedSize); 23.1191 - writtenSoFar += 4; 23.1192 - 23.1193 - // Write java time stamp of the file in the real Jar/Zip file 23.1194 - raf.writeLong(zfie.getLastModified()); 23.1195 - writtenSoFar += 8; 23.1196 - } 23.1197 - } 23.1198 - } catch (Throwable t) { 23.1199 - // Do nothing 23.1200 - } finally { 23.1201 - try { 23.1202 - if (raf != null) { 23.1203 - raf.close(); 23.1204 - } 23.1205 - } catch(IOException ioe) { 23.1206 - // Do nothing 23.1207 - } 23.1208 - } 23.1209 - 23.1210 - return ret; 23.1211 - } 23.1212 - 23.1213 - public boolean writeZipIndex() { 23.1214 - lock.lock(); 23.1215 - try { 23.1216 - return writeIndex(); 23.1217 - } 23.1218 - finally { 23.1219 - lock.unlock(); 23.1220 - } 23.1221 - } 23.1222 - 23.1223 - private File getIndexFile() { 23.1224 - if (zipIndexFile == null) { 23.1225 - if (zipFile == null) { 23.1226 - return null; 23.1227 - } 23.1228 - 23.1229 - zipIndexFile = new File((preindexedCacheLocation == null ? "" : preindexedCacheLocation) + 23.1230 - zipFile.getName() + ".index"); 23.1231 - } 23.1232 - 23.1233 - return zipIndexFile; 23.1234 - } 23.1235 - 23.1236 - public File getZipFile() { 23.1237 - return zipFile; 23.1238 - } 23.1239 -}
24.1 --- a/src/share/classes/com/sun/tools/javac/zip/ZipFileIndexEntry.java Fri Jun 06 15:17:35 2008 -0700 24.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 24.3 @@ -1,116 +0,0 @@ 24.4 -/* 24.5 - * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. 24.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 24.7 - * 24.8 - * This code is free software; you can redistribute it and/or modify it 24.9 - * under the terms of the GNU General Public License version 2 only, as 24.10 - * published by the Free Software Foundation. Sun designates this 24.11 - * particular file as subject to the "Classpath" exception as provided 24.12 - * by Sun in the LICENSE file that accompanied this code. 24.13 - * 24.14 - * This code is distributed in the hope that it will be useful, but WITHOUT 24.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 24.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 24.17 - * version 2 for more details (a copy is included in the LICENSE file that 24.18 - * accompanied this code). 24.19 - * 24.20 - * You should have received a copy of the GNU General Public License version 24.21 - * 2 along with this work; if not, write to the Free Software Foundation, 24.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 24.23 - * 24.24 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 24.25 - * CA 95054 USA or visit www.sun.com if you need additional information or 24.26 - * have any questions. 24.27 - */ 24.28 - 24.29 -package com.sun.tools.javac.zip; 24.30 - 24.31 -import java.io.File; 24.32 - 24.33 -public final class ZipFileIndexEntry implements Comparable<ZipFileIndexEntry> { 24.34 - public static final ZipFileIndexEntry[] EMPTY_ARRAY = {}; 24.35 - 24.36 - // Directory related 24.37 - String dir; 24.38 - boolean isDir; 24.39 - 24.40 - // File related 24.41 - String name; 24.42 - 24.43 - int offset; 24.44 - int size; 24.45 - int compressedSize; 24.46 - long javatime; 24.47 - 24.48 - private int nativetime; 24.49 - 24.50 - public ZipFileIndexEntry(String path) { 24.51 - int separator = path.lastIndexOf(File.separatorChar); 24.52 - if (separator == -1) { 24.53 - dir = "".intern(); 24.54 - name = path; 24.55 - } else { 24.56 - dir = path.substring(0, separator).intern(); 24.57 - name = path.substring(separator + 1); 24.58 - } 24.59 - } 24.60 - 24.61 - public ZipFileIndexEntry(String directory, String name) { 24.62 - this.dir = directory.intern(); 24.63 - this.name = name; 24.64 - } 24.65 - 24.66 - public String getName() { 24.67 - if (dir == null || dir.length() == 0) { 24.68 - return name; 24.69 - } 24.70 - 24.71 - StringBuilder sb = new StringBuilder(); 24.72 - sb.append(dir); 24.73 - sb.append(File.separatorChar); 24.74 - sb.append(name); 24.75 - return sb.toString(); 24.76 - } 24.77 - 24.78 - public String getFileName() { 24.79 - return name; 24.80 - } 24.81 - 24.82 - public long getLastModified() { 24.83 - if (javatime == 0) { 24.84 - javatime = dosToJavaTime(nativetime); 24.85 - } 24.86 - return javatime; 24.87 - } 24.88 - 24.89 - // From java.util.zip 24.90 - private static long dosToJavaTime(int nativetime) { 24.91 - // Bootstrap build problems prevent me from using the code directly 24.92 - // Convert the raw/native time to a long for now 24.93 - return (long)nativetime; 24.94 - } 24.95 - 24.96 - void setNativeTime(int natTime) { 24.97 - nativetime = natTime; 24.98 - } 24.99 - 24.100 - public boolean isDirectory() { 24.101 - return isDir; 24.102 - } 24.103 - 24.104 - public int compareTo(ZipFileIndexEntry other) { 24.105 - String otherD = other.dir; 24.106 - if (dir != otherD) { 24.107 - int c = dir.compareTo(otherD); 24.108 - if (c != 0) 24.109 - return c; 24.110 - } 24.111 - return name.compareTo(other.name); 24.112 - } 24.113 - 24.114 - 24.115 - public String toString() { 24.116 - return isDir ? ("Dir:" + dir + " : " + name) : 24.117 - (dir + ":" + name); 24.118 - } 24.119 -}
25.1 --- a/src/share/classes/com/sun/tools/javadoc/JavadocClassReader.java Fri Jun 06 15:17:35 2008 -0700 25.2 +++ b/src/share/classes/com/sun/tools/javadoc/JavadocClassReader.java Mon Jun 16 13:28:00 2008 -0700 25.3 @@ -26,10 +26,10 @@ 25.4 package com.sun.tools.javadoc; 25.5 25.6 import com.sun.tools.javac.code.Symbol.PackageSymbol; 25.7 +import com.sun.tools.javac.file.JavacFileManager; 25.8 +import com.sun.tools.javac.file.Old199; 25.9 import com.sun.tools.javac.jvm.ClassReader; 25.10 import com.sun.tools.javac.util.Context; 25.11 -import com.sun.tools.javac.util.JavacFileManager; 25.12 -import com.sun.tools.javac.util.Old199; 25.13 25.14 import java.io.File; 25.15 import java.util.EnumSet;
26.1 --- a/src/share/classes/com/sun/tools/javadoc/JavadocTool.java Fri Jun 06 15:17:35 2008 -0700 26.2 +++ b/src/share/classes/com/sun/tools/javadoc/JavadocTool.java Mon Jun 16 13:28:00 2008 -0700 26.3 @@ -29,19 +29,14 @@ 26.4 26.5 import java.util.Collection; 26.6 26.7 -import com.sun.tools.javac.code.*; 26.8 import com.sun.tools.javac.code.Symbol.*; 26.9 import com.sun.tools.javac.comp.*; 26.10 -import com.sun.tools.javac.jvm.ClassReader; 26.11 -import com.sun.tools.javac.jvm.ClassWriter; 26.12 +import com.sun.tools.javac.file.Paths; 26.13 import com.sun.tools.javac.parser.DocCommentScanner; 26.14 -import com.sun.tools.javac.util.Paths; 26.15 import com.sun.tools.javac.tree.*; 26.16 import com.sun.tools.javac.tree.JCTree.*; 26.17 import com.sun.tools.javac.util.*; 26.18 26.19 -import com.sun.javadoc.LanguageVersion; 26.20 -import static com.sun.javadoc.LanguageVersion.*; 26.21 26.22 /** 26.23 * This class could be the main entry point for Javadoc when Javadoc is used as a 26.24 @@ -147,7 +142,7 @@ 26.25 } else if (isValidPackageName(name)) { 26.26 names = names.append(name); 26.27 } else if (name.endsWith(".java")) { 26.28 - docenv.error(null, "main.file_not_found", name);; 26.29 + docenv.error(null, "main.file_not_found", name); 26.30 } else { 26.31 docenv.error(null, "main.illegal_package_name", name); 26.32 }
27.1 --- a/src/share/classes/com/sun/tools/javap/JavapFileManager.java Fri Jun 06 15:17:35 2008 -0700 27.2 +++ b/src/share/classes/com/sun/tools/javap/JavapFileManager.java Mon Jun 16 13:28:00 2008 -0700 27.3 @@ -32,9 +32,9 @@ 27.4 import javax.tools.DiagnosticListener; 27.5 import javax.tools.JavaFileObject; 27.6 27.7 +import com.sun.tools.javac.file.JavacFileManager; 27.8 import com.sun.tools.javac.util.Context; 27.9 import com.sun.tools.javac.util.JCDiagnostic; 27.10 -import com.sun.tools.javac.util.JavacFileManager; 27.11 27.12 /** 27.13 * javap's implementation of JavaFileManager.
28.1 --- a/test/tools/javac/6304921/TestLog.java Fri Jun 06 15:17:35 2008 -0700 28.2 +++ b/test/tools/javac/6304921/TestLog.java Mon Jun 16 13:28:00 2008 -0700 28.3 @@ -32,12 +32,12 @@ 28.4 import java.net.URI; 28.5 import javax.tools.JavaFileObject; 28.6 import javax.tools.SimpleJavaFileObject; 28.7 +import com.sun.tools.javac.file.JavacFileManager; 28.8 import com.sun.tools.javac.parser.Parser; 28.9 import com.sun.tools.javac.parser.Scanner; 28.10 import com.sun.tools.javac.tree.JCTree; 28.11 import com.sun.tools.javac.tree.TreeScanner; 28.12 import com.sun.tools.javac.util.Context; 28.13 -import com.sun.tools.javac.util.JavacFileManager; 28.14 import com.sun.tools.javac.util.Log; 28.15 import com.sun.tools.javac.util.JCDiagnostic; 28.16 import com.sun.tools.javac.util.Options;
29.1 --- a/test/tools/javac/6589361/T6589361.java Fri Jun 06 15:17:35 2008 -0700 29.2 +++ b/test/tools/javac/6589361/T6589361.java Mon Jun 16 13:28:00 2008 -0700 29.3 @@ -4,8 +4,8 @@ 29.4 * @summary 6589361:Failing building ct.sym file as part of the control build 29.5 */ 29.6 29.7 +import com.sun.tools.javac.file.JavacFileManager; 29.8 import com.sun.tools.javac.util.Context; 29.9 -import com.sun.tools.javac.util.JavacFileManager; 29.10 import java.io.File; 29.11 import javax.tools.FileObject; 29.12 import javax.tools.JavaFileObject;
30.1 --- a/test/tools/javac/T6358024.java Fri Jun 06 15:17:35 2008 -0700 30.2 +++ b/test/tools/javac/T6358024.java Mon Jun 16 13:28:00 2008 -0700 30.3 @@ -35,6 +35,7 @@ 30.4 import javax.tools.*; 30.5 import com.sun.source.util.*; 30.6 import com.sun.tools.javac.api.*; 30.7 +import com.sun.tools.javac.file.*; 30.8 import com.sun.tools.javac.main.*; 30.9 import com.sun.tools.javac.util.*; 30.10
31.1 --- a/test/tools/javac/T6358166.java Fri Jun 06 15:17:35 2008 -0700 31.2 +++ b/test/tools/javac/T6358166.java Mon Jun 16 13:28:00 2008 -0700 31.3 @@ -32,6 +32,7 @@ 31.4 import javax.annotation.processing.*; 31.5 import javax.lang.model.element.*; 31.6 import javax.tools.*; 31.7 +import com.sun.tools.javac.file.*; 31.8 import com.sun.tools.javac.main.JavaCompiler; 31.9 import com.sun.tools.javac.main.*; 31.10 import com.sun.tools.javac.util.*;
32.1 --- a/test/tools/javac/T6358168.java Fri Jun 06 15:17:35 2008 -0700 32.2 +++ b/test/tools/javac/T6358168.java Mon Jun 16 13:28:00 2008 -0700 32.3 @@ -33,6 +33,7 @@ 32.4 import javax.annotation.processing.*; 32.5 import javax.lang.model.element.*; 32.6 import javax.tools.*; 32.7 +import com.sun.tools.javac.file.*; 32.8 import com.sun.tools.javac.main.JavaCompiler; 32.9 import com.sun.tools.javac.main.*; 32.10 import com.sun.tools.javac.util.*;
33.1 --- a/test/tools/javac/T6705935.java Fri Jun 06 15:17:35 2008 -0700 33.2 +++ b/test/tools/javac/T6705935.java Mon Jun 16 13:28:00 2008 -0700 33.3 @@ -30,7 +30,7 @@ 33.4 import java.io.*; 33.5 import java.util.*; 33.6 import javax.tools.*; 33.7 -import com.sun.tools.javac.util.*; 33.8 +import com.sun.tools.javac.file.*; 33.9 33.10 public class T6705935 { 33.11 public static void main(String... args) throws Exception {
34.1 --- a/test/tools/javac/api/T6358786.java Fri Jun 06 15:17:35 2008 -0700 34.2 +++ b/test/tools/javac/api/T6358786.java Mon Jun 16 13:28:00 2008 -0700 34.3 @@ -30,7 +30,7 @@ 34.4 */ 34.5 34.6 import com.sun.tools.javac.api.JavacTaskImpl; 34.7 -import com.sun.tools.javac.util.JavacFileManager; 34.8 +import com.sun.tools.javac.file.JavacFileManager; 34.9 import java.util.Arrays; 34.10 34.11 import javax.lang.model.util.Elements;
35.1 --- a/test/tools/javac/api/TestResolveIdent.java Fri Jun 06 15:17:35 2008 -0700 35.2 +++ b/test/tools/javac/api/TestResolveIdent.java Mon Jun 16 13:28:00 2008 -0700 35.3 @@ -30,8 +30,8 @@ 35.4 */ 35.5 35.6 import com.sun.tools.javac.api.JavacTaskImpl; 35.7 +import com.sun.tools.javac.file.JavacFileManager; 35.8 import com.sun.tools.javac.main.JavaCompiler; 35.9 -import com.sun.tools.javac.util.JavacFileManager; 35.10 import java.io.File; 35.11 import java.io.IOException; 35.12 import javax.lang.model.element.TypeElement;
36.1 --- a/test/tools/javac/util/filemanager/TestName.java Fri Jun 06 15:17:35 2008 -0700 36.2 +++ b/test/tools/javac/util/filemanager/TestName.java Mon Jun 16 13:28:00 2008 -0700 36.3 @@ -29,7 +29,7 @@ 36.4 * @author Peter von der Ah\u00e9 36.5 */ 36.6 36.7 -import com.sun.tools.javac.util.JavacFileManager; 36.8 +import com.sun.tools.javac.file.JavacFileManager; 36.9 36.10 public class TestName { 36.11 public static void main(String... args) {