/* IndexListParser.java -- 
   Copyright (C) 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.java.net;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.jar.JarFile;

/**
 * The INDEX.LIST file contains sections each separated by a blank line. 
 * Each section defines the content of a jar, with a
 * header defining the jar file path name, followed by a list of paths.
 * The jar file paths are relative to the codebase of the root jar.
 * 
    Specification
    index file :            version-info blankline section*
    version-info :          JarIndex-Version: version-number
    version-number :        digit+{.digit+}*
    section :               body blankline
    body :                  header name*
    header :                char+.jar newline
    name :                  char+ newline
    
 * @author langel at redhat dot com
 */
public class IndexListParser
{
  public static final String JAR_INDEX_FILE = "META-INF/INDEX.LIST";
  public static final String JAR_INDEX_VERSION_KEY = "JarIndex-Version: ";

  double versionNumber;
  // Map each jar to the prefixes defined for the jar.
  // This is intentionally kept in insertion order.
  LinkedHashMap prefixes = new LinkedHashMap();
  
  /**
   * Parses the given jarfile's INDEX.LIST file if it exists.
   * 
   * @param jarfile - the given jar file
   * @param baseJarURL - the codebase of the jar file
   * @param baseURL - the base url for the headers
   */
  public IndexListParser(JarFile jarfile, URL baseJarURL, URL baseURL)
  {
    try
    {
    // Parse INDEX.LIST if it exists
    if (jarfile.getEntry(JAR_INDEX_FILE) != null)
      {
        BufferedReader br = new BufferedReader(new InputStreamReader(new URL(baseJarURL,
                                                                             JAR_INDEX_FILE).openStream()));
        
        // Must start with version info
        String line = br.readLine();
        if (!line.startsWith(JAR_INDEX_VERSION_KEY))
          return;
        versionNumber = Double.parseDouble(line.substring(JAR_INDEX_VERSION_KEY.length()).trim());
        
        // Blank line must be next
        line = br.readLine();
        if (! "".equals(line))
          {
            clearAll();
            return;
          }
        
        // May contain sections.
        while ((line = br.readLine()) != null)
          {
            URL jarURL = new URL(baseURL, line);
            HashSet values = new HashSet();
            
            // Read the names in the section.
            while ((line = br.readLine()) != null)
              {
                // Stop at section boundary.
                if ("".equals(line))
                  break;
                values.add(line.trim());
              }
            prefixes.put(jarURL, values);
            // Might have seen an early EOF.
            if (line == null)
              break;
          }

        br.close();
      }
    else
      {
        // INDEX.LIST does not exist
        clearAll();
      }
    }
    catch (Exception ex)
    {
      clearAll();
    }
  }
  
  /**
   * Clears all the variables. This is called when parsing fails.
   */
  void clearAll()
  {
    versionNumber = 0;
    prefixes = null;
  }
  
  /**
   * Gets the version info for the file.
   * 
   * @return the version info.
   */
  public String getVersionInfo()
  {
    return JAR_INDEX_VERSION_KEY + getVersionNumber();
  }
  
  /**
   * Gets the version number of the file.
   * 
   * @return the version number.
   */
  public double getVersionNumber()
  {
    return versionNumber;
  }
  
  /**
   * Gets the map of all the headers found in the file.
   * The keys in the map are URLs of jars.  The values in the map
   * are Sets of package prefixes (and top-level file names), as
   * specifed in INDEX.LIST.
   * 
   * @return an map of all the headers, or null if no INDEX.LIST was found
   */
  public LinkedHashMap getHeaders()
  {
    return prefixes;
  }
}
