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

Sat, 01 Dec 2007 00:00:00 +0000

author
duke
date
Sat, 01 Dec 2007 00:00:00 +0000
changeset 1
55540e827aef
child 158
91006f157c46
permissions
-rw-r--r--

Initial load

     1 /*
     2  * Copyright 2000-2003 Sun Microsystems, Inc.  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.  Sun designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
    23  * have any questions.
    24  */
    26 package com.sun.corba.se.impl.interceptors;
    28 import java.util.HashMap ;
    30 import org.omg.CORBA.Any;
    31 import org.omg.CORBA.BAD_INV_ORDER;
    32 import org.omg.CORBA.BAD_PARAM;
    33 import org.omg.CORBA.CompletionStatus;
    34 import org.omg.CORBA.Context;
    35 import org.omg.CORBA.ContextList;
    36 import org.omg.CORBA.CTX_RESTRICT_SCOPE;
    37 import org.omg.CORBA.ExceptionList;
    38 import org.omg.CORBA.LocalObject;
    39 import org.omg.CORBA.NamedValue;
    40 import org.omg.CORBA.NO_IMPLEMENT;
    41 import org.omg.CORBA.NO_RESOURCES;
    42 import org.omg.CORBA.NVList;
    43 import org.omg.CORBA.Object;
    44 import org.omg.CORBA.ParameterMode;
    45 import org.omg.CORBA.Policy;
    46 import org.omg.CORBA.SystemException;
    47 import org.omg.CORBA.TypeCode;
    48 import org.omg.CORBA.INTERNAL;
    49 import org.omg.CORBA.UserException;
    50 import org.omg.CORBA.portable.ApplicationException;
    51 import org.omg.CORBA.portable.InputStream;
    52 import com.sun.corba.se.spi.servicecontext.ServiceContexts;
    53 import com.sun.corba.se.spi.servicecontext.UnknownServiceContext;
    55 import org.omg.IOP.ServiceContext;
    56 import org.omg.IOP.ServiceContextHelper;
    57 import org.omg.IOP.TaggedProfile;
    58 import org.omg.IOP.TaggedProfileHelper;
    59 import org.omg.IOP.TaggedComponent;
    60 import org.omg.IOP.TaggedComponentHelper;
    61 import org.omg.IOP.TAG_INTERNET_IOP;
    62 import org.omg.Dynamic.Parameter;
    63 import org.omg.PortableInterceptor.ClientRequestInfo;
    64 import org.omg.PortableInterceptor.LOCATION_FORWARD;
    65 import org.omg.PortableInterceptor.SUCCESSFUL;
    66 import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
    67 import org.omg.PortableInterceptor.TRANSPORT_RETRY;
    68 import org.omg.PortableInterceptor.USER_EXCEPTION;
    70 import com.sun.corba.se.pept.protocol.MessageMediator;
    72 import com.sun.corba.se.spi.ior.IOR;
    73 import com.sun.corba.se.spi.ior.iiop.IIOPProfileTemplate;
    74 import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
    75 import com.sun.corba.se.spi.orb.ORB;
    76 import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
    77 import com.sun.corba.se.spi.transport.CorbaContactInfo;
    78 import com.sun.corba.se.spi.transport.CorbaContactInfoList;
    79 import com.sun.corba.se.spi.transport.CorbaContactInfoListIterator;
    81 import com.sun.corba.se.impl.encoding.CDROutputStream;
    82 import com.sun.corba.se.impl.encoding.CDRInputStream_1_0;
    83 import com.sun.corba.se.impl.orbutil.ORBUtility;
    84 import com.sun.corba.se.impl.protocol.CorbaInvocationInfo;
    85 import com.sun.corba.se.impl.util.RepositoryId;
    87 /**
    88  * Implementation of the ClientRequestInfo interface as specified in
    89  * orbos/99-12-02 section 5.4.2.
    90  */
    91 public final class ClientRequestInfoImpl
    92     extends RequestInfoImpl
    93     implements ClientRequestInfo
    94 {
    96     // The available constants for startingPointCall
    97     static final int CALL_SEND_REQUEST = 0;
    98     static final int CALL_SEND_POLL = 1;
   100     // The available constants for endingPointCall
   101     static final int CALL_RECEIVE_REPLY = 0;
   102     static final int CALL_RECEIVE_EXCEPTION = 1;
   103     static final int CALL_RECEIVE_OTHER = 2;
   105     //////////////////////////////////////////////////////////////////////
   106     //
   107     // NOTE: IF AN ATTRIBUTE IS ADDED, PLEASE UPDATE RESET();
   108     //
   109     //////////////////////////////////////////////////////////////////////
   111     // The current retry request status.  True if this request is being
   112     // retried and this info object is to be reused, or false otherwise.
   113     private boolean retryRequest;
   115     // The number of times this info object has been (re)used.  This is
   116     // incremented every time a request is retried, and decremented every
   117     // time a request is complete.  When this reaches zero, the info object
   118     // is popped from the ClientRequestInfoImpl ThreadLocal stack in the ORB.
   119     private int entryCount = 0;
   121     // The RequestImpl is set when the call is DII based.
   122     // The DII query calls like ParameterList, ExceptionList,
   123     // ContextList will be delegated to RequestImpl.
   124     private org.omg.CORBA.Request request;
   126     // Sources of client request information
   127     private boolean diiInitiate;
   128     private CorbaMessageMediator messageMediator;
   130     // Cached information:
   131     private org.omg.CORBA.Object cachedTargetObject;
   132     private org.omg.CORBA.Object cachedEffectiveTargetObject;
   133     private Parameter[] cachedArguments;
   134     private TypeCode[] cachedExceptions;
   135     private String[] cachedContexts;
   136     private String[] cachedOperationContext;
   137     private String cachedReceivedExceptionId;
   138     private Any cachedResult;
   139     private Any cachedReceivedException;
   140     private TaggedProfile cachedEffectiveProfile;
   141     // key = Integer, value = IOP.ServiceContext.
   142     private HashMap cachedRequestServiceContexts;
   143     // key = Integer, value = IOP.ServiceContext.
   144     private HashMap cachedReplyServiceContexts;
   145     // key = Integer, value = TaggedComponent
   146     private HashMap cachedEffectiveComponents;
   149     protected boolean piCurrentPushed;
   151     //////////////////////////////////////////////////////////////////////
   152     //
   153     // NOTE: IF AN ATTRIBUTE IS ADDED, PLEASE UPDATE RESET();
   154     //
   155     //////////////////////////////////////////////////////////////////////
   157     /**
   158      * Reset the info object so that it can be reused for a retry,
   159      * for example.
   160      */
   161     void reset() {
   162         super.reset();
   164         // Please keep these in the same order that they're declared above.
   166         retryRequest = false;
   168         // Do not reset entryCount because we need to know when to pop this
   169         // from the stack.
   171         request = null;
   172         diiInitiate = false;
   173         messageMediator = null;
   175         // Clear cached attributes:
   176         cachedTargetObject = null;
   177         cachedEffectiveTargetObject = null;
   178         cachedArguments = null;
   179         cachedExceptions = null;
   180         cachedContexts = null;
   181         cachedOperationContext = null;
   182         cachedReceivedExceptionId = null;
   183         cachedResult = null;
   184         cachedReceivedException = null;
   185         cachedEffectiveProfile = null;
   186         cachedRequestServiceContexts = null;
   187         cachedReplyServiceContexts = null;
   188         cachedEffectiveComponents = null;
   190         piCurrentPushed = false;
   192         startingPointCall = CALL_SEND_REQUEST;
   193         endingPointCall = CALL_RECEIVE_REPLY;
   195     }
   197     /*
   198      **********************************************************************
   199      * Access protection
   200      **********************************************************************/
   202     // Method IDs for all methods in ClientRequestInfo.  This allows for a
   203     // convenient O(1) lookup for checkAccess().
   204     protected static final int MID_TARGET                  = MID_RI_LAST + 1;
   205     protected static final int MID_EFFECTIVE_TARGET        = MID_RI_LAST + 2;
   206     protected static final int MID_EFFECTIVE_PROFILE       = MID_RI_LAST + 3;
   207     protected static final int MID_RECEIVED_EXCEPTION      = MID_RI_LAST + 4;
   208     protected static final int MID_RECEIVED_EXCEPTION_ID   = MID_RI_LAST + 5;
   209     protected static final int MID_GET_EFFECTIVE_COMPONENT = MID_RI_LAST + 6;
   210     protected static final int MID_GET_EFFECTIVE_COMPONENTS
   211                                                            = MID_RI_LAST + 7;
   212     protected static final int MID_GET_REQUEST_POLICY      = MID_RI_LAST + 8;
   213     protected static final int MID_ADD_REQUEST_SERVICE_CONTEXT
   214                                                            = MID_RI_LAST + 9;
   216     // ClientRequestInfo validity table (see ptc/00-08-06 table 21-1).
   217     // Note: These must be in the same order as specified in contants.
   218     protected static final boolean validCall[][] = {
   219         // LEGEND:
   220         // s_req = send_request     r_rep = receive_reply
   221         // s_pol = send_poll        r_exc = receive_exception
   222         //                          r_oth = receive_other
   223         //
   224         // A true value indicates call is valid at specified point.
   225         // A false value indicates the call is invalid.
   226         //
   227         //
   228         // NOTE: If the order or number of columns change, update
   229         // checkAccess() accordingly.
   230         //
   231         //                              { s_req, s_pol, r_rep, r_exc, r_oth }
   232         // RequestInfo methods:
   233         /*request_id*/                  { true , true , true , true , true  },
   234         /*operation*/                   { true , true , true , true , true  },
   235         /*arguments*/                   { true , false, true , false, false },
   236         /*exceptions*/                  { true , false, true , true , true  },
   237         /*contexts*/                    { true , false, true , true , true  },
   238         /*operation_context*/           { true , false, true , true , true  },
   239         /*result*/                      { false, false, true , false, false },
   240         /*response_expected*/           { true , true , true , true , true  },
   241         /*sync_scope*/                  { true , false, true , true , true  },
   242         /*reply_status*/                { false, false, true , true , true  },
   243         /*forward_reference*/           { false, false, false, false, true  },
   244         /*get_slot*/                    { true , true , true , true , true  },
   245         /*get_request_service_context*/ { true , false, true , true , true  },
   246         /*get_reply_service_context*/   { false, false, true , true , true  },
   247         //
   248         // ClientRequestInfo methods::
   249         /*target*/                      { true , true , true , true , true  },
   250         /*effective_target*/            { true , true , true , true , true  },
   251         /*effective_profile*/           { true , true , true , true , true  },
   252         /*received_exception*/          { false, false, false, true , false },
   253         /*received_exception_id*/       { false, false, false, true , false },
   254         /*get_effective_component*/     { true , false, true , true , true  },
   255         /*get_effective_components*/    { true , false, true , true , true  },
   256         /*get_request_policy*/          { true , false, true , true , true  },
   257         /*add_request_service_context*/ { true , false, false, false, false }
   258     };
   261     /*
   262      **********************************************************************
   263      * Public ClientRequestInfo interfaces
   264      **********************************************************************/
   266     /**
   267      * Creates a new ClientRequestInfo implementation.
   268      * The constructor is package scope since no other package need create
   269      * an instance of this class.
   270      */
   271     protected ClientRequestInfoImpl( ORB myORB ) {
   272         super( myORB );
   273         startingPointCall = CALL_SEND_REQUEST;
   274         endingPointCall = CALL_RECEIVE_REPLY;
   275     }
   277     /**
   278      * The object which the client called to perform the operation.
   279      */
   280     public org.omg.CORBA.Object target (){
   281         // access is currently valid for all states:
   282         //checkAccess( MID_TARGET );
   283         if (cachedTargetObject == null) {
   284             CorbaContactInfo corbaContactInfo = (CorbaContactInfo)
   285                 messageMediator.getContactInfo();
   286             cachedTargetObject =
   287                 iorToObject(corbaContactInfo.getTargetIOR());
   288         }
   289         return cachedTargetObject;
   290     }
   292     /**
   293      * The actual object on which the operation will be invoked.  If the
   294      * reply_status is LOCATION_FORWARD, then on subsequent requests,
   295      * effective_target will contain the forwarded IOR while target will
   296      * remain unchanged.
   297      */
   298     public org.omg.CORBA.Object effective_target() {
   299         // access is currently valid for all states:
   300         //checkAccess( MID_EFFECTIVE_TARGET );
   302         // Note: This is not necessarily the same as locatedIOR.
   303         // Reason: See the way we handle COMM_FAILURES in
   304         // ClientRequestDispatcher.createRequest, v1.32
   306         if (cachedEffectiveTargetObject == null) {
   307             CorbaContactInfo corbaContactInfo = (CorbaContactInfo)
   308                 messageMediator.getContactInfo();
   309             // REVISIT - get through chain like getLocatedIOR helper below.
   310             cachedEffectiveTargetObject =
   311                 iorToObject(corbaContactInfo.getEffectiveTargetIOR());
   312         }
   313         return cachedEffectiveTargetObject;
   314     }
   316     /**
   317      * The profile that will be used to send the request.  If a location
   318      * forward has occurred for this operation's object and that object's
   319      * profile change accordingly, then this profile will be that located
   320      * profile.
   321      */
   322     public TaggedProfile effective_profile (){
   323         // access is currently valid for all states:
   324         //checkAccess( MID_EFFECTIVE_PROFILE );
   326         if( cachedEffectiveProfile == null ) {
   327             CorbaContactInfo corbaContactInfo = (CorbaContactInfo)
   328                 messageMediator.getContactInfo();
   329             cachedEffectiveProfile =
   330                 corbaContactInfo.getEffectiveProfile().getIOPProfile();
   331         }
   333         // Good citizen: In the interest of efficiency, we assume interceptors
   334         // will not modify the returned TaggedProfile in any way so we need
   335         // not make a deep copy of it.
   337         return cachedEffectiveProfile;
   338     }
   340     /**
   341      * Contains the exception to be returned to the client.
   342      */
   343     public Any received_exception (){
   344         checkAccess( MID_RECEIVED_EXCEPTION );
   346         if( cachedReceivedException == null ) {
   347             cachedReceivedException = exceptionToAny( exception );
   348         }
   350         // Good citizen: In the interest of efficiency, we assume interceptors
   351         // will not modify the returned Any in any way so we need
   352         // not make a deep copy of it.
   354         return cachedReceivedException;
   355     }
   357     /**
   358      * The CORBA::RepositoryId of the exception to be returned to the client.
   359      */
   360     public String received_exception_id (){
   361         checkAccess( MID_RECEIVED_EXCEPTION_ID );
   363         if( cachedReceivedExceptionId == null ) {
   364             String result = null;
   366             if( exception == null ) {
   367                 // Note: exception should never be null here since we will
   368                 // throw a BAD_INV_ORDER if this is not called from
   369                 // receive_exception.
   370                 throw wrapper.exceptionWasNull() ;
   371             } else if( exception instanceof SystemException ) {
   372                 String name = exception.getClass().getName();
   373                 result = ORBUtility.repositoryIdOf(name);
   374             } else if( exception instanceof ApplicationException ) {
   375                 result = ((ApplicationException)exception).getId();
   376             }
   378             // _REVISIT_ We need to be able to handle a UserException in the
   379             // DII case.  How do we extract the ID from a UserException?
   381             cachedReceivedExceptionId = result;
   382         }
   384         return cachedReceivedExceptionId;
   385     }
   387     /**
   388      * Returns the IOP::TaggedComponent with the given ID from the profile
   389      * selected for this request.  IF there is more than one component for a
   390      * given component ID, it is undefined which component this operation
   391      * returns (get_effective_component should be called instead).
   392      */
   393     public TaggedComponent get_effective_component (int id){
   394         checkAccess( MID_GET_EFFECTIVE_COMPONENT );
   396         return get_effective_components( id )[0];
   397     }
   399     /**
   400      * Returns all the tagged components with the given ID from the profile
   401      * selected for this request.
   402      */
   403     public TaggedComponent[] get_effective_components (int id){
   404         checkAccess( MID_GET_EFFECTIVE_COMPONENTS );
   405         Integer integerId = new Integer( id );
   406         TaggedComponent[] result = null;
   407         boolean justCreatedCache = false;
   409         if( cachedEffectiveComponents == null ) {
   410             cachedEffectiveComponents = new HashMap();
   411             justCreatedCache = true;
   412         }
   413         else {
   414             // Look in cache:
   415             result = (TaggedComponent[])cachedEffectiveComponents.get(
   416                 integerId );
   417         }
   419         // null could mean we cached null or not in cache.
   420         if( (result == null) &&
   421             (justCreatedCache ||
   422             !cachedEffectiveComponents.containsKey( integerId ) ) )
   423         {
   424             // Not in cache.  Get it from the profile:
   425             CorbaContactInfo corbaContactInfo = (CorbaContactInfo)
   426                 messageMediator.getContactInfo();
   427             IIOPProfileTemplate ptemp =
   428                 (IIOPProfileTemplate)corbaContactInfo.getEffectiveProfile().
   429                 getTaggedProfileTemplate();
   430             result = ptemp.getIOPComponents(myORB, id);
   431             cachedEffectiveComponents.put( integerId, result );
   432         }
   434         // As per ptc/00-08-06, section 21.3.13.6., If not found, raise
   435         // BAD_PARAM with minor code INVALID_COMPONENT_ID.
   436         if( (result == null) || (result.length == 0) ) {
   437             throw stdWrapper.invalidComponentId( integerId ) ;
   438         }
   440         // Good citizen: In the interest of efficiency, we will assume
   441         // interceptors will not modify the returned TaggedCompoent[], or
   442         // the TaggedComponents inside of it.  Otherwise, we would need to
   443         // clone the array and make a deep copy of its contents.
   445         return result;
   446     }
   448     /**
   449      * Returns the given policy in effect for this operation.
   450      */
   451     public Policy get_request_policy (int type){
   452         checkAccess( MID_GET_REQUEST_POLICY );
   453         // _REVISIT_ Our ORB is not policy-based at this time.
   454         throw wrapper.piOrbNotPolicyBased() ;
   455     }
   457     /**
   458      * Allows interceptors to add service contexts to the request.
   459      * <p>
   460      * There is no declaration of the order of the service contexts.  They
   461      * may or may not appear in the order they are added.
   462      */
   463     public void add_request_service_context (ServiceContext service_context,
   464                                              boolean replace)
   465     {
   466         checkAccess( MID_ADD_REQUEST_SERVICE_CONTEXT );
   468         if( cachedRequestServiceContexts == null ) {
   469             cachedRequestServiceContexts = new HashMap();
   470         }
   472         addServiceContext( cachedRequestServiceContexts,
   473                            messageMediator.getRequestServiceContexts(),
   474                            service_context, replace );
   475     }
   477     // NOTE: When adding a method, be sure to:
   478     // 1. Add a MID_* constant for that method
   479     // 2. Call checkAccess at the start of the method
   480     // 3. Define entries in the validCall[][] table for interception points.
   482     /*
   483      **********************************************************************
   484      * Public RequestInfo interfaces
   485      *
   486      * These are implemented here because they have differing
   487      * implementations depending on whether this is a client or a server
   488      * request info object.
   489      **********************************************************************/
   491     /**
   492      * See RequestInfoImpl for javadoc.
   493      */
   494     public int request_id (){
   495         // access is currently valid for all states:
   496         //checkAccess( MID_REQUEST_ID );
   497         /*
   498          * NOTE: The requestId in client interceptors is the same as the
   499          * GIOP request id.  This works because both interceptors and
   500          * request ids are scoped by the ORB on the client side.
   501          */
   502         return messageMediator.getRequestId();
   503     }
   505     /**
   506      * See RequestInfoImpl for javadoc.
   507      */
   508     public String operation (){
   509         // access is currently valid for all states:
   510         //checkAccess( MID_OPERATION );
   511         return messageMediator.getOperationName();
   512     }
   514     /**
   515      * See RequestInfoImpl for javadoc.
   516      */
   517     public Parameter[] arguments (){
   518         checkAccess( MID_ARGUMENTS );
   520         if( cachedArguments == null ) {
   521             if( request == null ) {
   522                 throw stdWrapper.piOperationNotSupported1() ;
   523             }
   525             // If it is DII request then get the arguments from the DII req
   526             // and convert that into parameters.
   527             cachedArguments = nvListToParameterArray( request.arguments() );
   528         }
   530         // Good citizen: In the interest of efficiency, we assume
   531         // interceptors will be "good citizens" in that they will not
   532         // modify the contents of the Parameter[] array.  We also assume
   533         // they will not change the values of the containing Anys.
   535         return cachedArguments;
   536     }
   538     /**
   539      * See RequestInfoImpl for javadoc.
   540      */
   541     public TypeCode[] exceptions (){
   542         checkAccess( MID_EXCEPTIONS );
   544         if( cachedExceptions == null ) {
   545             if( request == null ) {
   546                throw stdWrapper.piOperationNotSupported2() ;
   547             }
   549             // Get the list of exceptions from DII request data, If there are
   550             // no exceptions raised then this method will return null.
   551             ExceptionList excList = request.exceptions( );
   552             int count = excList.count();
   553             TypeCode[] excTCList = new TypeCode[count];
   554             try {
   555                 for( int i = 0; i < count; i++ ) {
   556                     excTCList[i] = excList.item( i );
   557                 }
   558             } catch( Exception e ) {
   559                 throw wrapper.exceptionInExceptions( e ) ;
   560             }
   562             cachedExceptions = excTCList;
   563         }
   565         // Good citizen: In the interest of efficiency, we assume
   566         // interceptors will be "good citizens" in that they will not
   567         // modify the contents of the TypeCode[] array.  We also assume
   568         // they will not change the values of the containing TypeCodes.
   570         return cachedExceptions;
   571     }
   573     /**
   574      * See RequestInfoImpl for javadoc.
   575      */
   576     public String[] contexts (){
   577         checkAccess( MID_CONTEXTS );
   579         if( cachedContexts == null ) {
   580             if( request == null ) {
   581                 throw stdWrapper.piOperationNotSupported3() ;
   582             }
   584             // Get the list of contexts from DII request data, If there are
   585             // no contexts then this method will return null.
   586             ContextList ctxList = request.contexts( );
   587             int count = ctxList.count();
   588             String[] ctxListToReturn = new String[count];
   589             try {
   590                 for( int i = 0; i < count; i++ ) {
   591                     ctxListToReturn[i] = ctxList.item( i );
   592                 }
   593             } catch( Exception e ) {
   594                 throw wrapper.exceptionInContexts( e ) ;
   595             }
   597             cachedContexts = ctxListToReturn;
   598         }
   600         // Good citizen: In the interest of efficiency, we assume
   601         // interceptors will be "good citizens" in that they will not
   602         // modify the contents of the String[] array.
   604         return cachedContexts;
   605     }
   607     /**
   608      * See RequestInfoImpl for javadoc.
   609      */
   610     public String[] operation_context (){
   611         checkAccess( MID_OPERATION_CONTEXT );
   613         if( cachedOperationContext == null ) {
   614             if( request == null ) {
   615                 throw stdWrapper.piOperationNotSupported4() ;
   616             }
   618             // Get the list of contexts from DII request data, If there are
   619             // no contexts then this method will return null.
   620             Context ctx = request.ctx( );
   621             // _REVISIT_ The API for get_values is not compliant with the spec,
   622             // Revisit this code once it's fixed.
   623             // _REVISIT_ Our ORB doesn't support Operation Context, This code
   624             // will not be excerscised until it's supported.
   625             // The first parameter in get_values is the start_scope which
   626             // if blank makes it as a global scope.
   627             // The second parameter is op_flags which is set to RESTRICT_SCOPE
   628             // As there is only one defined in the spec.
   629             // The Third param is the pattern which is '*' requiring it to
   630             // get all the contexts.
   631             NVList nvList = ctx.get_values( "", CTX_RESTRICT_SCOPE.value,"*" );
   632             String[] context = new String[(nvList.count() * 2) ];
   633             if( ( nvList != null ) &&( nvList.count() != 0 ) ) {
   634                 // The String[] array will contain Name and Value for each
   635                 // context and hence double the size in the array.
   636                 int index = 0;
   637                 for( int i = 0; i < nvList.count(); i++ ) {
   638                     NamedValue nv;
   639                     try {
   640                         nv = nvList.item( i );
   641                     }
   642                     catch (Exception e ) {
   643                         return (String[]) null;
   644                     }
   645                     context[index] = nv.name();
   646                     index++;
   647                     context[index] = nv.value().extract_string();
   648                     index++;
   649                 }
   650             }
   652             cachedOperationContext = context;
   653         }
   655         // Good citizen: In the interest of efficiency, we assume
   656         // interceptors will be "good citizens" in that they will not
   657         // modify the contents of the String[] array.
   659         return cachedOperationContext;
   660     }
   662     /**
   663      * See RequestInfoImpl for javadoc.
   664      */
   665     public Any result (){
   666         checkAccess( MID_RESULT );
   668         if( cachedResult == null ) {
   669             if( request == null ) {
   670                 throw stdWrapper.piOperationNotSupported5() ;
   671             }
   672             // Get the result from the DII request data.
   673             NamedValue nvResult = request.result( );
   675             if( nvResult == null ) {
   676                 throw wrapper.piDiiResultIsNull() ;
   677             }
   679             cachedResult = nvResult.value();
   680         }
   682         // Good citizen: In the interest of efficiency, we assume that
   683         // interceptors will not modify the contents of the result Any.
   684         // Otherwise, we would need to create a deep copy of the Any.
   686         return cachedResult;
   687     }
   689     /**
   690      * See RequestInfoImpl for javadoc.
   691      */
   692     public boolean response_expected (){
   693         // access is currently valid for all states:
   694         //checkAccess( MID_RESPONSE_EXPECTED );
   695         return ! messageMediator.isOneWay();
   696     }
   698     /**
   699      * See RequestInfoImpl for javadoc.
   700      */
   701     public Object forward_reference (){
   702         checkAccess( MID_FORWARD_REFERENCE );
   703         // Check to make sure we are in LOCATION_FORWARD
   704         // state as per ptc/00-08-06, table 21-1
   705         // footnote 2.
   706         if( replyStatus != LOCATION_FORWARD.value ) {
   707             throw stdWrapper.invalidPiCall1() ;
   708         }
   710         // Do not cache this value since if an interceptor raises
   711         // forward request then the next interceptor in the
   712         // list should see the new value.
   713         IOR ior = getLocatedIOR();
   714         return iorToObject(ior);
   715     }
   717     private IOR getLocatedIOR()
   718     {
   719         IOR ior;
   720         CorbaContactInfoList contactInfoList = (CorbaContactInfoList)
   721             messageMediator.getContactInfo().getContactInfoList();
   722         ior = contactInfoList.getEffectiveTargetIOR();
   723         return ior;
   724     }
   726     protected void setLocatedIOR(IOR ior)
   727     {
   728         ORB orb = (ORB) messageMediator.getBroker();
   730         CorbaContactInfoListIterator iterator = (CorbaContactInfoListIterator)
   731             ((CorbaInvocationInfo)orb.getInvocationInfo())
   732             .getContactInfoListIterator();
   734         // REVISIT - this most likely causes reportRedirect to happen twice.
   735         // Once here and once inside the request dispatcher.
   736         iterator.reportRedirect(
   737             (CorbaContactInfo)messageMediator.getContactInfo(),
   738             ior);
   739     }
   741     /**
   742      * See RequestInfoImpl for javadoc.
   743      */
   744     public org.omg.IOP.ServiceContext get_request_service_context( int id ) {
   745         checkAccess( MID_GET_REQUEST_SERVICE_CONTEXT );
   747         if( cachedRequestServiceContexts == null ) {
   748             cachedRequestServiceContexts = new HashMap();
   749         }
   751         return  getServiceContext(cachedRequestServiceContexts,
   752                                   messageMediator.getRequestServiceContexts(),
   753                                   id);
   754     }
   756     /**
   757      * does not contain an etry for that ID, BAD_PARAM with a minor code of
   758      * TBD_BP is raised.
   759      */
   760     public org.omg.IOP.ServiceContext get_reply_service_context( int id ) {
   761         checkAccess( MID_GET_REPLY_SERVICE_CONTEXT );
   763         if( cachedReplyServiceContexts == null ) {
   764             cachedReplyServiceContexts = new HashMap();
   765         }
   767         // In the event this is called from a oneway, we will have no
   768         // response object.
   769         //
   770         // In the event this is called after a IIOPConnection.purgeCalls,
   771         // we will have a response object, but that object will
   772         // not contain a header (which would hold the service context
   773         // container).  See bug 4624102.
   774         //
   775         // REVISIT: this is the only thing used
   776         // from response at this time.  However, a more general solution
   777         // would avoid accessing other parts of response's header.
   778         //
   779         // Instead of throwing a NullPointer, we will
   780         // "gracefully" handle these with a BAD_PARAM with minor code 25.
   782         try {
   783             ServiceContexts serviceContexts =
   784                 messageMediator.getReplyServiceContexts();
   785             if (serviceContexts == null) {
   786                 throw new NullPointerException();
   787             }
   788             return getServiceContext(cachedReplyServiceContexts,
   789                                      serviceContexts, id);
   790         } catch (NullPointerException e) {
   791             // REVISIT how this is programmed - not what it does.
   792             // See purge calls test.  The waiter is woken up by the
   793             // call to purge calls - but there is no reply containing
   794             // service contexts.
   795             throw stdWrapper.invalidServiceContextId( e ) ;
   796         }
   797     }
   799     //
   800     // REVISIT
   801     // Override RequestInfoImpl connection to work in framework.
   802     //
   804     public com.sun.corba.se.spi.legacy.connection.Connection connection()
   805     {
   806         return (com.sun.corba.se.spi.legacy.connection.Connection)
   807             messageMediator.getConnection();
   808     }
   812     /*
   813      **********************************************************************
   814      * Package-scope interfaces
   815      **********************************************************************/
   817     protected void setInfo(MessageMediator messageMediator)
   818     {
   819         this.messageMediator = (CorbaMessageMediator)messageMediator;
   820         // REVISIT - so mediator can handle DII in subcontract.
   821         this.messageMediator.setDIIInfo(request);
   822     }
   824     /**
   825      * Set or reset the retry request flag.
   826      */
   827     void setRetryRequest( boolean retryRequest ) {
   828         this.retryRequest = retryRequest;
   829     }
   831     /**
   832      * Retrieve the current retry request status.
   833      */
   834     boolean getRetryRequest() {
   835         return this.retryRequest;
   836     }
   838     /**
   839      * Increases the entry count by 1.
   840      */
   841     void incrementEntryCount() {
   842         this.entryCount++;
   843     }
   845     /**
   846      * Decreases the entry count by 1.
   847      */
   848     void decrementEntryCount() {
   849         this.entryCount--;
   850     }
   852     /**
   853      * Retrieve the current entry count
   854      */
   855     int getEntryCount() {
   856         return this.entryCount;
   857     }
   859     /**
   860      * Overridden from RequestInfoImpl.  Calls the super class, then
   861      * sets the ending point call depending on the reply status.
   862      */
   863     protected void setReplyStatus( short replyStatus ) {
   864         super.setReplyStatus( replyStatus );
   865         switch( replyStatus ) {
   866         case SUCCESSFUL.value:
   867             endingPointCall = CALL_RECEIVE_REPLY;
   868             break;
   869         case SYSTEM_EXCEPTION.value:
   870         case USER_EXCEPTION.value:
   871             endingPointCall = CALL_RECEIVE_EXCEPTION;
   872             break;
   873         case LOCATION_FORWARD.value:
   874         case TRANSPORT_RETRY.value:
   875             endingPointCall = CALL_RECEIVE_OTHER;
   876             break;
   877         }
   878     }
   880     /**
   881      * Sets DII request object in the RequestInfoObject.
   882      */
   883     protected void setDIIRequest(org.omg.CORBA.Request req) {
   884          request = req;
   885     }
   887     /**
   888      * Keeps track of whether initiate was called for a DII request.  The ORB
   889      * needs to know this so it knows whether to ignore a second call to
   890      * initiateClientPIRequest or not.
   891      */
   892     protected void setDIIInitiate( boolean diiInitiate ) {
   893         this.diiInitiate = diiInitiate;
   894     }
   896     /**
   897      * See comment for setDIIInitiate
   898      */
   899     protected boolean isDIIInitiate() {
   900         return this.diiInitiate;
   901     }
   903     /**
   904      * The PICurrent stack should only be popped if it was pushed.
   905      * This is generally the case.  But exceptions which occur
   906      * after the stub's entry to _request but before the push
   907      * end up in _releaseReply which will try to pop unless told not to.
   908      */
   909     protected void setPICurrentPushed( boolean piCurrentPushed ) {
   910         this.piCurrentPushed = piCurrentPushed;
   911     }
   913     protected boolean isPICurrentPushed() {
   914         return this.piCurrentPushed;
   915     }
   917     /**
   918      * Overridden from RequestInfoImpl.
   919      */
   920     protected void setException( Exception exception ) {
   921         super.setException( exception );
   923         // Clear cached values:
   924         cachedReceivedException = null;
   925         cachedReceivedExceptionId = null;
   926     }
   928     protected boolean getIsOneWay() {
   929         return ! response_expected();
   930     }
   932     /**
   933      * See description for RequestInfoImpl.checkAccess
   934      */
   935     protected void checkAccess( int methodID )
   936         throws BAD_INV_ORDER
   937     {
   938         // Make sure currentPoint matches the appropriate index in the
   939         // validCall table:
   940         int validCallIndex = 0;
   941         switch( currentExecutionPoint ) {
   942         case EXECUTION_POINT_STARTING:
   943             switch( startingPointCall ) {
   944             case CALL_SEND_REQUEST:
   945                 validCallIndex = 0;
   946                 break;
   947             case CALL_SEND_POLL:
   948                 validCallIndex = 1;
   949                 break;
   950             }
   951             break;
   952         case EXECUTION_POINT_ENDING:
   953             switch( endingPointCall ) {
   954             case CALL_RECEIVE_REPLY:
   955                 validCallIndex = 2;
   956                 break;
   957             case CALL_RECEIVE_EXCEPTION:
   958                 validCallIndex = 3;
   959                 break;
   960             case CALL_RECEIVE_OTHER:
   961                 validCallIndex = 4;
   962                 break;
   963             }
   964             break;
   965         }
   967         // Check the validCall table:
   968         if( !validCall[methodID][validCallIndex] ) {
   969             throw stdWrapper.invalidPiCall2() ;
   970         }
   971     }
   973 }
   975 // End of file.

mercurial