src/share/classes/com/sun/tools/javac/file/JavacFileManager.java

changeset 57
aa67a5da66e3
parent 56
f9a4b9e1a521
child 62
07c916ecfc71
equal deleted inserted replaced
56:f9a4b9e1a521 57:aa67a5da66e3
1 /* 1 /*
2 * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. 2 * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this 7 * published by the Free Software Foundation. Sun designates this
23 * have any questions. 23 * have any questions.
24 */ 24 */
25 25
26 package com.sun.tools.javac.file; 26 package com.sun.tools.javac.file;
27 27
28 import java.io.ByteArrayInputStream;
29 import java.io.ByteArrayOutputStream; 28 import java.io.ByteArrayOutputStream;
30 import java.io.File; 29 import java.io.File;
31 import java.io.FileInputStream; 30 import java.io.FileInputStream;
32 import java.io.FileNotFoundException; 31 import java.io.FileNotFoundException;
33 import java.io.FileOutputStream;
34 import java.io.IOException; 32 import java.io.IOException;
35 import java.io.InputStream; 33 import java.io.InputStream;
36 import java.io.OutputStream;
37 import java.io.OutputStreamWriter; 34 import java.io.OutputStreamWriter;
38 import java.io.Writer;
39 import java.lang.ref.SoftReference; 35 import java.lang.ref.SoftReference;
40 import java.net.MalformedURLException; 36 import java.net.MalformedURLException;
41 import java.net.URI; 37 import java.net.URI;
42 import java.net.URISyntaxException;
43 import java.net.URL; 38 import java.net.URL;
44 import java.net.URLClassLoader; 39 import java.net.URLClassLoader;
45 import java.nio.ByteBuffer; 40 import java.nio.ByteBuffer;
46 import java.nio.CharBuffer; 41 import java.nio.CharBuffer;
47 import java.nio.channels.FileChannel; 42 import java.nio.channels.FileChannel;
54 import java.util.ArrayList; 49 import java.util.ArrayList;
55 import java.util.Arrays; 50 import java.util.Arrays;
56 import java.util.Collection; 51 import java.util.Collection;
57 import java.util.Collections; 52 import java.util.Collections;
58 import java.util.EnumSet; 53 import java.util.EnumSet;
59 import java.util.Enumeration;
60 import java.util.HashMap; 54 import java.util.HashMap;
61 import java.util.Iterator; 55 import java.util.Iterator;
62 import java.util.Map; 56 import java.util.Map;
63 import java.util.Set; 57 import java.util.Set;
64 import java.util.concurrent.ConcurrentHashMap; 58 import java.util.concurrent.ConcurrentHashMap;
65 import java.util.zip.ZipEntry;
66 import java.util.zip.ZipFile; 59 import java.util.zip.ZipFile;
67 60
68 import javax.lang.model.SourceVersion; 61 import javax.lang.model.SourceVersion;
69 import javax.tools.FileObject; 62 import javax.tools.FileObject;
70 import javax.tools.JavaFileManager; 63 import javax.tools.JavaFileManager;
94 private static final String[] symbolFileLocation = { "lib", "ct.sym" }; 87 private static final String[] symbolFileLocation = { "lib", "ct.sym" };
95 private static final String symbolFilePrefix = "META-INF/sym/rt.jar/"; 88 private static final String symbolFilePrefix = "META-INF/sym/rt.jar/";
96 89
97 boolean useZipFileIndex; 90 boolean useZipFileIndex;
98 91
99 private static int symbolFilePrefixLength = 0;
100 static {
101 try {
102 symbolFilePrefixLength = symbolFilePrefix.getBytes("UTF-8").length;
103 } catch (java.io.UnsupportedEncodingException uee) {
104 // Can't happen...UTF-8 is always supported.
105 }
106 }
107
108 private static boolean CHECK_ZIP_TIMESTAMP = false; 92 private static boolean CHECK_ZIP_TIMESTAMP = false;
109 private static Map<File, Boolean> isDirectory = new ConcurrentHashMap<File, Boolean>(); 93 private static Map<File, Boolean> isDirectory = new ConcurrentHashMap<File, Boolean>();
110 94
111 95
112 public static char[] toArray(CharBuffer buffer) { 96 public static char[] toArray(CharBuffer buffer) {
200 public JavaFileObject getFileForInput(String name) { 184 public JavaFileObject getFileForInput(String name) {
201 return getRegularFile(new File(name)); 185 return getRegularFile(new File(name));
202 } 186 }
203 187
204 public JavaFileObject getRegularFile(File file) { 188 public JavaFileObject getRegularFile(File file) {
205 return new RegularFileObject(file); 189 return new RegularFileObject(this, file);
206 } 190 }
207 191
208 public JavaFileObject getFileForOutput(String classname, 192 public JavaFileObject getFileForOutput(String classname,
209 JavaFileObject.Kind kind, 193 JavaFileObject.Kind kind,
210 JavaFileObject sibling) 194 JavaFileObject sibling)
403 l); 387 l);
404 } 388 }
405 } else { 389 } else {
406 if (isValidFile(fname, fileKinds)) { 390 if (isValidFile(fname, fileKinds)) {
407 JavaFileObject fe = 391 JavaFileObject fe =
408 new RegularFileObject(fname, new File(d, fname)); 392 new RegularFileObject(this, fname, new File(d, fname));
409 l.append(fe); 393 l.append(fe);
410 } 394 }
411 } 395 }
412 } 396 }
413 } 397 }
467 List<String> getFiles(String subdirectory); 451 List<String> getFiles(String subdirectory);
468 452
469 Set<String> getSubdirectories(); 453 Set<String> getSubdirectories();
470 } 454 }
471 455
472 public class ZipArchive implements Archive {
473 protected final Map<String,List<String>> map;
474 protected final ZipFile zdir;
475 public ZipArchive(ZipFile zdir) throws IOException {
476 this.zdir = zdir;
477 this.map = new HashMap<String,List<String>>();
478 for (Enumeration<? extends ZipEntry> e = zdir.entries(); e.hasMoreElements(); ) {
479 ZipEntry entry;
480 try {
481 entry = e.nextElement();
482 } catch (InternalError ex) {
483 IOException io = new IOException();
484 io.initCause(ex); // convenience constructors added in Mustang :-(
485 throw io;
486 }
487 addZipEntry(entry);
488 }
489 }
490
491 void addZipEntry(ZipEntry entry) {
492 String name = entry.getName();
493 int i = name.lastIndexOf('/');
494 String dirname = name.substring(0, i+1);
495 String basename = name.substring(i+1);
496 if (basename.length() == 0)
497 return;
498 List<String> list = map.get(dirname);
499 if (list == null)
500 list = List.nil();
501 list = list.prepend(basename);
502 map.put(dirname, list);
503 }
504
505 public boolean contains(String name) {
506 int i = name.lastIndexOf('/');
507 String dirname = name.substring(0, i+1);
508 String basename = name.substring(i+1);
509 if (basename.length() == 0)
510 return false;
511 List<String> list = map.get(dirname);
512 return (list != null && list.contains(basename));
513 }
514
515 public List<String> getFiles(String subdirectory) {
516 return map.get(subdirectory);
517 }
518
519 public JavaFileObject getFileObject(String subdirectory, String file) {
520 ZipEntry ze = zdir.getEntry(subdirectory + file);
521 return new ZipFileObject(file, zdir, ze);
522 }
523
524 public Set<String> getSubdirectories() {
525 return map.keySet();
526 }
527
528 public void close() throws IOException {
529 zdir.close();
530 }
531 }
532
533 public class SymbolArchive extends ZipArchive {
534 final File origFile;
535 public SymbolArchive(File orig, ZipFile zdir) throws IOException {
536 super(zdir);
537 this.origFile = orig;
538 }
539
540 @Override
541 void addZipEntry(ZipEntry entry) {
542 // called from super constructor, may not refer to origFile.
543 String name = entry.getName();
544 if (!name.startsWith(symbolFilePrefix))
545 return;
546 name = name.substring(symbolFilePrefix.length());
547 int i = name.lastIndexOf('/');
548 String dirname = name.substring(0, i+1);
549 String basename = name.substring(i+1);
550 if (basename.length() == 0)
551 return;
552 List<String> list = map.get(dirname);
553 if (list == null)
554 list = List.nil();
555 list = list.prepend(basename);
556 map.put(dirname, list);
557 }
558
559 @Override
560 public JavaFileObject getFileObject(String subdirectory, String file) {
561 return super.getFileObject(symbolFilePrefix + subdirectory, file);
562 }
563 }
564
565 public class MissingArchive implements Archive { 456 public class MissingArchive implements Archive {
566 final File zipFileName; 457 final File zipFileName;
567 public MissingArchive(File name) { 458 public MissingArchive(File name) {
568 zipFileName = name; 459 zipFileName = name;
569 } 460 }
570 public boolean contains(String name) { 461 public boolean contains(String name) {
571 return false; 462 return false;
572 } 463 }
573 464
574 public void close() { 465 public void close() {
575 } 466 }
576 467
645 } 536 }
646 } 537 }
647 538
648 if (origZipFileName == zipFileName) { 539 if (origZipFileName == zipFileName) {
649 if (!useZipFileIndex) { 540 if (!useZipFileIndex) {
650 archive = new ZipArchive(zdir); 541 archive = new ZipArchive(this, zdir);
651 } else { 542 } else {
652 archive = new ZipFileIndexArchive(this, ZipFileIndex.getZipFileIndex(zipFileName, 0, 543 archive = new ZipFileIndexArchive(this, ZipFileIndex.getZipFileIndex(zipFileName, null,
653 usePreindexedCache, preindexCacheLocation, options.get("writezipindexfiles") != null)); 544 usePreindexedCache, preindexCacheLocation, options.get("writezipindexfiles") != null));
654 } 545 }
655 } 546 }
656 else { 547 else {
657 if (!useZipFileIndex) { 548 if (!useZipFileIndex) {
658 archive = new SymbolArchive(origZipFileName, zdir); 549 archive = new SymbolArchive(this, origZipFileName, zdir, symbolFilePrefix);
659 } 550 }
660 else { 551 else {
661 archive = new ZipFileIndexArchive(this, ZipFileIndex.getZipFileIndex(zipFileName, symbolFilePrefixLength, 552 archive = new ZipFileIndexArchive(this,
662 usePreindexedCache, preindexCacheLocation, options.get("writezipindexfiles") != null)); 553 ZipFileIndex.getZipFileIndex(zipFileName,
554 symbolFilePrefix,
555 usePreindexedCache,
556 preindexCacheLocation,
557 options.get("writezipindexfiles") != null));
663 } 558 }
664 } 559 }
665 } catch (FileNotFoundException ex) { 560 } catch (FileNotFoundException ex) {
666 archive = new MissingArchive(zipFileName); 561 archive = new MissingArchive(zipFileName);
667 } catch (IOException ex) { 562 } catch (IOException ex) {
693 } catch (IOException e) { 588 } catch (IOException e) {
694 } 589 }
695 } 590 }
696 } 591 }
697 592
698 private Map<JavaFileObject, SoftReference<CharBuffer>> contentCache = new HashMap<JavaFileObject, SoftReference<CharBuffer>>(); 593 CharBuffer getCachedContent(JavaFileObject file) {
594 SoftReference<CharBuffer> r = contentCache.get(file);
595 return (r == null ? null : r.get());
596 }
597
598 void cache(JavaFileObject file, CharBuffer cb) {
599 contentCache.put(file, new SoftReference<CharBuffer>(cb));
600 }
601
602 private final Map<JavaFileObject, SoftReference<CharBuffer>> contentCache
603 = new HashMap<JavaFileObject, SoftReference<CharBuffer>>();
699 604
700 private String defaultEncodingName; 605 private String defaultEncodingName;
701 private String getDefaultEncodingName() { 606 private String getDefaultEncodingName() {
702 if (defaultEncodingName == null) { 607 if (defaultEncodingName == null) {
703 defaultEncodingName = 608 defaultEncodingName =
723 } 628 }
724 629
725 /** 630 /**
726 * Make a byte buffer from an input stream. 631 * Make a byte buffer from an input stream.
727 */ 632 */
728 private ByteBuffer makeByteBuffer(InputStream in) 633 ByteBuffer makeByteBuffer(InputStream in)
729 throws IOException { 634 throws IOException {
730 int limit = in.available(); 635 int limit = in.available();
731 if (mmappedIO && in instanceof FileInputStream) { 636 if (mmappedIO && in instanceof FileInputStream) {
732 // Experimental memory mapped I/O 637 // Experimental memory mapped I/O
733 FileInputStream fin = (FileInputStream)in; 638 FileInputStream fin = (FileInputStream)in;
749 result.position(position += count); 654 result.position(position += count);
750 } 655 }
751 return (ByteBuffer)result.flip(); 656 return (ByteBuffer)result.flip();
752 } 657 }
753 658
659 void recycleByteBuffer(ByteBuffer bb) {
660 byteBufferCache.put(bb);
661 }
662
754 /** 663 /**
755 * A single-element cache of direct byte buffers. 664 * A single-element cache of direct byte buffers.
756 */ 665 */
757 private static class ByteBufferCache { 666 private static class ByteBufferCache {
758 private ByteBuffer cached; 667 private ByteBuffer cached;
767 } 676 }
768 void put(ByteBuffer x) { 677 void put(ByteBuffer x) {
769 cached = x; 678 cached = x;
770 } 679 }
771 } 680 }
681
772 private final ByteBufferCache byteBufferCache; 682 private final ByteBufferCache byteBufferCache;
773 683
774 private CharsetDecoder getDecoder(String encodingName, boolean ignoreEncodingErrors) { 684 CharsetDecoder getDecoder(String encodingName, boolean ignoreEncodingErrors) {
775 Charset charset = (this.charset == null) 685 Charset charset = (this.charset == null)
776 ? Charset.forName(encodingName) 686 ? Charset.forName(encodingName)
777 : this.charset; 687 : this.charset;
778 CharsetDecoder decoder = charset.newDecoder(); 688 CharsetDecoder decoder = charset.newDecoder();
779 689
789 } 699 }
790 700
791 /** 701 /**
792 * Decode a ByteBuffer into a CharBuffer. 702 * Decode a ByteBuffer into a CharBuffer.
793 */ 703 */
794 private CharBuffer decode(ByteBuffer inbuf, boolean ignoreEncodingErrors) { 704 CharBuffer decode(ByteBuffer inbuf, boolean ignoreEncodingErrors) {
795 String encodingName = getEncodingName(); 705 String encodingName = getEncodingName();
796 CharsetDecoder decoder; 706 CharsetDecoder decoder;
797 try { 707 try {
798 decoder = getDecoder(encodingName, ignoreEncodingErrors); 708 decoder = getDecoder(encodingName, ignoreEncodingErrors);
799 } catch (IllegalCharsetNameException e) { 709 } catch (IllegalCharsetNameException e) {
899 file.getClass(); // null check 809 file.getClass(); // null check
900 location.getClass(); // null check 810 location.getClass(); // null check
901 // Need to match the path semantics of list(location, ...) 811 // Need to match the path semantics of list(location, ...)
902 Iterable<? extends File> path = getLocation(location); 812 Iterable<? extends File> path = getLocation(location);
903 if (path == null) { 813 if (path == null) {
904 //System.err.println("Path for " + location + " is null");
905 return null; 814 return null;
906 } 815 }
907 //System.err.println("Path for " + location + " is " + path); 816
908 817 if (file instanceof BaseFileObject) {
909 if (file instanceof RegularFileObject) { 818 return ((BaseFileObject) file).inferBinaryName(path);
910 RegularFileObject r = (RegularFileObject) file;
911 String rPath = r.getPath();
912 //System.err.println("RegularFileObject " + file + " " +r.getPath());
913 for (File dir: path) {
914 //System.err.println("dir: " + dir);
915 String dPath = dir.getPath();
916 if (!dPath.endsWith(File.separator))
917 dPath += File.separator;
918 if (rPath.regionMatches(true, 0, dPath, 0, dPath.length())
919 && new File(rPath.substring(0, dPath.length())).equals(new File(dPath))) {
920 String relativeName = rPath.substring(dPath.length());
921 return removeExtension(relativeName).replace(File.separatorChar, '.');
922 }
923 }
924 } else if (file instanceof ZipFileObject) {
925 ZipFileObject z = (ZipFileObject) file;
926 String entryName = z.getZipEntryName();
927 if (entryName.startsWith(symbolFilePrefix))
928 entryName = entryName.substring(symbolFilePrefix.length());
929 return removeExtension(entryName).replace('/', '.');
930 } else if (file instanceof ZipFileIndexFileObject) {
931 ZipFileIndexFileObject z = (ZipFileIndexFileObject) file;
932 String entryName = z.getZipEntryName();
933 if (entryName.startsWith(symbolFilePrefix))
934 entryName = entryName.substring(symbolFilePrefix.length());
935 return removeExtension(entryName).replace(File.separatorChar, '.');
936 } else 819 } else
937 throw new IllegalArgumentException(file.getClass().getName()); 820 throw new IllegalArgumentException(file.getClass().getName());
938 // System.err.println("inferBinaryName failed for " + file); 821 }
939 return null;
940 }
941 // where
942 private static String removeExtension(String fileName) {
943 int lastDot = fileName.lastIndexOf(".");
944 return (lastDot == -1 ? fileName : fileName.substring(0, lastDot));
945 }
946 822
947 public boolean isSameFile(FileObject a, FileObject b) { 823 public boolean isSameFile(FileObject a, FileObject b) {
948 nullCheck(a); 824 nullCheck(a);
949 nullCheck(b); 825 nullCheck(b);
950 if (!(a instanceof BaseFileObject)) 826 if (!(a instanceof BaseFileObject))
1027 903
1028 for (File dir: path) { 904 for (File dir: path) {
1029 if (dir.isDirectory()) { 905 if (dir.isDirectory()) {
1030 File f = new File(dir, name.replace('/', File.separatorChar)); 906 File f = new File(dir, name.replace('/', File.separatorChar));
1031 if (f.exists()) 907 if (f.exists())
1032 return new RegularFileObject(f); 908 return new RegularFileObject(this, f);
1033 } else { 909 } else {
1034 Archive a = openArchive(dir); 910 Archive a = openArchive(dir);
1035 if (a.contains(name)) { 911 if (a.contains(name)) {
1036 int i = name.lastIndexOf('/'); 912 int i = name.lastIndexOf('/');
1037 String dirname = name.substring(0, i+1); 913 String dirname = name.substring(0, i+1);
1089 } else { 965 } else {
1090 File siblingDir = null; 966 File siblingDir = null;
1091 if (sibling != null && sibling instanceof RegularFileObject) { 967 if (sibling != null && sibling instanceof RegularFileObject) {
1092 siblingDir = ((RegularFileObject)sibling).f.getParentFile(); 968 siblingDir = ((RegularFileObject)sibling).f.getParentFile();
1093 } 969 }
1094 return new RegularFileObject(new File(siblingDir, baseName(fileName))); 970 return new RegularFileObject(this, new File(siblingDir, baseName(fileName)));
1095 } 971 }
1096 } else if (location == SOURCE_OUTPUT) { 972 } else if (location == SOURCE_OUTPUT) {
1097 dir = (getSourceOutDir() != null ? getSourceOutDir() : getClassOutDir()); 973 dir = (getSourceOutDir() != null ? getSourceOutDir() : getClassOutDir());
1098 } else { 974 } else {
1099 Iterable<? extends File> path = paths.getPathForLocation(location); 975 Iterable<? extends File> path = paths.getPathForLocation(location);
1103 break; 979 break;
1104 } 980 }
1105 } 981 }
1106 982
1107 File file = (dir == null ? new File(fileName) : new File(dir, fileName)); 983 File file = (dir == null ? new File(fileName) : new File(dir, fileName));
1108 return new RegularFileObject(file); 984 return new RegularFileObject(this, file);
1109 985
1110 } 986 }
1111 987
1112 public Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles( 988 public Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles(
1113 Iterable<? extends File> files) 989 Iterable<? extends File> files)
1116 if (files instanceof Collection) 992 if (files instanceof Collection)
1117 result = new ArrayList<RegularFileObject>(((Collection)files).size()); 993 result = new ArrayList<RegularFileObject>(((Collection)files).size());
1118 else 994 else
1119 result = new ArrayList<RegularFileObject>(); 995 result = new ArrayList<RegularFileObject>();
1120 for (File f: files) 996 for (File f: files)
1121 result.add(new RegularFileObject(nullCheck(f))); 997 result.add(new RegularFileObject(this, nullCheck(f)));
1122 return result; 998 return result;
1123 } 999 }
1124 1000
1125 public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files) { 1001 public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files) {
1126 return getJavaFileObjectsFromFiles(Arrays.asList(nullCheck(files))); 1002 return getJavaFileObjectsFromFiles(Arrays.asList(nullCheck(files)));
1266 private static <T> Iterable<T> nullCheck(Iterable<T> it) { 1142 private static <T> Iterable<T> nullCheck(Iterable<T> it) {
1267 for (T t : it) 1143 for (T t : it)
1268 t.getClass(); // null check 1144 t.getClass(); // null check
1269 return it; 1145 return it;
1270 } 1146 }
1271
1272 /**
1273 * A subclass of JavaFileObject representing regular files.
1274 */
1275 private class RegularFileObject extends BaseFileObject {
1276 /** Have the parent directories been created?
1277 */
1278 private boolean hasParents=false;
1279
1280 /** The file's name.
1281 */
1282 private String name;
1283
1284 /** The underlying file.
1285 */
1286 final File f;
1287
1288 public RegularFileObject(File f) {
1289 this(f.getName(), f);
1290 }
1291
1292 public RegularFileObject(String name, File f) {
1293 if (f.isDirectory())
1294 throw new IllegalArgumentException("directories not supported");
1295 this.name = name;
1296 this.f = f;
1297 }
1298
1299 public InputStream openInputStream() throws IOException {
1300 return new FileInputStream(f);
1301 }
1302
1303 protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
1304 return JavacFileManager.this.getDecoder(getEncodingName(), ignoreEncodingErrors);
1305 }
1306
1307 public OutputStream openOutputStream() throws IOException {
1308 ensureParentDirectoriesExist();
1309 return new FileOutputStream(f);
1310 }
1311
1312 public Writer openWriter() throws IOException {
1313 ensureParentDirectoriesExist();
1314 return new OutputStreamWriter(new FileOutputStream(f), getEncodingName());
1315 }
1316
1317 private void ensureParentDirectoriesExist() throws IOException {
1318 if (!hasParents) {
1319 File parent = f.getParentFile();
1320 if (parent != null && !parent.exists()) {
1321 if (!parent.mkdirs()) {
1322 // if the mkdirs failed, it may be because another process concurrently
1323 // created the directory, so check if the directory got created
1324 // anyway before throwing an exception
1325 if (!parent.exists() || !parent.isDirectory())
1326 throw new IOException("could not create parent directories");
1327 }
1328 }
1329 hasParents = true;
1330 }
1331 }
1332
1333 /** @deprecated see bug 6410637 */
1334 @Deprecated
1335 public String getName() {
1336 return name;
1337 }
1338
1339 public boolean isNameCompatible(String cn, JavaFileObject.Kind kind) {
1340 cn.getClass(); // null check
1341 if (kind == Kind.OTHER && getKind() != kind)
1342 return false;
1343 String n = cn + kind.extension;
1344 if (name.equals(n))
1345 return true;
1346 if (name.equalsIgnoreCase(n)) {
1347 try {
1348 // allow for Windows
1349 return (f.getCanonicalFile().getName().equals(n));
1350 } catch (IOException e) {
1351 }
1352 }
1353 return false;
1354 }
1355
1356 /** @deprecated see bug 6410637 */
1357 @Deprecated
1358 public String getPath() {
1359 return f.getPath();
1360 }
1361
1362 public long getLastModified() {
1363 return f.lastModified();
1364 }
1365
1366 public boolean delete() {
1367 return f.delete();
1368 }
1369
1370 public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
1371 SoftReference<CharBuffer> r = contentCache.get(this);
1372 CharBuffer cb = (r == null ? null : r.get());
1373 if (cb == null) {
1374 InputStream in = new FileInputStream(f);
1375 try {
1376 ByteBuffer bb = makeByteBuffer(in);
1377 JavaFileObject prev = log.useSource(this);
1378 try {
1379 cb = decode(bb, ignoreEncodingErrors);
1380 } finally {
1381 log.useSource(prev);
1382 }
1383 byteBufferCache.put(bb); // save for next time
1384 if (!ignoreEncodingErrors)
1385 contentCache.put(this, new SoftReference<CharBuffer>(cb));
1386 } finally {
1387 in.close();
1388 }
1389 }
1390 return cb;
1391 }
1392
1393 @Override
1394 public boolean equals(Object other) {
1395 if (!(other instanceof RegularFileObject))
1396 return false;
1397 RegularFileObject o = (RegularFileObject) other;
1398 try {
1399 return f.equals(o.f)
1400 || f.getCanonicalFile().equals(o.f.getCanonicalFile());
1401 } catch (IOException e) {
1402 return false;
1403 }
1404 }
1405
1406 @Override
1407 public int hashCode() {
1408 return f.hashCode();
1409 }
1410
1411 public URI toUri() {
1412 try {
1413 // Do no use File.toURI to avoid file system access
1414 String path = f.getAbsolutePath().replace(File.separatorChar, '/');
1415 return new URI("file://" + path).normalize();
1416 } catch (URISyntaxException ex) {
1417 return f.toURI();
1418 }
1419 }
1420
1421 }
1422
1423 /**
1424 * A subclass of JavaFileObject representing zip entries.
1425 */
1426 public class ZipFileObject extends BaseFileObject {
1427
1428 /** The entry's name.
1429 */
1430 private String name;
1431
1432 /** The zipfile containing the entry.
1433 */
1434 ZipFile zdir;
1435
1436 /** The underlying zip entry object.
1437 */
1438 ZipEntry entry;
1439
1440 public ZipFileObject(String name, ZipFile zdir, ZipEntry entry) {
1441 this.name = name;
1442 this.zdir = zdir;
1443 this.entry = entry;
1444 }
1445
1446 public InputStream openInputStream() throws IOException {
1447 return zdir.getInputStream(entry);
1448 }
1449
1450 public OutputStream openOutputStream() throws IOException {
1451 throw new UnsupportedOperationException();
1452 }
1453
1454 protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
1455 return JavacFileManager.this.getDecoder(getEncodingName(), ignoreEncodingErrors);
1456 }
1457
1458 public Writer openWriter() throws IOException {
1459 throw new UnsupportedOperationException();
1460 }
1461
1462 /** @deprecated see bug 6410637 */
1463 @Deprecated
1464 public String getName() {
1465 return name;
1466 }
1467
1468 public boolean isNameCompatible(String cn, JavaFileObject.Kind k) {
1469 cn.getClass(); // null check
1470 if (k == Kind.OTHER && getKind() != k)
1471 return false;
1472 return name.equals(cn + k.extension);
1473 }
1474
1475 /** @deprecated see bug 6410637 */
1476 @Deprecated
1477 public String getPath() {
1478 return zdir.getName() + "(" + entry + ")";
1479 }
1480
1481 public long getLastModified() {
1482 return entry.getTime();
1483 }
1484
1485 public boolean delete() {
1486 throw new UnsupportedOperationException();
1487 }
1488
1489 public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
1490 SoftReference<CharBuffer> r = contentCache.get(this);
1491 CharBuffer cb = (r == null ? null : r.get());
1492 if (cb == null) {
1493 InputStream in = zdir.getInputStream(entry);
1494 try {
1495 ByteBuffer bb = makeByteBuffer(in);
1496 JavaFileObject prev = log.useSource(this);
1497 try {
1498 cb = decode(bb, ignoreEncodingErrors);
1499 } finally {
1500 log.useSource(prev);
1501 }
1502 byteBufferCache.put(bb); // save for next time
1503 if (!ignoreEncodingErrors)
1504 contentCache.put(this, new SoftReference<CharBuffer>(cb));
1505 } finally {
1506 in.close();
1507 }
1508 }
1509 return cb;
1510 }
1511
1512 @Override
1513 public boolean equals(Object other) {
1514 if (!(other instanceof ZipFileObject))
1515 return false;
1516 ZipFileObject o = (ZipFileObject) other;
1517 return zdir.equals(o.zdir) || name.equals(o.name);
1518 }
1519
1520 @Override
1521 public int hashCode() {
1522 return zdir.hashCode() + name.hashCode();
1523 }
1524
1525 public String getZipName() {
1526 return zdir.getName();
1527 }
1528
1529 public String getZipEntryName() {
1530 return entry.getName();
1531 }
1532
1533 public URI toUri() {
1534 String zipName = new File(getZipName()).toURI().normalize().getPath();
1535 String entryName = getZipEntryName();
1536 return URI.create("jar:" + zipName + "!" + entryName);
1537 }
1538
1539 }
1540
1541 /**
1542 * A subclass of JavaFileObject representing zip entries using the com.sun.tools.javac.zip.ZipFileIndex implementation.
1543 */
1544 public class ZipFileIndexFileObject extends BaseFileObject {
1545
1546 /** The entry's name.
1547 */
1548 private String name;
1549
1550 /** The zipfile containing the entry.
1551 */
1552 ZipFileIndex zfIndex;
1553
1554 /** The underlying zip entry object.
1555 */
1556 ZipFileIndexEntry entry;
1557
1558 /** The InputStream for this zip entry (file.)
1559 */
1560 InputStream inputStream = null;
1561
1562 /** The name of the zip file where this entry resides.
1563 */
1564 String zipName;
1565
1566 JavacFileManager defFileManager = null;
1567
1568 public ZipFileIndexFileObject(JavacFileManager fileManager, ZipFileIndex zfIndex, ZipFileIndexEntry entry, String zipFileName) {
1569 super();
1570 this.name = entry.getFileName();
1571 this.zfIndex = zfIndex;
1572 this.entry = entry;
1573 this.zipName = zipFileName;
1574 defFileManager = fileManager;
1575 }
1576
1577 public InputStream openInputStream() throws IOException {
1578
1579 if (inputStream == null) {
1580 inputStream = new ByteArrayInputStream(read());
1581 }
1582 return inputStream;
1583 }
1584
1585 protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
1586 return JavacFileManager.this.getDecoder(getEncodingName(), ignoreEncodingErrors);
1587 }
1588
1589 public OutputStream openOutputStream() throws IOException {
1590 throw new UnsupportedOperationException();
1591 }
1592
1593 public Writer openWriter() throws IOException {
1594 throw new UnsupportedOperationException();
1595 }
1596
1597 /** @deprecated see bug 6410637 */
1598 @Deprecated
1599 public String getName() {
1600 return name;
1601 }
1602
1603 public boolean isNameCompatible(String cn, JavaFileObject.Kind k) {
1604 cn.getClass(); // null check
1605 if (k == Kind.OTHER && getKind() != k)
1606 return false;
1607 return name.equals(cn + k.extension);
1608 }
1609
1610 /** @deprecated see bug 6410637 */
1611 @Deprecated
1612 public String getPath() {
1613 return zipName + "(" + entry.getName() + ")";
1614 }
1615
1616 public long getLastModified() {
1617 return entry.getLastModified();
1618 }
1619
1620 public boolean delete() {
1621 throw new UnsupportedOperationException();
1622 }
1623
1624 @Override
1625 public boolean equals(Object other) {
1626 if (!(other instanceof ZipFileIndexFileObject))
1627 return false;
1628 ZipFileIndexFileObject o = (ZipFileIndexFileObject) other;
1629 return entry.equals(o.entry);
1630 }
1631
1632 @Override
1633 public int hashCode() {
1634 return zipName.hashCode() + (name.hashCode() << 10);
1635 }
1636
1637 public String getZipName() {
1638 return zipName;
1639 }
1640
1641 public String getZipEntryName() {
1642 return entry.getName();
1643 }
1644
1645 public URI toUri() {
1646 String zipName = new File(getZipName()).toURI().normalize().getPath();
1647 String entryName = getZipEntryName();
1648 if (File.separatorChar != '/') {
1649 entryName = entryName.replace(File.separatorChar, '/');
1650 }
1651 return URI.create("jar:" + zipName + "!" + entryName);
1652 }
1653
1654 private byte[] read() throws IOException {
1655 if (entry == null) {
1656 entry = zfIndex.getZipIndexEntry(name);
1657 if (entry == null)
1658 throw new FileNotFoundException();
1659 }
1660 return zfIndex.read(entry);
1661 }
1662
1663 public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
1664 SoftReference<CharBuffer> r = defFileManager.contentCache.get(this);
1665 CharBuffer cb = (r == null ? null : r.get());
1666 if (cb == null) {
1667 InputStream in = new ByteArrayInputStream(zfIndex.read(entry));
1668 try {
1669 ByteBuffer bb = makeByteBuffer(in);
1670 JavaFileObject prev = log.useSource(this);
1671 try {
1672 cb = decode(bb, ignoreEncodingErrors);
1673 } finally {
1674 log.useSource(prev);
1675 }
1676 byteBufferCache.put(bb); // save for next time
1677 if (!ignoreEncodingErrors)
1678 defFileManager.contentCache.put(this, new SoftReference<CharBuffer>(cb));
1679 } finally {
1680 in.close();
1681 }
1682 }
1683 return cb;
1684 }
1685 }
1686
1687 public class ZipFileIndexArchive implements Archive {
1688 private final ZipFileIndex zfIndex;
1689 private JavacFileManager fileManager;
1690
1691 public ZipFileIndexArchive(JavacFileManager fileManager, ZipFileIndex zdir) throws IOException {
1692 this.fileManager = fileManager;
1693 this.zfIndex = zdir;
1694 }
1695
1696 public boolean contains(String name) {
1697 return zfIndex.contains(name);
1698 }
1699
1700 public com.sun.tools.javac.util.List<String> getFiles(String subdirectory) {
1701 return zfIndex.getFiles(((subdirectory.endsWith("/") || subdirectory.endsWith("\\"))? subdirectory.substring(0, subdirectory.length() - 1) : subdirectory));
1702 }
1703
1704 public JavaFileObject getFileObject(String subdirectory, String file) {
1705 String fullZipFileName = subdirectory + file;
1706 ZipFileIndexEntry entry = zfIndex.getZipIndexEntry(fullZipFileName);
1707 JavaFileObject ret = new ZipFileIndexFileObject(fileManager, zfIndex, entry, zfIndex.getZipFile().getPath());
1708 return ret;
1709 }
1710
1711 public Set<String> getSubdirectories() {
1712 return zfIndex.getAllDirectories();
1713 }
1714
1715 public void close() throws IOException {
1716 zfIndex.close();
1717 }
1718 }
1719 } 1147 }

mercurial