151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 248faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.misc; 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.*; 2948faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniakimport java.security.AccessController; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.*; 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.jar.*; 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.zip.*; 3348faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniakimport sun.security.action.GetPropertyAction; 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This class is used to maintain mappings from packages, classes 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and resources to their enclosing JAR files. Mappings are kept 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * at the package level except for class or resource files that 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * are located at the root directory. URLClassLoader uses the mapping 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * information to determine where to fetch an extension class or 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * resource from. 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Zhenghua Li 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.3 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class JarIndex { 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The hash map that maintains mappings from 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * package/classe/resource to jar file list(s) 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 5348faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak private HashMap<String,LinkedList<String>> indexMap; 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The hash map that maintains mappings from 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * jar file to package/class/resource lists 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 5948faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak private HashMap<String,LinkedList<String>> jarMap; 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * An ordered list of jar file names. 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private String[] jarFiles; 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The index file name. 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final String INDEX_NAME = "META-INF/INDEX.LIST"; 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * true if, and only if, sun.misc.JarIndex.metaInfFilenames is set to true. 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If true, the names of the files in META-INF, and its subdirectories, will 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * be added to the index. Otherwise, just the directory names are added. 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final boolean metaInfFilenames = 7748faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak "true".equals(AccessController.doPrivileged( 7848faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak new GetPropertyAction("sun.misc.JarIndex.metaInfFilenames"))); 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Constructs a new, empty jar index. 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public JarIndex() { 8448faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak indexMap = new HashMap<>(); 8548faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak jarMap = new HashMap<>(); 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Constructs a new index from the specified input stream. 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param is the input stream containing the index data 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public JarIndex(InputStream is) throws IOException { 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this(); 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski read(is); 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Constructs a new index for the specified list of jar files. 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param files the list of jar files to construct the index from. 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public JarIndex(String[] files) throws IOException { 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this(); 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.jarFiles = files; 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski parseJars(files); 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the jar index, or <code>null</code> if none. 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This single parameter version of the method is retained 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * for binary compatibility with earlier releases. 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param jar the JAR file to get the index from. 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException if an I/O error has occurred. 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static JarIndex getJarIndex(JarFile jar) throws IOException { 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getJarIndex(jar, null); 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the jar index, or <code>null</code> if none. 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param jar the JAR file to get the index from. 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException if an I/O error has occurred. 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static JarIndex getJarIndex(JarFile jar, MetaIndex metaIndex) throws IOException { 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JarIndex index = null; 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* If metaIndex is not null, check the meta index to see 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if META-INF/INDEX.LIST is contained in jar file or not. 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (metaIndex != null && 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski !metaIndex.mayContain(INDEX_NAME)) { 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JarEntry e = jar.getJarEntry(INDEX_NAME); 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if found, then load the index 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (e != null) { 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski index = new JarIndex(jar.getInputStream(e)); 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return index; 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the jar files that are defined in this index. 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String[] getJarFiles() { 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return jarFiles; 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Add the key, value pair to the hashmap, the value will 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * be put in a linked list which is created if necessary. 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 15648faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak private void addToList(String key, String value, 15748faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak HashMap<String,LinkedList<String>> t) { 15848faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak LinkedList<String> list = t.get(key); 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (list == null) { 16048faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak list = new LinkedList<>(); 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski list.add(value); 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski t.put(key, list); 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (!list.contains(value)) { 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski list.add(value); 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the list of jar files that are mapped to the file. 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param fileName the key of the mapping 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 17348faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak public LinkedList<String> get(String fileName) { 17448faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak LinkedList<String> jarFiles = null; 17548faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak if ((jarFiles = indexMap.get(fileName)) == null) { 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* try the package name again */ 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int pos; 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if((pos = fileName.lastIndexOf("/")) != -1) { 17948faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak jarFiles = indexMap.get(fileName.substring(0, pos)); 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return jarFiles; 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Add the mapping from the specified file to the specified 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * jar file. If there were no mapping for the package of the 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * specified file before, a new linked list will be created, 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the jar file is added to the list and a new mapping from 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the package to the jar file list is added to the hashmap. 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Otherwise, the jar file will be added to the end of the 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * existing list. 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param fileName the file name 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param jarName the jar file that the file is mapped to 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void add(String fileName, String jarName) { 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String packageName; 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int pos; 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if((pos = fileName.lastIndexOf("/")) != -1) { 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski packageName = fileName.substring(0, pos); 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski packageName = fileName; 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20748faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak addMapping(packageName, jarName); 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Same as add(String,String) except that it doesn't strip off from the 21248faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak * last index of '/'. It just adds the jarItem (filename or package) 21348faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak * as it is received. 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 21548faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak private void addMapping(String jarItem, String jarName) { 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // add the mapping to indexMap 21748faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak addToList(jarItem, jarName, indexMap); 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // add the mapping to jarMap 22048faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak addToList(jarName, jarItem, jarMap); 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Go through all the jar files and construct the 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * index table. 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void parseJars(String[] files) throws IOException { 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (files == null) { 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String currentJar = null; 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < files.length; i++) { 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski currentJar = files[i]; 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ZipFile zrf = new ZipFile(currentJar.replace 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ('/', File.separatorChar)); 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23948faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak Enumeration<? extends ZipEntry> entries = zrf.entries(); 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while(entries.hasMoreElements()) { 24148faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak ZipEntry entry = entries.nextElement(); 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String fileName = entry.getName(); 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Skip the META-INF directory, the index, and manifest. 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Any files in META-INF/ will be indexed explicitly 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (fileName.equals("META-INF/") || 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski fileName.equals(INDEX_NAME) || 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski fileName.equals(JarFile.MANIFEST_NAME)) 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25148faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak if (!metaInfFilenames || !fileName.startsWith("META-INF/")) { 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski add(fileName, currentJar); 25348faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak } else if (!entry.isDirectory()) { 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Add files under META-INF explicitly so that certain 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // services, like ServiceLoader, etc, can be located 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // with greater accuracy. Directories can be skipped 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // since each file will be added explicitly. 25848faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak addMapping(fileName, currentJar); 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski zrf.close(); 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Writes the index to the specified OutputStream 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param out the output stream 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException if an I/O error has occurred 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void write(OutputStream out) throws IOException { 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski BufferedWriter bw = new BufferedWriter 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (new OutputStreamWriter(out, "UTF8")); 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bw.write("JarIndex-Version: 1.0\n\n"); 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (jarFiles != null) { 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < jarFiles.length; i++) { 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* print out the jar file name */ 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String jar = jarFiles[i]; 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bw.write(jar + "\n"); 28248faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak LinkedList<String> jarlist = jarMap.get(jar); 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (jarlist != null) { 28448faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak Iterator<String> listitr = jarlist.iterator(); 28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while(listitr.hasNext()) { 28648faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak bw.write(listitr.next() + "\n"); 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bw.write("\n"); 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bw.flush(); 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads the index from the specified InputStream. 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param is the input stream 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException if an I/O error has occurred 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void read(InputStream is) throws IOException { 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski BufferedReader br = new BufferedReader 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (new InputStreamReader(is, "UTF8")); 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String line = null; 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String currentJar = null; 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* an ordered list of jar file names */ 30948faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak Vector<String> jars = new Vector<>(); 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* read until we see a .jar line */ 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while((line = br.readLine()) != null && !line.endsWith(".jar")); 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for(;line != null; line = br.readLine()) { 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (line.length() == 0) 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (line.endsWith(".jar")) { 31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski currentJar = line; 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jars.add(currentJar); 32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String name = line; 32348faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak addMapping(name, currentJar); 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 32748faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak jarFiles = jars.toArray(new String[jars.size()]); 32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Merges the current index into another index, taking into account 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the relative path of the current index. 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param toIndex The destination index which the current index will 33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * merge into. 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param path The relative path of the this index to the destination 33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * index. 33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void merge(JarIndex toIndex, String path) { 34148faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak Iterator<Map.Entry<String,LinkedList<String>>> itr = indexMap.entrySet().iterator(); 34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while(itr.hasNext()) { 34348faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak Map.Entry<String,LinkedList<String>> e = itr.next(); 34448faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak String packageName = e.getKey(); 34548faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak LinkedList<String> from_list = e.getValue(); 34648faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak Iterator<String> listItr = from_list.iterator(); 34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while(listItr.hasNext()) { 34848faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak String jarName = listItr.next(); 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (path != null) { 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jarName = path.concat(jarName); 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35248faf4ee21028b39dac2b459f0b560d743426801Przemyslaw Szczepaniak toIndex.addMapping(packageName, jarName); 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 357