/* gnuAny.java --
   Copyright (C) 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., 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.CORBA;

import gnu.CORBA.CDR.Vio;
import gnu.CORBA.CDR.BufferredCdrInput;
import gnu.CORBA.CDR.BufferedCdrOutput;
import gnu.CORBA.typecodes.PrimitiveTypeCode;
import gnu.CORBA.typecodes.StringTypeCode;

import org.omg.CORBA.Any;
import org.omg.CORBA.AnyHolder;
import org.omg.CORBA.BAD_OPERATION;
import org.omg.CORBA.BooleanHolder;
import org.omg.CORBA.CharHolder;
import org.omg.CORBA.DoubleHolder;
import org.omg.CORBA.FixedHolder;
import org.omg.CORBA.FloatHolder;
import org.omg.CORBA.IntHolder;
import org.omg.CORBA.LongHolder;
import org.omg.CORBA.MARSHAL;
import org.omg.CORBA.ORB;
import org.omg.CORBA.ObjectHolder;
import org.omg.CORBA.Principal;
import org.omg.CORBA.PrincipalHolder;
import org.omg.CORBA.ShortHolder;
import org.omg.CORBA.StringHolder;
import org.omg.CORBA.TCKind;
import org.omg.CORBA.TypeCode;
import org.omg.CORBA.TypeCodeHolder;
import org.omg.CORBA.ValueBaseHolder;
import org.omg.CORBA.portable.Streamable;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.zip.Adler32;

/**
 * The implementation of {@link Any}.
 *
 * For performance reasonse, the inserted values are not cloned.
 * If the value object allows modifications (like {@link Streamable}),
 * these subsequent alterations are reflected by the instance of
 * this gnuAny, and the gnuAny alterations are reflected by the
 * returned value. If it is required to have the uncoupled value,
 * it must be requested from the copy of the current instance.
 * The {@link gnuAny} can be simply cloned by the provided
 * {@link Clone()} method.
 *
 * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
 */
public class gnuAny
  extends Any
{
  /** 
   * Use serialVersionUID for interoperability. 
   */
  private static final long serialVersionUID = 1;
  
  /**
   * The value, returned by {@link #type()} if the value has been
   * not intialized.
   */
  protected static final TypeCode nullType =
    new PrimitiveTypeCode(TCKind.tk_null);

  /**
   * The Streamable, representing the value, held by this gnuAny.
   */
  protected Streamable has;

  /**
   * The complete typecode of the Streamable, if explicitly set.
   */
  protected TypeCode typecode;

  /**
   * The typecode kind of the Streamable, if explicitly set.
   */
  protected int xKind = -1;

  /**
   * The associated ORB.
   */
  private ORB orb;

  /**
   * Set the associated orb.
   */
  public void setOrb(ORB an_orb)
  {
    orb = an_orb;
  }

  /**
   * Creates a deep copy of this gnuAny, writing to and subsequently
   * reading from from the byte buffer.
   *
   * @return the uncoupled gnuAny with all fields set to identical
   * values.
   */
  public gnuAny Clone()
  {
    BufferedCdrOutput out = new BufferedCdrOutput();
    out.setOrb(orb);
    out.write_any(this);

    BufferredCdrInput in = new BufferredCdrInput(out.buffer.toByteArray());
    in.setOrb(orb);
    return (gnuAny) in.read_any();
  }

  /**
   * Create the buffered CDR input stream, containing the
   * value, stored inside of this {@link Any}.
   */
  public org.omg.CORBA.portable.InputStream create_input_stream()
  {
    if (has instanceof GeneralHolder)
      {
        GeneralHolder u = (GeneralHolder) has;
        return u.getInputStream();
      }
    else
      {
        BufferedCdrOutput out = new BufferedCdrOutput();
        out.setOrb(orb);
        write_value(out);

        BufferredCdrInput in = new BufferredCdrInput(out.buffer.toByteArray());
        in.setOrb(orb);
        return in;
      }
  }

  /**
   * Create the buffered CDR output stream (empty).
   */
  public org.omg.CORBA.portable.OutputStream create_output_stream()
  {
    BufferedCdrOutput stream = new BufferedCdrOutput();
    stream.setOrb(orb);
    return stream;
  }

  /**
   * Compare two Any's for equality.
   * @param other the other Any to compare.
   */
  public boolean equal(Any other)
  {
    if (other == this)
      return true;
    if (type().kind() != other.type().kind())
      return false;

    if (has != null && other instanceof gnuAny)
      if (has.equals(((gnuAny) other).has))
        return true;

    BufferedCdrOutput a = new BufferedCdrOutput();
    a.setOrb(orb);
    write_value(a);

    BufferedCdrOutput b = new BufferedCdrOutput();
    b.setOrb(orb);
    other.write_value(b);

    byte[] ba = a.buffer.toByteArray();
    byte[] bb = b.buffer.toByteArray();

    return Arrays.equals(ba, bb);
  }
  
  /**
   * Get the content - dependent hashcode.
   */
  public int hashCode()
  {
    if (has == null)
      return type().kind().value();
    else
      {
        Adler32 adler = new Adler32();

        BufferedCdrOutput a = new BufferedCdrOutput();
        a.setOrb(orb);
        write_value(a);
        
        adler.update(a.buffer.toByteArray());
        adler.update(type().kind().value());
        
        return (int) adler.getValue() & Integer.MAX_VALUE;
      }
  }

  /**
   * Delegates functionality to {@link #equal(Any)}.
   */
  public boolean equals(java.lang.Object other)
  {
    if (other == this)
      return true;
    if (!(other instanceof Any))
      return false;

    return equal((Any) other);
  }

  /**
   * Extract the previously stored object.
   */
  public org.omg.CORBA.Object extract_Object()
  {
    try
      {
        return ((ObjectHolder) has).value;
      }
    catch (ClassCastException ex)
      {
        BAD_OPERATION bad = new BAD_OPERATION();
        bad.initCause(ex);
        bad.minor = Minor.Any;
        throw bad;
      }
  }

  /**
   * Extract the previously inserted CORBA <code>Principal</code>/
   * @return the previously inserted value.
   *
   * @throws org.omg.CORBA.BAD_OPERATION if the holder contains something
   * else than Principal.
   *
   * @deprecated by CORBA 2.2.
   */
  public Principal extract_Principal()
  {
    check(TCKind._tk_Principal);
    return ((PrincipalHolder) has).value;
  }

  /**
   * Return the value, encapsulated in a suitable holder.
   * This implementation returns the direct reference,
   * so the alterations on the returned streamable are
   * directly reflected to the content of this {@link Any}.
   */
  public Streamable extract_Streamable()
  {
    return has;
  }

  public TypeCode extract_TypeCode()
                            throws BAD_OPERATION
  {
    check(TCKind._tk_TypeCode);
    return ((TypeCodeHolder) has).value;
  }

  /**
   * Extract the stored value type.
   *
   * @return the previously stored value type.
   *
   * @throws BAD_OPERATION if the Any contains something different.
   *
   * @see org.omg.CORBA.portable.ValueBase
   */
  public Serializable extract_Value()
                             throws BAD_OPERATION
  {
    try
      {
        if (has instanceof ValueBaseHolder)
          return ((ValueBaseHolder) has).value;
        else
          {
            // Normally, ValueBase holder must be an instance of the
            // ValueBaseHolder. However some IDL compilers probably
            // have a bug, do not deriving this way. The the only
            // way to access the wrapped value is via reflection.
            Field f = has.getClass().getField("value");
            return (Serializable) f.get(has);
          }
      }
    catch (Exception ex)
      {
        BAD_OPERATION bad = new BAD_OPERATION("Value type expected");
        bad.minor = Minor.Any;
        bad.initCause(ex);
        throw bad;
      }
  }

  /** {@inheritDoc} */
  public Any extract_any()
                  throws BAD_OPERATION
  {
    check(TCKind._tk_any);
    return ((AnyHolder) has).value;
  }

  /** {@inheritDoc} */
  public boolean extract_boolean()
                          throws BAD_OPERATION
  {
    check(TCKind._tk_boolean);
    return ((BooleanHolder) has).value;
  }

  /** {@inheritDoc} */
  public char extract_char()
                    throws BAD_OPERATION
  {
    check(TCKind._tk_char);
    return ((CharHolder) has).value;
  }

  /** {@inheritDoc} */
  public double extract_double()
                        throws BAD_OPERATION
  {
    check(TCKind._tk_double);
    return ((DoubleHolder) has).value;
  }

  /**
   * Extract the previously inserted CORBA <code>fixed</code>/
   * @return the previously inserted value.
   *
   * @throws org.omg.CORBA.BAD_OPERATION if the holder contains something
   * else than BigDecimal.
   */
  public BigDecimal extract_fixed()
                           throws org.omg.CORBA.BAD_OPERATION
  {
    check(TCKind._tk_fixed);
    return ((FixedHolder) has).value;
  }

  /** {@inheritDoc} */
  public float extract_float()
                      throws BAD_OPERATION
  {
    check(TCKind._tk_float);
    return ((FloatHolder) has).value;
  }

  /** {@inheritDoc} */
  public int extract_long()
                   throws BAD_OPERATION
  {
    // CORBA long = java int.
    check(TCKind._tk_long);
    return ((IntHolder) has).value;
  }

  /** {@inheritDoc} */
  public long extract_longlong()
                        throws BAD_OPERATION
  {
    check(TCKind._tk_longlong);
    return ((LongHolder) has).value;
  }

  /** {@inheritDoc} */
  public byte extract_octet()
                     throws BAD_OPERATION
  {
    // ShortHolder holds also octets.
    check(TCKind._tk_octet);
    return (byte) ((OctetHolder) has).value;
  }

  /** {@inheritDoc} */
  public short extract_short()
                      throws BAD_OPERATION
  {
    check(TCKind._tk_short);
    return ((ShortHolder) has).value;
  }

  /** {@inheritDoc} */
  public String extract_string()
                        throws BAD_OPERATION
  {
    check(TCKind._tk_string);
    return ((StringHolder) has).value;
  }

  /** {@inheritDoc} */
  public int extract_ulong()
                    throws BAD_OPERATION
  {
    // IntHolder also holds ulongs.
    check(TCKind._tk_ulong);
    return ((IntHolder) has).value;
  }

  /** {@inheritDoc} */
  public long extract_ulonglong()
                         throws BAD_OPERATION
  {
    // LongHolder also holds ulonglong
    check(TCKind._tk_ulonglong);
    return ((LongHolder) has).value;
  }

  /** {@inheritDoc} */
  public short extract_ushort()
                       throws BAD_OPERATION
  {
    // ShortHolder also holds ushorts.
    check(TCKind._tk_ushort);
    return ((ShortHolder) has).value;
  }

  /** {@inheritDoc} */
  public char extract_wchar()
                     throws BAD_OPERATION
  {
    check(TCKind._tk_wchar);
    return ((WCharHolder) has).value;
  }

  /** {@inheritDoc} */
  public String extract_wstring()
                         throws BAD_OPERATION
  {
    // StringHolder also holds wstrings.
    check(TCKind._tk_wstring);
    return ((WStringHolder) has).value;
  }

  /**
   * Inserts the CORBA object and sets the typecode to the given type.
   */
  public void insert_Object(org.omg.CORBA.Object x, TypeCode typecode)
  {
    has = new ObjectHolder(x);
    type(typecode);
  }

  /**
   * Inserts the CORBA object.
   */
  public void insert_Object(org.omg.CORBA.Object x)
  {
    has = new ObjectHolder(x);
  }

  /**
   * Insert the CORBA Principal.
   * This implementation uses direct assignment, so the later
   * alterations of that BigDecimal are reflected on the
   * content of this {@link Any}.
   *
   * @deprecated by CORBA 2.2.
   */
  public void insert_Principal(Principal x)
  {
    resetTypes();
    if (has instanceof PrincipalHolder)
      ((PrincipalHolder) has).value = x;
    else
      has = new PrincipalHolder(x);
  }

  /**
   * Sets the value to the value, encapsulated in this holder.
   * This implementation uses direct assignment, so the later
   * alterations of that streamable are reflected on the
   * content of this {@link Any}.
   */
  public void insert_Streamable(Streamable x)
  {
    resetTypes();
    has = x;
  }

  /**
   * Insert the typecode into this Any
   * @param typecode the typecode to insert.
   */
  public void insert_TypeCode(TypeCode typecode)
  {
    resetTypes();
    if (has instanceof TypeCodeHolder)
      ((TypeCodeHolder) has).value = typecode;
    else
      has = new TypeCodeHolder(typecode);
  }

  /** {@inheritDoc} */
  public void insert_Value(Serializable x, TypeCode c_typecode)
  {
    if (typecode != null && typecode.kind() == TCKind.tk_value_box)
      {
        has = new gnuValueHolder(x, typecode);
      }
    else
      {
        type(typecode);
        insert_Value(x);
      }
  }

  /** {@inheritDoc} */
  public void insert_Value(Serializable x)
  {
    if (typecode != null && typecode.kind() == TCKind.tk_value_box)
      {
        has = new gnuValueHolder(x, typecode);
      }
    else
      {
        if (has instanceof ValueBaseHolder)
          ((ValueBaseHolder) has).value = x;
        else
          has = new ValueBaseHolder(x);
      }
  }

  /**
  * Insert another {@link Any} into this {@link Any}.
  * This implementation uses direct assignment, so the later
  * alterations of that {@link Any} are reflected on the
  * content of this {@link Any}.
  */
  public void insert_any(Any an_any)
  {
    resetTypes();
    if (has instanceof AnyHolder)
      ((AnyHolder) has).value = an_any;
    else
      has = new AnyHolder(an_any);
  }

  /** {@inheritDoc} */
  public void insert_boolean(boolean x)
  {
    resetTypes();
    if (has instanceof BooleanHolder)
      ((BooleanHolder) has).value = x;
    else
      has = new BooleanHolder(x);
  }

  /** {@inheritDoc} */
  public void insert_char(char x)
  {
    resetTypes();
    if (has instanceof CharHolder)
      ((CharHolder) has).value = x;
    else
      has = new CharHolder(x);
  }

  /** {@inheritDoc} */
  public void insert_double(double x)
  {
    resetTypes();
    if (has instanceof DoubleHolder)
      ((DoubleHolder) has).value = x;
    else
      has = new DoubleHolder(x);
  }

  /**
   * Inserts the CORBA <code>fixed</code>, setting the typecode
   * explicitly.
   * This implementation uses direct assignment, so the later
   * alterations of that BigDecimal are reflected on the
   * content of this {@link Any}.
   */
  public void insert_fixed(BigDecimal x, TypeCode x_typecode)
  {
    resetTypes();
    insert_fixed(x);
    typecode = x_typecode;
  }

  /**
   * Inserts the CORBA <code>fixed</code>, setting the typecode
   * by example of the currently passed value.
   * This implementation uses direct assignment, so the later
   * alterations of that BigDecimal are reflected on the
   * content of this {@link Any}, including the typecode.
   */
  public void insert_fixed(BigDecimal x)
  {
    resetTypes();
    if (has instanceof FixedHolder)
      ((FixedHolder) has).value = x;
    else
      has = new FixedHolder(x);
  }

  /** {@inheritDoc} */
  public void insert_float(float x)
  {
    resetTypes();
    if (has instanceof FloatHolder)
      ((FloatHolder) has).value = x;
    else
      has = new FloatHolder(x);
  }

  /** {@inheritDoc} */
  public void insert_long(int x)
  {
    resetTypes();
    if (has instanceof IntHolder)
      ((IntHolder) has).value = x;
    else
      has = new IntHolder(x);
  }

  /** {@inheritDoc} */
  public void insert_longlong(long x)
  {
    resetTypes();
    if (has instanceof LongHolder)
      ((LongHolder) has).value = x;
    else
      has = new LongHolder(x);
  }

  /** {@inheritDoc} */
  public void insert_octet(byte x)
  {
    resetTypes();
    if (has instanceof OctetHolder)
      ((OctetHolder) has).value = x;
    else
      has = new OctetHolder(x);
  }

  /** {@inheritDoc} */
  public void insert_short(short x)
  {
    resetTypes();
    if (has instanceof ShortHolder)
      ((ShortHolder) has).value = x;
    else
      has = new ShortHolder(x);
  }

  /** {@inheritDoc} */
  public void insert_string(String x)
  {
    resetTypes();
    if (has instanceof StringHolder)
      ((StringHolder) has).value = x;
    else
      has = new StringHolder(x);

    typecode = new StringTypeCode(TCKind.tk_string);
  }

  /** {@inheritDoc} */
  public void insert_ulong(int x)
  {
    resetTypes();
    if (has instanceof IntHolder)
      ((IntHolder) has).value = x;
    else
      has = new IntHolder(x);
    xKind = TCKind._tk_ulong;
  }

  /** {@inheritDoc} */
  public void insert_ulonglong(long x)
  {
    resetTypes();
    if (has instanceof LongHolder)
      ((LongHolder) has).value = x;
    else
      has = new LongHolder(x);
    xKind = TCKind._tk_ulonglong;
  }

  /** {@inheritDoc} */
  public void insert_ushort(short x)
  {
    resetTypes();
    if (has instanceof ShortHolder)
      ((ShortHolder) has).value = x;
    else
      has = new ShortHolder(x);
    xKind = TCKind._tk_ushort;
  }

  /** {@inheritDoc} */
  public void insert_wchar(char x)
  {
    resetTypes();
    if (has instanceof WCharHolder)
      ((WCharHolder) has).value = x;
    else
      has = new WCharHolder(x);
  }

  /** {@inheritDoc} */
  public void insert_wstring(String x)
  {
    resetTypes();
    if (has instanceof WStringHolder)
      ((WStringHolder) has).value = x;
    else
      has = new WStringHolder(x);
  }

  /**
   * Return the associated orb.
   */
  public ORB orb()
  {
    return orb;
  }

  /**
   * Read the value of the given type from the given stream.
   *
   * @param input a stream to read from.
   * @param a_type a typecode of the value to read.
   */
  public void read_value(org.omg.CORBA.portable.InputStream input,
                         TypeCode a_type
                        )
                  throws MARSHAL
  {
    try
      {
        int kind = a_type.kind().value();

        // Fixed needs special handling.
        if (kind == TCKind._tk_fixed)
          {
            BigDecimal dec = BigDecimalHelper.read(input, a_type.fixed_scale());
            has = new FixedHolder(dec);
          }
        else
          {
            has = HolderLocator.createHolder(a_type);
            if (has == null)
              {
                // Use the Universal Holder that reads till the end of stream.
                // This works with the extract/insert pair of the typical
                // Helper.
                BufferedCdrOutput buffer = new BufferedCdrOutput();
                buffer.setOrb(orb);
                has = new GeneralHolder(buffer);
              }
          }
        type(a_type);

        if (!(has instanceof GeneralHolder) &&
            (kind == TCKind._tk_value_box))
          {
            // The streamable only contains operations for
            // reading the value, not the value header.
            Field vField = has.getClass().getField("value");

            Object content = Vio.read(input, a_type.id());
            vField.set(has, content);
          }
        else
          has._read(input);
      }
    catch (Exception ex)
      {
        MARSHAL m = new MARSHAL();
        m.minor = Minor.Any;
        m.initCause(ex);
        throw m;
      }
  }

  /** {@inheritDoc} */
  public TypeCode type()
  {
    if (typecode != null)
      return typecode;
    else if (xKind >= 0)
      {
        typecode = new PrimitiveTypeCode(TCKind.from_int(xKind));
        return typecode;
      }
    else
      return has != null ? has._type() : nullType;
  }

  /**
   * Explicitly set the typecode of the value to the given type.
   *
   * @param valueTypeCode the typecode of the value.
   */
  public void type(TypeCode valueTypeCode)
  {
    xKind = valueTypeCode.kind().value();
    typecode = valueTypeCode;
  }

  /** {@inheritDoc} */
  public void write_value(org.omg.CORBA.portable.OutputStream output)
  {
    if (has != null)
      has._write(output);
    else
    // These kinds support null.
    if (xKind == TCKind._tk_null || xKind == TCKind._tk_objref ||
        xKind == TCKind._tk_value || xKind == TCKind._tk_value_box
       )
      output.write_long(0);
  }

  /**
   * Check if the current value if the value of the given kind.
   * 
   * @param kind a kind to check.
   * @throws BAD_OPERATION if the value is not set of is different kind.
   */
  protected void check(int kind)
    throws BAD_OPERATION
  {
    if (has == null)
      {
        BAD_OPERATION bad = new BAD_OPERATION("value not set");
        bad.minor = Minor.Any;
        throw bad;
      }

    if (xKind >= 0)
      {
        if (xKind != kind)
          if (!(xKind == TCKind._tk_alias && has._type().kind().value() == kind))
            {
              BAD_OPERATION bad = new BAD_OPERATION("Extracting "
                + TypeKindNamer.nameIt(kind) + " when stored "
                + TypeKindNamer.nameIt(xKind));
              bad.minor = Minor.Any;
              throw bad;
            }
      }
    else
      {
        if (type().kind().value() != kind)
          if (!(type().kind().value() == TCKind._tk_alias && has._type().kind().value() == kind))
            {
              BAD_OPERATION bad = new BAD_OPERATION("Extracting "
                + TypeKindNamer.nameIt(kind) + " stored "
                + TypeKindNamer.nameIt(type()));
              bad.minor = Minor.Any;
              throw bad;
            }
      }
  }

  /**
   * Clear the additional type information before reusing this instance.
   */
  private final void resetTypes()
  {
    typecode = null;
    xKind = -1;
  }
}