src/share/classes/com/sun/corba/se/impl/interceptors/RequestInfoImpl.java

Tue, 28 Dec 2010 15:52:36 -0800

author
ohair
date
Tue, 28 Dec 2010 15:52:36 -0800
changeset 240
f90b3e014e83
parent 215
cff5a173ec1e
child 475
39d15bbb5741
permissions
-rw-r--r--

6962318: Update copyright year
Reviewed-by: xdono

     1 /*
     2  * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    25 package com.sun.corba.se.impl.interceptors;
    27 import java.io.IOException ;
    29 import java.lang.reflect.Method ;
    30 import java.lang.reflect.InvocationTargetException ;
    32 import java.util.HashMap ;
    34 import org.omg.PortableInterceptor.ForwardRequest;
    35 import org.omg.PortableInterceptor.InvalidSlot;
    36 import org.omg.PortableInterceptor.RequestInfo;
    37 import org.omg.PortableInterceptor.LOCATION_FORWARD;
    38 import org.omg.IOP.TaggedProfile;
    39 import org.omg.IOP.TaggedComponent;
    40 import org.omg.IOP.ServiceContextHelper;
    41 import org.omg.Messaging.SYNC_WITH_TRANSPORT;
    42 import org.omg.CORBA.ParameterMode;
    44 import org.omg.CORBA.Any;
    45 import org.omg.CORBA.BAD_INV_ORDER;
    46 import org.omg.CORBA.BAD_PARAM;
    47 import org.omg.CORBA.CompletionStatus;
    48 import org.omg.CORBA.Context;
    49 import org.omg.CORBA.ContextList;
    50 import org.omg.CORBA.CTX_RESTRICT_SCOPE;
    51 import org.omg.CORBA.ExceptionList;
    52 import org.omg.CORBA.INTERNAL;
    53 import org.omg.CORBA.LocalObject;
    54 import org.omg.CORBA.NamedValue;
    55 import org.omg.CORBA.NO_IMPLEMENT;
    56 import org.omg.CORBA.NO_RESOURCES;
    57 import org.omg.CORBA.NVList;
    58 import org.omg.CORBA.Object;
    59 import org.omg.CORBA.Policy;
    60 import org.omg.CORBA.SystemException;
    61 import org.omg.CORBA.TypeCode;
    62 import org.omg.CORBA.UNKNOWN;
    63 import org.omg.CORBA.UserException;
    64 import org.omg.CORBA.portable.ApplicationException;
    65 import org.omg.CORBA.portable.Delegate;
    66 import org.omg.CORBA.portable.InputStream;
    68 import org.omg.Dynamic.Parameter;
    70 import com.sun.corba.se.spi.legacy.connection.Connection;
    72 import com.sun.corba.se.spi.legacy.interceptor.RequestInfoExt;
    74 import com.sun.corba.se.spi.ior.IOR;
    76 import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
    78 import com.sun.corba.se.spi.orb.ORB;
    80 import com.sun.corba.se.spi.logging.CORBALogDomains;
    82 import com.sun.corba.se.spi.servicecontext.ServiceContexts;
    83 import com.sun.corba.se.spi.servicecontext.UnknownServiceContext;
    85 import com.sun.corba.se.impl.encoding.CDRInputStream_1_0;
    86 import com.sun.corba.se.impl.encoding.EncapsOutputStream;
    88 import com.sun.corba.se.impl.orbutil.ORBUtility;
    89 import com.sun.corba.se.impl.orbutil.ORBClassLoader;
    91 import com.sun.corba.se.impl.util.RepositoryId;
    93 import com.sun.corba.se.impl.logging.InterceptorsSystemException;
    94 import com.sun.corba.se.impl.logging.OMGSystemException;
    96 /**
    97  * Implementation of the RequestInfo interface as specified in
    98  * orbos/99-12-02 section 5.4.1.
    99  */
   100 public abstract class RequestInfoImpl
   101     extends LocalObject
   102     implements RequestInfo, RequestInfoExt
   103 {
   104     //////////////////////////////////////////////////////////////////////
   105     //
   106     // NOTE: IF AN ATTRIBUTE IS ADDED, PLEASE UPDATE RESET();
   107     //
   108     //////////////////////////////////////////////////////////////////////
   110     // The ORB from which to get PICurrent and other info
   111     protected ORB myORB;
   112     protected InterceptorsSystemException wrapper ;
   113     protected OMGSystemException stdWrapper ;
   115     // The number of interceptors actually invoked for this client request.
   116     // See setFlowStackIndex for a detailed description.
   117     protected int flowStackIndex = 0;
   119     // The type of starting point call to make to the interceptors
   120     // See ClientRequestInfoImpl and ServerRequestInfoImpl for a list of
   121     // appropriate constants.
   122     protected int startingPointCall;
   124     // The type of intermediate point call to make to the interceptors
   125     // See ServerRequestInfoImpl for a list of appropriate constants.
   126     // This does not currently apply to client request interceptors but is
   127     // here in case intermediate points are introduced in the future.
   128     protected int intermediatePointCall;
   130     // The type of ending point call to make to the interceptors
   131     // See ClientRequestInfoImpl and ServerRequestInfoImpl for a list of
   132     // appropriate constants.
   133     protected int endingPointCall;
   135     // The reply status to return in reply_status.  This is initialized
   136     // to UNINITIALIZED so that we can tell if this has been set or not.
   137     protected short replyStatus = UNINITIALIZED;
   139     // Constant for an uninitizlied reply status.
   140     protected static final short UNINITIALIZED = -1;
   142     // Which points we are currently executing (so we can implement the
   143     // validity table).
   144     protected int currentExecutionPoint;
   145     protected static final int EXECUTION_POINT_STARTING = 0;
   146     protected static final int EXECUTION_POINT_INTERMEDIATE = 1;
   147     protected static final int EXECUTION_POINT_ENDING = 2;
   149     // Set to true if all interceptors have had all their points
   150     // executed.
   151     protected boolean alreadyExecuted;
   153     // Sources of request information
   154     protected Connection     connection;
   155     protected ServiceContexts serviceContexts;
   157     // The ForwardRequest object if this request is being forwarded.
   158     // Either the forwardRequest or the forwardRequestIOR field is set.
   159     // When set, the other field is set to null initially.  If the other
   160     // field is queried, it is lazily calculated and cached.  These
   161     // two attributes are always kept in sync.
   162     protected ForwardRequest forwardRequest;
   163     protected IOR forwardRequestIOR;
   165     // PICurrent's  SlotTable
   166     protected SlotTable slotTable;
   168     // The exception to be returned by received_exception and
   169     // received_exception_id
   170     protected Exception exception;
   172     //////////////////////////////////////////////////////////////////////
   173     //
   174     // NOTE: IF AN ATTRIBUTE IS ADDED, PLEASE UPDATE RESET();
   175     //
   176     //////////////////////////////////////////////////////////////////////
   178     /**
   179      * Reset the info object so that it can be reused for a retry,
   180      * for example.
   181      */
   182     void reset() {
   184         // Please keep these in the same order as declared above.
   186         flowStackIndex = 0;
   187         startingPointCall = 0;
   188         intermediatePointCall = 0;
   189         endingPointCall = 0;
   190         // 6763340
   191         setReplyStatus( UNINITIALIZED ) ;
   192         currentExecutionPoint = EXECUTION_POINT_STARTING;
   193         alreadyExecuted = false;
   194         connection = null;
   195         serviceContexts = null;
   196         forwardRequest = null;
   197         forwardRequestIOR = null;
   198         exception = null;
   200         // We don't need to reset the Slots because they are
   201         // already in the clean state after recieve_<point> interceptor
   202         // are called.
   203     }
   205     /*
   206      **********************************************************************
   207      * Access protection
   208      **********************************************************************/
   210     // Method IDs for all methods in RequestInfo.  This allows for a
   211     // convenient O(1) lookup for checkAccess().
   212     protected static final int MID_REQUEST_ID                   =  0;
   213     protected static final int MID_OPERATION                    =  1;
   214     protected static final int MID_ARGUMENTS                    =  2;
   215     protected static final int MID_EXCEPTIONS                   =  3;
   216     protected static final int MID_CONTEXTS                     =  4;
   217     protected static final int MID_OPERATION_CONTEXT            =  5;
   218     protected static final int MID_RESULT                       =  6;
   219     protected static final int MID_RESPONSE_EXPECTED            =  7;
   220     protected static final int MID_SYNC_SCOPE                   =  8;
   221     protected static final int MID_REPLY_STATUS                 =  9;
   222     protected static final int MID_FORWARD_REFERENCE            = 10;
   223     protected static final int MID_GET_SLOT                     = 11;
   224     protected static final int MID_GET_REQUEST_SERVICE_CONTEXT  = 12;
   225     protected static final int MID_GET_REPLY_SERVICE_CONTEXT    = 13;
   226     // The last value from RequestInfo (be sure to update this):
   227     protected static final int MID_RI_LAST                      = 13;
   229     /*
   230      **********************************************************************
   231      * Public interfaces
   232      **********************************************************************/
   234     /**
   235      * Creates a new RequestInfoImpl object.
   236      */
   237     public RequestInfoImpl( ORB myORB ) {
   238         super();
   240         this.myORB = myORB;
   241         wrapper = InterceptorsSystemException.get( myORB,
   242             CORBALogDomains.RPC_PROTOCOL ) ;
   243         stdWrapper = OMGSystemException.get( myORB,
   244             CORBALogDomains.RPC_PROTOCOL ) ;
   246         // Capture the current TSC and make it the RSC of this request.
   247         PICurrent current = (PICurrent)(myORB.getPIHandler().getPICurrent());
   248         slotTable = current.getSlotTable( );
   249     }
   251     /**
   252      * Implementation for request_id() differs for client and server
   253      * implementations.
   254      *
   255      * Uniquely identifies an active request/reply sequence.  Once a
   256      * request/reply sequence is concluded this ID may be reused.  (this
   257      * is NOT necessarily the same as the GIOP request_id).
   258      */
   259     abstract public int request_id ();
   261     /**
   262      * Implementation for operation() differs for client and server
   263      * implementations.
   264      *
   265      * The name of the operation being invoked.
   266      */
   267     abstract public String operation ();
   270     /**
   271      * This method returns the list of arguments for the operation that was
   272      * invoked. It raises NO_RESOURCES exception if the operation is not invoked
   273      * by using DII mechanism.
   274      */
   275     abstract public Parameter[] arguments ();
   277     /**
   278      * This method returns the list of exceptios  that was raised when the
   279      * operation was invoked. It raises NO_RESOURCES exception if the operation
   280      * is not invoked by using DII mechanism.
   281      */
   282     abstract public TypeCode[] exceptions ();
   284     /**
   285      * This method returns the list of contexts for the DII operation.
   286      * It raises NO_RESOURCES exception if the operation is not invoked by
   287      * using DII mechanism.
   288      */
   289     abstract public String[] contexts ();
   291     /**
   292      * This method returns the list of operation_context for the DII operation.
   293      * It raises NO_RESOURCES exception if the operation is not invoked by
   294      * using DII mechanism.
   295      */
   296     abstract public String[] operation_context ();
   298     /**
   299      * This method returns the result from the invoked DII operation.
   300      * It raises NO_RESOURCES exception if the operation is not invoked by
   301      * using DII mechanism.
   302      */
   303     abstract public Any result ();
   305     /**
   306      * Implementation for response_expected() differs for client and server
   307      * implementations.
   308      *
   309      * Indicates whether a response is expected.  On the client, a reply is
   310      * not returned when response_expected is false, so receive_reply cannot
   311      * be called.  receive_other is called unless an exception occurs, in
   312      * which case receive_exception is called.  On the client, within
   313      * send_poll, this attribute is true.
   314      */
   315     abstract public boolean response_expected ();
   317     /**
   318      * Defined in the Messaging specification.  Pertinent only when
   319      * response_expected is false.  If response_expected is true, the value
   320      * of sync_scope is undefined.  It defines how far the request shall
   321      * progress before control is returned to the client.  This attribute may
   322      * have one of the follwing values:
   323      * <ul>
   324      *   <li>Messaging::SYNC_NONE</li>
   325      *   <li>Messaging::SYNC_WITH_TRANSPORT</li>
   326      *   <li>Messaging::SYNC_WITH_SERVER</li>
   327      *   <li>Messaging::SYNC_WITH_TARGET</li>
   328      * </ul>
   329      */
   330     public short sync_scope (){
   331         checkAccess( MID_SYNC_SCOPE );
   332         return SYNC_WITH_TRANSPORT.value; // REVISIT - get from MessageMediator
   333     }
   335     /**
   336      * Describes the state of the result of the operation invocation.  Its
   337      * value can be one of the following:
   338      * <ul>
   339      *   <li>PortableInterceptor::SUCCESSFUL</li>
   340      *   <li>PortableInterceptor::SYSTEM_EXCEPTION</li>
   341      *   <li>PortableInterceptor::USER_EXCEPTION</li>
   342      *   <li>PortableInterceptor::LOCATION_FORWARD</li>
   343      *   <li>PortableInterceptor::TRANSPORT_RETRY</li>
   344      * </ul>
   345      */
   346     public short reply_status (){
   347         checkAccess( MID_REPLY_STATUS );
   348         return replyStatus;
   349     }
   351     /**
   352      * Implementation for forward_reference() differs for client and server
   353      * implementations.
   354      *
   355      * If the reply_status attribute is LOCATION_FORWARD
   356      * then this attribute will contain the object
   357      * to which the request will be forwarded.  It is indeterminate whether a
   358      * forwarded request will actually occur.
   359      */
   360     abstract public Object forward_reference ();
   363     /**
   364      * Returns the data from the given slot of the PortableInterceptor::Current
   365      * that is in the scope of the request.
   366      * <p>
   367      * If the given slot has not been set, then an any containing a type code
   368      * with a TCKind value of tk_null is returned.
   369      * <p>
   370      * If the ID does not define an allocated slot, InvalidSlot is raised.
   371      */
   372     public Any get_slot (int id)
   373         throws InvalidSlot
   374     {
   375         // access is currently valid for all states:
   376         //checkAccess( MID_GET_SLOT );
   377         // Delegate the call to the slotTable which was set when RequestInfo was
   378         // created.
   379         return slotTable.get_slot( id );
   380     }
   382     /**
   383      * Implementation for get_request_service_context() differs for client
   384      * and server implementations.
   385      *
   386      * This operation returns a copy of the service context with the given ID
   387      * that is associated with the request.  If the request's service context
   388      * does not contain an etry for that ID, BAD_PARAM with a minor code of
   389      * TBD_BP is raised.
   390      */
   391     abstract public org.omg.IOP.ServiceContext
   392         get_request_service_context(int id);
   394     /**
   395      * Implementation for get_reply_service_context() differs for client
   396      * and server implementations.
   397      *
   398      * This operation returns a copy of the service context with the given ID
   399      * that is associated with the reply.  IF the request's service context
   400      * does not contain an entry for that ID, BAD_PARAM with a minor code of
   401      * TBD_BP is raised.
   402      */
   403     abstract public org.omg.IOP.ServiceContext
   404         get_reply_service_context (int id);
   407     // NOTE: When adding a method, be sure to:
   408     // 1. Add a MID_* constant for that method
   409     // 2. Call checkAccess at the start of the method
   410     // 3. Define entries in the validCall[][] table for interception points
   411     //    in both ClientRequestInfoImpl and ServerRequestInfoImpl.
   415     /*
   416      **********************************************************************
   417      * Proprietary methods
   418      **********************************************************************/
   420     /**
   421      * @return The connection on which the request is made.
   422      *
   423      * Note: we store the connection as an internal type but
   424      * expose it here as an external type.
   425      */
   426     public com.sun.corba.se.spi.legacy.connection.Connection connection()
   427     {
   428         return connection;
   429     }
   431     /*
   432      **********************************************************************
   433      * Private utility methods
   434      **********************************************************************/
   436     /**
   437      * Inserts the UserException inside the given ApplicationException
   438      * into the given Any.  Throws an UNKNOWN with minor code
   439      * OMGSYstemException.UNKNOWN_USER_EXCEPTION if the Helper class could not be
   440      * found to insert it with.
   441      */
   442     private void insertApplicationException( ApplicationException appException,
   443                                              Any result )
   444         throws UNKNOWN
   445     {
   446         try {
   447             // Extract the UserException from the ApplicationException.
   448             // Look up class name from repository id:
   449             RepositoryId repId = RepositoryId.cache.getId(
   450                 appException.getId() );
   451             String className = repId.getClassName();
   453             // Find the read method on the helper class:
   454             String helperClassName = className + "Helper";
   455             Class helperClass = ORBClassLoader.loadClass( helperClassName );
   456             Class[] readParams = new Class[1];
   457             readParams[0] = org.omg.CORBA.portable.InputStream.class;
   458             Method readMethod = helperClass.getMethod( "read", readParams );
   460             // Invoke the read method, passing in the input stream to
   461             // retrieve the user exception.  Mark and reset the stream
   462             // as to not disturb it.
   463             InputStream ueInputStream = appException.getInputStream();
   464             ueInputStream.mark( 0 );
   465             UserException userException = null;
   466             try {
   467                 java.lang.Object[] readArguments = new java.lang.Object[1];
   468                 readArguments[0] = ueInputStream;
   469                 userException = (UserException)readMethod.invoke(
   470                     null, readArguments );
   471             }
   472             finally {
   473                 try {
   474                     ueInputStream.reset();
   475                 }
   476                 catch( IOException e ) {
   477                     throw wrapper.markAndResetFailed( e ) ;
   478                 }
   479             }
   481             // Insert this UserException into the provided Any using the
   482             // helper class.
   483             insertUserException( userException, result );
   484         } catch( ClassNotFoundException e ) {
   485             throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e ) ;
   486         } catch( NoSuchMethodException e ) {
   487             throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e ) ;
   488         } catch( SecurityException e ) {
   489             throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e ) ;
   490         } catch( IllegalAccessException e ) {
   491             throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e ) ;
   492         } catch( IllegalArgumentException e ) {
   493             throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e ) ;
   494         } catch( InvocationTargetException e ) {
   495             throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e ) ;
   496         }
   497     }
   499     /**
   500      * Inserts the UserException into the given Any.
   501      * Throws an UNKNOWN with minor code
   502      * OMGSYstemException.UNKNOWN_USER_EXCEPTION if the Helper class could not be
   503      * found to insert it with.
   504      */
   505     private void insertUserException( UserException userException, Any result )
   506         throws UNKNOWN
   507     {
   508         try {
   509             // Insert this UserException into the provided Any using the
   510             // helper class.
   511             if( userException != null ) {
   512                 Class exceptionClass = userException.getClass();
   513                 String className = exceptionClass.getName();
   514                 String helperClassName = className + "Helper";
   515                 Class helperClass = ORBClassLoader.loadClass( helperClassName );
   517                 // Find insert( Any, class ) method
   518                 Class[] insertMethodParams = new Class[2];
   519                 insertMethodParams[0] = org.omg.CORBA.Any.class;
   520                 insertMethodParams[1] = exceptionClass;
   521                 Method insertMethod = helperClass.getMethod(
   522                     "insert", insertMethodParams );
   524                 // Call helper.insert( result, userException ):
   525                 java.lang.Object[] insertMethodArguments =
   526                     new java.lang.Object[2];
   527                 insertMethodArguments[0] = result;
   528                 insertMethodArguments[1] = userException;
   529                 insertMethod.invoke( null, insertMethodArguments );
   530             }
   531         } catch( ClassNotFoundException e ) {
   532             throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e );
   533         } catch( NoSuchMethodException e ) {
   534             throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e );
   535         } catch( SecurityException e ) {
   536             throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e );
   537         } catch( IllegalAccessException e ) {
   538             throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e );
   539         } catch( IllegalArgumentException e ) {
   540             throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e );
   541         } catch( InvocationTargetException e ) {
   542             throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e );
   543         }
   544     }
   546     /*
   547      **********************************************************************
   548      * Protected utility methods
   549      **********************************************************************/
   551     /**
   552      * Internal utility method to convert an NVList into a PI Parameter[]
   553      */
   554     protected Parameter[] nvListToParameterArray( NVList parNVList ) {
   556         // _REVISIT_ This utility method should probably be doing a deep
   557         // copy so interceptor can't accidentally change the arguments.
   559         int count = parNVList.count();
   560         Parameter[] plist = new Parameter[count];
   561         try {
   562             for( int i = 0; i < count; i++ ) {
   563                 Parameter p = new Parameter();
   564                 plist[i] = p;
   565                 NamedValue nv = parNVList.item( i );
   566                 plist[i].argument = nv.value();
   567                 // ParameterMode spec can be found in 99-10-07.pdf
   568                 // Section:10.5.22
   569                 // nv.flags spec can be found in 99-10-07.pdf
   570                 // Section 7.1.1
   571                 // nv.flags has ARG_IN as 1, ARG_OUT as 2 and ARG_INOUT as 3
   572                 // To convert this into enum PARAM_IN, PARAM_OUT and
   573                 // PARAM_INOUT the value is subtracted by 1.
   574                 plist[i].mode = ParameterMode.from_int( nv.flags() - 1 );
   575             }
   576         } catch ( Exception e ) {
   577             throw wrapper.exceptionInArguments( e ) ;
   578         }
   580         return plist;
   581     }
   583     /**
   584      * Utility to wrap the given Exception in an Any object and return it.
   585      * If the exception is a UserException which cannot be inserted into
   586      * an any, then this returns an Any containing the system exception
   587      * UNKNOWN.
   588      */
   589     protected Any exceptionToAny( Exception exception ){
   590         Any result = myORB.create_any();
   592         if( exception == null ) {
   593             // Note: exception should never be null here since we will throw
   594             // a BAD_INV_ORDER if this is not called from receive_exception.
   595             throw wrapper.exceptionWasNull2() ;
   596         } else if( exception instanceof SystemException ) {
   597             ORBUtility.insertSystemException(
   598                 (SystemException)exception, result );
   599         } else if( exception instanceof ApplicationException ) {
   600             // Use the Helper class for this exception to insert it into an
   601             // Any.
   602             try {
   603                 // Insert the user exception inside the application exception
   604                 // into the Any result:
   605                 ApplicationException appException =
   606                     (ApplicationException)exception;
   607                 insertApplicationException( appException, result );
   608             } catch( UNKNOWN e ) {
   609                 // As per ptc/00-08-06, 21.3.13.4. if we cannot find the
   610                 // appropriate class, then return an any containing UNKNOWN,
   611                 // with a minor code of 1.  This is conveniently the same
   612                 // exception that is returned from the
   613                 // insertApplicationException utility method.
   614                 ORBUtility.insertSystemException( e, result );
   615             }
   616         } else if( exception instanceof UserException ) {
   617             try {
   618                 UserException userException = (UserException)exception;
   619                 insertUserException( userException, result );
   620             } catch( UNKNOWN e ) {
   621                 ORBUtility.insertSystemException( e, result );
   622             }
   623         }
   626         return result;
   627     }
   629     /**
   630      * Utility method to look up a service context with the given id and
   631      * convert it to an IOP.ServiceContext.  Uses the given HashMap as
   632      * a cache.  If not found in cache, the result is inserted in the cache.
   633      */
   634     protected org.omg.IOP.ServiceContext
   635         getServiceContext ( HashMap cachedServiceContexts,
   636                             ServiceContexts serviceContexts, int id )
   637     {
   638         org.omg.IOP.ServiceContext result = null;
   639         Integer integerId = new Integer( id );
   641         // Search cache first:
   642         result = (org.omg.IOP.ServiceContext)
   643             cachedServiceContexts.get( integerId );
   645         // null could normally mean that either we cached the value null
   646         // or it's not in the cache.  However, there is no way for us to
   647         // cache the value null in the following code.
   648         if( result == null ) {
   649             // Not in cache.  Find it and put in cache.
   650             // Get the desired "core" service context.
   651             com.sun.corba.se.spi.servicecontext.ServiceContext context =
   652                 serviceContexts.get( id );
   653             if (context == null)
   654                 throw stdWrapper.invalidServiceContextId() ;
   656             // Convert the "core" service context to an
   657             // "IOP" ServiceContext by writing it to a
   658             // CDROutputStream and reading it back.
   659             EncapsOutputStream out = new EncapsOutputStream(myORB);
   661             context.write( out, GIOPVersion.V1_2 );
   662             InputStream inputStream = out.create_input_stream();
   663             result = ServiceContextHelper.read( inputStream );
   665             cachedServiceContexts.put( integerId, result );
   666         }
   668         // Good citizen: For increased efficiency, we assume that interceptors
   669         // will not modify the returned ServiceContext.  Otherwise, we would
   670         // have to make a deep copy.
   672         return result;
   673     }
   676     /**
   677      * Utility method to add an IOP.ServiceContext to a core.ServiceContexts
   678      * object.  If replace is true, any service context with the given id
   679      * is replaced.
   680      * <p>
   681      * Raises BAD_INV_ORDER if replace is false and a service context with
   682      * the given id already exists.
   683      * <p>
   684      * Uses the given HashMap as a cache.  If a service context is placed
   685      * in the container, it goes in the HashMap as well.
   686      */
   687     protected void addServiceContext(
   688         HashMap cachedServiceContexts,
   689         ServiceContexts serviceContexts,
   690         org.omg.IOP.ServiceContext service_context,
   691         boolean replace )
   692     {
   693         int id = 0 ;
   694         // Convert IOP.service_context to core.ServiceContext:
   695         EncapsOutputStream outputStream = new EncapsOutputStream(
   696             myORB );
   697         InputStream inputStream = null;
   698         UnknownServiceContext coreServiceContext = null;
   699         ServiceContextHelper.write( outputStream, service_context );
   700         inputStream = outputStream.create_input_stream();
   702         // Constructor expects id to already have been read from stream.
   703         coreServiceContext = new UnknownServiceContext(
   704             inputStream.read_long(),
   705             (org.omg.CORBA_2_3.portable.InputStream)inputStream );
   707         id = coreServiceContext.getId();
   709         if (serviceContexts.get(id) != null)
   710             if (replace)
   711                 serviceContexts.delete( id );
   712             else
   713                 throw stdWrapper.serviceContextAddFailed( new Integer(id) ) ;
   715         serviceContexts.put( coreServiceContext );
   717         // Place IOP.ServiceContext in cache as well:
   718         cachedServiceContexts.put( new Integer( id ), service_context );
   719     }
   721     /**
   722      * Sets the number of interceptors whose starting interception
   723      * points were successfully invoked on this client call.  As specified
   724      * in orbos/99-12-02, section 5.2.1., not all interceptors will
   725      * be invoked if a ForwardRequest exception or a system exception
   726      * is raised.  This keeps track of how many were successfully executed
   727      * so we know not to execute the corresponding ending interception
   728      * points for the interceptors whose starting interception points
   729      * were not completed.  This simulates the "Flow Stack Visual Model"
   730      * presented in section 5.1.3.*/
   731     protected void setFlowStackIndex(int num ) {
   732         this.flowStackIndex = num;
   733     }
   735     /**
   736      * Returns the number of interceptors whose starting interception
   737      * points were actually invoked on this client request.  See
   738      * setFlowStackIndex for more details.
   739      */
   740     protected int getFlowStackIndex() {
   741         return this.flowStackIndex;
   742     }
   744     /**
   745      * Sets which ending interception point should be called
   746      * for each interceptor in the virtual flow stack.
   747      */
   748     protected void setEndingPointCall( int call ) {
   749         this.endingPointCall = call;
   750     }
   752     /**
   753      * Retrieves the current ending point call type (see
   754      * setEndingPointCall for more details).
   755      */
   756     protected int getEndingPointCall() {
   757         return this.endingPointCall;
   758     }
   760     /**
   761      * Sets which intermediate interception point should be called
   762      * for each interceptor in the virtual flow stack.
   763      */
   764     protected void setIntermediatePointCall( int call ) {
   765         this.intermediatePointCall = call;
   766     }
   768     /**
   769      * Retrieves the current intermediate point call type (see
   770      * setEndingPointCall for more details).
   771      */
   772     protected int getIntermediatePointCall() {
   773         return this.intermediatePointCall;
   774     }
   776     /**
   777      * Sets which starting interception point should be called
   778      * for each interceptor in the virtual flow stack.
   779      */
   780     protected void setStartingPointCall( int call ) {
   781         this.startingPointCall = call;
   782     }
   784     /**
   785      * Retrieves the current starting point call type (see
   786      * setStartingPointCall for more details).
   787      */
   788     protected int getStartingPointCall() {
   789         return this.startingPointCall;
   790     }
   792     /**
   793      * Returns true if all interceptors' starting and ending points
   794      * have already executed to completion, or false if not yet.
   795      */
   796     protected boolean getAlreadyExecuted() {
   797         return this.alreadyExecuted;
   798     }
   800     /**
   801      * Sets whether all interceotrs' starting and ending points
   802      * have already been executed to completion.
   803      */
   804     protected void setAlreadyExecuted( boolean alreadyExecuted ) {
   805         this.alreadyExecuted = alreadyExecuted;
   806     }
   808     /**
   809      * Sets the value to be returned by reply_status
   810      */
   811     protected void setReplyStatus( short replyStatus ) {
   812         this.replyStatus = replyStatus;
   813     }
   815     /**
   816      * Gets the current reply_status without doing an access check
   817      * (available only to package and subclasses)
   818      */
   819     protected short getReplyStatus() {
   820         return this.replyStatus;
   821     }
   823     /**
   824      * Stores the given ForwardRequest object for later analysis.
   825      * This version supplements setForwardRequest( IOR );
   826      */
   827     protected void setForwardRequest( ForwardRequest forwardRequest ) {
   828         this.forwardRequest = forwardRequest;
   829         this.forwardRequestIOR = null;
   830     }
   832     /**
   833      * Stores the given IOR for later forward request analysis.
   834      * This version supplements setForwardRequest( ForwardRequest );
   835      */
   836     protected void setForwardRequest( IOR ior ) {
   837         this.forwardRequestIOR = ior;
   838         this.forwardRequest = null;
   839     }
   841     /**
   842      * Retrieves the ForwardRequest object as a ForwardRequest exception.
   843      */
   844     protected ForwardRequest getForwardRequestException() {
   845         if( this.forwardRequest == null ) {
   846             if( this.forwardRequestIOR != null ) {
   847                 // Convert the internal IOR to a forward request exception
   848                 // by creating an object reference.
   849                 org.omg.CORBA.Object obj = iorToObject(this.forwardRequestIOR);
   850                 this.forwardRequest = new ForwardRequest( obj );
   851             }
   852         }
   854         return this.forwardRequest;
   855     }
   857     /**
   858      * Retrieves the IOR of the ForwardRequest exception.
   859      */
   860     protected IOR getForwardRequestIOR() {
   861         if( this.forwardRequestIOR == null ) {
   862             if( this.forwardRequest != null ) {
   863                 this.forwardRequestIOR = ORBUtility.getIOR(
   864                     this.forwardRequest.forward ) ;
   865             }
   866         }
   868         return this.forwardRequestIOR;
   869     }
   871     /**
   872      * Sets the exception to be returned by received_exception and
   873      * received_exception_id.
   874      */
   875     protected void setException( Exception exception ) {
   876         this.exception = exception;
   877     }
   879     /**
   880      * Returns the exception to be returned by received_exception and
   881      * received_exception_id.
   882      */
   883     Exception getException() {
   884         return this.exception;
   885     }
   887     /**
   888      * Sets the execution point that we are currently executing
   889      * (starting points, intermediate points, or ending points).
   890      * This allows us to enforce the validity table.
   891      */
   892     protected void setCurrentExecutionPoint( int executionPoint ) {
   893         this.currentExecutionPoint = executionPoint;
   894     }
   896     /**
   897      * Check whether the caller is allowed to access this method at
   898      * this particular time.  This is overridden in subclasses to implement
   899      * the validity table specified in ptc/00-04-05, table 21-1 and 21-2.
   900      * The currentExecutionPoint attribute is checked, and if access is
   901      * forbidden at this time, BAD_INV_ORDER is raised with a minor code of
   902      * TBD_BIO.
   903      *
   904      * @param methodID The ID of this method, one of the MID_* constants.
   905      *     This allows us to easily look up the method access in a table.
   906      *     Note that method ids may overlap between subclasses.
   907      */
   908     protected abstract void checkAccess( int methodID )
   909         throws BAD_INV_ORDER;
   911     /**
   912      * The server side does an explicit set rather than taking the
   913      * current PICurrent table as is done in the general RequestInfoImpl
   914      * constructor.
   915      */
   916     void setSlotTable(SlotTable slotTable)
   917     {
   918         this.slotTable = slotTable;
   919     }
   921     protected org.omg.CORBA.Object iorToObject( IOR ior )
   922     {
   923         return ORBUtility.makeObjectReference( ior ) ;
   924     }
   925 }

mercurial