/* Servant.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.PortableServer;

import org.omg.CORBA.BAD_OPERATION;
import org.omg.CORBA.BAD_INV_ORDER;
import org.omg.CORBA.NO_IMPLEMENT;
import org.omg.CORBA.OBJECT_NOT_EXIST;
import org.omg.CORBA.ORB;
import org.omg.PortableServer.POAPackage.ServantNotActive;
import org.omg.PortableServer.POAPackage.WrongPolicy;
import org.omg.PortableServer.portable.Delegate;

import gnu.CORBA.Minor;
import gnu.CORBA.Poa.ORB_1_4;
import gnu.CORBA.Poa.gnuPOA;

/**
 * <p>
 * The servant is responsible for handling the method invocation on the
 * target object. It can be one servant per object, or the same servant can
 * support several (possibly all) objects, associated with the given POA.
 * </p> <p>
 * Till JDK 1.3 inclusive, a typical IDL to java compiler generates an
 * implementation base (name pattern _*ImplBase.java) that is derived from the
 * {@link org.omg.CORBA.portable.ObjectImpl}. Since JDK 1.4 the implementation
 * base is derived from the Servant, also having a different name pattern
 * (*POA.java). This suffix may be confusing, as the servant itself is
 * <i>not</i> POA nor it is derived from it.
 * </p><p>
 * In both cases, the implementation base also inherits an interface, containing
 * definitions of the application specific methods. The application programmer
 * writes a child of the implementation base, implementing these methods
 * for the application-specific functionality. The ObjectImpl is connected
 * directly to the ORB. The Servant is connected to POA that can be obtained
 * from the ORB.
 * </p><p>
 * If the servant is connected to more than one object, the exact object
 * being currently served can be identified with {@link #_object_id}.
 * </p><p>
 * The derivativ of Servant, being directly connected to serve requests,
 * must inherit either from {@link org.omg.CORBA.portable.InvokeHandler}
 * or from {@link org.omg.PortableServer.DynamicImplementation}).
 * </p><p>
 * The Servant type is a CORBA <code>native</code> type.
 * </p>
 *
 * @see POA#servant_to_reference(Servant)
 *
 * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
 */
public abstract class Servant
{
  /**
   * The delegate, where calls to some Servant methods are forwarded.
   */
  private Delegate delegate;

  /**
   * Get the repository ids of all interfaces, supported by the
   * CORBA object, identified by the passed Id. In the typical code the
   * passed parameters are ignored, returning an array of repository ids,
   * supported by the servant implementation.
   *
   * @param poa a POA of the given object.
   * @param object_ID the object Id of the given object.
   *
   * @return an array, containing the repository ids.
   */
  public abstract String[] _all_interfaces(POA poa, byte[] object_ID);

  /**
   * Get the delegate, where calls to some Servant methods are forwarded.
   */
  public final Delegate _get_delegate()
  {
    if (delegate == null) {
      throw new BAD_INV_ORDER
	("The Servant has not been associated with an ORBinstance");
    }
    return delegate;
  }

  /**
  * Get the interface repository definition <code>InterfaceDef</code> for this
  * Object. By default, forwards request to the delegate.
  *
  * @specnote The interface repository is officially not implemented up till
  * JDK 1.5 inclusive. The delegate throws NO_IMPLEMENT, always.
  */
  public org.omg.CORBA.Object _get_interface_def()
  {
    throw new NO_IMPLEMENT();
  }

  /**
  * Checks if the passed servant is an instance of the given CORBA IDL type.
  * By default, forwards the requet to the delegate.
  *
  * @param repository_id a repository ID, representing an IDL type for that the
  * servant must be checked.
  *
  * @return true if the servant is an instance of the given type, false
  * otherwise.
  */
  public boolean _is_a(String repository_id)
  {
    return delegate.is_a(this, repository_id);
  }

  /**
   * Determines if the server object for this reference has already
   * been destroyed. By default, forwards request to the delegate.
   *
   * @return true if the object has been destroyed, false otherwise.
   */
  public boolean _non_existent()
  {
    return delegate.non_existent(this);
  }

  /**
  * Returns the ORB that is directly associated with the given servant.
  * In this implementation, the method is overridden to return
  */
  public final ORB _orb()
  {
    return delegate.orb(this);
  }

  /**
   * Returns the root POA of the ORB instance, associated with this servant.
   * It is the same POA that would be returned by resolving the initial
   * reference "RootPOA" for that orb. By default, forwards request to the
   * delegate.
   *
   * @see ORB#resolve_initial_references
   */
  public POA _default_POA()
  {
    return delegate == null ? null : delegate.default_POA(this);
  }

  /**
  * Return the invocation target object identifier as a byte array.
  * This is typically used when the same servant serves multiple objects,
  * and the object id can encapsulated the whole description of the
  * object.
  *
  * This method returns correct values even when the same
  * servant serves several objects in parallel threads. The ORB maintains the
  * thread to invocation data map for all calls that are currently being
  * processed.
  */
  public final byte[] _object_id()
  {
    if (delegate != null)
      return delegate.object_id(this);
    else
      throw new OBJECT_NOT_EXIST();
  }

  /**
  * Get POA that is directly associated with the given servant.
  * By default, forwards request to the delegate.
  */
  public final POA _poa()
  {
    return delegate.poa(this);
  }

  /**
  * Set the delegate for this servant.
  */
  public final void _set_delegate(Delegate a_delegate)
  {
    delegate = a_delegate;
  }

  /**
  * Obtains the CORBA object reference that is a current invocation target for
  * the given servant. This is important when the same servant serves
  * multiple objects. If the servant is not yet connected to the passed
  * orb, the method will try to connect it to that orb on POA, returned
  * by the method {@link #_default_POA}. That method can be overridden to
  * get poa where the object must be automatically connected when
  * calling this method.
  *
  * @param an_orb the ORB with relate to that the object is requested.
  */
  public final org.omg.CORBA.Object _this_object(ORB an_orb)
  {
    if (delegate != null)
      return delegate.this_object(this);
    else
      {
        if (an_orb instanceof ORB_1_4)
          {
            ORB_1_4 m_orb = (ORB_1_4) an_orb;

            gnuPOA dp = (gnuPOA) _default_POA();
            if (dp == null)
              dp = m_orb.rootPOA;

            try
              {
                return dp.servant_to_reference(this);
              }
            catch (WrongPolicy unexp)
              {
                BAD_OPERATION bad = new BAD_OPERATION();
                bad.minor = Minor.Policy;
                bad.initCause(unexp);
                throw bad;
              }
            catch (ServantNotActive ex)
              {
                try
                  {
                    return dp.id_to_reference(dp.activate_object(this));
                  }
                catch (Exception unexp)
                  {
                    unexp.initCause(ex);

                    BAD_OPERATION bad = new BAD_OPERATION();
                    bad.minor = Minor.Activation;
                    bad.initCause(unexp);
                    throw bad;
                  }
              }
          }
      }
    throw new OBJECT_NOT_EXIST();
  }

  /**
  * Obtains the CORBA object reference that is a current invocation target for
  * the given servant. This is important when the same servant serves
  * multiple objects. This method required the servant to be connected
  * to a single orb, and a delegate set.
  *
  * This method returns correct values even when the same
  * servant serves several objects in parallel threads. The ORB maintains the
  * thread to invocation data map for all calls that are currently being
  * processed.
  */
  public final org.omg.CORBA.Object _this_object()
  {
    if (delegate != null)
      return _this_object(_orb());
    else
      {
        POA def = _default_POA();
        if (def instanceof gnuPOA)
          return _this_object(((gnuPOA) def).orb());
      }
    throw new OBJECT_NOT_EXIST();
  }
}