/* 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;
  }

}
