1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.net; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.Certificate; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.jar.Attributes; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.jar.JarEntry; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.jar.JarFile; 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.jar.Manifest; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class establishes a connection to a {@code jar:} URL using the {@code 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * JAR} protocol. A {@code JarURLConnection} instance can refer to either a JAR 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * archive file or to an entry of such a file. {@code jar:} URLs are specified 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * as follows: <i>jar:{archive-url}!/{entry}</i> where "!/" is called a 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * separator. This separator is important to determine if an archive or an entry 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of an archive is referred. 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Examples: 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>Archive: {@code jar:http://www.example.com/applets/archive.jar!/}</li> 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>File Entry: {@code 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * jar:http://www.example.com/applets/archive.jar!/test.class}</li> 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>Directory Entry: {@code 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * jar:http://www.example.com/applets/archive.jar!/applets/}</li> 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic abstract class JarURLConnection extends URLConnection { 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The location part of the represented URL. 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected URLConnection jarFileURLConnection; 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private String entryName; 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private URL fileURL; 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // the file component of the URL 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private String file; 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs an instance of {@code JarURLConnection} that refers to the 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified URL. 59f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param url 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the URL that contains the location to connect to. 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws MalformedURLException 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an invalid URL has been entered. 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected JarURLConnection(URL url) throws MalformedURLException { 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(url); 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project file = url.getFile(); 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int sepIdx; 69f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes if ((sepIdx = file.indexOf("!/")) < 0) { 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new MalformedURLException(); 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 725839b909d9528b7726e678a4b696ed37df15d897Jesse Wilson fileURL = new URL(url.getFile().substring(0,sepIdx)); 73f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson sepIdx += 2; 74f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (file.length() == sepIdx) { 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 77f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson entryName = file.substring(sepIdx, file.length()); 78b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (url.getRef() != null) { 79f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes entryName += "#" + url.getRef(); 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns all attributes of the {@code JarEntry} referenced by this {@code 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * JarURLConnection}. 86f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the attributes of the referenced {@code JarEntry}. 88f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws IOException 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an I/O exception occurs while retrieving the 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * JAR-entries. 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Attributes getAttributes() throws java.io.IOException { 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project JarEntry jEntry = getJarEntry(); 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (jEntry == null) ? null : jEntry.getAttributes(); 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns all certificates of the {@code JarEntry} referenced by this 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code JarURLConnection} instance. This method will return {@code null} 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * until the {@code InputStream} has been completely verified. 101f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the certificates of the {@code JarEntry} as an array. 103f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws IOException 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if there is an I/O exception occurs while getting the 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code JarEntry}. 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Certificate[] getCertificates() throws java.io.IOException { 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project JarEntry jEntry = getJarEntry(); 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (jEntry == null) { 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return jEntry.getCertificates(); 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the name of the entry referenced by this {@code JarURLConnection}. 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The return value will be {@code null} if this instance refers to a JAR 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * file rather than an JAR file entry. 120f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the {@code JarEntry} name this instance refers to. 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getEntryName() { 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return entryName; 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the {@code JarEntry} object of the entry referenced by this {@code 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * JarURLConnection}. 130f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the referenced {@code JarEntry} object or {@code null} if no 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * entry name is specified. 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while getting the file or file-entry. 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public JarEntry getJarEntry() throws IOException { 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!connected) { 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project connect(); 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (entryName == null) { 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // The entry must exist since the connect succeeded 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return getJarFile().getJarEntry(entryName); 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the manifest file associated with this JAR-URL. 149f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the manifest of the referenced JAR-file. 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while getting the manifest file. 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Manifest getManifest() throws java.io.IOException { 155f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return (Manifest)getJarFile().getManifest().clone(); 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the {@code JarFile} object referenced by this {@code 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * JarURLConnection}. 161f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the referenced JarFile object. 163f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws IOException 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an I/O exception occurs while retrieving the JAR-file. 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract JarFile getJarFile() throws java.io.IOException; 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the URL to the JAR-file referenced by this {@code JarURLConnection}. 170f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the URL to the JAR-file or {@code null} if there was an error 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * retrieving the URL. 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public URL getJarFileURL() { 175f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return fileURL; 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets all attributes of the manifest file referenced by this {@code 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * JarURLConnection}. If this instance refers to a JAR-file rather than a 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * JAR-file entry, {@code null} will be returned. 182f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the attributes of the manifest file or {@code null}. 184f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws IOException 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an I/O exception occurs while retrieving the {@code 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * JarFile}. 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Attributes getMainAttributes() throws java.io.IOException { 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Manifest m = getJarFile().getManifest(); 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (m == null) ? null : m.getMainAttributes(); 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 193