1.1 --- a/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Thu Dec 10 20:35:31 2009 -0800 1.2 +++ b/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Fri Dec 11 14:26:27 2009 -0800 1.3 @@ -26,29 +26,16 @@ 1.4 package com.sun.tools.javac.file; 1.5 1.6 import java.io.ByteArrayOutputStream; 1.7 -import java.io.Closeable; 1.8 import java.io.File; 1.9 -import java.io.FileInputStream; 1.10 import java.io.FileNotFoundException; 1.11 import java.io.IOException; 1.12 -import java.io.InputStream; 1.13 import java.io.OutputStreamWriter; 1.14 -import java.lang.ref.SoftReference; 1.15 -import java.lang.reflect.Constructor; 1.16 import java.net.MalformedURLException; 1.17 import java.net.URI; 1.18 import java.net.URISyntaxException; 1.19 import java.net.URL; 1.20 -import java.net.URLClassLoader; 1.21 -import java.nio.ByteBuffer; 1.22 import java.nio.CharBuffer; 1.23 -import java.nio.channels.FileChannel; 1.24 import java.nio.charset.Charset; 1.25 -import java.nio.charset.CharsetDecoder; 1.26 -import java.nio.charset.CoderResult; 1.27 -import java.nio.charset.CodingErrorAction; 1.28 -import java.nio.charset.IllegalCharsetNameException; 1.29 -import java.nio.charset.UnsupportedCharsetException; 1.30 import java.util.ArrayList; 1.31 import java.util.Arrays; 1.32 import java.util.Collection; 1.33 @@ -66,18 +53,13 @@ 1.34 import javax.tools.JavaFileObject; 1.35 import javax.tools.StandardJavaFileManager; 1.36 1.37 -import com.sun.tools.javac.code.Source; 1.38 import com.sun.tools.javac.file.RelativePath.RelativeFile; 1.39 import com.sun.tools.javac.file.RelativePath.RelativeDirectory; 1.40 -import com.sun.tools.javac.main.JavacOption; 1.41 import com.sun.tools.javac.main.OptionName; 1.42 -import com.sun.tools.javac.main.RecognizedOptions; 1.43 +import com.sun.tools.javac.util.BaseFileManager; 1.44 import com.sun.tools.javac.util.Context; 1.45 -import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition; 1.46 import com.sun.tools.javac.util.List; 1.47 import com.sun.tools.javac.util.ListBuffer; 1.48 -import com.sun.tools.javac.util.Log; 1.49 -import com.sun.tools.javac.util.Options; 1.50 1.51 import static javax.tools.StandardLocation.*; 1.52 import static com.sun.tools.javac.main.OptionName.*; 1.53 @@ -91,7 +73,7 @@ 1.54 * This code and its internal interfaces are subject to change or 1.55 * deletion without notice.</b> 1.56 */ 1.57 -public class JavacFileManager implements StandardJavaFileManager { 1.58 +public class JavacFileManager extends BaseFileManager implements StandardJavaFileManager { 1.59 1.60 boolean useZipFileIndex; 1.61 1.62 @@ -102,17 +84,10 @@ 1.63 return buffer.toString().toCharArray(); 1.64 } 1.65 1.66 - /** 1.67 - * The log to be used for error reporting. 1.68 - */ 1.69 - protected Log log; 1.70 - 1.71 /** Encapsulates knowledge of paths 1.72 */ 1.73 private Paths paths; 1.74 1.75 - private Options options; 1.76 - 1.77 private FSInfo fsInfo; 1.78 1.79 private final File uninited = new File("U N I N I T E D"); 1.80 @@ -134,12 +109,6 @@ 1.81 1.82 protected boolean mmappedIO; 1.83 protected boolean ignoreSymbolFile; 1.84 - protected String classLoaderClass; 1.85 - 1.86 - /** 1.87 - * User provided charset (through javax.tools). 1.88 - */ 1.89 - protected Charset charset; 1.90 1.91 /** 1.92 * Register a Context.Factory to create a JavacFileManager. 1.93 @@ -157,18 +126,18 @@ 1.94 * it as the JavaFileManager for that context. 1.95 */ 1.96 public JavacFileManager(Context context, boolean register, Charset charset) { 1.97 + super(charset); 1.98 if (register) 1.99 context.put(JavaFileManager.class, this); 1.100 - byteBufferCache = new ByteBufferCache(); 1.101 - this.charset = charset; 1.102 setContext(context); 1.103 } 1.104 1.105 /** 1.106 * Set the context for JavacFileManager. 1.107 */ 1.108 + @Override 1.109 public void setContext(Context context) { 1.110 - log = Log.instance(context); 1.111 + super.setContext(context); 1.112 if (paths == null) { 1.113 paths = Paths.instance(context); 1.114 } else { 1.115 @@ -177,14 +146,12 @@ 1.116 paths.setContext(context); 1.117 } 1.118 1.119 - options = Options.instance(context); 1.120 fsInfo = FSInfo.instance(context); 1.121 1.122 useZipFileIndex = System.getProperty("useJavaUtilZip") == null;// TODO: options.get("useJavaUtilZip") == null; 1.123 1.124 mmappedIO = options.get("mmappedIO") != null; 1.125 ignoreSymbolFile = options.get("ignore.symbol.file") != null; 1.126 - classLoaderClass = options.get("procloader"); 1.127 } 1.128 1.129 public JavaFileObject getFileForInput(String name) { 1.130 @@ -214,17 +181,6 @@ 1.131 return getJavaFileObjectsFromStrings(Arrays.asList(nullCheck(names))); 1.132 } 1.133 1.134 - protected JavaFileObject.Kind getKind(String extension) { 1.135 - if (extension.equals(JavaFileObject.Kind.CLASS.extension)) 1.136 - return JavaFileObject.Kind.CLASS; 1.137 - else if (extension.equals(JavaFileObject.Kind.SOURCE.extension)) 1.138 - return JavaFileObject.Kind.SOURCE; 1.139 - else if (extension.equals(JavaFileObject.Kind.HTML.extension)) 1.140 - return JavaFileObject.Kind.HTML; 1.141 - else 1.142 - return JavaFileObject.Kind.OTHER; 1.143 - } 1.144 - 1.145 private static boolean isValidName(String name) { 1.146 // Arguably, isValidName should reject keywords (such as in SourceVersion.isName() ), 1.147 // but the set of keywords depends on the source level, and we don't want 1.148 @@ -359,9 +315,7 @@ 1.149 } 1.150 1.151 private boolean isValidFile(String s, Set<JavaFileObject.Kind> fileKinds) { 1.152 - int lastDot = s.lastIndexOf("."); 1.153 - String extn = (lastDot == -1 ? s : s.substring(lastDot)); 1.154 - JavaFileObject.Kind kind = getKind(extn); 1.155 + JavaFileObject.Kind kind = getKind(s); 1.156 return fileKinds.contains(kind); 1.157 } 1.158 1.159 @@ -564,18 +518,6 @@ 1.160 } 1.161 } 1.162 1.163 - CharBuffer getCachedContent(JavaFileObject file) { 1.164 - SoftReference<CharBuffer> r = contentCache.get(file); 1.165 - return (r == null ? null : r.get()); 1.166 - } 1.167 - 1.168 - void cache(JavaFileObject file, CharBuffer cb) { 1.169 - contentCache.put(file, new SoftReference<CharBuffer>(cb)); 1.170 - } 1.171 - 1.172 - private final Map<JavaFileObject, SoftReference<CharBuffer>> contentCache 1.173 - = new HashMap<JavaFileObject, SoftReference<CharBuffer>>(); 1.174 - 1.175 private String defaultEncodingName; 1.176 private String getDefaultEncodingName() { 1.177 if (defaultEncodingName == null) { 1.178 @@ -585,161 +527,6 @@ 1.179 return defaultEncodingName; 1.180 } 1.181 1.182 - protected String getEncodingName() { 1.183 - String encName = options.get(OptionName.ENCODING); 1.184 - if (encName == null) 1.185 - return getDefaultEncodingName(); 1.186 - else 1.187 - return encName; 1.188 - } 1.189 - 1.190 - protected Source getSource() { 1.191 - String sourceName = options.get(OptionName.SOURCE); 1.192 - Source source = null; 1.193 - if (sourceName != null) 1.194 - source = Source.lookup(sourceName); 1.195 - return (source != null ? source : Source.DEFAULT); 1.196 - } 1.197 - 1.198 - /** 1.199 - * Make a byte buffer from an input stream. 1.200 - */ 1.201 - ByteBuffer makeByteBuffer(InputStream in) 1.202 - throws IOException { 1.203 - int limit = in.available(); 1.204 - if (mmappedIO && in instanceof FileInputStream) { 1.205 - // Experimental memory mapped I/O 1.206 - FileInputStream fin = (FileInputStream)in; 1.207 - return fin.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, limit); 1.208 - } 1.209 - if (limit < 1024) limit = 1024; 1.210 - ByteBuffer result = byteBufferCache.get(limit); 1.211 - int position = 0; 1.212 - while (in.available() != 0) { 1.213 - if (position >= limit) 1.214 - // expand buffer 1.215 - result = ByteBuffer. 1.216 - allocate(limit <<= 1). 1.217 - put((ByteBuffer)result.flip()); 1.218 - int count = in.read(result.array(), 1.219 - position, 1.220 - limit - position); 1.221 - if (count < 0) break; 1.222 - result.position(position += count); 1.223 - } 1.224 - return (ByteBuffer)result.flip(); 1.225 - } 1.226 - 1.227 - void recycleByteBuffer(ByteBuffer bb) { 1.228 - byteBufferCache.put(bb); 1.229 - } 1.230 - 1.231 - /** 1.232 - * A single-element cache of direct byte buffers. 1.233 - */ 1.234 - private static class ByteBufferCache { 1.235 - private ByteBuffer cached; 1.236 - ByteBuffer get(int capacity) { 1.237 - if (capacity < 20480) capacity = 20480; 1.238 - ByteBuffer result = 1.239 - (cached != null && cached.capacity() >= capacity) 1.240 - ? (ByteBuffer)cached.clear() 1.241 - : ByteBuffer.allocate(capacity + capacity>>1); 1.242 - cached = null; 1.243 - return result; 1.244 - } 1.245 - void put(ByteBuffer x) { 1.246 - cached = x; 1.247 - } 1.248 - } 1.249 - 1.250 - private final ByteBufferCache byteBufferCache; 1.251 - 1.252 - CharsetDecoder getDecoder(String encodingName, boolean ignoreEncodingErrors) { 1.253 - Charset cs = (this.charset == null) 1.254 - ? Charset.forName(encodingName) 1.255 - : this.charset; 1.256 - CharsetDecoder decoder = cs.newDecoder(); 1.257 - 1.258 - CodingErrorAction action; 1.259 - if (ignoreEncodingErrors) 1.260 - action = CodingErrorAction.REPLACE; 1.261 - else 1.262 - action = CodingErrorAction.REPORT; 1.263 - 1.264 - return decoder 1.265 - .onMalformedInput(action) 1.266 - .onUnmappableCharacter(action); 1.267 - } 1.268 - 1.269 - /** 1.270 - * Decode a ByteBuffer into a CharBuffer. 1.271 - */ 1.272 - CharBuffer decode(ByteBuffer inbuf, boolean ignoreEncodingErrors) { 1.273 - String encodingName = getEncodingName(); 1.274 - CharsetDecoder decoder; 1.275 - try { 1.276 - decoder = getDecoder(encodingName, ignoreEncodingErrors); 1.277 - } catch (IllegalCharsetNameException e) { 1.278 - log.error("unsupported.encoding", encodingName); 1.279 - return (CharBuffer)CharBuffer.allocate(1).flip(); 1.280 - } catch (UnsupportedCharsetException e) { 1.281 - log.error("unsupported.encoding", encodingName); 1.282 - return (CharBuffer)CharBuffer.allocate(1).flip(); 1.283 - } 1.284 - 1.285 - // slightly overestimate the buffer size to avoid reallocation. 1.286 - float factor = 1.287 - decoder.averageCharsPerByte() * 0.8f + 1.288 - decoder.maxCharsPerByte() * 0.2f; 1.289 - CharBuffer dest = CharBuffer. 1.290 - allocate(10 + (int)(inbuf.remaining()*factor)); 1.291 - 1.292 - while (true) { 1.293 - CoderResult result = decoder.decode(inbuf, dest, true); 1.294 - dest.flip(); 1.295 - 1.296 - if (result.isUnderflow()) { // done reading 1.297 - // make sure there is at least one extra character 1.298 - if (dest.limit() == dest.capacity()) { 1.299 - dest = CharBuffer.allocate(dest.capacity()+1).put(dest); 1.300 - dest.flip(); 1.301 - } 1.302 - return dest; 1.303 - } else if (result.isOverflow()) { // buffer too small; expand 1.304 - int newCapacity = 1.305 - 10 + dest.capacity() + 1.306 - (int)(inbuf.remaining()*decoder.maxCharsPerByte()); 1.307 - dest = CharBuffer.allocate(newCapacity).put(dest); 1.308 - } else if (result.isMalformed() || result.isUnmappable()) { 1.309 - // bad character in input 1.310 - 1.311 - // report coding error (warn only pre 1.5) 1.312 - if (!getSource().allowEncodingErrors()) { 1.313 - log.error(new SimpleDiagnosticPosition(dest.limit()), 1.314 - "illegal.char.for.encoding", 1.315 - charset == null ? encodingName : charset.name()); 1.316 - } else { 1.317 - log.warning(new SimpleDiagnosticPosition(dest.limit()), 1.318 - "illegal.char.for.encoding", 1.319 - charset == null ? encodingName : charset.name()); 1.320 - } 1.321 - 1.322 - // skip past the coding error 1.323 - inbuf.position(inbuf.position() + result.length()); 1.324 - 1.325 - // undo the flip() to prepare the output buffer 1.326 - // for more translation 1.327 - dest.position(dest.limit()); 1.328 - dest.limit(dest.capacity()); 1.329 - dest.put((char)0xfffd); // backward compatible 1.330 - } else { 1.331 - throw new AssertionError(result); 1.332 - } 1.333 - } 1.334 - // unreached 1.335 - } 1.336 - 1.337 public ClassLoader getClassLoader(Location location) { 1.338 nullCheck(location); 1.339 Iterable<? extends File> path = getLocation(location); 1.340 @@ -754,39 +541,7 @@ 1.341 } 1.342 } 1.343 1.344 - URL[] urls = lb.toArray(new URL[lb.size()]); 1.345 - ClassLoader thisClassLoader = getClass().getClassLoader(); 1.346 - 1.347 - // Bug: 6558476 1.348 - // Ideally, ClassLoader should be Closeable, but before JDK7 it is not. 1.349 - // On older versions, try the following, to get a closeable classloader. 1.350 - 1.351 - // 1: Allow client to specify the class to use via hidden option 1.352 - if (classLoaderClass != null) { 1.353 - try { 1.354 - Class<? extends ClassLoader> loader = 1.355 - Class.forName(classLoaderClass).asSubclass(ClassLoader.class); 1.356 - Class<?>[] constrArgTypes = { URL[].class, ClassLoader.class }; 1.357 - Constructor<? extends ClassLoader> constr = loader.getConstructor(constrArgTypes); 1.358 - return constr.newInstance(new Object[] { urls, thisClassLoader }); 1.359 - } catch (Throwable t) { 1.360 - // ignore errors loading user-provided class loader, fall through 1.361 - } 1.362 - } 1.363 - 1.364 - // 2: If URLClassLoader implements Closeable, use that. 1.365 - if (Closeable.class.isAssignableFrom(URLClassLoader.class)) 1.366 - return new URLClassLoader(urls, thisClassLoader); 1.367 - 1.368 - // 3: Try using private reflection-based CloseableURLClassLoader 1.369 - try { 1.370 - return new CloseableURLClassLoader(urls, thisClassLoader); 1.371 - } catch (Throwable t) { 1.372 - // ignore errors loading workaround class loader, fall through 1.373 - } 1.374 - 1.375 - // 4: If all else fails, use plain old standard URLClassLoader 1.376 - return new URLClassLoader(urls, thisClassLoader); 1.377 + return getClassLoader(lb.toArray(new URL[lb.size()])); 1.378 } 1.379 1.380 public Iterable<JavaFileObject> list(Location location, 1.381 @@ -836,38 +591,6 @@ 1.382 return a.equals(b); 1.383 } 1.384 1.385 - public boolean handleOption(String current, Iterator<String> remaining) { 1.386 - for (JavacOption o: javacFileManagerOptions) { 1.387 - if (o.matches(current)) { 1.388 - if (o.hasArg()) { 1.389 - if (remaining.hasNext()) { 1.390 - if (!o.process(options, current, remaining.next())) 1.391 - return true; 1.392 - } 1.393 - } else { 1.394 - if (!o.process(options, current)) 1.395 - return true; 1.396 - } 1.397 - // operand missing, or process returned false 1.398 - throw new IllegalArgumentException(current); 1.399 - } 1.400 - } 1.401 - 1.402 - return false; 1.403 - } 1.404 - // where 1.405 - private static JavacOption[] javacFileManagerOptions = 1.406 - RecognizedOptions.getJavacFileManagerOptions( 1.407 - new RecognizedOptions.GrumpyHelper()); 1.408 - 1.409 - public int isSupportedOption(String option) { 1.410 - for (JavacOption o : javacFileManagerOptions) { 1.411 - if (o.matches(option)) 1.412 - return o.hasArg() ? 1 : 0; 1.413 - } 1.414 - return -1; 1.415 - } 1.416 - 1.417 public boolean hasLocation(Location location) { 1.418 return getLocation(location) != null; 1.419 } 1.420 @@ -1115,15 +838,4 @@ 1.421 } 1.422 throw new IllegalArgumentException("Invalid relative path: " + file); 1.423 } 1.424 - 1.425 - private static <T> T nullCheck(T o) { 1.426 - o.getClass(); // null check 1.427 - return o; 1.428 - } 1.429 - 1.430 - private static <T> Iterable<T> nullCheck(Iterable<T> it) { 1.431 - for (T t : it) 1.432 - t.getClass(); // null check 1.433 - return it; 1.434 - } 1.435 }