package jacorb.orb.portableInterceptor;

import org.omg.IOP.*;
import org.omg.CORBA.*;
import org.omg.PortableInterceptor.*;
import org.omg.Dynamic.Parameter;
import java.util.*;
/**
 * This class represents the type of info object,
 * that will be passed to the ClientRequestInterceptors.<br>
 * See PI Spec p.5-46ff
 *
 * @author Nicolas Noffke
 * @version $Id: ClientRequestInfoImpl.java,v 1.1 2000/03/30 12:20:37 noffke Exp $
 */

public class ClientRequestInfoImpl extends RequestInfoImpl 
  implements ClientRequestInfo  {

  //from ClientRequestInfo
  public org.omg.CORBA.Object target = null;
  public org.omg.CORBA.Object effective_target = null;
  public TaggedProfile effective_profile = null;
  public Any received_exception = null;
  public String received_exception_id = null;
  public TaggedComponent[] effective_components = null;
  public jacorb.orb.Delegate delegate = null;
  public jacorb.orb.ORB orb = null;


  public ClientRequestInfoImpl() {
    super();
  }

  /**
   * This method builds an array of ServiceContexts.
   * The last ServiceContext is a dummy object for
   * data aligning purposes.
   */
  public ServiceContext[] getRequestServiceContexts(){
    //copying manually for jdk1.1 compatibility
    ServiceContext[] _ctx = new ServiceContext[request_ctx.size() + 1];
    Enumeration _enum = request_ctx.elements(); 
    int _i = 0;
    while(_enum.hasMoreElements())
      _ctx[_i++] = (ServiceContext) _enum.nextElement();

    _ctx[_ctx.length - 1] = new ServiceContext(Integer.MAX_VALUE, new byte[0]);

    return _ctx;
  }

  // implementation of org.omg.PortableInterceptor.RequestInfoOperations interface
  public Parameter[] arguments() {
    if (! (caller_op == ClientInterceptorEnumeration.SEND_REQUEST) &&
	! (caller_op == ClientInterceptorEnumeration.RECEIVE_REPLY))
      //Supposed to have a minor code of TBD_BIO - has to wait until implemented
      throw new org.omg.CORBA.BAD_INV_ORDER("The attribute \"arguments\" is currently invalid!");

    if (arguments == null)
      //Supposed to have a minor code of TBD_NR - has to wait until implemented
      throw new org.omg.CORBA.NO_RESOURCES("Stream-based skeletons/stubs do not support this op");
    else
      return arguments;
  }

  public TypeCode[] exceptions() {
    if (caller_op == ClientInterceptorEnumeration.SEND_POLL)
      //Supposed to have a minor code of TBD_BIO - has to wait until implemented
      throw new org.omg.CORBA.BAD_INV_ORDER("The attribute \"exceptions\" is currently invalid!");

    if (exceptions == null)
      //Supposed to have a minor code of TBD_NR - has to wait until implemented
      throw new org.omg.CORBA.NO_RESOURCES("Stream-based skeletons/stubs do not support this op");
    else
      return exceptions;
  }

  public Any result() {
    if (caller_op != ClientInterceptorEnumeration.RECEIVE_REPLY)
      //Supposed to have a minor code of TBD_BIO - has to wait until implemented
      throw new org.omg.CORBA.BAD_INV_ORDER("The attribute \"result\" is currently invalid!");

    if (result == null)
      //Supposed to have a minor code of TBD_NR - has to wait until implemented
      throw new org.omg.CORBA.NO_RESOURCES("Stream-based skeletons/stubs do not support this op");
    else
      return result;
  }

  public short sync_scope() {
    if (caller_op == ClientInterceptorEnumeration.SEND_POLL)
      //Supposed to have a minor code of TBD_BIO - has to wait until implemented
      throw new org.omg.CORBA.BAD_INV_ORDER("The attribute \"operation_context\" is currently invalid!");

    return org.omg.Messaging.SYNC_WITH_TRANSPORT.value;
  }
 
  public short reply_status() {
    if ((caller_op == ClientInterceptorEnumeration.SEND_REQUEST) ||
	(caller_op == ClientInterceptorEnumeration.SEND_POLL))
      //Supposed to have a minor code of TBD_BIO - has to wait until implemented
      throw new org.omg.CORBA.BAD_INV_ORDER("The attribute \"reply_status\" is currently invalid!");

    return reply_status;
  }

  /**
   *
   * @return <description>
   */
  public org.omg.CORBA.Object forward_reference() {
    if (! (caller_op != ClientInterceptorEnumeration.RECEIVE_OTHER) ||
	((reply_status != LOCATION_FORWARD_PERMANENT.value) &&
	 (reply_status != LOCATION_FORWARD.value)))
      //Supposed to have a minor code of TBD_BIO - has to wait until implemented
      throw new org.omg.CORBA.BAD_INV_ORDER("The attribute \"forward_reference\" is currently invalid!");

    return forward_reference;
  }

  public ServiceContext get_request_service_context(int id) {
    if (caller_op == ClientInterceptorEnumeration.SEND_POLL)
      //Supposed to have a minor code of TBD_BIO - has to wait until implemented
      throw new org.omg.CORBA.BAD_INV_ORDER("The attribute \"operation_context\" is currently invalid!");

      return super.get_request_service_context(id);
  }

  public ServiceContext get_reply_service_context(int id) {
    if ((caller_op == ClientInterceptorEnumeration.SEND_REQUEST) ||
	(caller_op == ClientInterceptorEnumeration.SEND_POLL))
      //Supposed to have a minor code of TBD_BIO - has to wait until implemented
      throw new org.omg.CORBA.BAD_INV_ORDER("The attribute \"reply_status\" is currently invalid!");

      return super.get_reply_service_context(id);
  }
  
  // implementation of org.omg.PortableInterceptor.ClientRequestInfoOperations interface
  public org.omg.CORBA.Object target() {
    return target;
  }
  
  public org.omg.CORBA.Object effective_target() {
    return effective_target;
  }

  public TaggedProfile effective_profile() {
    return effective_profile;
  }
  
  public Any received_exception() {
    if (caller_op != ClientInterceptorEnumeration.RECEIVE_EXCEPTION)
      //Supposed to have a minor code of TBD_BIO - has to wait until implemented
      throw new org.omg.CORBA.BAD_INV_ORDER("The attribute \"received_exception\" is currently invalid!");

    return received_exception;
  }

  public String received_exception_id() {
    if (caller_op != ClientInterceptorEnumeration.RECEIVE_EXCEPTION)
      //Supposed to have a minor code of TBD_BIO - has to wait until implemented
      throw new org.omg.CORBA.BAD_INV_ORDER("The attribute \"received_exception_id\" is currently invalid!");

    return received_exception_id;
  }
   
  public TaggedComponent get_effective_component(int id) {
    if (caller_op == ClientInterceptorEnumeration.SEND_POLL)
      //Supposed to have a minor code of TBD_BIO - has to wait until implemented
      throw new org.omg.CORBA.BAD_INV_ORDER("The operation \"get_effective_component\" is currently invalid!");

    for(int _i = 0; _i < effective_components.length; _i++)
      if (effective_components[_i].tag == id)
	return effective_components[_i];
    
    //Supposed to have a minor code of TBD_BP+2 - has to wait until implemented
    throw new org.omg.CORBA.BAD_PARAM("No TaggedComponent with id " + id + " found"); 
  }
  
  public TaggedComponent[] get_effective_components(int id) {
    if (caller_op == ClientInterceptorEnumeration.SEND_POLL)
      //Supposed to have a minor code of TBD_BIO - has to wait until implemented
      throw new org.omg.CORBA.BAD_INV_ORDER("The operation \"get_effective_components\" is currently invalid!");
    Vector _store = new Vector();
    for(int _i = 0; _i < effective_components.length; _i++)
      if (effective_components[_i].tag == id)
	_store.addElement(effective_components[_i]);

    if (_store.size() == 0)
      //Supposed to have a minor code of TBD_BP+2 - has to wait until implemented
      throw new org.omg.CORBA.BAD_PARAM("No TaggedComponents with id " + id + " found");
    else{
      TaggedComponent[] _result = new TaggedComponent[_store.size()];
      for (int _i = 0; _i < _result.length; _i++)
	_result[_i] = (TaggedComponent) _store.elementAt(_i);

      return _result;
    }
  }
  
  /**
   * WARNING: This method relies on the DomainService to be available.
   * Make shure that the DS is running, if you want to call this method.
   */
  public Policy get_request_policy(int type) {
    if (caller_op == ClientInterceptorEnumeration.SEND_POLL)
      //Supposed to have a minor code of TBD_BIO - has to wait until implemented
      throw new org.omg.CORBA.BAD_INV_ORDER("The operation \"get_request_policy\" is currently invalid!");

    if (! orb.hasPolicyFactoryForType(type))
      //Supposed to have a minor code of TBD_IP - has to wait until implemented
      throw new org.omg.CORBA.INV_POLICY("No PolicyFactory for type " +
					 type + " has been registered!");
    try{
      return delegate.get_policy_no_intercept(target, type);
    }catch(org.omg.CORBA.INV_POLICY _e){
      //Supposed to have a minor code of TBD_IP - has to wait until implemented
      //_e.minor = ;
      throw _e;
    }
  }
 
  public void add_request_service_context(ServiceContext service_context, boolean replace) {
    if (caller_op != ClientInterceptorEnumeration.SEND_REQUEST)
      //Supposed to have a minor code of TBD_BIO - has to wait until implemented
      throw new org.omg.CORBA.BAD_INV_ORDER("The operation \"add_request_service_context\" is currently invalid!");
    Integer _id = new Integer(service_context.context_id);

    if (! replace && request_ctx.containsKey(_id))
      //Supposed to have a minor code of TBD_BIO+1 - has to wait until implemented
      throw new org.omg.CORBA.BAD_INV_ORDER("The ServiceContext with id " + _id.toString() 
					    + " has already been set!");
    request_ctx.put(_id, service_context);
  }
} // ClientRequestInfoImpl
