langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java
changeset 34569 8b372e28f106
parent 34559 9229cc3b3802
parent 34568 afc0330fa0d4
child 34570 8a8f52a733dd
equal deleted inserted replaced
34559:9229cc3b3802 34569:8b372e28f106
     1 /*
       
     2  * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     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
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package com.sun.tools.javac.file;
       
    27 
       
    28 import java.io.ByteArrayInputStream;
       
    29 import java.io.IOException;
       
    30 import java.io.InputStream;
       
    31 import java.io.OutputStream;
       
    32 import java.io.Writer;
       
    33 import java.net.URI;
       
    34 import java.nio.ByteBuffer;
       
    35 import java.nio.CharBuffer;
       
    36 import java.nio.charset.CharsetDecoder;
       
    37 import java.nio.file.Path;
       
    38 import java.util.Objects;
       
    39 import java.util.Set;
       
    40 
       
    41 import javax.tools.JavaFileObject;
       
    42 
       
    43 import com.sun.tools.javac.file.JavacFileManager.Archive;
       
    44 import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
       
    45 import com.sun.tools.javac.file.RelativePath.RelativeFile;
       
    46 import com.sun.tools.javac.util.Assert;
       
    47 import com.sun.tools.javac.util.DefinedBy;
       
    48 import com.sun.tools.javac.util.DefinedBy.Api;
       
    49 import com.sun.tools.javac.util.List;
       
    50 
       
    51 /**
       
    52  * <p><b>This is NOT part of any supported API.
       
    53  * 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
       
    55  * deletion without notice.</b>
       
    56  */
       
    57 public class ZipFileIndexArchive implements Archive {
       
    58 
       
    59     private final ZipFileIndex zfIndex;
       
    60     private final JavacFileManager fileManager;
       
    61 
       
    62     public ZipFileIndexArchive(JavacFileManager fileManager, ZipFileIndex zdir) throws IOException {
       
    63         super();
       
    64         this.fileManager = fileManager;
       
    65         this.zfIndex = zdir;
       
    66     }
       
    67 
       
    68     public boolean contains(RelativePath name) {
       
    69         return zfIndex.contains(name);
       
    70     }
       
    71 
       
    72     public List<String> getFiles(RelativeDirectory subdirectory) {
       
    73         return zfIndex.getFiles(subdirectory);
       
    74     }
       
    75 
       
    76     public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) {
       
    77         RelativeFile fullZipFileName = new RelativeFile(subdirectory, file);
       
    78         ZipFileIndex.Entry entry = zfIndex.getZipIndexEntry(fullZipFileName);
       
    79         JavaFileObject ret = new ZipFileIndexFileObject(fileManager, zfIndex, entry, zfIndex.getZipFile());
       
    80         return ret;
       
    81     }
       
    82 
       
    83     public Set<RelativeDirectory> getSubdirectories() {
       
    84         return zfIndex.getAllDirectories();
       
    85     }
       
    86 
       
    87     public void close() throws IOException {
       
    88         zfIndex.close();
       
    89     }
       
    90 
       
    91     @Override
       
    92     public String toString() {
       
    93         return "ZipFileIndexArchive[" + zfIndex + "]";
       
    94     }
       
    95 
       
    96     /**
       
    97      * A subclass of JavaFileObject representing zip entries using the com.sun.tools.javac.file.ZipFileIndex implementation.
       
    98      */
       
    99     public static class ZipFileIndexFileObject extends BaseFileObject {
       
   100 
       
   101         /** The entry's name.
       
   102          */
       
   103         private String name;
       
   104 
       
   105         /** The zipfile containing the entry.
       
   106          */
       
   107         ZipFileIndex zfIndex;
       
   108 
       
   109         /** The underlying zip entry object.
       
   110          */
       
   111         ZipFileIndex.Entry entry;
       
   112 
       
   113         /** The name of the zip file where this entry resides.
       
   114          */
       
   115         Path zipName;
       
   116 
       
   117 
       
   118         ZipFileIndexFileObject(JavacFileManager fileManager, ZipFileIndex zfIndex, ZipFileIndex.Entry entry, Path zipFileName) {
       
   119             super(fileManager);
       
   120             this.name = entry.getFileName();
       
   121             this.zfIndex = zfIndex;
       
   122             this.entry = entry;
       
   123             this.zipName = zipFileName;
       
   124         }
       
   125 
       
   126         @Override @DefinedBy(Api.COMPILER)
       
   127         public URI toUri() {
       
   128             return createJarUri(zipName, getPrefixedEntryName());
       
   129         }
       
   130 
       
   131         @Override @DefinedBy(Api.COMPILER)
       
   132         public String getName() {
       
   133             return zipName + "(" + getPrefixedEntryName() + ")";
       
   134         }
       
   135 
       
   136         @Override
       
   137         public String getShortName() {
       
   138             return zipName.getFileName() + "(" + entry.getName() + ")";
       
   139         }
       
   140 
       
   141         @Override @DefinedBy(Api.COMPILER)
       
   142         public JavaFileObject.Kind getKind() {
       
   143             return getKind(entry.getName());
       
   144         }
       
   145 
       
   146         @Override @DefinedBy(Api.COMPILER)
       
   147         public InputStream openInputStream() throws IOException {
       
   148             Assert.checkNonNull(entry); // see constructor
       
   149             return new ByteArrayInputStream(zfIndex.read(entry));
       
   150         }
       
   151 
       
   152         @Override @DefinedBy(Api.COMPILER)
       
   153         public OutputStream openOutputStream() throws IOException {
       
   154             throw new UnsupportedOperationException();
       
   155         }
       
   156 
       
   157         @Override @DefinedBy(Api.COMPILER)
       
   158         public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
       
   159             CharBuffer cb = fileManager.getCachedContent(this);
       
   160             if (cb == null) {
       
   161                 try (InputStream in = new ByteArrayInputStream(zfIndex.read(entry))) {
       
   162                     ByteBuffer bb = fileManager.makeByteBuffer(in);
       
   163                     JavaFileObject prev = fileManager.log.useSource(this);
       
   164                     try {
       
   165                         cb = fileManager.decode(bb, ignoreEncodingErrors);
       
   166                     } finally {
       
   167                         fileManager.log.useSource(prev);
       
   168                     }
       
   169                     fileManager.recycleByteBuffer(bb); // save for next time
       
   170                     if (!ignoreEncodingErrors)
       
   171                         fileManager.cache(this, cb);
       
   172                 }
       
   173             }
       
   174             return cb;
       
   175         }
       
   176 
       
   177         @Override @DefinedBy(Api.COMPILER)
       
   178         public Writer openWriter() throws IOException {
       
   179             throw new UnsupportedOperationException();
       
   180         }
       
   181 
       
   182         @Override @DefinedBy(Api.COMPILER)
       
   183         public long getLastModified() {
       
   184             return entry.getLastModified();
       
   185         }
       
   186 
       
   187         @Override @DefinedBy(Api.COMPILER)
       
   188         public boolean delete() {
       
   189             throw new UnsupportedOperationException();
       
   190         }
       
   191 
       
   192         @Override
       
   193         protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
       
   194             return fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors);
       
   195         }
       
   196 
       
   197         @Override
       
   198         protected String inferBinaryName(Iterable<? extends Path> path) {
       
   199             String entryName = entry.getName();
       
   200             if (zfIndex.symbolFilePrefix != null) {
       
   201                 String prefix = zfIndex.symbolFilePrefix.path;
       
   202                 if (entryName.startsWith(prefix))
       
   203                     entryName = entryName.substring(prefix.length());
       
   204             }
       
   205             return removeExtension(entryName).replace('/', '.');
       
   206         }
       
   207 
       
   208         @Override @DefinedBy(Api.COMPILER)
       
   209         public boolean isNameCompatible(String cn, JavaFileObject.Kind k) {
       
   210             Objects.requireNonNull(cn);
       
   211             if (k == Kind.OTHER && getKind() != k)
       
   212                 return false;
       
   213             return name.equals(cn + k.extension);
       
   214         }
       
   215 
       
   216         /**
       
   217          * Check if two file objects are equal.
       
   218          * Two ZipFileIndexFileObjects are equal if the absolute paths of the underlying
       
   219          * zip files are equal and if the paths within those zip files are equal.
       
   220          */
       
   221         @Override
       
   222         public boolean equals(Object other) {
       
   223             if (this == other)
       
   224                 return true;
       
   225 
       
   226             if (!(other instanceof ZipFileIndexFileObject))
       
   227                 return false;
       
   228 
       
   229             ZipFileIndexFileObject o = (ZipFileIndexFileObject) other;
       
   230             return zfIndex.getAbsoluteFile().equals(o.zfIndex.getAbsoluteFile())
       
   231                     && entry.equals(o.entry);
       
   232         }
       
   233 
       
   234         @Override
       
   235         public int hashCode() {
       
   236             return zfIndex.getAbsoluteFile().hashCode() + entry.hashCode();
       
   237         }
       
   238 
       
   239         private String getPrefixedEntryName() {
       
   240             if (zfIndex.symbolFilePrefix != null)
       
   241                 return zfIndex.symbolFilePrefix.path + entry.getName();
       
   242             else
       
   243                 return entry.getName();
       
   244         }
       
   245     }
       
   246 
       
   247 }