/* java.beans.Beans
   Copyright (C) 1998, 1999, 2004, 2005 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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 java.beans;

import gnu.java.beans.DummyAppletStub;
import gnu.java.io.ClassLoaderObjectInputStream;

import java.applet.Applet;
import java.beans.beancontext.BeanContext;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.URL;

/**
 * <code>Beans</code> provides some helper methods that allow the basic
 * operations of Bean-ness.
 *
 * @author John Keiser
 * @author Robert Schuster
 * 
 * @since 1.1
 * @status updated to 1.4
 *
 */
public class Beans
{
  static boolean designTime = false;
  static boolean guiAvailable = true;

  /**
   * Once again, we have a java.beans class with only
   * static methods that can be instantiated.  When
   * will the madness end? :)
   */
  public Beans()
  {
    // Does intentionally nothing here.
  }

   /** Creates a bean.
    * <p>This is a convenience method that calls <code>instantiate(cl, beanName, null, null)</code>.</p>
    * 
    * @see instantiate(ClassLoader, String, BeanContext, AppletInitializer)
    * @param cl ClassLoader to be used or <code>null</code> for the system classloader.
    * @param beanName Name of a serialized bean or class name.
    * @return A newly created bean.
    * @throws IOException If access of an IO resource failed.
    * @throws ClassNotFoundException If the class name is not known or does not lead to a proper bean class. 
    */
    public static Object instantiate(ClassLoader cl, String beanName)
        throws IOException, ClassNotFoundException
    {
        return instantiate(cl, beanName, null, null);
    }

   /** Creates a bean.
    * 
    * <p>This is a convenience method that calls <code>instantiate(cl, beanName, beanContext, null)</code>.</p>
    * 
    * @see instantiate(ClassLoader, String, BeanContext, AppletInitializer)
    * @param cl ClassLoader to be used or <code>null</code> for the system classloader.
    * @param beanName Name of a serialized bean or class name.
    * @param beanContext Context to which the newly created Bean should be added.
    * @return A newly created bean.
    * @throws IOException If access of an IO resource failed.
    * @throws ClassNotFoundException If the class name is not known or does not lead to a proper bean class. 
    */
    public static Object instantiate(
        ClassLoader cl,
        String beanName,
        BeanContext beanContext)
        throws IOException, ClassNotFoundException
    {
        return instantiate(cl, beanName, beanContext, null);
    }

   /** Instantiates a bean according to Beans 1.0.
    * 
    * <p>In Beans 1.0 the instantiation scheme is as follows:</p>
    * <p>The name should be dot-separated (e.g "place.for.beans.myBean") and indicate either a
    * serialized object or a class name. In the first case all dots in the name are replaced with
    * slashes ('/') and ".ser" is appended ("place.for.beans.myBean" becomes "place/for/beans/myBean.ser").
    * The bean is then loaded as an application or system resource depending on whether a
    * <code>ClassLoader</code> was provided.</p>
    * 
    * <p>If no such resource exists or if it contains no bean the name is interpreted as a class name of
    * which an instance is then created.</p>
    * 
    * <p>If a <code>BeanContext</code> instance is available the created bean is added to it.</p>
    * 
    * <p>If the created Bean is an <code>Applet</code> or subclass and an <code>AppletInitializer</code>
    * instance is available the applet is initialized and afterwards activated using the initializer. Additionally
    * every instantiated <code>Applet</code> bean is initialized using the {@link Applet.init} method.
    * Furthermore every applet gets a default <code>AppletStub</code>. The <code>Applet</code>'s
    * document base is the location of the ".ser" file if it was deserialized or the location of its class
    * file if it was instantiated.</p>
    * 
    * <p>A <code>ClassNotFoundException</code> is not only thrown when a class name was unknown
    * but even when the class has public no-argument constructor
    * (<code>IllegalAccessException</code> is wrapped) or an exception is thrown while
    * invoking such a constructor (causing exception is wrapped).</p>
    * 
    * @param cl ClassLoader to be used or <code>null</code> for the system classloader.
    * @param beanName Name of a serialized bean or class name.
    * @param beanContext Context to which the newly created Bean should be added.
    * @param initializer The AppletInitializer which is used for initializing <code>Applet</code> beans.
    * @return A newly created bean.
    * @throws IOException If access of an IO resource failed.
    * @throws ClassNotFoundException If the class name is not known or does not lead to a proper bean class. 
    */
   public static Object instantiate(
        ClassLoader cl,
        String beanName,
        BeanContext beanContext,
        AppletInitializer initializer)
        throws IOException, ClassNotFoundException
   {
        Object bean = null;
        URL beanLocation = null;
        URL classLocation = null;

        // Converts bean name into a resource name (eg. "a.b.c" -> "a/b/c").  
        String resourceName = beanName.replace('.', '/');

        /* Tries to get an input stream of the Bean, reading it as a system resource
         * if no ClassLoader is present or as an application resource if a classloader
         * is given. 
         */
        beanLocation =
            (cl == null)
                ? ClassLoader.getSystemResource(resourceName + ".ser")
                : cl.getResource(resourceName + ".ser");

        // Reads the serialized Bean from the returned URL.
        if (beanLocation != null)
        {
            // Deserializes the bean instance.
            ObjectInputStream ois =
                (cl == null)
                    ? new ObjectInputStream(beanLocation.openStream())
                    : new ClassLoaderObjectInputStream(
                        beanLocation.openStream(),
                        cl);

            bean = ois.readObject();

            /* Implementation note: The result of ObjectInputStream.readObject()
            * may have been null at this point (its a valid value to deserialize)
            * and we explicitly want to try instantiation in such a case
            * (this is important for compatibility).
            */
        }

        // Instantiates the Bean using reflective instantiation if it has not been created yet.
        if (bean == null)
        {
            // Makes sure that the deserialization was NOT done.
            beanLocation = null;

            Class beanClass;
            if (cl == null)
            {
                beanClass = Class.forName(beanName);
                classLocation =
                    ClassLoader.getSystemResource(resourceName + ".class");
            }
            else
            {
                beanClass = cl.loadClass(beanName);
                classLocation = cl.getResource(resourceName + ".class");
            }

            // Instantiates and optionally registers the new bean.
            try
            {
                bean = beanClass.newInstance();
            }
            catch(Exception e) {
		/* Wraps all kinds of Exceptions in a ClassNotFoundException (this behavior
		 * matches with official >= 1.5, this was different for <=1.4)
		 */
		throw new ClassNotFoundException(null, e);
            }
        }

        /* Applet beans are treated in the following way:
         * - all AppletS get a default AppletStub
         * - all AppletS are initialized using the AppletInitializer instance (if it is available)
         * - as every other Bean Applets are added to a BeanContext if one is available
         * - each instantiated Applet is initialized using Applet.init() (this is not done for deserialized ones)
         * - finally AppletS get activated using the AppletInitializerS activate-Method
         * 
         * The order of operations is important for compatibility.    
         */
        Applet applet = null;
        if (bean instanceof Applet)
        {
            // Makes a second instanceof call unneccessary (instanceof is expensive).
            applet = (Applet) bean;

            /* The AppletStub's code and document base is set as follows:
             * The code base is always the URL from where the class data originated
             * (without the package name).
             * If the Applet was deserialized the document base is the location of
             * the serialized instance (usually the ".ser" file) otherwise its the URL
             * from where the class data originated (usually the absolute directory
             * location of the ".class" file).
             */
            applet.setStub(
                new DummyAppletStub(
                    applet
                        .getClass()
                        .getProtectionDomain()
                        .getCodeSource()
                        .getLocation(),
                    (beanLocation == null) ? classLocation : beanLocation));

            // Runs the Applet's initialization using an AppletInitializer.
            if (initializer != null)
            {
                initializer.initialize(applet, beanContext);
            }
        }

        // Adds the new bean to its BeanContext.
        if (beanContext != null)
        {
            beanContext.add(bean);
        }

        if (applet != null)
        {

            // Initializes an instantiated (not deserialized) Applet using its own method.
            if (beanLocation == null)
            {
                applet.init();
            }

            // Runs the Applet's activation using an AppletInitializer.
            if (initializer != null)
            {
                initializer.activate(applet);
            }
        }

        return bean;
   }

   /**
    * Returns the Bean as a different class type.
    * This should be used instead of casting to get a new
    * type view of a Bean, because in the future there may
    * be new types of Bean, even Beans spanning multiple
    * Objects.
    *
    * @param bean the Bean to cast.
    * @param newClass the Class to cast it to.
    *
    * @return the Bean as a new view, or if the operation
    *         could not be performed, the Bean itself.
    */
   public static Object getInstanceOf(Object bean, Class newClass)
   {
        return bean;
   }

   /**
    * Determines whether the Bean can be cast to a different
    * class type.
    * This should be used instead of instanceof to determine
    * a Bean's castability, because in the future there may
    * be new types of Bean, even Beans spanning multiple
    * Objects.
    *
    * @param bean the Bean to cast.
    * @param newClass the Class to cast it to.
    *
    * @return whether the Bean can be cast to the class type
    *         in question.
    */
   public static boolean isInstanceOf(Object bean, Class newBeanClass)
   {
       return newBeanClass.isInstance(bean);
   }

   /**
    * Returns whether the GUI is available to use.
    * <p>Defaults to true.</p>
    *
    * @return whether the GUI is available to use.
    */
   public static boolean isGuiAvailable()
   {
       return guiAvailable;
   }

   /**
    * Returns whether it is design time.  Design time means
    * we are in a RAD tool.
    * <p>Defaults to false.</p>
    *
    * @return whether it is design time.
    */
   public static boolean isDesignTime()
   {
       return designTime;
   }

   /**
    * Sets whether the GUI is available to use.
    * 
    * @param guiAvailable whether the GUI is available to use.
    */
   public static void setGuiAvailable(boolean guiAvailable)
       throws SecurityException
   {
        Beans.guiAvailable = guiAvailable;
   }

   /**
    * Sets whether it is design time.  Design time means we
    * are in a RAD tool.
    *
    * @param designTime whether it is design time.
    */
   public static void setDesignTime(boolean designTime)
       throws SecurityException
   {
       Beans.designTime = designTime;
   }

}
