package gnu.java.net.loader;

import gnu.java.net.IndexListParser;

import java.io.IOException;
import java.net.JarURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLStreamHandlerFactory;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;

/**
 * A <code>JarURLLoader</code> is a type of <code>URLLoader</code>
 * only loading from jar url.
 */
public final class JarURLLoader extends URLLoader
{
  // True if we've initialized -- i.e., tried open the jar file.
  boolean initialized;
  // The jar file for this url.
  JarFile jarfile;
  // Base jar: url for all resources loaded from jar.
  final URL baseJarURL;
  // The "Class-Path" attribute of this Jar's manifest.
  ArrayList classPath;
  // If not null, a mapping from INDEX.LIST for this jar only.
  // This is a set of all prefixes and top-level files that
  // ought to be available in this jar.
  Set indexSet;

  // This constructor is used internally.  It purposely does not open
  // the jar file -- it defers this until later.  This allows us to
  // implement INDEX.LIST lazy-loading semantics.
  private JarURLLoader(URLClassLoader classloader, URLStreamHandlerCache cache,
                       URLStreamHandlerFactory factory,
                       URL baseURL, URL absoluteUrl,
                       Set indexSet)
  {
    super(classloader, cache, factory, baseURL, absoluteUrl);

    URL newBaseURL = null;
    try
      {
        // Cache url prefix for all resources in this jar url.
        String base = baseURL.toExternalForm() + "!/";
        newBaseURL = new URL("jar", "", -1, base, cache.get(factory, "jar"));
      }
    catch (MalformedURLException ignore)
      {
        // Ignore.
      }
    this.baseJarURL = newBaseURL;
    this.classPath = null;
    this.indexSet = indexSet;
  }

  // This constructor is used by URLClassLoader.  It will immediately
  // try to read the jar file, in case we've found an index or a class-path
  // setting.  FIXME: it would be nice to defer this as well, but URLClassLoader
  // makes this hard.
  public JarURLLoader(URLClassLoader classloader, URLStreamHandlerCache cache,
                      URLStreamHandlerFactory factory,
                      URL baseURL, URL absoluteUrl)
  {
    this(classloader, cache, factory, baseURL, absoluteUrl, null);
    initialize();
  }

  private void initialize()
  {
    JarFile jarfile = null;
    try
      {
        jarfile =
          ((JarURLConnection) baseJarURL.openConnection()).getJarFile();
        
        Manifest manifest;
        Attributes attributes;
        String classPathString;

        IndexListParser parser = new IndexListParser(jarfile, baseJarURL,
                                                     baseURL);
        LinkedHashMap indexMap = parser.getHeaders();
        if (indexMap != null)
          {
            // Note that the index also computes
            // the resulting Class-Path -- there are jars out there
            // where the index lists some required jars which do
            // not appear in the Class-Path attribute in the manifest.
            this.classPath = new ArrayList();
            Iterator it = indexMap.entrySet().iterator();
            while (it.hasNext())
              {
                Map.Entry entry = (Map.Entry) it.next();
                URL subURL = (URL) entry.getKey();
                Set prefixes = (Set) entry.getValue();
                if (subURL.equals(baseURL))
                  this.indexSet = prefixes;
                else
                  {
                    JarURLLoader subLoader = new JarURLLoader(classloader,
                                                              cache,
                                                              factory, subURL,
                                                              subURL,
                                                              prefixes);
                    // Note that we don't care if the sub-loader itself has an
                    // index or a class-path -- only the top-level jar
                    // file gets this treatment; its index should cover
                    // everything.
                    this.classPath.add(subLoader);
                  }
              }
          }
        else if ((manifest = jarfile.getManifest()) != null
                 && (attributes = manifest.getMainAttributes()) != null
                 && ((classPathString
                      = attributes.getValue(Attributes.Name.CLASS_PATH)) 
                     != null))
          {
            this.classPath = new ArrayList();
            StringTokenizer st = new StringTokenizer(classPathString, " ");
            while (st.hasMoreElements ()) 
              {
                String e = st.nextToken ();
                try
                  {
                    URL subURL = new URL(baseURL, e);
                    // We've seen at least one jar file whose Class-Path
                    // attribute includes the original jar.  If we process
                    // that normally we end up with infinite recursion.
                    if (subURL.equals(baseURL))
                      continue;
                    JarURLLoader subLoader = new JarURLLoader(classloader,
                                                              cache, factory,
                                                              subURL, subURL);
                    this.classPath.add(subLoader);
                    ArrayList extra = subLoader.getClassPath();
                    if (extra != null)
                      this.classPath.addAll(extra);
                  }
                catch (java.net.MalformedURLException xx)
                  {
                    // Give up
                  }
              }
          }
      }
    catch (IOException ioe)
      {
        /* ignored */
      }

    this.jarfile = jarfile;
    this.initialized = true;
  }

  /** get resource with the name "name" in the jar url */
  public Resource getResource(String name)
  {
    if (name.startsWith("/"))
      name = name.substring(1);
    if (indexSet != null)
      {
        // Trust the index.
        String basename = name;
        int offset = basename.lastIndexOf('/');
        if (offset != -1)
          basename = basename.substring(0, offset);
        if (! indexSet.contains(basename))
          return null;
        // FIXME: if the index claim to hold the resource, and jar file
        // doesn't have it, we're supposed to throw an exception.  However,
        // in our model this is tricky to implement, as another URLLoader from
        // the same top-level jar may have an overlapping index entry.
      }

    if (! initialized)
      initialize();
    if (jarfile == null)
      return null;

    JarEntry je = jarfile.getJarEntry(name);
    if (je != null)
      return new JarURLResource(this, name, je);
    else
      return null;
  }

  public Manifest getManifest()
  {
    try
      {
        return (jarfile == null) ? null : jarfile.getManifest();
      }
    catch (IOException ioe)
      {
        return null;
      }
  }

  public ArrayList getClassPath()
  {
    return classPath;
  }
}
