/* UnknownExceptionCtxHandler.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.CDR;

import gnu.CORBA.Minor;
import gnu.CORBA.ObjectCreator;
import gnu.CORBA.GIOP.ServiceContext;

import org.omg.CORBA.MARSHAL;
import org.omg.CORBA.NO_IMPLEMENT;
import org.omg.CORBA.StringValueHelper;
import org.omg.CORBA.portable.OutputStream;

import java.lang.reflect.Constructor;
import java.util.StringTokenizer;

import javax.rmi.CORBA.Util;

/**
 * Reads the data about an unknown exception from the UnknownExceptionInfo.
 * 
 * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
 */
public class UnknownExceptionCtxHandler
  extends Vio
{
  /**
   * Encode exception and add its recored to the message service contexts.
   */
  public static ServiceContext[] addExceptionContext(ServiceContext[] current,
    Throwable exception, Object details)
  {
    try
      {
        ServiceContext[] c = new ServiceContext[current.length + 1];
        if (current.length > 0)
          System.arraycopy(current, 0, c, 0, current.length);

        BufferedCdrOutput output = new BufferedCdrOutput();

        if (details instanceof OutputStream)
          output.setOrb(((OutputStream) output).orb());

        if (details instanceof AbstractCdrOutput)
          ((AbstractCdrOutput) details).cloneSettings(output);

        write(output, exception);

        ServiceContext xc = new ServiceContext();
        xc.context_id = ServiceContext.UnknownExceptionInfo;
        xc.context_data = output.buffer.toByteArray();
        c[current.length] = xc;
        return c;
      }
    catch (Exception ex)
      {
        ex.printStackTrace();
        return current;
      }
  }

  /**
   * Write data about unknown exception.
   */
  public static void write(BufferedCdrOutput output, Throwable t)
  {
    t.fillInStackTrace();
    output.write_Value(t);
  }

  /**
   * Read the data about an unknown exception from the UnknownExceptionInfo.
   * Following the documentation, this must be just value type, but it seems
   * that in Sun's implementation is is not, as starts from 0x0. For value type,
   * this would be null.
   * 
   * TODO Implement reading and writing in Sun format, making Classpath IIOP
   * interoperable with Sun's implementation. Current inmplementation reads and
   * reproduces the exception class type only.
   * 
   * @param input the input stream to read the context (orb and other settings
   * are inherited from the main stream that received the message).
   * 
   * @param contexts all service contexts that were present in the message.
   * 
   * @return the Throwable, extracted from context, on null, if this has failed.
   */
  public static Throwable read(BufferredCdrInput input, ServiceContext[] contexts)
  {
    input.mark(Integer.MAX_VALUE);

    int h = input.read_long();
    if (h == 0)
      {
        // This block reads exception info in the Sun specific format.
        // (currently we read the exception name only).
        try
          {
            // We may need to jump back if the value is read via value
            // factory.
            input.mark(512);

            int value_tag = input.read_long();
            checkTag(value_tag);

            String codebase = null;
            String[] ids = null;
            String id = null;

            // Check for the agreed null value.
            if (value_tag == vt_NULL)
              return null;
            else if (value_tag == vt_INDIRECTION)
              return (Throwable) readIndirection(input);
            else
              {
                // Read the value.
                if ((value_tag & vf_CODEBASE) != 0)
                  {
                    // The codebase is present. The codebase is a space
                    // separated list of URLs from where the implementing
                    // code can be downloaded.
                    codebase = read_string(input);
                  }

                if ((value_tag & vf_MULTIPLE_IDS) != 0)
                  {
                    // Multiple supported repository ids are present.
                    ids = read_string_array(input);
                  }
                else if ((value_tag & vf_ID) != 0)
                  {
                    // Single supported repository id is present.
                    id = read_string(input);
                  }
              }

            java.lang.Object ox = createInstance(id, ids, codebase);

            return (Throwable) ox;
          }
        catch (Exception ex)
          {
            ex.printStackTrace();
            return null;
          }
      }
    else
      {
        input.reset();
        // Read as defined in OMG documentation.
        return (Throwable) input.read_Value();
      }
  }

  /**
   * Load exception by name and create the instance. The reason why this is
   * different from Vio is because some exceptions have no parameterless
   * constructor, but have a constructor with the string parameter instead.
   */
  static Object createInstance(String id, String[] ids, String codebase)
  {
    Object o = _createInstance(id, codebase);

    if (ids != null)
      for (int i = 0; i < ids.length && o == null; i++)
        o = _createInstance(ids[i], codebase);
    return o;
  }

  static Object _createInstance(String id, String codebase)
  {
    if (id == null)
      return null;
    if (id.equals(StringValueHelper.id()))
      return "";
    StringTokenizer st = new StringTokenizer(id, ":");

    String prefix = st.nextToken();
    if (prefix.equalsIgnoreCase("IDL"))
      return ObjectCreator.Idl2Object(id);
    else if (prefix.equalsIgnoreCase("RMI"))
      {
        String className = st.nextToken();
        String hashCode = st.nextToken();
        String sid = null;
        if (st.hasMoreElements())
          sid = st.nextToken();

        try
          {
            Class objectClass = Util.loadClass(className, codebase,
              Vio.class.getClassLoader());

            String rid = ObjectCreator.getRepositoryId(objectClass);

            if (!rid.equals(id))
              {
                // If direct string comparison fails, compare by meaning.
                StringTokenizer st2 = new StringTokenizer(rid, ":");
                if (!st2.nextToken().equals("RMI"))
                  throw new InternalError("RMI format expected: '" + rid + "'");
                if (!st2.nextToken().equals(className))
                  throwIt("Class name mismatch", id, rid, null);

                try
                  {
                    long h1 = Long.parseLong(hashCode, 16);
                    long h2 = Long.parseLong(st2.nextToken(), 16);
                    if (h1 != h2)
                      throwIt("Hashcode mismatch", id, rid, null);

                    if (sid != null && st2.hasMoreTokens())
                      {
                        long s1 = Long.parseLong(hashCode, 16);
                        long s2 = Long.parseLong(st2.nextToken(), 16);
                        if (s1 != s2)
                          throwIt("serialVersionUID mismatch", id, rid, null);
                      }
                  }
                catch (NumberFormatException e)
                  {
                    throwIt("Invalid hashcode or svuid format: ", id, rid, e);
                  }
              }

            // Some RemoteExceptions have no public parameterless constructor,
            // but they have constructor taking string as parameter.
            try
              {
                return objectClass.newInstance();
              }
            catch (Exception ex)
              {
                // Try instantiate passing string as parameter.
                Constructor c = objectClass.getConstructor(new Class[] { String.class });
                return c.newInstance(new Object[] { "<message unavailable>" });
              }
          }
        catch (MARSHAL m)
          {
            m.minor = Minor.Instantiation;
            throw m;
          }
        catch (Exception ex)
          {
            MARSHAL m = new MARSHAL("Unable to instantiate " + id);
            m.minor = Minor.Instantiation;
            m.initCause(ex);
            throw m;
          }
      }
    else
      throw new NO_IMPLEMENT("Unsupported prefix " + prefix + ":");
  }
}
