1 /* IndexListParser.java -- 2 Copyright (C) 2006 Free Software Foundation, Inc. 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 39 package gnu.java.net; 40 41 import java.io.BufferedReader; 42 import java.io.InputStreamReader; 43 import java.net.URL; 44 import java.util.HashSet; 45 import java.util.LinkedHashMap; 46 import java.util.Set; 47 import java.util.jar.JarFile; 48 49 /** 50 * The INDEX.LIST file contains sections each separated by a blank line. 51 * Each section defines the content of a jar, with a 52 * header defining the jar file path name, followed by a list of paths. 53 * The jar file paths are relative to the codebase of the root jar. 54 * 55 Specification 56 index file : version-info blankline section* 57 version-info : JarIndex-Version: version-number 58 version-number : digit+{.digit+}* 59 section : body blankline 60 body : header name* 61 header : char+.jar newline 62 name : char+ newline 63 64 * @author langel at redhat dot com 65 */ 66 public class IndexListParser 67 { 68 public static final String JAR_INDEX_FILE = "META-INF/INDEX.LIST"; 69 public static final String JAR_INDEX_VERSION_KEY = "JarIndex-Version: "; 70 71 double versionNumber; 72 // Map each jar to the prefixes defined for the jar. 73 // This is intentionally kept in insertion order. 74 LinkedHashMap<URL, Set<String>> prefixes 75 = new LinkedHashMap<URL, Set<String>>(); 76 77 /** 78 * Parses the given jarfile's INDEX.LIST file if it exists. 79 * 80 * @param jarfile - the given jar file 81 * @param baseJarURL - the codebase of the jar file 82 * @param baseURL - the base url for the headers 83 */ IndexListParser(JarFile jarfile, URL baseJarURL, URL baseURL)84 public IndexListParser(JarFile jarfile, URL baseJarURL, URL baseURL) 85 { 86 try 87 { 88 // Parse INDEX.LIST if it exists 89 if (jarfile.getEntry(JAR_INDEX_FILE) != null) 90 { 91 BufferedReader br = new BufferedReader(new InputStreamReader(new URL(baseJarURL, 92 JAR_INDEX_FILE).openStream())); 93 94 // Must start with version info 95 String line = br.readLine(); 96 if (!line.startsWith(JAR_INDEX_VERSION_KEY)) 97 return; 98 versionNumber = Double.parseDouble(line.substring(JAR_INDEX_VERSION_KEY.length()).trim()); 99 100 // Blank line must be next 101 line = br.readLine(); 102 if (! "".equals(line)) 103 { 104 clearAll(); 105 return; 106 } 107 108 // May contain sections. 109 while ((line = br.readLine()) != null) 110 { 111 URL jarURL = new URL(baseURL, line); 112 HashSet<String> values = new HashSet<String>(); 113 114 // Read the names in the section. 115 while ((line = br.readLine()) != null) 116 { 117 // Stop at section boundary. 118 if ("".equals(line)) 119 break; 120 values.add(line.trim()); 121 } 122 prefixes.put(jarURL, values); 123 // Might have seen an early EOF. 124 if (line == null) 125 break; 126 } 127 128 br.close(); 129 } 130 else 131 { 132 // INDEX.LIST does not exist 133 clearAll(); 134 } 135 } 136 catch (Exception ex) 137 { 138 clearAll(); 139 } 140 } 141 142 /** 143 * Clears all the variables. This is called when parsing fails. 144 */ clearAll()145 void clearAll() 146 { 147 versionNumber = 0; 148 prefixes = null; 149 } 150 151 /** 152 * Gets the version info for the file. 153 * 154 * @return the version info. 155 */ getVersionInfo()156 public String getVersionInfo() 157 { 158 return JAR_INDEX_VERSION_KEY + getVersionNumber(); 159 } 160 161 /** 162 * Gets the version number of the file. 163 * 164 * @return the version number. 165 */ getVersionNumber()166 public double getVersionNumber() 167 { 168 return versionNumber; 169 } 170 171 /** 172 * Gets the map of all the headers found in the file. 173 * The keys in the map are URLs of jars. The values in the map 174 * are Sets of package prefixes (and top-level file names), as 175 * specifed in INDEX.LIST. 176 * 177 * @return an map of all the headers, or null if no INDEX.LIST was found 178 */ getHeaders()179 public LinkedHashMap<URL, Set<String>> getHeaders() 180 { 181 return prefixes; 182 } 183 } 184