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

Fri, 09 May 2014 20:33:21 -0700

author
mfang
date
Fri, 09 May 2014 20:33:21 -0700
changeset 2388
0add97444be9
parent 581
f2fdd52e4e87
child 2525
2eb010b6cb22
permissions
-rw-r--r--

8041424: 8u20 l10n resource file translation update 1
Reviewed-by: naoto, yhuang

jjg@57 1 /*
ohair@554 2 * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
jjg@57 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jjg@57 4 *
jjg@57 5 * This code is free software; you can redistribute it and/or modify it
jjg@57 6 * under the terms of the GNU General Public License version 2 only, as
ohair@554 7 * published by the Free Software Foundation. Oracle designates this
jjg@57 8 * particular file as subject to the "Classpath" exception as provided
ohair@554 9 * by Oracle in the LICENSE file that accompanied this code.
jjg@57 10 *
jjg@57 11 * This code is distributed in the hope that it will be useful, but WITHOUT
jjg@57 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jjg@57 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
jjg@57 14 * version 2 for more details (a copy is included in the LICENSE file that
jjg@57 15 * accompanied this code).
jjg@57 16 *
jjg@57 17 * You should have received a copy of the GNU General Public License version
jjg@57 18 * 2 along with this work; if not, write to the Free Software Foundation,
jjg@57 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jjg@57 20 *
ohair@554 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@554 22 * or visit www.oracle.com if you need additional information or have any
ohair@554 23 * questions.
jjg@57 24 */
jjg@57 25
jjg@57 26 package com.sun.tools.javac.file;
jjg@57 27
jjg@103 28 import java.io.File;
jjg@57 29 import java.io.IOException;
jjg@57 30 import java.io.InputStream;
jjg@57 31 import java.io.OutputStream;
jjg@57 32 import java.io.Writer;
jjg@57 33 import java.net.URI;
jjg@57 34 import java.nio.ByteBuffer;
jjg@57 35 import java.nio.CharBuffer;
jjg@57 36 import java.nio.charset.CharsetDecoder;
jjg@103 37 import java.util.Enumeration;
jjg@103 38 import java.util.HashMap;
jjg@103 39 import java.util.Map;
jjg@103 40 import java.util.Set;
jjg@103 41 import java.util.zip.ZipEntry;
jjg@103 42 import java.util.zip.ZipFile;
jjg@103 43
jjg@103 44 import javax.tools.JavaFileObject;
jjg@103 45
jjg@103 46 import com.sun.tools.javac.file.JavacFileManager.Archive;
jjg@103 47 import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
jjg@103 48 import com.sun.tools.javac.file.RelativePath.RelativeFile;
jjg@103 49 import com.sun.tools.javac.util.List;
jjg@424 50 import java.lang.ref.Reference;
jjg@424 51 import java.lang.ref.SoftReference;
jjg@57 52
jjg@333 53 /**
jjg@581 54 * <p><b>This is NOT part of any supported API.
jjg@333 55 * If you write code that depends on this, you do so at your own risk.
jjg@333 56 * This code and its internal interfaces are subject to change or
jjg@333 57 * deletion without notice.</b>
jjg@333 58 */
jjg@57 59 public class ZipArchive implements Archive {
jjg@57 60
jjg@424 61 public ZipArchive(JavacFileManager fm, ZipFile zfile) throws IOException {
jjg@424 62 this(fm, zfile, true);
jjg@103 63 }
jjg@103 64
jjg@424 65 protected ZipArchive(JavacFileManager fm, ZipFile zfile, boolean initMap) throws IOException {
jjg@57 66 this.fileManager = fm;
jjg@424 67 this.zfile = zfile;
jjg@103 68 this.map = new HashMap<RelativeDirectory,List<String>>();
jjg@103 69 if (initMap)
jjg@103 70 initMap();
jjg@103 71 }
jjg@103 72
jjg@103 73 protected void initMap() throws IOException {
jjg@424 74 for (Enumeration<? extends ZipEntry> e = zfile.entries(); e.hasMoreElements(); ) {
jjg@57 75 ZipEntry entry;
jjg@57 76 try {
jjg@57 77 entry = e.nextElement();
jjg@57 78 } catch (InternalError ex) {
jjg@57 79 IOException io = new IOException();
jjg@57 80 io.initCause(ex); // convenience constructors added in Mustang :-(
jjg@57 81 throw io;
jjg@57 82 }
jjg@57 83 addZipEntry(entry);
jjg@57 84 }
jjg@57 85 }
jjg@57 86
jjg@57 87 void addZipEntry(ZipEntry entry) {
jjg@57 88 String name = entry.getName();
jjg@57 89 int i = name.lastIndexOf('/');
jjg@103 90 RelativeDirectory dirname = new RelativeDirectory(name.substring(0, i+1));
jjg@57 91 String basename = name.substring(i+1);
jjg@57 92 if (basename.length() == 0)
jjg@57 93 return;
jjg@57 94 List<String> list = map.get(dirname);
jjg@57 95 if (list == null)
jjg@57 96 list = List.nil();
jjg@57 97 list = list.prepend(basename);
jjg@57 98 map.put(dirname, list);
jjg@57 99 }
jjg@57 100
jjg@103 101 public boolean contains(RelativePath name) {
jjg@103 102 RelativeDirectory dirname = name.dirname();
jjg@103 103 String basename = name.basename();
jjg@57 104 if (basename.length() == 0)
jjg@57 105 return false;
jjg@57 106 List<String> list = map.get(dirname);
jjg@57 107 return (list != null && list.contains(basename));
jjg@57 108 }
jjg@57 109
jjg@103 110 public List<String> getFiles(RelativeDirectory subdirectory) {
jjg@57 111 return map.get(subdirectory);
jjg@57 112 }
jjg@57 113
jjg@103 114 public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) {
jjg@424 115 ZipEntry ze = new RelativeFile(subdirectory, file).getZipEntry(zfile);
jjg@57 116 return new ZipFileObject(this, file, ze);
jjg@57 117 }
jjg@57 118
jjg@103 119 public Set<RelativeDirectory> getSubdirectories() {
jjg@57 120 return map.keySet();
jjg@57 121 }
jjg@57 122
jjg@57 123 public void close() throws IOException {
jjg@424 124 zfile.close();
jjg@57 125 }
jjg@57 126
jjg@400 127 @Override
jjg@103 128 public String toString() {
jjg@424 129 return "ZipArchive[" + zfile.getName() + "]";
jjg@103 130 }
jjg@103 131
jjg@424 132 private File getAbsoluteFile() {
jjg@424 133 File absFile = (absFileRef == null ? null : absFileRef.get());
jjg@424 134 if (absFile == null) {
jjg@424 135 absFile = new File(zfile.getName()).getAbsoluteFile();
jjg@424 136 absFileRef = new SoftReference<File>(absFile);
jjg@424 137 }
jjg@424 138 return absFile;
jjg@424 139 }
jjg@424 140
jjg@424 141 /**
jjg@424 142 * The file manager that created this archive.
jjg@424 143 */
jjg@57 144 protected JavacFileManager fileManager;
jjg@424 145 /**
jjg@424 146 * The index for the contents of this archive.
jjg@424 147 */
jjg@103 148 protected final Map<RelativeDirectory,List<String>> map;
jjg@424 149 /**
jjg@424 150 * The zip file for the archive.
jjg@424 151 */
jjg@424 152 protected final ZipFile zfile;
jjg@424 153 /**
jjg@424 154 * A reference to the absolute filename for the zip file for the archive.
jjg@424 155 */
jjg@424 156 protected Reference<File> absFileRef;
jjg@57 157
jjg@57 158 /**
jjg@57 159 * A subclass of JavaFileObject representing zip entries.
jjg@57 160 */
jjg@57 161 public static class ZipFileObject extends BaseFileObject {
jjg@57 162
jjg@57 163 private String name;
jjg@57 164 ZipArchive zarch;
jjg@57 165 ZipEntry entry;
jjg@57 166
jjg@103 167 protected ZipFileObject(ZipArchive zarch, String name, ZipEntry entry) {
jjg@57 168 super(zarch.fileManager);
jjg@57 169 this.zarch = zarch;
jjg@57 170 this.name = name;
jjg@57 171 this.entry = entry;
jjg@57 172 }
jjg@57 173
jjg@415 174 public URI toUri() {
jjg@424 175 File zipFile = new File(zarch.zfile.getName());
jjg@415 176 return createJarUri(zipFile, entry.getName());
jjg@415 177 }
jjg@415 178
jjg@415 179 @Override
jjg@415 180 public String getName() {
jjg@424 181 return zarch.zfile.getName() + "(" + entry.getName() + ")";
jjg@415 182 }
jjg@415 183
jjg@415 184 @Override
jjg@415 185 public String getShortName() {
jjg@424 186 return new File(zarch.zfile.getName()).getName() + "(" + entry + ")";
jjg@415 187 }
jjg@415 188
jjg@415 189 @Override
jjg@415 190 public JavaFileObject.Kind getKind() {
jjg@415 191 return getKind(entry.getName());
jjg@415 192 }
jjg@415 193
jjg@415 194 @Override
jjg@57 195 public InputStream openInputStream() throws IOException {
jjg@424 196 return zarch.zfile.getInputStream(entry);
jjg@57 197 }
jjg@57 198
jjg@415 199 @Override
jjg@57 200 public OutputStream openOutputStream() throws IOException {
jjg@57 201 throw new UnsupportedOperationException();
jjg@57 202 }
jjg@57 203
jjg@400 204 @Override
jjg@57 205 public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
jjg@57 206 CharBuffer cb = fileManager.getCachedContent(this);
jjg@57 207 if (cb == null) {
jjg@424 208 InputStream in = zarch.zfile.getInputStream(entry);
jjg@57 209 try {
jjg@57 210 ByteBuffer bb = fileManager.makeByteBuffer(in);
jjg@57 211 JavaFileObject prev = fileManager.log.useSource(this);
jjg@57 212 try {
jjg@57 213 cb = fileManager.decode(bb, ignoreEncodingErrors);
jjg@57 214 } finally {
jjg@57 215 fileManager.log.useSource(prev);
jjg@57 216 }
jjg@57 217 fileManager.recycleByteBuffer(bb);
jjg@57 218 if (!ignoreEncodingErrors) {
jjg@57 219 fileManager.cache(this, cb);
jjg@57 220 }
jjg@57 221 } finally {
jjg@57 222 in.close();
jjg@57 223 }
jjg@57 224 }
jjg@57 225 return cb;
jjg@57 226 }
jjg@57 227
jjg@57 228 @Override
jjg@415 229 public Writer openWriter() throws IOException {
jjg@415 230 throw new UnsupportedOperationException();
jjg@415 231 }
jjg@415 232
jjg@415 233 @Override
jjg@415 234 public long getLastModified() {
jjg@415 235 return entry.getTime();
jjg@415 236 }
jjg@415 237
jjg@415 238 @Override
jjg@415 239 public boolean delete() {
jjg@415 240 throw new UnsupportedOperationException();
jjg@415 241 }
jjg@415 242
jjg@415 243 @Override
jjg@415 244 protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
jjg@415 245 return fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors);
jjg@415 246 }
jjg@415 247
jjg@415 248 @Override
jjg@415 249 protected String inferBinaryName(Iterable<? extends File> path) {
jjg@415 250 String entryName = entry.getName();
jjg@415 251 return removeExtension(entryName).replace('/', '.');
jjg@415 252 }
jjg@415 253
jjg@415 254 @Override
jjg@415 255 public boolean isNameCompatible(String cn, JavaFileObject.Kind k) {
jjg@415 256 cn.getClass();
jjg@415 257 // null check
jjg@415 258 if (k == Kind.OTHER && getKind() != k) {
jjg@415 259 return false;
jjg@415 260 }
jjg@415 261 return name.equals(cn + k.extension);
jjg@415 262 }
jjg@415 263
jjg@424 264 /**
jjg@424 265 * Check if two file objects are equal.
jjg@424 266 * Two ZipFileObjects are equal if the absolute paths of the underlying
jjg@424 267 * zip files are equal and if the paths within those zip files are equal.
jjg@424 268 */
jjg@415 269 @Override
jjg@57 270 public boolean equals(Object other) {
jjg@424 271 if (this == other)
jjg@424 272 return true;
jjg@424 273
jjg@424 274 if (!(other instanceof ZipFileObject))
jjg@57 275 return false;
jjg@424 276
jjg@57 277 ZipFileObject o = (ZipFileObject) other;
jjg@424 278 return zarch.getAbsoluteFile().equals(o.zarch.getAbsoluteFile())
jjg@424 279 && name.equals(o.name);
jjg@57 280 }
jjg@57 281
jjg@57 282 @Override
jjg@57 283 public int hashCode() {
jjg@424 284 return zarch.getAbsoluteFile().hashCode() + name.hashCode();
jjg@57 285 }
jjg@57 286 }
jjg@57 287
jjg@57 288 }

mercurial