/* Delegate.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 org.omg.CORBA.portable;

import org.omg.CORBA.BAD_PARAM;
import org.omg.CORBA.Context;
import org.omg.CORBA.ContextList;
import org.omg.CORBA.DomainManager;
import org.omg.CORBA.ExceptionList;
import org.omg.CORBA.NO_IMPLEMENT;
import org.omg.CORBA.NVList;
import org.omg.CORBA.NamedValue;
import org.omg.CORBA.ORB;
import org.omg.CORBA.Policy;
import org.omg.CORBA.Request;
import org.omg.CORBA.SetOverrideType;

/**
 * Specifies a vendor specific implementation of the
 * {@link org.omg.CORBA.Object} methods. The calls to these
 * methods are forwarded to the object delegate that can be
 * replaced, if needed. The first parameter is the actual
 * CORBA object to that the operation must be applied.
 *
 * Some methods in this class are not abstract, but no implemented,
 * thowing the {@link NO_IMPLEMENT}. This, however, does not mean that
 * they are not implemented in the derived classes as well.
 *
 * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
 */
public abstract class Delegate
{
  /**
   * Explains the reason of throwing the NO_IMPLEMENT.
   */
  private static final String WHY =
    "Following 1.4 API, this Delegate method must not be implemented. Override.";

  /**
   * Create a request to invoke the method of this object.
   *
   * @param target the CORBA object, to that this operation must be applied.
   * @param context a list of additional properties.
   * @param operation the name of method to be invoked.
   * @param parameters the method parameters.
   * @param returns the container for tge method returned value.
   *
   * @return the created reaquest.
   */
  public abstract Request create_request(org.omg.CORBA.Object target,
                                         Context context, String operation,
                                         NVList parameters, NamedValue returns
                                        );

  /**
   * Create a request to invoke the method of this object, specifying
   * context list and the list of the expected exception.
   *
   * @param target the CORBA object, to that this operation must be applied.
   * @param context a list of additional properties.
   * @param operation the name of method to be invoked.
   * @param parameters the method parameters.
   * @param returns the container for tge method returned value.
   * @param exceptions the list of the possible exceptions that the method
   * can throw.
   * @param ctx_list the list of the context strings that need to be
   * resolved and send as a context instance.
   *
   * @return the created reaquest.
   */
  public abstract Request create_request(org.omg.CORBA.Object target,
                                         Context context, String operation,
                                         NVList parameters, NamedValue returns,
                                         ExceptionList exceptions,
                                         ContextList ctx_list
                                        );

  /**
   * Duplicate the object reference. This does not make much sense for
   * java platform and is just included for the sake of compliance with
   * CORBA APIs.
   *
   * @param target the CORBA object, to that this operation must be applied.
   *
   * The method may return the object reference itself.
   *
   * @return as a rule, <code>this</code>.
   */
  public abstract org.omg.CORBA.Object duplicate(org.omg.CORBA.Object target);

  /**
   * Retrieve the domain managers for this object.
   *
   * @param target the CORBA object, to that this operation must be applied.
   *
   * @return the domain managers.
   *
   * @throws NO_IMPLEMENT, always (following the 1.4 specification).
   */
  public DomainManager[] get_domain_managers(org.omg.CORBA.Object target)
  {
    throw new NO_IMPLEMENT(WHY);
  }

  /**
   *
   * @param target the CORBA object, to that this operation must be applied.
   *
   * Get the <code>InterfaceDef</code> for this Object.
   */
  public abstract org.omg.CORBA.Object get_interface_def(org.omg.CORBA.Object target);

  /**
   * Returns the {@link Policy}, applying to this object.
   *
   * @param target the CORBA object, to that this operation must be applied.
   * @param a_policy_type a type of policy to be obtained.
   * @return a corresponding Policy object.
   *
   * @throws NO_IMPLEMENT, always (following the 1.4 specification).
   */
  public Policy get_policy(org.omg.CORBA.Object target, int a_policy_type)
                    throws BAD_PARAM
  {
    throw new NO_IMPLEMENT(WHY);
  }

  /**
   * Get the hashcode this object reference. The same hashcode still
   * does not means that the references are the same. From the other
   * side, two different references may still refer to the same CORBA
   * object. The returned value must not change during the object
   * lifetime.
   *
   * @param target the CORBA object, to that this operation must be applied.
   * @param maximum the maximal value to return.
   *
   * @return the hashcode.
   */
  public abstract int hash(org.omg.CORBA.Object target, int maximum);

  /**
   * Check if this object can be referenced by the given repository id.
   *
   * @param target the CORBA object, to that this operation must be applied.
   * @param repositoryIdentifer the repository id.
   *
   * @return true if the passed parameter is a repository id of this
   * CORBA object.
   */
  public abstract boolean is_a(org.omg.CORBA.Object target,
                               String repositoryIdentifer
                              );

  /**
   * Return true if the other object references are equivalent, so far as
   * it is possible to determine this easily.
   *
   * @param target the CORBA object, to that this operation must be applied.
   * @param other the other object reference.
   *
   * @return true if both references refer the same object, false
   * if they probably can refer different objects.
   *
   */
  public abstract boolean is_equivalent(org.omg.CORBA.Object target,
                                        org.omg.CORBA.Object other
                                       );

  /**
   * Returns true if the object is local.
   *
   * @param self the object to check.
   *
   * @return false, always (following 1.4 specs). Override to get
   * functionality.
   */
  public boolean is_local(org.omg.CORBA.Object self)
  {
    return false;
  }

  /**
   * Determines if the server object for this reference has already
   * been destroyed.
   *
   * @param target the CORBA object, to that this operation must be applied.
   *
   * @return true if the object has been destroyed, false otherwise.
   */
  public abstract boolean non_existent(org.omg.CORBA.Object target);

  /**
   * Compares two objects for equality. The default implementations
   * delegated call to {@link java.lang.Object#equals(java.lang.Object)}.
   *
   * @param self this CORBA object.
   * @param other the other CORBA object.
   *
   * @return true if the objects are equal.
   */
  public boolean equals(org.omg.CORBA.Object self, java.lang.Object other)
  {
    return self==other;
  }

  /**
   * Return the hashcode for this CORBA object. The default implementation
   * delegates call to {@link #hash(int)}, passing Integer.MAX_VALUE as an
   * argument.
   *
   * @param target the object, for that the hash code must be computed.
   *
   * @return the hashcode.
   */
  public int hashCode(org.omg.CORBA.Object target)
  {
    return hash(target, Integer.MAX_VALUE);
  }

  /**
   * Invoke the operation.
   *
   * @param target the invocation target.
   * @param output the stream, containing the written arguments.
   *
   * @return the stream, from where the input parameters could be read.
   *
   * @throws ApplicationException if the application throws an exception,
   * defined as a part of its remote method definition.
   *
   * @throws RemarshalException if reading(remarshalling) fails.
   *
   * @throws NO_IMPLEMENT, always (following the 1.4 specification).
   */
  public InputStream invoke(org.omg.CORBA.Object target,
                            org.omg.CORBA.portable.OutputStream output
                           )
                     throws ApplicationException, RemarshalException
  {
    throw new NO_IMPLEMENT(WHY);
  }

  /**
   * Provides the reference to ORB.
   *
   * @param target the object reference.
   *
   * @return the associated ORB.
   *
   * @throws NO_IMPLEMENT, always (following the 1.4 specification).
   */
  public ORB orb(org.omg.CORBA.Object target)
  {
    throw new NO_IMPLEMENT(WHY);
  }

  /**
   * Free resoureces, occupied by this reference. The object implementation
   * is not notified, and the other references to the same object are not
   * affected.
   *
   * @param target the CORBA object, to that this operation must be applied.
   */
  public abstract void release(org.omg.CORBA.Object target);

  /**
   * Release the reply stream back to ORB after finishing reading the data
   * from it.
   *
   * @param target the CORBA object, to that this operation must be applied.
   * @param input the stream, normally returned by {@link #invoke} or
   * {@link ApplicationException#getInputStream()}, can be null.
   *
   * The default method returns without action.
   */
  public void releaseReply(org.omg.CORBA.Object target,
                           org.omg.CORBA.portable.InputStream input
                          )
  {
  }

  /**
   * Create a request to invoke the method of this CORBA object.
   *
   * @param target the CORBA object, to that this operation must be applied.
   * @param operation the name of the method to invoke.
   *
   * @return the request.
   */
  public abstract Request request(org.omg.CORBA.Object target, String operation);

  /**
   * Create a request to invoke the method of this CORBA object.
   *
   * @param target the CORBA object, to that this operation must be applied.
   * @param operation the name of the method to invoke.
   * @param response_expected specifies if this is one way message or the
   * response to the message is expected.
   *
   * @return the stream where the method arguments should be written.
   */
  public org.omg.CORBA.portable.OutputStream request(org.omg.CORBA.Object target,
                                                     String operation,
                                                     boolean response_expected
                                                    )
  {
    throw new NO_IMPLEMENT(WHY);
  }

  /**
   * This method is always called after invoking the operation on the
   * local servant.
   *
   * The default method returns without action.
   *
   * @param self the object.
   * @param servant the servant.
   */
  public void servant_postinvoke(org.omg.CORBA.Object self,
                                 ServantObject servant
                                )
  {
  }

  /**
   * Returns a servant that should be used for this request.
   * The servant can also be casted to the expected type, calling the
   * required method directly.
   *
   * @param self the object
   * @param operation the operation
   * @param expectedType the expected type of the servant.
   *
   * This implementation always returns null; override for different
   * behavior.
   *
   * @return the servant or null if the servant is not an expected type
   * of the method is not supported, for example, due security reasons.
   */
  public ServantObject servant_preinvoke(org.omg.CORBA.Object self,
                                         String operation, Class expectedType
                                        )
  {
    return null;
  }

  /**
   * Returns a new object with the new policies either replacing or
   * extending the current policies, depending on the second parameter.
   *
   * @param target the CORBA object, to that this operation must be applied.
   * @param policies the policy additions or replacements.
   * @param how either {@link SetOverrideType#SET_OVERRIDE} to override the
   * current policies of {@link SetOverrideType#ADD_OVERRIDE} to replace
   * them.
   *
   * @throws NO_IMPLEMENT, always (following the 1.4 specification).
   *
   * @return the new reference with the changed policies.
   */
  public org.omg.CORBA.Object set_policy_override(org.omg.CORBA.Object target,
                                                  Policy[] policies,
                                                  SetOverrideType how
                                                 )
  {
    throw new NO_IMPLEMENT(WHY);
  }

  /**
   * Return a string representation of the passed object.
   *
   * @param self the CORBA object, to that the string representation must be
   * returned. By default, the call is delegated to
   * {@link java.lang.Object.toString()}.
   *
   * @return the string representation.
   */
  public String toString(org.omg.CORBA.Object self)
  {
    if (self instanceof ObjectImpl)
      {
        ObjectImpl x = (ObjectImpl) self;
        StringBuffer b = new StringBuffer(x.getClass().getName());
        b.append(": [");
        for (int i = 0; i < x._ids().length; i++)
          {
            b.append(x._ids() [ i ]);
            b.append(" ");
          }
        b.append("]");
        return b.toString();
      }
    else
      return self.getClass().getName();
  }
}
