/* ActivationGroupDesc.java -- the RMI activation group descriptor
   Copyright (c) 1996, 1997, 1998, 1999, 2004, 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 java.rmi.activation;

import gnu.java.rmi.activation.DefaultActivationGroup;

import java.io.Serializable;
import java.rmi.MarshalledObject;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Properties;
import java.util.TreeSet;
import java.util.zip.Adler32;

/**
 * Contains information, necessary to create of recreate the activation objects.
 * The group descriptor contains:
 * <ul>
 * <li>The name of the group's class. This class is derived from the
 * {@link ActivationGroup}.</li>
 * <li>The group class code location.</li>
 * <li>The marshalled object that contains the group specific initialization
 * information</li>
 * </ul>
 * The groups are created by the {@link ActivationGroup#createGroup} method that
 * expectes the group class to have the two parameter constructor, the first
 * parameter being the {@link ActivationGroupID} and the second the
 * {@link MarshalledObject}.
 *
 * @author Audrius Meskauskas (audriusa@bioinformatics.org) (from stub)
 */
public final class ActivationGroupDesc
    implements Serializable
{
  /**
   * Contains the startup options for the {@link ActivationGroup}
   * implementations. Allows to override system properties and specify other
   * options for the implementation groups.
   *
   * @author Audrius Meskauskas (audriusa@bioinformatics.org) (from stub)
   */
  public static class CommandEnvironment
      implements Serializable
  {

    /**
     * Use the SVUID for interoperability.
     */
    static final long serialVersionUID = 6165754737887770191L;

    /**
     * The zero size string array used as argv value when null is passed.
     */
    private static final String[] NO_ARGS = new String[0];

    /**
     * The path to the java executable (or null for using default jre).
     */
    final String command;

    /**
     * The extra parameters (may be empty array but never null).
     */
    final String[] options;

    /**
     * Create the new command environment.
     *
     * @param commandPatch the full path (and name) to the java executable of
     *          null for using the default executable.
     * @param args extra options that will be used when creating the activation
     *          group. Null has the same effect as the empty list.
     */
    public CommandEnvironment(String commandPatch, String[] args)
    {
      command = commandPatch;
      if (args != null)
        options = args;
      else
        options = NO_ARGS;
    }

    /**
     * Get the path to the java executable.
     *
     * @return the path to the java executable or null for using the default
     * jre.
     */
    public String getCommandPath()
    {
      return command;
    }

    /**
     * Get the additional command options.
     *
     * @return the command options array, may be empty string
     */
    public String[] getCommandOptions()
    {
      return options;
    }

    /**
     * Compare for content equality.
     */
    public boolean equals(Object obj)
    {
      if (obj instanceof CommandEnvironment)
        {
          CommandEnvironment that = (CommandEnvironment) obj;

          if (command == null || that.command == null)
            {
              // Use direct comparison if null is involved.
              if (command != that.command)
                return false;
            }
          else
            {
              // Use .equals if null is not involved.
              if (! this.command.equals(that.command))
                return false;
            }

          return Arrays.equals(options, that.options);
        }
      else
        return false;
    }

    /**
     * Get the hash code.
     */
    public int hashCode()
    {
      int h = command == null ? 0 : command.hashCode();
      for (int i = 0; i < options.length; i++)
        h ^= options[i].hashCode();

      return h;
    }
  }

  /**
   * Use the SVUID for interoperability.
   */
  static final long serialVersionUID = - 4936225423168276595L;

  /**
   * The group class name or null for the default group class implementation.
   */
  final String className;

  /**
   * The group class download location URL (codebase), ignored by the
   * default implementation.
   */
  final String location;

  /**
   * The group initialization data.
   */
  final MarshalledObject<?> data;

  /**
   * The path to the group jre and the parameters of this jre, may be
   * null for the default jre.
   */
  final ActivationGroupDesc.CommandEnvironment env;

  /**
   * The properties that override the system properties.
   */
  final Properties props;

  /**
   * The cached hash code.
   */
  transient long hash;

  /**
   * Create the new activation group descriptor that will use the default
   * activation group implementation with the given properties and
   * environment.
   *
   * @param aProperties the properties that override the system properties
   * @param environment the command line (and parameters), indicating, where to
   *          find the jre executable and with that parameters to call it. May
   *          be null if the default executable should be used. In this case,
   *          the activation group with the null name (the system default group)
   *          will be created.
   */
  public ActivationGroupDesc(Properties aProperties,
                             ActivationGroupDesc.CommandEnvironment environment)
  {
    this(DefaultActivationGroup.class.getName(), null, null, aProperties,
         environment);
  }

  /**
   * Create the new activation group descriptor.
   *
   * @param aClassName the name of the group implementation class. The null
   *          value indicates the default implementation.
   * @param aLocation the location, from where the group implementation class
   *          should be loaded (ignored for the system default implementation).
   * @param aData the group intialization data
   * @param aProperties the properties that will override the system properties
   *          of the new group. These properties will be translated into -D
   *          options.
   * @param environment the record, containing path to the jre executable and
   *          start options for the jre or null for using the default jre and
   *          options.
   */
  public ActivationGroupDesc(String aClassName, String aLocation,
                             MarshalledObject<?> aData, Properties aProperties,
                             ActivationGroupDesc.CommandEnvironment environment)
  {
    className = aClassName;
    location = aLocation;
    data = aData;
    props = aProperties;
    env = environment;
  }

  /**
   * Get the activation group class name.
   *
   * @return the activation group class name (null for default implementation)
   */
  public String getClassName()
  {
    return className;
  }

  /**
   * Get the location, from where the group class will be loaded
   *
   * @return the location, from where the implementation should be loaded (null
   *         for the default implementation)
   */
  public String getLocation()
  {
    return location;
  }

  /**
   * Get the group intialization data.
   *
   * @return the group intialization data in the marshalled form.
   */
  public MarshalledObject<?> getData()
  {
    return data;
  }

  /**
   * Get the overridded system properties.
   *
   * @return the overridden group system properties.
   */
  public Properties getPropertyOverrides()
  {
    return props;
  }

  /**
   * Get the group command environment, containing path to the jre executable
   * and startup options.
   *
   * @return the command environment or null if the default environment should
   *         be used.
   */
  public ActivationGroupDesc.CommandEnvironment getCommandEnvironment()
  {
    return env;
  }

  /**
   * Compare for the content equality.
   */
  public boolean equals(Object obj)
  {
    if (obj instanceof ActivationGroupDesc)
      {
        ActivationGroupDesc that = (ActivationGroupDesc) obj;

        // Ensure the hashcodes are computed.
        if (hash == 0)
          hashCode();
        if (that.hash == 0)
          that.hashCode();

        // We compare the hash fields as they are type long rather than int.
        if (hash != that.hash)
          return false;

        if (! eq(className, that.className))
          return false;
        if (! eq(data, that.data))
          return false;
        if (! eq(env, that.env))
          return false;
        if (! eq(location, that.location))
          return false;

        // Compare the properties.
        if (eq(props, that.props))
          return true;

        if (props.size() != that.props.size())
          return false;

        Enumeration en = props.propertyNames();
        Object key, value;

        while (en.hasMoreElements())
          {
            key = en.nextElement();
            if (! that.props.containsKey(key))
              return false;
            if (! eq(props.get(key), that.props.get(key)))
              return false;
          }
        return true;
      }
    else
      return false;
  }

  /**
   * Compare for direct equality if one or both parameters are null, otherwise
   * call .equals.
   */
  static boolean eq(Object a, Object b)
  {
    if (a == null || b == null)
      return a == b;
    else
      return a.equals(b);
  }

  /**
   * Return the hashcode.
   */
  public int hashCode()
  {
    if (hash==0)
      {
        // Using Adler32 - the hashcode is cached, will be computed only
        // once and due need to scan properties is the expensive operation
        // anyway. Reliability is more important.
        Adler32 adler = new Adler32();
        if (className!=null)
          adler.update(className.getBytes());
        if (data!=null)
          adler.update(data.hashCode());
        if (env!=null)
          adler.update(env.hashCode());
        if (location!=null)
          adler.update(location.getBytes());
        if (props!=null)
          {
            Enumeration en = props.propertyNames();

            // Using the intermediate sorted set to ensure that the
            // properties are sorted.
            TreeSet pr = new TreeSet();

            Object key;
            Object value;
            while (en.hasMoreElements())
              {
                key = en.nextElement();
                if (key!=null)
                  pr.add(key);
              }

            Iterator it = pr.iterator();
            while (it.hasNext())
              {
                key = it.next();
                value = props.get(key);
                adler.update(key.hashCode());
                if (value!=null)
                  adler.update(value.hashCode());
              }
          }
          hash = adler.getValue();
        }
    return (int) hash;
  }

}
