langtools/src/share/classes/com/sun/tools/javac/file/ZipArchive.java
changeset 4073 9788f4549740
parent 3998 c66be272f350
child 5520 86e4b9a9da40
equal deleted inserted replaced
4072:70eaf9773f81 4073:9788f4549740
    45 
    45 
    46 import com.sun.tools.javac.file.JavacFileManager.Archive;
    46 import com.sun.tools.javac.file.JavacFileManager.Archive;
    47 import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
    47 import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
    48 import com.sun.tools.javac.file.RelativePath.RelativeFile;
    48 import com.sun.tools.javac.file.RelativePath.RelativeFile;
    49 import com.sun.tools.javac.util.List;
    49 import com.sun.tools.javac.util.List;
       
    50 import java.lang.ref.Reference;
       
    51 import java.lang.ref.SoftReference;
    50 
    52 
    51 /**
    53 /**
    52  * <p><b>This is NOT part of any API supported by Sun Microsystems.
    54  * <p><b>This is NOT part of any API supported by Sun Microsystems.
    53  * If you write code that depends on this, you do so at your own risk.
    55  * If you write code that depends on this, you do so at your own risk.
    54  * This code and its internal interfaces are subject to change or
    56  * This code and its internal interfaces are subject to change or
    55  * deletion without notice.</b>
    57  * deletion without notice.</b>
    56  */
    58  */
    57 public class ZipArchive implements Archive {
    59 public class ZipArchive implements Archive {
    58 
    60 
    59     public ZipArchive(JavacFileManager fm, ZipFile zdir) throws IOException {
    61     public ZipArchive(JavacFileManager fm, ZipFile zfile) throws IOException {
    60         this(fm, zdir, true);
    62         this(fm, zfile, true);
    61     }
    63     }
    62 
    64 
    63     protected ZipArchive(JavacFileManager fm, ZipFile zdir, boolean initMap) throws IOException {
    65     protected ZipArchive(JavacFileManager fm, ZipFile zfile, boolean initMap) throws IOException {
    64         this.fileManager = fm;
    66         this.fileManager = fm;
    65         this.zdir = zdir;
    67         this.zfile = zfile;
    66         this.map = new HashMap<RelativeDirectory,List<String>>();
    68         this.map = new HashMap<RelativeDirectory,List<String>>();
    67         if (initMap)
    69         if (initMap)
    68             initMap();
    70             initMap();
    69     }
    71     }
    70 
    72 
    71     protected void initMap() throws IOException {
    73     protected void initMap() throws IOException {
    72         for (Enumeration<? extends ZipEntry> e = zdir.entries(); e.hasMoreElements(); ) {
    74         for (Enumeration<? extends ZipEntry> e = zfile.entries(); e.hasMoreElements(); ) {
    73             ZipEntry entry;
    75             ZipEntry entry;
    74             try {
    76             try {
    75                 entry = e.nextElement();
    77                 entry = e.nextElement();
    76             } catch (InternalError ex) {
    78             } catch (InternalError ex) {
    77                 IOException io = new IOException();
    79                 IOException io = new IOException();
   108     public List<String> getFiles(RelativeDirectory subdirectory) {
   110     public List<String> getFiles(RelativeDirectory subdirectory) {
   109         return map.get(subdirectory);
   111         return map.get(subdirectory);
   110     }
   112     }
   111 
   113 
   112     public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) {
   114     public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) {
   113         ZipEntry ze = new RelativeFile(subdirectory, file).getZipEntry(zdir);
   115         ZipEntry ze = new RelativeFile(subdirectory, file).getZipEntry(zfile);
   114         return new ZipFileObject(this, file, ze);
   116         return new ZipFileObject(this, file, ze);
   115     }
   117     }
   116 
   118 
   117     public Set<RelativeDirectory> getSubdirectories() {
   119     public Set<RelativeDirectory> getSubdirectories() {
   118         return map.keySet();
   120         return map.keySet();
   119     }
   121     }
   120 
   122 
   121     public void close() throws IOException {
   123     public void close() throws IOException {
   122         zdir.close();
   124         zfile.close();
   123     }
   125     }
   124 
   126 
   125     @Override
   127     @Override
   126     public String toString() {
   128     public String toString() {
   127         return "ZipArchive[" + zdir.getName() + "]";
   129         return "ZipArchive[" + zfile.getName() + "]";
   128     }
   130     }
   129 
   131 
       
   132     private File getAbsoluteFile() {
       
   133         File absFile = (absFileRef == null ? null : absFileRef.get());
       
   134         if (absFile == null) {
       
   135             absFile = new File(zfile.getName()).getAbsoluteFile();
       
   136             absFileRef = new SoftReference<File>(absFile);
       
   137         }
       
   138         return absFile;
       
   139     }
       
   140 
       
   141     /**
       
   142      * The file manager that created this archive.
       
   143      */
   130     protected JavacFileManager fileManager;
   144     protected JavacFileManager fileManager;
       
   145     /**
       
   146      * The index for the contents of this archive.
       
   147      */
   131     protected final Map<RelativeDirectory,List<String>> map;
   148     protected final Map<RelativeDirectory,List<String>> map;
   132     protected final ZipFile zdir;
   149     /**
       
   150      * The zip file for the archive.
       
   151      */
       
   152     protected final ZipFile zfile;
       
   153     /**
       
   154      * A reference to the absolute filename for the zip file for the archive.
       
   155      */
       
   156     protected Reference<File> absFileRef;
   133 
   157 
   134     /**
   158     /**
   135      * A subclass of JavaFileObject representing zip entries.
   159      * A subclass of JavaFileObject representing zip entries.
   136      */
   160      */
   137     public static class ZipFileObject extends BaseFileObject {
   161     public static class ZipFileObject extends BaseFileObject {
   146             this.name = name;
   170             this.name = name;
   147             this.entry = entry;
   171             this.entry = entry;
   148         }
   172         }
   149 
   173 
   150         public URI toUri() {
   174         public URI toUri() {
   151             File zipFile = new File(zarch.zdir.getName());
   175             File zipFile = new File(zarch.zfile.getName());
   152             return createJarUri(zipFile, entry.getName());
   176             return createJarUri(zipFile, entry.getName());
   153         }
   177         }
   154 
   178 
   155         @Override
   179         @Override
   156         public String getName() {
   180         public String getName() {
   157             return zarch.zdir.getName() + "(" + entry.getName() + ")";
   181             return zarch.zfile.getName() + "(" + entry.getName() + ")";
   158         }
   182         }
   159 
   183 
   160         @Override
   184         @Override
   161         public String getShortName() {
   185         public String getShortName() {
   162             return new File(zarch.zdir.getName()).getName() + "(" + entry + ")";
   186             return new File(zarch.zfile.getName()).getName() + "(" + entry + ")";
   163         }
   187         }
   164 
   188 
   165         @Override
   189         @Override
   166         public JavaFileObject.Kind getKind() {
   190         public JavaFileObject.Kind getKind() {
   167             return getKind(entry.getName());
   191             return getKind(entry.getName());
   168         }
   192         }
   169 
   193 
   170         @Override
   194         @Override
   171         public InputStream openInputStream() throws IOException {
   195         public InputStream openInputStream() throws IOException {
   172             return zarch.zdir.getInputStream(entry);
   196             return zarch.zfile.getInputStream(entry);
   173         }
   197         }
   174 
   198 
   175         @Override
   199         @Override
   176         public OutputStream openOutputStream() throws IOException {
   200         public OutputStream openOutputStream() throws IOException {
   177             throw new UnsupportedOperationException();
   201             throw new UnsupportedOperationException();
   179 
   203 
   180         @Override
   204         @Override
   181         public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
   205         public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
   182             CharBuffer cb = fileManager.getCachedContent(this);
   206             CharBuffer cb = fileManager.getCachedContent(this);
   183             if (cb == null) {
   207             if (cb == null) {
   184                 InputStream in = zarch.zdir.getInputStream(entry);
   208                 InputStream in = zarch.zfile.getInputStream(entry);
   185                 try {
   209                 try {
   186                     ByteBuffer bb = fileManager.makeByteBuffer(in);
   210                     ByteBuffer bb = fileManager.makeByteBuffer(in);
   187                     JavaFileObject prev = fileManager.log.useSource(this);
   211                     JavaFileObject prev = fileManager.log.useSource(this);
   188                     try {
   212                     try {
   189                         cb = fileManager.decode(bb, ignoreEncodingErrors);
   213                         cb = fileManager.decode(bb, ignoreEncodingErrors);
   235                 return false;
   259                 return false;
   236             }
   260             }
   237             return name.equals(cn + k.extension);
   261             return name.equals(cn + k.extension);
   238         }
   262         }
   239 
   263 
       
   264         /**
       
   265          * Check if two file objects are equal.
       
   266          * Two ZipFileObjects are equal if the absolute paths of the underlying
       
   267          * zip files are equal and if the paths within those zip files are equal.
       
   268          */
   240         @Override
   269         @Override
   241         public boolean equals(Object other) {
   270         public boolean equals(Object other) {
   242             if (!(other instanceof ZipFileObject)) {
   271             if (this == other)
       
   272                 return true;
       
   273 
       
   274             if (!(other instanceof ZipFileObject))
   243                 return false;
   275                 return false;
   244             }
   276 
   245             ZipFileObject o = (ZipFileObject) other;
   277             ZipFileObject o = (ZipFileObject) other;
   246             return zarch.zdir.equals(o.zarch.zdir) || name.equals(o.name);
   278             return zarch.getAbsoluteFile().equals(o.zarch.getAbsoluteFile())
       
   279                     && name.equals(o.name);
   247         }
   280         }
   248 
   281 
   249         @Override
   282         @Override
   250         public int hashCode() {
   283         public int hashCode() {
   251             return zarch.zdir.hashCode() + name.hashCode();
   284             return zarch.getAbsoluteFile().hashCode() + name.hashCode();
   252         }
   285         }
   253     }
   286     }
   254 
   287 
   255 }
   288 }