/* RMIClassLoaderImpl.java -- FIXME: briefly describe file purpose
   Copyright (C) 2005, 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.rmi.server;

import gnu.java.lang.CPStringBuilder;

import java.lang.reflect.Proxy;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.rmi.server.RMIClassLoaderSpi;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Map;
import java.util.StringTokenizer;

/**
 * The default implementation of {@link java.rmi.server.RMIClassLoaderSpi}.
 *
 * @author Roman Kennke (kennke@aicas.com)
 */
public class RMIClassLoaderImpl extends RMIClassLoaderSpi
{
  private static class MyClassLoader extends URLClassLoader
  {
    // Package-private to avoid a trampoline constructor.
    MyClassLoader (URL[] urls, ClassLoader parent, String annotation)
    {
      super (urls, parent);
      this.annotation = annotation;
    }

    public static String urlToAnnotation (URL[] urls)
    {
      if (urls.length == 0)
        return null;

      CPStringBuilder annotation = new CPStringBuilder (64 * urls.length);

      for (int i = 0; i < urls.length; i++)
      {
        annotation.append (urls [i].toExternalForm());
        annotation.append (' ');
      }

      return annotation.toString();
    }

    public final String getClassAnnotation()
    {
      return annotation;
    }

    private final String annotation;
  }

  /**
   * This class is used to identify a cached classloader by its codebase and
   * the context classloader that is its parent.
   */
  private static class CacheKey
  {
     private String mCodeBase;
     private ClassLoader mContextClassLoader;

     public CacheKey (String theCodebase, ClassLoader theContextClassLoader)
     {
       mCodeBase = theCodebase;
       mContextClassLoader = theContextClassLoader;
     }

    /**
     * @return true if the codebase and the context classloader are equal
     */
    public boolean equals (Object theOther)
    {
      if (theOther instanceof CacheKey)
      {
        CacheKey key = (CacheKey) theOther;

        return (equals (this.mCodeBase,key.mCodeBase)
                && equals (this.mContextClassLoader, key.mContextClassLoader));
        }
      return false;
    }

    /**
     * Test if the two objects are equal or both null.
     * @param theOne
     * @param theOther
     * @return
     */
    private boolean equals (Object theOne, Object theOther)
    {
      return theOne != null ? theOne.equals (theOther) : theOther == null;
    }

    /**
     * @return hashCode
     */
    public int hashCode()
    {
      return ((mCodeBase != null           ? mCodeBase.hashCode()           :  0)
              ^(mContextClassLoader != null ? mContextClassLoader.hashCode() : -1));
    }

    public String toString()
    {
      return "[" + mCodeBase + "," + mContextClassLoader + "]";
    }

  }

  private static RMIClassLoaderImpl instance = null;

  private static Map cacheLoaders; //map annotations to loaders
  private static Map cacheAnnotations; //map loaders to annotations
  //class loader for defaultAnnotation
  private static MyClassLoader defaultClassLoader;

  //defaultAnnotation is got from system property
  // "java.rmi.server.defaultAnnotation"
  private static String defaultAnnotation;

  //URL object for defaultAnnotation
  private static URL defaultCodebase;

  static
  {
    // 89 is a nice prime number for Hashtable initial capacity
    cacheLoaders = new Hashtable (89);
    cacheAnnotations = new Hashtable (89);

    defaultAnnotation = System.getProperty ("java.rmi.server.defaultAnnotation");

    try
      {
        if (defaultAnnotation != null)
          defaultCodebase = new URL (defaultAnnotation);
      }
    catch (Exception _)
      {
        defaultCodebase = null;
      }

    if (defaultCodebase != null)
      {
        defaultClassLoader = new MyClassLoader (new URL[] { defaultCodebase }, null,
                                               defaultAnnotation);
        // XXX using getContextClassLoader here *cannot* be right
        cacheLoaders.put (new CacheKey (defaultAnnotation,
                                        Thread.currentThread().getContextClassLoader()),
                                        defaultClassLoader);
      }
    }

  /**
   * This is a singleton class and may only be instantiated once from within
   * the {@link #getInstance} method.
   */
  private RMIClassLoaderImpl()
  {
  }

  /**
   * Returns an instance of RMIClassLoaderImpl.
   *
   * @return an instance of RMIClassLoaderImpl
   */
  public static RMIClassLoaderSpi getInstance()
  {
    if (instance == null)
      instance = new RMIClassLoaderImpl();
    return instance;
  }

  public Class loadClass(String codeBase, String name,
                         ClassLoader defaultLoader)
    throws MalformedURLException, ClassNotFoundException
  {
    try
      {
        if (defaultLoader != null)
            return Class.forName(name, false, defaultLoader);
      }
    catch (ClassNotFoundException e)
      {
      }

    return Class.forName(name, false, getClassLoader(codeBase));
  }

  public Class loadProxyClass(String codeBase, String[] interfaces,
                              ClassLoader defaultLoader)
      throws MalformedURLException, ClassNotFoundException
  {
    Class clss[] = new Class[interfaces.length];

    for (int i = 0; i < interfaces.length; i++)
      {
        clss[i] = loadClass(codeBase, interfaces[i], defaultLoader);
      }

    // Chain all class loaders (they may differ).
    ArrayList loaders = new ArrayList(clss.length);
    ClassLoader loader = null;
    for (int i = 0; i < clss.length; i++)
      {
        loader = clss[i].getClassLoader();
        if (! loaders.contains(loader))
          {
            loaders.add(0, loader);
          }
      }
    if (loaders.size() > 1)
      {
        loader = new CombinedClassLoader(loaders);
      }

    try
      {
        return Proxy.getProxyClass(loader, clss);
      }
    catch (IllegalArgumentException e)
      {
        throw new ClassNotFoundException(null, e);
      }
  }

  /**
   * Gets a classloader for the given codebase and with the current
   * context classloader as parent.
   *
   * @param codebase
   *
   * @return a classloader for the given codebase
   *
   * @throws MalformedURLException if the codebase contains a malformed URL
   */
  public ClassLoader getClassLoader(String codebase)
    throws MalformedURLException
  {
    if (codebase == null || codebase.length() == 0)
      return Thread.currentThread().getContextClassLoader();

    ClassLoader loader;
    CacheKey loaderKey = new CacheKey
    (codebase, Thread.currentThread().getContextClassLoader());
    loader = (ClassLoader) cacheLoaders.get (loaderKey);

    if (loader == null)
      {
        //create an entry in cacheLoaders mapping a loader to codebases.
        // codebases are separated by " "
        StringTokenizer tok = new StringTokenizer (codebase, " ");
        ArrayList urls = new ArrayList();

        while (tok.hasMoreTokens())
          urls.add (new URL(tok.nextToken()));

        loader = new MyClassLoader((URL[]) urls.toArray(new URL [urls.size()]),
                                 Thread.currentThread().getContextClassLoader(),
                                 codebase);
        cacheLoaders.put (loaderKey, loader);
      }

    return loader;
  }

  /**
   * Returns a string representation of the network location where a remote
   * endpoint can get the class-definition of the given class.
   *
   * @param cl
   *
   * @return a space seperated list of URLs where the class-definition
   * of cl may be found
   */
  public String getClassAnnotation(Class cl)
  {
    ClassLoader loader = cl.getClassLoader();

    if (loader == null
        || loader == ClassLoader.getSystemClassLoader())
      {
        return System.getProperty ("java.rmi.server.codebase");
      }

    if (loader instanceof MyClassLoader)
      {
        return ((MyClassLoader) loader).getClassAnnotation();
      }

    String s = (String) cacheAnnotations.get (loader);

    if (s != null)
      return s;

    if (loader instanceof URLClassLoader)
      {
        URL[] urls = ((URLClassLoader) loader).getURLs();

        if (urls.length == 0)
          return null;

        CPStringBuilder annotation = new CPStringBuilder (64 * urls.length);

        for (int i = 0; i < urls.length; i++)
          {
            annotation.append (urls [i].toExternalForm());
            annotation.append (' ');
          }

        s = annotation.toString();
        cacheAnnotations.put (loader, s);
        return s;
      }

    return System.getProperty ("java.rmi.server.codebase");
  }
}
