Home » openjdk-7 » com.sun.tools » javac » file » [javadoc | source]

    1   /*
    2    * Copyright (c) 2005, 2009, 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.File;
   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.util.Enumeration;
   38   import java.util.HashMap;
   39   import java.util.Map;
   40   import java.util.Set;
   41   import java.util.zip.ZipEntry;
   42   import java.util.zip.ZipFile;
   43   
   44   import javax.tools.JavaFileObject;
   45   
   46   import com.sun.tools.javac.file.JavacFileManager.Archive;
   47   import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
   48   import com.sun.tools.javac.file.RelativePath.RelativeFile;
   49   import com.sun.tools.javac.util.List;
   50   import java.lang.ref.Reference;
   51   import java.lang.ref.SoftReference;
   52   
   53   /**
   54    * <p><b>This is NOT part of any supported API.
   55    * If you write code that depends on this, you do so at your own risk.
   56    * This code and its internal interfaces are subject to change or
   57    * deletion without notice.</b>
   58    */
   59   public class ZipArchive implements Archive {
   60   
   61       public ZipArchive(JavacFileManager fm, ZipFile zfile) throws IOException {
   62           this(fm, zfile, true);
   63       }
   64   
   65       protected ZipArchive(JavacFileManager fm, ZipFile zfile, boolean initMap) throws IOException {
   66           this.fileManager = fm;
   67           this.zfile = zfile;
   68           this.map = new HashMap<RelativeDirectory,List<String>>();
   69           if (initMap)
   70               initMap();
   71       }
   72   
   73       protected void initMap() throws IOException {
   74           for (Enumeration<? extends ZipEntry> e = zfile.entries(); e.hasMoreElements(); ) {
   75               ZipEntry entry;
   76               try {
   77                   entry = e.nextElement();
   78               } catch (InternalError ex) {
   79                   IOException io = new IOException();
   80                   io.initCause(ex); // convenience constructors added in Mustang :-(
   81                   throw io;
   82               }
   83               addZipEntry(entry);
   84           }
   85       }
   86   
   87       void addZipEntry(ZipEntry entry) {
   88           String name = entry.getName();
   89           int i = name.lastIndexOf('/');
   90           RelativeDirectory dirname = new RelativeDirectory(name.substring(0, i+1));
   91           String basename = name.substring(i+1);
   92           if (basename.length() == 0)
   93               return;
   94           List<String> list = map.get(dirname);
   95           if (list == null)
   96               list = List.nil();
   97           list = list.prepend(basename);
   98           map.put(dirname, list);
   99       }
  100   
  101       public boolean contains(RelativePath name) {
  102           RelativeDirectory dirname = name.dirname();
  103           String basename = name.basename();
  104           if (basename.length() == 0)
  105               return false;
  106           List<String> list = map.get(dirname);
  107           return (list != null && list.contains(basename));
  108       }
  109   
  110       public List<String> getFiles(RelativeDirectory subdirectory) {
  111           return map.get(subdirectory);
  112       }
  113   
  114       public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) {
  115           ZipEntry ze = new RelativeFile(subdirectory, file).getZipEntry(zfile);
  116           return new ZipFileObject(this, file, ze);
  117       }
  118   
  119       public Set<RelativeDirectory> getSubdirectories() {
  120           return map.keySet();
  121       }
  122   
  123       public void close() throws IOException {
  124           zfile.close();
  125       }
  126   
  127       @Override
  128       public String toString() {
  129           return "ZipArchive[" + zfile.getName() + "]";
  130       }
  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        */
  144       protected JavacFileManager fileManager;
  145       /**
  146        * The index for the contents of this archive.
  147        */
  148       protected final Map<RelativeDirectory,List<String>> map;
  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;
  157   
  158       /**
  159        * A subclass of JavaFileObject representing zip entries.
  160        */
  161       public static class ZipFileObject extends BaseFileObject {
  162   
  163           private String name;
  164           ZipArchive zarch;
  165           ZipEntry entry;
  166   
  167           protected ZipFileObject(ZipArchive zarch, String name, ZipEntry entry) {
  168               super(zarch.fileManager);
  169               this.zarch = zarch;
  170               this.name = name;
  171               this.entry = entry;
  172           }
  173   
  174           public URI toUri() {
  175               File zipFile = new File(zarch.zfile.getName());
  176               return createJarUri(zipFile, entry.getName());
  177           }
  178   
  179           @Override
  180           public String getName() {
  181               return zarch.zfile.getName() + "(" + entry.getName() + ")";
  182           }
  183   
  184           @Override
  185           public String getShortName() {
  186               return new File(zarch.zfile.getName()).getName() + "(" + entry + ")";
  187           }
  188   
  189           @Override
  190           public JavaFileObject.Kind getKind() {
  191               return getKind(entry.getName());
  192           }
  193   
  194           @Override
  195           public InputStream openInputStream() throws IOException {
  196               return zarch.zfile.getInputStream(entry);
  197           }
  198   
  199           @Override
  200           public OutputStream openOutputStream() throws IOException {
  201               throw new UnsupportedOperationException();
  202           }
  203   
  204           @Override
  205           public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
  206               CharBuffer cb = fileManager.getCachedContent(this);
  207               if (cb == null) {
  208                   InputStream in = zarch.zfile.getInputStream(entry);
  209                   try {
  210                       ByteBuffer bb = fileManager.makeByteBuffer(in);
  211                       JavaFileObject prev = fileManager.log.useSource(this);
  212                       try {
  213                           cb = fileManager.decode(bb, ignoreEncodingErrors);
  214                       } finally {
  215                           fileManager.log.useSource(prev);
  216                       }
  217                       fileManager.recycleByteBuffer(bb);
  218                       if (!ignoreEncodingErrors) {
  219                           fileManager.cache(this, cb);
  220                       }
  221                   } finally {
  222                       in.close();
  223                   }
  224               }
  225               return cb;
  226           }
  227   
  228           @Override
  229           public Writer openWriter() throws IOException {
  230               throw new UnsupportedOperationException();
  231           }
  232   
  233           @Override
  234           public long getLastModified() {
  235               return entry.getTime();
  236           }
  237   
  238           @Override
  239           public boolean delete() {
  240               throw new UnsupportedOperationException();
  241           }
  242   
  243           @Override
  244           protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
  245               return fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors);
  246           }
  247   
  248           @Override
  249           protected String inferBinaryName(Iterable<? extends File> path) {
  250               String entryName = entry.getName();
  251               return removeExtension(entryName).replace('/', '.');
  252           }
  253   
  254           @Override
  255           public boolean isNameCompatible(String cn, JavaFileObject.Kind k) {
  256               cn.getClass();
  257               // null check
  258               if (k == Kind.OTHER && getKind() != k) {
  259                   return false;
  260               }
  261               return name.equals(cn + k.extension);
  262           }
  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            */
  269           @Override
  270           public boolean equals(Object other) {
  271               if (this == other)
  272                   return true;
  273   
  274               if (!(other instanceof ZipFileObject))
  275                   return false;
  276   
  277               ZipFileObject o = (ZipFileObject) other;
  278               return zarch.getAbsoluteFile().equals(o.zarch.getAbsoluteFile())
  279                       && name.equals(o.name);
  280           }
  281   
  282           @Override
  283           public int hashCode() {
  284               return zarch.getAbsoluteFile().hashCode() + name.hashCode();
  285           }
  286       }
  287   
  288   }

Home » openjdk-7 » com.sun.tools » javac » file » [javadoc | source]