/*
 * The Syncro Soft SRL License
 *
 *
 * Copyright (c) 1998-2002 Syncro Soft SRL, Romania.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistribution of source or in binary form is allowed only with
 *    the prior written permission of Syncro Soft SRL.
 *
 * 2. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Syncro Soft SRL (http://www.sync.ro/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Oxygen" and "Syncro Soft SRL" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact contact@sync.ro.
 *
 * 5. Products derived from this software may not be called "Oxygen",
 *    nor may "Oxygen" appear in their name, without prior written
 *    permission of the Syncro Soft SRL.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
package ro.sync.util;

import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLStreamHandlerFactory;

/**
 * Title:        eXML
 * Description:
 * Copyright:    Copyright (c) 2002
 * Company:      S.C. Syncro Soft S.R.L.
 * @author       George
 * @version      $Revision: 1.2 $
 */
public class LateDelegationClassLoader extends URLClassLoader {
  /**
   * Constructs a new ClassLoader for the specified URLs using the
   * default delegation parent <code>ClassLoader</code>. The URLs will
   * be searched in the order specified for classes and resources then
   * searching in the parent class loader. Any URL that ends with
   * a '/' is assumed to refer to a directory. Otherwise, the URL is
   * assumed to refer to a JAR file which will be downloaded and opened
   * as needed.
   *
   * @param urls the URLs from which to load classes and resources
   *
   * @exception  SecurityException  if a security manager exists and its
   *             <code>checkCreateClassLoader</code> method doesn't allow
   *             creation of a class loader.
   * @see SecurityManager#checkCreateClassLoader
   */
  public LateDelegationClassLoader(URL[] urls) {
    super(urls);
  }

  /**
   * Constructs a new ClassLoader for the given URLs. The URLs will be
   * searched in the order specified for classes and resources then
   * searching in the specified parent class loader. Any URL that ends with
   * a '/' is assumed to refer to a directory. Otherwise, the URL is assumed
   * to refer to a JAR file which will be downloaded and opened as needed.
   *
   * @param urls the URLs from which to load classes and resources
   * @param parent the parent class loader for delegation
   * @exception  SecurityException  if a security manager exists and its
   *             <code>checkCreateClassLoader</code> method doesn't allow
   *             creation of a class loader.
   * @see SecurityManager#checkCreateClassLoader
   */
  public LateDelegationClassLoader(URL[] urls, ClassLoader parent) {
    super(urls, parent);
  }

  /**
   * Constructs a new ClassLoader for the specified URLs, parent
   * class loader, and URLStreamHandlerFactory. The parent argument
   * will be used as the parent class loader for delegation. The
   * factory argument will be used as the stream handler factory to
   * obtain protocol handlers when creating new URLs.
   *
   * @param urls the URLs from which to load classes and resources
   * @param parent the parent class loader for delegation
   * @param factory the URLStreamHandlerFactory to use when creating URLs
   *
   * @exception  SecurityException  if a security manager exists and its
   *             <code>checkCreateClassLoader</code> method doesn't allow
   *             creation of a class loader.
   * @see SecurityManager#checkCreateClassLoader
   */
  public LateDelegationClassLoader(URL[] urls, ClassLoader parent,
                        URLStreamHandlerFactory factory) {

    super(urls, parent, factory);
  }

  /**
   * Finds the resource with the given name. A resource is some data
   * (images, audio, text, etc) that can be accessed by class code in a way
   * that is independent of the location of the code.<p>
   *
   * The name of a resource is a "/"-separated path name that identifies
   * the resource.<p>
   *
   * Rewrite the default implementation of getting a resource calling first
   * <code>findResource</code> to find the resource. If this fails the
   * method will search the parent class loader for the resource;
   * if the parent is <code>null</code> the path of the class loader
   * built-in to the virtual machine is searched.
   *
   * @param  name resource name
   * @return a URL for reading the resource, or <code>null</code> if
   *         the resource could not be found or the caller doesn't have
   *         adequate privileges to get the resource.
   * @since  JDK1.1
   * @see #findResource(String)
   */
  public URL getResource(String name) {
    URL url;
    // Try locally.
    url = findResource(name);
    if (url == null) {
      // Delegate to super.
      url = super.getResource(name);
    }
    return url;
  }


  /**
   * Loads the class with the specified name.  Rewrite the default
   * implementation of this method to search for classes in the
   * following order:<p>
   *
   * <ol>
   * <li> Call {@link #findLoadedClass(String)} to check if the class has
   *      already been loaded. <p>
   * <li> Call the {@link #findClass(String)} method to find the class. <p>
   * <li> Call the <code>loadClass</code> method on the parent class
   *      loader.  If the parent is <code>null</code> the class loader
   *      built-in to the virtual machine is used, instead. <p>
   * </ol>
   *
   * If the <code>resolve</code> flag is true, this method will then call the
   * {@link #resolveClass(Class)} method on the resulting class object.
   * <p>
   * From the Java 2 SDK, v1.2, subclasses of ClassLoader are
   * encouraged to override
   * {@link #findClass(String)}, rather than this method.<p>
   *
   * @param     name the name of the class
   * @param     resolve if <code>true</code> then resolve the class
   * @return	  the resulting <code>Class</code> object
   * @exception ClassNotFoundException if the class could not be found
   */
  protected synchronized Class loadClass(String name, boolean resolve)
      throws ClassNotFoundException
  {
    // First, check if the class has already been loaded
    Class c = findLoadedClass(name);
    if (c == null) {
      try {
        // Try locally
        c = findClass(name);
      } catch (ClassNotFoundException e) {
        // Delegate to super.
        c = super.loadClass(name, false);
      }
    }
    if (resolve) {
      resolveClass(c);
    }
    return c;
  }
}
