/*
 * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#ifndef _IOP_IDL_
#define _IOP_IDL_

#include "CORBAX.idl"

#pragma prefix "omg.org"

#ifndef CORBA3
#define local
#endif

module IOP {
    //
    // Standard Protocol Profile tag values
    //
    /** Profile ID */
    typedef unsigned long ProfileId;

    /**
     * Identifies profiles that 
     * support the Internet Inter-ORB Protocol. The <code>ProfileBody</code>
     * of this profile contains a CDR encapsulation of a structure 
     * containing addressing and object identification information used by 
     * IIOP. Version 1.1 of the <code>TAG_INTERNET_IOP</code> profile 
     * also includes an array of TaggedComponent objects that can 
     * contain additional information supporting optional IIOP features, 
     * ORB services such as security, and future protocol extensions. 
     * <p>
     * Protocols other than IIOP (such as ESIOPs and other GIOPs) can share 
     * profile information (such as object identity or security 
     * information) with IIOP by encoding their additional profile information 
     * as components in the <code>TAG_INTERNET_IOP</code> profile. All 
     * <code>TAG_INTERNET_IOP</code> profiles support IIOP, regardless of 
     * whether they also support additional protocols. Interoperable 
     * ORBs are not required to create or understand any other profile, 
     * nor are they required to create or understand any of the components 
     * defined for other protocols that might share the 
     * <code>TAG_INTERNET_IOP</code> profile with IIOP. 
     * <p>
     * The <code>profile_data</code> for the <code>TAG_INTERNET_IOP</code> 
     * profile is a CDR encapsulation of the <code>IIOP.ProfileBody_1_1</code>
     * type.
     */
    const ProfileId TAG_INTERNET_IOP = 0;

    /** 
     * Indicates that the value encapsulated is of type 
     * <code>MultipleComponentProfile</code>. In this case, the profile 
     * consists of a list of protocol components, the use of which must 
     * be specified by the protocol using this profile. This profile may 
     * be used to carry IOR components.  
     * <p>
     * The <code>profile_data</code> for the 
     * <code>TAG_MULTIPLE_COMPONENTS</code> profile is a CDR encapsulation 
     * of the <code>MultipleComponentProfile</code> type shown above.
     */
    const ProfileId TAG_MULTIPLE_COMPONENTS = 1;

    /** 
     * Object references have at least one tagged profile. Each profile 
     * supports one or more protocols and encapsulates all the basic 
     * information the protocols it supports need to identify an object. 
     * Any single profile holds enough information to drive a complete 
     * invocation using any of the protocols it supports; the content 
     * and structure of those profile entries are wholly specified by 
     * these protocols.
     */
    struct TaggedProfile {
	/** The tag, represented as a profile id. */
        ProfileId tag;

	/** The associated profile data. */
        sequence <octet> profile_data;
    };

    /**
     * Captures information about a object references, such as whether the
     * object is null, what type it is, what protocols are supported, and what
     * ORB services are available.
     * <p>
     * This data structure need not be used internally to any given ORB, 
     * and is not intended to be visible to application-level ORB programmers.
     * It should be used only when crossing object reference domain 
     * boundaries, within bridges.
     * <p>
     * This data structure is designed to be efficient in typical 
     * single-protocol configurations, while not penalizing multiprotocol ones.
     * <p>
     * Object references have at least one tagged profile. Each profile 
     * supports one or more protocols and encapsulates all the basic 
     * information the protocols it supports need to identify an object. 
     * Any single profile holds enough information to drive a complete
     * invocation using any of the protocols it supports; the content 
     * and structure of those profile entries are wholly specified by 
     * these protocols. A bridge between two domains may need to know the 
     * detailed content of the profile for those domains' profiles,
     * depending on the technique it uses to bridge the domains.
     * <p>
     * Each profile has a unique numeric tag, assigned by the OMG. 
     * Profile tags in the range 0x80000000 through 0xffffffff are reserved 
     * for future use, and are not currently available for assignment.
     * <p>
     * Null object references are indicated by an empty set of profiles, 
     * and by a "Null" type ID (a string which contains only a single 
     * terminating character). A Null <code>TypeID</code> is the only 
     * mechanism that can be used to represent the type 
     * <code>CORBA.Object</code>. Type IDs may only be "Null" in any message, 
     * requiring the client to use existing knowledge or to consult the 
     * object, to determine interface types supported. The type ID 
     * is a Repository ID identifying the interface type, and is provided 
     * to allow ORBs to preserve strong typing. This identifier is agreed 
     * on within the bridge and, for reasons outside the scope of the
     * interoperability specification, needs to have a much broader scope to
     * address various problems in system evolution and maintenance. 
     * Type IDs support detection of type equivalence, and in conjunction 
     * with an Interface Repository, allow processes to reason about the 
     * relationship of the type of the object referred to and any other type.
     * <p>
     * The type ID, if provided by the server, indicates the most derived 
     * type that the server wishes to publish, at the time the reference 
     * is generated. The object's actual most derived type may later change 
     * to a more derived type. Therefore, the type ID in the IOR can only 
     * be interpreted by the client as a hint that the object supports at 
     * least the indicated interface. The client can succeed in narrowing 
     * the reference to the indicated interface, or to one of its base 
     * interfaces, based solely on the type ID in the IOR, but must not fail 
     * to narrow the reference without consulting the object via the
     * "_is_a" or "_get_interface" pseudo-operations.
     */
    struct IOR {
	/** The type id, represented as a String. */
        string type_id;

	/** 
	 * An array of tagged profiles associated with this 
	 * object reference. 
	 */
        sequence <TaggedProfile> profiles;
    };

    /**
     * Standard way of representing multicomponent profiles.
     * This would be encapsulated in a TaggedProfile.
     */
    typedef unsigned long ComponentId;

    /**
     * <code>TaggedComponents</code> contained in 
     * <code>TAG_INTERNET_IOP</code> and 
     * <code>TAG_MULTIPLE_COMPONENTS</code> profiles are identified by 
     * unique numeric tags using a namespace distinct form that is used for 
     * profile tags. Component tags are assigned by the OMG.
     * <p>
     * Specifications of components must include the following information:
     * <ul>
     *   <li><i>Component ID</i>: The compound tag that is obtained 
     *       from OMG.</li>
     *   <li><i>Structure and encoding</i>: The syntax of the component 
     *       data and the encoding rules.  If the component value is 
     *       encoded as a CDR encapsulation, the IDL type that is
     *       encapsulated and the GIOP version which is used for encoding 
     *       the value, if different than GIOP 1.0, must be specified as 
     *       part of the component definition.</li>
     *   <li><i>Semantics</i>: How the component data is intended to be 
     *       used.</li>
     *   <li><i>Protocols</i>: The protocol for which the component is 
     *       defined, and whether it is intended that the component be 
     *       usable by other protocols.</li>
     *   <li><i>At most once</i>: whether more than one instance of this 
     *       component can be included in a profile.</li>
     * </ul>
     * Specification of protocols must describe how the components affect 
     * the protocol. The following should be specified in any protocol 
     * definition for each <code>TaggedComponent</code> that the protocol uses:
     * <ul>
     *   <li><i>Mandatory presence</i>: Whether inclusion of the component 
     *       in profiles supporting the protocol is required (MANDATORY 
     *       PRESENCE) or not required (OPTIONAL PRESENCE).</li>
     *   <li><i>Droppable</i>: For optional presence component, whether 
     *       component, if present, must be retained or may be dropped.</li>
     * </ul>
     */
    struct TaggedComponent {
	/** The tag, represented as a component id. */
        ComponentId tag;

	/** The component data associated with the component id. */
        sequence <octet> component_data;
    };

    /**
     * It is often useful in the real world to be able to identify the 
     * particular kind of ORB an object reference is coming from, to work 
     * around problems with that particular ORB, or exploit shared 
     * efficiencies. 
     * <p>
     * The <code>TAG_ORB_TYPE</code> component has an associated value of 
     * type unsigned long (Java long), encoded as a CDR encapsulation, 
     * designating an ORB type ID allocated by the OMG for the ORB type of the 
     * originating ORB. Anyone may register any ORB types by submitting 
     * a short (one-paragraph) description of the ORB type to the OMG, 
     * and will receive a new ORB type ID in return. A list of ORB type 
     * descriptions and values will be made available on the OMG web server. 
     * <p>
     * The <code>TAG_ORB_TYPE</code> component can appear at most once in 
     * any IOR profile. For profiles supporting IIOP 1.1 or greater, it 
     * is optionally present.
     */
    const ComponentId TAG_ORB_TYPE = 0 ;

    /**
     * The code set component of the IOR multi-component profile structure
     * contains:
     * <ul>
     *   <li>server's native char code set and conversion code sets, and</li>
     *   <li>server's native wchar code set and conversion code sets.</li>
     * </ul>
     * Both char and wchar conversion code sets are listed in order of 
     * preference.
     */
    const ComponentId TAG_CODE_SETS = 1 ;

    /**
     * A profile component containing the sequence of QoS policies exported
     * with the object reference by an object adapter.
     */
    const ComponentId TAG_POLICIES = 2 ;

    /**
     * In cases where the same object key is used for more than one 
     * internet location, the following standard IOR Component is defined 
     * for support in IIOP version 1.2. 
     * <p>
     * The <code>TAG_ALTERNATE_IIOP_ADDRESS</code> component has an 
     * associated value of type:
     * <code>
     *   <pre>
     *     struct { 
     *         string HostID, 
     *         short Port 
     *     }; 
     *   </pre>
     * </code>
     * encoded as a CDR encapsulation. 
     * <p>
     * Zero or more instances of the <code>TAG_ALTERNATE_IIOP_ADDRESS</code> 
     * component type may be included in a version 1.2 
     * <code>TAG_INTERNET_IOP</code> Profile. Each of these alternative 
     * addresses may be used by the client orb, in addition to the host 
     * and port address expressed in the body of the Profile. In cases 
     * where one or more <code>TAG_ALTERNATE_IIOP_ADDRESS</code> components 
     * are present in a <code>TAG_INTERNET_IOP</code> Profile, no order of 
     * use is prescribed by Version 1.2 of IIOP.
     */
    const ComponentId TAG_ALTERNATE_IIOP_ADDRESS = 3 ;

    /**
     * Class downloading is supported for stubs, ties, values, and 
     * value helpers. The specification allows transmission of codebase 
     * information on the wire for stubs and ties, and enables usage of 
     * pre-existing ClassLoaders when relevant.  
     * <p>
     * For values and value helpers, the codebase is transmitted after the 
     * value tag.  For stubs and ties, the codebase is transmitted as 
     * the TaggedComponent <code>TAG_JAVA_CODEBASE</code> in the IOR 
     * profile, where the <code>component_data</code> is a CDR encapsulation 
     * of the codebase written as an IDL string. The codebase is a 
     * space-separated list of one or more URLs.
     */
    const ComponentId TAG_JAVA_CODEBASE = 25 ;

    /**
     * RMI-IIOP has multiple stream format versions.  A server
     * can specify its maximum version by including the
     * TAG_RMI_CUSTOM_MAX_STREAM_FORMAT tagged component or
     * rely on the default of version 1 for GIOP 1.2 and less
     * and version 2 for GIOP 1.3 and higher.
     *
     * See Java to IDL ptc/02-01-12 1.4.11.
     */
    const ComponentId TAG_RMI_CUSTOM_MAX_STREAM_FORMAT = 38 ;

    /** An array of tagged components, forming a multiple component profile. */
    typedef sequence <TaggedComponent> MultipleComponentProfile;

    /** A service id, represented as an int */
    typedef unsigned long ServiceId;

    /**
     * Service-specific information to be passed implicitly with requests
     * and replies.  Service contexts are composed of service ids and
     * associated data.
     */
    struct ServiceContext {
	/** The service context id */
        ServiceId context_id;

	/** The data associated with this service context */
        sequence <octet> context_data;
    };

    /** An array of service contexts, forming a service context list. */
    typedef sequence <ServiceContext>ServiceContextList;

    /**
     * Identifies a CDR encapsulation of the 
     * <code>CosTSInteroperation.PropogationContext</code> defined in 
     * <i>CORBAservices: Common Object Services Specifications.</i>
     */
    const ServiceId TransactionService = 0;

    /**
     * Identifies a CDR encapsulation of the 
     * <code>CONV_FRAME.CodeSetContext</code> defined in 
     * Section 13.10.2.5, "GIOP Code Set Service Context," on page 13-43.
     */
    const ServiceId CodeSets = 1;

    /**
     * Identifies a CDR encapsulation of the RMICustomMaxStreamFormat
     * service context which contains a single byte specifying
     * the client's maximum RMI-IIOP stream format version.
     *
     * See Java to IDL ptc/02-01-12 1.4.12.
     */
    const ServiceId RMICustomMaxStreamFormat = 17 ;

    /**
     * DCOM-CORBA Interworking uses three service contexts as defined in 
     * "DCOM-CORBA Interworking" in the "Interoperability with non-CORBA 
     * Systems" chapter.
     * <p>
     * <code>ChainBypassCheck</code> carries a CDR encapsulation of the 
     * <code>struct CosBridging.ChainBypassCheck</code>. This is carried 
     * only in a Request message as described in Section 20.9.1, "CORBA 
     * Chain Bypass," on page 20-19. 
     */
    const ServiceId ChainBypassCheck = 2;

    /**
     * DCOM-CORBA Interworking uses three service contexts as defined in 
     * "DCOM-CORBA Interworking" in the "Interoperability with non-CORBA 
     * Systems" chapter.
     * <p>
     * <code>ChainBypassInfo</code> carries a CDR encapsulation of the 
     * <code>struct CosBridging.ChainBypassInfo</code>. This is carried 
     * only in a Reply message as described in Section 20.9.1, "CORBA Chain 
     * Bypass," on page 20-19.
     */
    const ServiceId ChainBypassInfo = 3;

    /**
     * DCOM-CORBA Interworking uses three service contexts as defined in 
     * "DCOM-CORBA Interworking" in the "Interoperability with non-CORBA 
     * Systems" chapter.
     * <p>
     * <code>LogicalThreadId</code>, carries a CDR encapsulation of 
     * the <code>struct CosBridging.LogicalThreadId</code> as described 
     * in Section 20.10, "Thread Identification," on page 20-21.
     */
    const ServiceId LogicalThreadId = 4;

    /**
     * Identifies a CDR encapsulation of the 
     * <code>IIOP.BiDirIIOPServiceContext</code> defined in Section 15.8, 
     * "Bi-Directional GIOP," on page 15-55.
     */
    const ServiceId BI_DIR_IIOP = 5;

    /**
     * Identifies a CDR encapsulation of the IOR of the 
     * <code>SendingContext.RunTime</code> object (see Section 5.6, "Access 
     * to the Sending Context Run Time," on page 5-15). 
     */
    const ServiceId SendingContextRunTime = 6;

    /**
     * For information on <code>INVOCATION_POLICIES</code> refer to the 
     * Asynchronous Messaging specification - orbos/98-05-05.
     */
    const ServiceId INVOCATION_POLICIES = 7;

    /**
     * For information on <code>FORWARDED_IDENTITY</code> refer to the 
     * Firewall specification - orbos/98-05-04.
     */
    const ServiceId FORWARDED_IDENTITY = 8;

    /**
     * Identifies a CDR encapsulation of a marshaled instance of a 
     * java.lang.Throwable or one of its subclasses as described in Java 
     * to IDL Language Mapping, Section 1.4.8.1, "Mapping of 
     * UnknownExceptionInfo Service Context," on page 1-32.
     */
    const ServiceId UnknownExceptionInfo = 9;

    /**
     * CORBA formal/02-06-01: 13.7.1:
     * ExceptionDetailMessage identifies a CDR encapsulation of a wstring,
     * encoded using GIOP 1.2 with a TCS-W of UTF-16.  This service context
     * may be sent on Reply messages with a reply_status of SYSTEM_EXCEPTION
     * or USER_EXCEPTION. The usage of this service context is defined
     * by language mappings. <br/> <br/>
     *
     * IDL/Java: ptc/02-01-22: 1.15.2: 
     * When a System Exception is marshaled, its GIOP Reply message shall
     * include an associated ExceptionDetailMessage service context. The
     * callee's stack trace is often very valuable debugging information but
     * may contain sensitive or unwanted information. The wstring within the
     * service context will therefore contain additional information relating
     * to the exception, for example the result of calling either
     * printStackTrace(PrintWriter) or getMessage() on the exception. When
     * unmarshaling a System Exception on the client side, the wstring from
     * any ExceptionDetailMessage service context shall become the Java error
     * message in the unmarshaled exception object.
     */
    const ServiceId ExceptionDetailMessage = 14;


    // BEGIN part which lived in Interceptors.idl.

  /**
   * An array of <code>TaggedComponent</code> objects.
   */
  typedef sequence<IOP::TaggedComponent> TaggedComponentSeq;

  /**
   * The formats of IOR components and service context data used by ORB 
   * services are often defined as CDR encapsulations encoding instances 
   * of IDL defined data types. The <code>Codec</code> provides a mechanism 
   * to transfer these components between their IDL data types and their CDR 
   * encapsulation representations. 
   * <p>
   * A <code>Codec</code> is obtained from the <code>CodecFactory</code>. 
   * The <code>CodecFactory</code> is obtained through a call to 
   * <code>ORB.resolve_initial_references( "CodecFactory" )</code>.
   */
  local interface Codec {

    /**
     * This exception is thrown by <code>Codec.encode</code> or 
     * <code>Codec.encode_value</code> when the type is invalid for the 
     * encoding. For example, this exception is thrown if the encoding is 
     * <code>ENCODING_CDR_ENCAPS</code> version 1.0 and a type 
     * that does not exist in that version, such as <code>wstring</code>, 
     * is passed to the operation.
     */
    exception InvalidTypeForEncoding {};

    /**
     * This exception is thrown by <code>Codec.decode</code> or 
     * <code>Codec.decode_value</code> when the data in the byte array 
     * cannot be decoded into an Any.
     */
    exception FormatMismatch {};

    /**
     * This exception is thrown by <code>decode_value</code> when the given 
     * <code>TypeCode</code> does not match the given byte array.
     */
    exception TypeMismatch {};

    /**
     * Converts the given any into a byte array based on the encoding 
     * format effective for this <code>Codec</code>. 
     *
     * @param data The data, in the form of an any, to be encoded into 
     *     a byte array.
     * @return A byte array containing the encoded Any. This byte array 
     *     contains both the <code>TypeCode</code> and the data of the type.
     * @exception InvalidTypeForEncoding thrown if the type is not valid for 
     *     the encoding format effective for this <code>Codec</code>.
     */
    CORBA::OctetSeq encode (in any data) 
      raises (InvalidTypeForEncoding);

    /**
     * Decodes the given byte array into an Any based on the encoding 
     * format effective for this <code>Codec</code>. 
     * 
     * @param data The data, in the form of a byte array, to be decoded into 
     *     an Any. 
     * @return An Any containing the data from the decoded byte array.
     * @exception FormatMismatch is thrown if the byte array cannot be 
     *     decoded into an Any. 
     */
    any decode (in CORBA::OctetSeq data) raises (FormatMismatch);

    /**
     * Converts the given any into a byte array based on the encoding 
     * format effective for this Codec. Only the data from the Any is 
     * encoded, not the <code>TypeCode</code>. 
     *
     * @param data The data, in the form of an Any, to be encoded into 
     *     a byte array. 
     * @return A byte array containing the data from the encoded any.
     * @exception InvalidTypeForEncoding thrown if the type is not valid for 
     *     the encoding format effective for this <code>Codec</code>.
     */
    CORBA::OctetSeq encode_value (in any data) 
      raises (InvalidTypeForEncoding);

    /**
     * Decodes the given byte array into an Any based on the given 
     * <code>TypeCode</code> and the encoding format effective for 
     * this <code>Codec</code>. 
     *
     * @param data The data, in the form of a byte array, to be decoded 
     *     into an Any. 
     * @param tc The TypeCode to be used to decode the data. 
     * @return An Any containing the data from the decoded byte array.
     * @exception FormatMismatch thrown if the byte array cannot be 
     *     decoded into an Any. 
     */
    any decode_value (in CORBA::OctetSeq data, in CORBA::TypeCode tc)
      raises (FormatMismatch, TypeMismatch);
  };

  /**
   * Defines an encoding format of a <code>Codec</code>, such as 
   * CDR Encapsulation (<code>ENCODING_CDR_ENCAPS</code>).
   */
  typedef short EncodingFormat;

  /**
   * The CDR Encapsulation encoding.
   * @see CodecFactory
   */
  const EncodingFormat ENCODING_CDR_ENCAPS = 0;

  /**
   * Defines the encoding format of a <code>Codec</code>. This class 
   * details the encoding format, such as CDR Encapsulation encoding, and 
   * the major and minor versions of that format. 
   * <p>
   * The encodings currently supported are: 
   * <ul>
   *   <li><code>ENCODING_CDR_ENCAPS</code>, version 1.0;</li>
   *   <li><code>ENCODING_CDR_ENCAPS</code>, version 1.1;</li>
   *   <li><code>ENCODING_CDR_ENCAPS</code>, version 1.2;</li>
   *   <li><code>ENCODING_CDR_ENCAPS</code> for all future versions of GIOP as 
   *       they arise.</li>
   * </ul>
   * Vendors are free to support additional encodings.
   *
   * @see ENCODING_CDR_ENCAPS
   */
  struct Encoding {
    /**
     * The encoding format.
     */
    EncodingFormat format;

    /**
     * The major version of this Encoding format.
     */
    octet major_version;

    /**
     * The minor version of this Encoding format.
     */
    octet minor_version;
  };
  
  /**
   * <code>Codecs</code> are obtained from the <code>CodecFactory</code>. 
   * The <code>CodecFactory</code> is obtained through a call to 
   * <code>ORB.resolve_initial_references( "CodecFactory" )</code>.
   */
  local interface CodecFactory {
    /**
     * This exception is thrown by <code>CodecFactory.create_codec</code> when
     * the factory cannot create a <code>Codec</code> for a given encoding.
     */
    exception UnknownEncoding {};

    /**
     * Create a <code>Codec</code> of the given encoding.
     * <p>
     * @param enc The encoding for which to create a <code>Codec</code>.
     * @return A <code>Codec</code> obtained with the given encoding.
     * @exception UnknownEncoding thrown if this factory cannot create a 
     *     <code>Codec</code> of the given encoding.
     */
    Codec create_codec (in Encoding enc) raises (UnknownEncoding);
  };

    // END part which lived in Interceptors.idl.

};

#endif // _IOP_IDL_
