JarURLConnectionImpl.java revision f6c387128427e121477c1b32ad35cdcaa5101ba3
1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this work for additional information regarding copyright ownership. 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (the "License"); you may not use this file except in compliance with 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the License. You may obtain a copy of the License at 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage org.apache.harmony.luni.internal.net.www.protocol.jar; 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.File; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.FileNotFoundException; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.FileOutputStream; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.FilterInputStream; 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.IOException; 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.InputStream; 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.lang.ref.ReferenceQueue; 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.lang.ref.WeakReference; 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.net.ContentHandler; 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.net.ContentHandlerFactory; 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.net.MalformedURLException; 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.net.URL; 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.AccessController; 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.Permission; 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.PrivilegedAction; 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Comparator; 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Date; 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Enumeration; 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Hashtable; 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.TreeSet; 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.jar.JarEntry; 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.jar.JarFile; 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.zip.ZipFile; 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// BEGIN android-removed 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// import org.apache.harmony.kernel.vm.VM; 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// END android-removed 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.luni.util.Msg; 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.luni.util.Util; 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This subclass extends <code>URLConnection</code>. 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p> 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This class is responsible for connecting and retrieving resources from a Jar 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * file which can be anywhere that can be refered to by an URL. 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class JarURLConnection extends java.net.JarURLConnection { 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static Hashtable<String, CacheEntry<? extends JarFile>> jarCache = new Hashtable<String, CacheEntry<?>>(); 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InputStream jarInput; 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private JarFile jarFile; 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private JarEntry jarEntry; 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private boolean closed; 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ReferenceQueue<JarFile> cacheQueue = new ReferenceQueue<JarFile>(); 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static TreeSet<LRUKey> lru = new TreeSet<LRUKey>( 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new LRUComparator<LRUKey>()); 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static int Limit; 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static { 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Limit = AccessController.doPrivileged(new PrivilegedAction<Integer>() { 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Integer run() { 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return Integer.getInteger("jar.cacheSize", 500); //$NON-NLS-1$ 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project }); 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // BEGIN android-removed 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // TODO this needs to be implemented once this is available. 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // VM.closeJars(); 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // END android-removed 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static final class CacheEntry<T extends JarFile> extends WeakReference<T> { 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object key; 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CacheEntry(T jar, String key, ReferenceQueue<JarFile> queue) { 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super(jar, queue); 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.key = key; 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static final class LRUKey { 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JarFile jar; 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long ts; 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LRUKey(JarFile file, long time) { 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project jar = file; 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ts = time; 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see java.lang.Object#equals(java.lang.Object) 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean equals(Object obj) { 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (obj instanceof LRUKey) && 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (jar == ((LRUKey) obj).jar); 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int hashCode() { 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return jar.hashCode(); 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static final class LRUComparator<T> implements Comparator<LRUKey> { 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LRUComparator() { 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int compare(LRUKey o1, LRUKey o2) { 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((o1).ts > (o2).ts) { 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (o1).ts == (o2).ts ? 0 : -1; 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param o1 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * an object to compare 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param o2 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * an object to compare 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return <code>true</code> if the objects are equal, 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <code>false</code> otherwise. 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean equals(Object o1, Object o2) { 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return o1.equals(o2); 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param url 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the URL of the JAR 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws MalformedURLException 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the URL is malformed 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public JarURLConnection(java.net.URL url) throws MalformedURLException { 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super(url); 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see java.net.URLConnection#connect() 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void connect() throws IOException { 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project jarFileURLConnection = getJarFileURL().openConnection(); 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project findJarFile(); // ensure the file can be found 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project findJarEntry(); // ensure the entry, if any, can be found 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project connected = true; 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the Jar file refered by this <code>URLConnection</code> 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the JAR file referenced by this connection 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * thrown if an IO error occurs while connecting to the 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * resource. 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public JarFile getJarFile() throws IOException { 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!connected) { 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project connect(); 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return jarFile; 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the Jar file refered by this <code>URLConnection</code> 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if an IO error occurs while connecting to the resource. 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void findJarFile() throws IOException { 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project URL jarFileURL = getJarFileURL(); 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (jarFileURL.getProtocol().equals("file")) { //$NON-NLS-1$ 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String fileName = jarFileURL.getFile(); 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if(!new File(Util.decode(fileName,false)).exists()){ 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // KA026=JAR entry {0} not found in {1} 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new FileNotFoundException(Msg.getString("KA026", //$NON-NLS-1$ 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project getEntryName(), fileName)); 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String host = jarFileURL.getHost(); 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (host != null && host.length() > 0) { 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fileName = "//" + host + fileName; //$NON-NLS-1$ 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project jarFile = openJarFile(fileName, fileName, false); 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project final String externalForm = jarFileURLConnection.getURL() 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .toExternalForm(); 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project jarFile = AccessController 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .doPrivileged(new PrivilegedAction<JarFile>() { 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public JarFile run() { 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return openJarFile(null, externalForm, false); 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (IOException e) { 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project }); 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (jarFile != null) { 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Build a temp jar file 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project final InputStream is = jarFileURLConnection.getInputStream(); 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project jarFile = AccessController 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .doPrivileged(new PrivilegedAction<JarFile>() { 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public JarFile run() { 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project File tempJar = File.createTempFile("hyjar_", //$NON-NLS-1$ 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ".tmp", null); //$NON-NLS-1$ 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FileOutputStream fos = new FileOutputStream( 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tempJar); 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] buf = new byte[4096]; 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nbytes = 0; 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while ((nbytes = is.read(buf)) > -1) { 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fos.write(buf, 0, nbytes); 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fos.close(); 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String path = tempJar.getPath(); 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return openJarFile(path, externalForm, true); 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (IOException e) { 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project }); 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } finally { 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project is.close(); 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (jarFile == null) { 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IOException(); 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JarFile openJarFile(String fileString, String key, boolean temp) 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException { 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JarFile jar = null; 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (useCaches) { 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CacheEntry<? extends JarFile> entry; 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while ((entry = (CacheEntry<? extends JarFile>) cacheQueue.poll()) != null) { 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project jarCache.remove(entry.key); 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project entry = jarCache.get(key); 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (entry != null) { 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project jar = entry.get(); 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (jar == null && fileString != null) { 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int flags = ZipFile.OPEN_READ 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project + (temp ? ZipFile.OPEN_DELETE : 0); 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project jar = new JarFile(new File(Util.decode(fileString, false)), 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project true, flags); 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project jarCache 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .put(key, new CacheEntry<JarFile>(jar, key, cacheQueue)); 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SecurityManager security = System.getSecurityManager(); 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (security != null) { 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project security.checkPermission(getPermission()); 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (temp) { 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lru.remove(new LRUKey(jar, 0)); 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (fileString != null) { 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int flags = ZipFile.OPEN_READ + (temp ? ZipFile.OPEN_DELETE : 0); 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project jar = new JarFile(new File(Util.decode(fileString, false)), true, 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project flags); 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (temp) { 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lru.add(new LRUKey(jar, new Date().getTime())); 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (lru.size() > Limit) { 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lru.remove(lru.first()); 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return jar; 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the JarEntry of the entry referenced by this 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <code>URLConnection</code>. 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return java.util.jar.JarEntry the JarEntry referenced 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if an IO error occurs while getting the entry 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public JarEntry getJarEntry() throws IOException { 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!connected) { 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project connect(); 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return jarEntry; 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Look up the JarEntry of the entry referenced by this 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <code>URLConnection</code>. 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void findJarEntry() throws IOException { 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (getEntryName() == null) { 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project jarEntry = jarFile.getJarEntry(getEntryName()); 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (jarEntry == null) { 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new FileNotFoundException(getEntryName()); 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Creates an input stream for reading from this URL Connection. 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the input stream 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if an IO error occurs while connecting to the resource. 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public InputStream getInputStream() throws IOException { 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (closed) { 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalStateException(Msg.getString("KA027")); 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!connected) { 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project connect(); 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (jarInput != null) { 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return jarInput; 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (jarEntry == null) { 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IOException(Msg.getString("K00fc")); //$NON-NLS-1$ 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return jarInput = new JarURLConnectionInputStream(jarFile 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .getInputStream(jarEntry), jarFile); 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the content type of the resource. Test cases reveal that only if 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the URL is refering to a Jar file, that this method returns a non-null 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * value - x-java/jar. 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the content type 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String getContentType() { 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // it could also return "x-java/jar" which jdk returns but here, we get 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // it from the URLConnection 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (url.getFile().endsWith("!/")) { //$NON-NLS-1$ 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return getJarFileURL().openConnection().getContentType(); 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (IOException ioe) { 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Ignore 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // if there is an Jar Entry, get the content type from the name 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return guessContentTypeFromName(url.getFile()); 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the content length of the resource. Test cases reveal that if the 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * URL is refering to a Jar file, this method returns a content-length 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * returned by URLConnection. If not, it will return -1. 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the content length 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getContentLength() { 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (url.getFile().endsWith("!/")) { //$NON-NLS-1$ 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return getJarFileURL().openConnection().getContentLength(); 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (IOException e) { 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //Ignored 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the object pointed by this <code>URL</code>. If this 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * URLConnection is pointing to a Jar File (no Jar Entry), this method will 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return a <code>JarFile</code> If there is a Jar Entry, it will return 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the object corresponding to the Jar entry content type. 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return a non-null object 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if an IO error occured 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see ContentHandler 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see ContentHandlerFactory 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see java.io.IOException 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see #setContentHandlerFactory(ContentHandlerFactory) 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Object getContent() throws IOException { 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!connected) { 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project connect(); 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // if there is no Jar Entry, return a JarFile 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (jarEntry == null) { 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return jarFile; 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return super.getContent(); 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the permission, in this case the subclass, FilePermission object 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * which represents the permission necessary for this URLConnection to 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * establish the connection. 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the permission required for this URLConnection. 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * thrown when an IO exception occurs while creating the 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * permission. 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Permission getPermission() throws IOException { 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (jarFileURLConnection != null) { 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return jarFileURLConnection.getPermission(); 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return getJarFileURL().openConnection().getPermission(); 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Closes the cached files. 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static void closeCachedFiles() { 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Enumeration<CacheEntry<? extends JarFile>> elemEnum = jarCache 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .elements(); 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (elemEnum.hasMoreElements()) { 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ZipFile zip = elemEnum.nextElement().get(); 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (zip != null) { 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project zip.close(); 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (IOException e) { 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Ignored 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private class JarURLConnectionInputStream extends FilterInputStream { 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InputStream inputStream; 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JarFile jarFile; 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected JarURLConnectionInputStream(InputStream in, JarFile file) { 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super(in); 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project inputStream = in; 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project jarFile = file; 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void close() throws IOException { 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super.close(); 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!useCaches) { 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project closed = true; 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project jarFile.close(); 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int read() throws IOException { 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return inputStream.read(); 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int read(byte[] buf, int off, int nbytes) throws IOException { 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return inputStream.read(buf, off, nbytes); 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public long skip(long nbytes) throws IOException { 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return inputStream.skip(nbytes); 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 503