src/share/classes/com/sun/corba/se/impl/interceptors/ClientRequestInfoImpl.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 371
e324dfb90c9e
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  */
    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.protocol.RetryType;
    78 import com.sun.corba.se.spi.transport.CorbaContactInfo;
    79 import com.sun.corba.se.spi.transport.CorbaContactInfoList;
    80 import com.sun.corba.se.spi.transport.CorbaContactInfoListIterator;
    82 import com.sun.corba.se.impl.encoding.CDROutputStream;
    83 import com.sun.corba.se.impl.encoding.CDRInputStream_1_0;
    84 import com.sun.corba.se.impl.orbutil.ORBUtility;
    85 import com.sun.corba.se.impl.protocol.CorbaInvocationInfo;
    86 import com.sun.corba.se.impl.util.RepositoryId;
    88 /**
    89  * Implementation of the ClientRequestInfo interface as specified in
    90  * orbos/99-12-02 section 5.4.2.
    91  */
    92 public final class ClientRequestInfoImpl
    93     extends RequestInfoImpl
    94     implements ClientRequestInfo
    95 {
    97     // The available constants for startingPointCall
    98     static final int CALL_SEND_REQUEST = 0;
    99     static final int CALL_SEND_POLL = 1;
   101     // The available constants for endingPointCall
   102     static final int CALL_RECEIVE_REPLY = 0;
   103     static final int CALL_RECEIVE_EXCEPTION = 1;
   104     static final int CALL_RECEIVE_OTHER = 2;
   106     //////////////////////////////////////////////////////////////////////
   107     //
   108     // NOTE: IF AN ATTRIBUTE IS ADDED, PLEASE UPDATE RESET();
   109     //
   110     //////////////////////////////////////////////////////////////////////
   112     // The current retry request status.  True if this request is being
   113     // retried and this info object is to be reused, or false otherwise.
   114     private RetryType retryRequest;
   116     // The number of times this info object has been (re)used.  This is
   117     // incremented every time a request is retried, and decremented every
   118     // time a request is complete.  When this reaches zero, the info object
   119     // is popped from the ClientRequestInfoImpl ThreadLocal stack in the ORB.
   120     private int entryCount = 0;
   122     // The RequestImpl is set when the call is DII based.
   123     // The DII query calls like ParameterList, ExceptionList,
   124     // ContextList will be delegated to RequestImpl.
   125     private org.omg.CORBA.Request request;
   127     // Sources of client request information
   128     private boolean diiInitiate;
   129     private CorbaMessageMediator messageMediator;
   131     // Cached information:
   132     private org.omg.CORBA.Object cachedTargetObject;
   133     private org.omg.CORBA.Object cachedEffectiveTargetObject;
   134     private Parameter[] cachedArguments;
   135     private TypeCode[] cachedExceptions;
   136     private String[] cachedContexts;
   137     private String[] cachedOperationContext;
   138     private String cachedReceivedExceptionId;
   139     private Any cachedResult;
   140     private Any cachedReceivedException;
   141     private TaggedProfile cachedEffectiveProfile;
   142     // key = Integer, value = IOP.ServiceContext.
   143     private HashMap cachedRequestServiceContexts;
   144     // key = Integer, value = IOP.ServiceContext.
   145     private HashMap cachedReplyServiceContexts;
   146     // key = Integer, value = TaggedComponent
   147     private HashMap cachedEffectiveComponents;
   150     protected boolean piCurrentPushed;
   152     //////////////////////////////////////////////////////////////////////
   153     //
   154     // NOTE: IF AN ATTRIBUTE IS ADDED, PLEASE UPDATE RESET();
   155     //
   156     //////////////////////////////////////////////////////////////////////
   158     /**
   159      * Reset the info object so that it can be reused for a retry,
   160      * for example.
   161      */
   162     void reset() {
   163         super.reset();
   165         // Please keep these in the same order that they're declared above.
   167         // 6763340
   168         retryRequest = RetryType.NONE;
   170         // Do not reset entryCount because we need to know when to pop this
   171         // from the stack.
   173         request = null;
   174         diiInitiate = false;
   175         messageMediator = null;
   177         // Clear cached attributes:
   178         cachedTargetObject = null;
   179         cachedEffectiveTargetObject = null;
   180         cachedArguments = null;
   181         cachedExceptions = null;
   182         cachedContexts = null;
   183         cachedOperationContext = null;
   184         cachedReceivedExceptionId = null;
   185         cachedResult = null;
   186         cachedReceivedException = null;
   187         cachedEffectiveProfile = null;
   188         cachedRequestServiceContexts = null;
   189         cachedReplyServiceContexts = null;
   190         cachedEffectiveComponents = null;
   192         piCurrentPushed = false;
   194         startingPointCall = CALL_SEND_REQUEST;
   195         endingPointCall = CALL_RECEIVE_REPLY;
   197     }
   199     /*
   200      **********************************************************************
   201      * Access protection
   202      **********************************************************************/
   204     // Method IDs for all methods in ClientRequestInfo.  This allows for a
   205     // convenient O(1) lookup for checkAccess().
   206     protected static final int MID_TARGET                  = MID_RI_LAST + 1;
   207     protected static final int MID_EFFECTIVE_TARGET        = MID_RI_LAST + 2;
   208     protected static final int MID_EFFECTIVE_PROFILE       = MID_RI_LAST + 3;
   209     protected static final int MID_RECEIVED_EXCEPTION      = MID_RI_LAST + 4;
   210     protected static final int MID_RECEIVED_EXCEPTION_ID   = MID_RI_LAST + 5;
   211     protected static final int MID_GET_EFFECTIVE_COMPONENT = MID_RI_LAST + 6;
   212     protected static final int MID_GET_EFFECTIVE_COMPONENTS
   213                                                            = MID_RI_LAST + 7;
   214     protected static final int MID_GET_REQUEST_POLICY      = MID_RI_LAST + 8;
   215     protected static final int MID_ADD_REQUEST_SERVICE_CONTEXT
   216                                                            = MID_RI_LAST + 9;
   218     // ClientRequestInfo validity table (see ptc/00-08-06 table 21-1).
   219     // Note: These must be in the same order as specified in contants.
   220     protected static final boolean validCall[][] = {
   221         // LEGEND:
   222         // s_req = send_request     r_rep = receive_reply
   223         // s_pol = send_poll        r_exc = receive_exception
   224         //                          r_oth = receive_other
   225         //
   226         // A true value indicates call is valid at specified point.
   227         // A false value indicates the call is invalid.
   228         //
   229         //
   230         // NOTE: If the order or number of columns change, update
   231         // checkAccess() accordingly.
   232         //
   233         //                              { s_req, s_pol, r_rep, r_exc, r_oth }
   234         // RequestInfo methods:
   235         /*request_id*/                  { true , true , true , true , true  },
   236         /*operation*/                   { true , true , true , true , true  },
   237         /*arguments*/                   { true , false, true , false, false },
   238         /*exceptions*/                  { true , false, true , true , true  },
   239         /*contexts*/                    { true , false, true , true , true  },
   240         /*operation_context*/           { true , false, true , true , true  },
   241         /*result*/                      { false, false, true , false, false },
   242         /*response_expected*/           { true , true , true , true , true  },
   243         /*sync_scope*/                  { true , false, true , true , true  },
   244         /*reply_status*/                { false, false, true , true , true  },
   245         /*forward_reference*/           { false, false, false, false, true  },
   246         /*get_slot*/                    { true , true , true , true , true  },
   247         /*get_request_service_context*/ { true , false, true , true , true  },
   248         /*get_reply_service_context*/   { false, false, true , true , true  },
   249         //
   250         // ClientRequestInfo methods::
   251         /*target*/                      { true , true , true , true , true  },
   252         /*effective_target*/            { true , true , true , true , true  },
   253         /*effective_profile*/           { true , true , true , true , true  },
   254         /*received_exception*/          { false, false, false, true , false },
   255         /*received_exception_id*/       { false, false, false, true , false },
   256         /*get_effective_component*/     { true , false, true , true , true  },
   257         /*get_effective_components*/    { true , false, true , true , true  },
   258         /*get_request_policy*/          { true , false, true , true , true  },
   259         /*add_request_service_context*/ { true , false, false, false, false }
   260     };
   263     /*
   264      **********************************************************************
   265      * Public ClientRequestInfo interfaces
   266      **********************************************************************/
   268     /**
   269      * Creates a new ClientRequestInfo implementation.
   270      * The constructor is package scope since no other package need create
   271      * an instance of this class.
   272      */
   273     protected ClientRequestInfoImpl( ORB myORB ) {
   274         super( myORB );
   275         startingPointCall = CALL_SEND_REQUEST;
   276         endingPointCall = CALL_RECEIVE_REPLY;
   277     }
   279     /**
   280      * The object which the client called to perform the operation.
   281      */
   282     public org.omg.CORBA.Object target (){
   283         // access is currently valid for all states:
   284         //checkAccess( MID_TARGET );
   285         if (cachedTargetObject == null) {
   286             CorbaContactInfo corbaContactInfo = (CorbaContactInfo)
   287                 messageMediator.getContactInfo();
   288             cachedTargetObject =
   289                 iorToObject(corbaContactInfo.getTargetIOR());
   290         }
   291         return cachedTargetObject;
   292     }
   294     /**
   295      * The actual object on which the operation will be invoked.  If the
   296      * reply_status is LOCATION_FORWARD, then on subsequent requests,
   297      * effective_target will contain the forwarded IOR while target will
   298      * remain unchanged.
   299      */
   300     public org.omg.CORBA.Object effective_target() {
   301         // access is currently valid for all states:
   302         //checkAccess( MID_EFFECTIVE_TARGET );
   304         // Note: This is not necessarily the same as locatedIOR.
   305         // Reason: See the way we handle COMM_FAILURES in
   306         // ClientRequestDispatcher.createRequest, v1.32
   308         if (cachedEffectiveTargetObject == null) {
   309             CorbaContactInfo corbaContactInfo = (CorbaContactInfo)
   310                 messageMediator.getContactInfo();
   311             // REVISIT - get through chain like getLocatedIOR helper below.
   312             cachedEffectiveTargetObject =
   313                 iorToObject(corbaContactInfo.getEffectiveTargetIOR());
   314         }
   315         return cachedEffectiveTargetObject;
   316     }
   318     /**
   319      * The profile that will be used to send the request.  If a location
   320      * forward has occurred for this operation's object and that object's
   321      * profile change accordingly, then this profile will be that located
   322      * profile.
   323      */
   324     public TaggedProfile effective_profile (){
   325         // access is currently valid for all states:
   326         //checkAccess( MID_EFFECTIVE_PROFILE );
   328         if( cachedEffectiveProfile == null ) {
   329             CorbaContactInfo corbaContactInfo = (CorbaContactInfo)
   330                 messageMediator.getContactInfo();
   331             cachedEffectiveProfile =
   332                 corbaContactInfo.getEffectiveProfile().getIOPProfile();
   333         }
   335         // Good citizen: In the interest of efficiency, we assume interceptors
   336         // will not modify the returned TaggedProfile in any way so we need
   337         // not make a deep copy of it.
   339         return cachedEffectiveProfile;
   340     }
   342     /**
   343      * Contains the exception to be returned to the client.
   344      */
   345     public Any received_exception (){
   346         checkAccess( MID_RECEIVED_EXCEPTION );
   348         if( cachedReceivedException == null ) {
   349             cachedReceivedException = exceptionToAny( exception );
   350         }
   352         // Good citizen: In the interest of efficiency, we assume interceptors
   353         // will not modify the returned Any in any way so we need
   354         // not make a deep copy of it.
   356         return cachedReceivedException;
   357     }
   359     /**
   360      * The CORBA::RepositoryId of the exception to be returned to the client.
   361      */
   362     public String received_exception_id (){
   363         checkAccess( MID_RECEIVED_EXCEPTION_ID );
   365         if( cachedReceivedExceptionId == null ) {
   366             String result = null;
   368             if( exception == null ) {
   369                 // Note: exception should never be null here since we will
   370                 // throw a BAD_INV_ORDER if this is not called from
   371                 // receive_exception.
   372                 throw wrapper.exceptionWasNull() ;
   373             } else if( exception instanceof SystemException ) {
   374                 String name = exception.getClass().getName();
   375                 result = ORBUtility.repositoryIdOf(name);
   376             } else if( exception instanceof ApplicationException ) {
   377                 result = ((ApplicationException)exception).getId();
   378             }
   380             // _REVISIT_ We need to be able to handle a UserException in the
   381             // DII case.  How do we extract the ID from a UserException?
   383             cachedReceivedExceptionId = result;
   384         }
   386         return cachedReceivedExceptionId;
   387     }
   389     /**
   390      * Returns the IOP::TaggedComponent with the given ID from the profile
   391      * selected for this request.  IF there is more than one component for a
   392      * given component ID, it is undefined which component this operation
   393      * returns (get_effective_component should be called instead).
   394      */
   395     public TaggedComponent get_effective_component (int id){
   396         checkAccess( MID_GET_EFFECTIVE_COMPONENT );
   398         return get_effective_components( id )[0];
   399     }
   401     /**
   402      * Returns all the tagged components with the given ID from the profile
   403      * selected for this request.
   404      */
   405     public TaggedComponent[] get_effective_components (int id){
   406         checkAccess( MID_GET_EFFECTIVE_COMPONENTS );
   407         Integer integerId = new Integer( id );
   408         TaggedComponent[] result = null;
   409         boolean justCreatedCache = false;
   411         if( cachedEffectiveComponents == null ) {
   412             cachedEffectiveComponents = new HashMap();
   413             justCreatedCache = true;
   414         }
   415         else {
   416             // Look in cache:
   417             result = (TaggedComponent[])cachedEffectiveComponents.get(
   418                 integerId );
   419         }
   421         // null could mean we cached null or not in cache.
   422         if( (result == null) &&
   423             (justCreatedCache ||
   424             !cachedEffectiveComponents.containsKey( integerId ) ) )
   425         {
   426             // Not in cache.  Get it from the profile:
   427             CorbaContactInfo corbaContactInfo = (CorbaContactInfo)
   428                 messageMediator.getContactInfo();
   429             IIOPProfileTemplate ptemp =
   430                 (IIOPProfileTemplate)corbaContactInfo.getEffectiveProfile().
   431                 getTaggedProfileTemplate();
   432             result = ptemp.getIOPComponents(myORB, id);
   433             cachedEffectiveComponents.put( integerId, result );
   434         }
   436         // As per ptc/00-08-06, section 21.3.13.6., If not found, raise
   437         // BAD_PARAM with minor code INVALID_COMPONENT_ID.
   438         if( (result == null) || (result.length == 0) ) {
   439             throw stdWrapper.invalidComponentId( integerId ) ;
   440         }
   442         // Good citizen: In the interest of efficiency, we will assume
   443         // interceptors will not modify the returned TaggedCompoent[], or
   444         // the TaggedComponents inside of it.  Otherwise, we would need to
   445         // clone the array and make a deep copy of its contents.
   447         return result;
   448     }
   450     /**
   451      * Returns the given policy in effect for this operation.
   452      */
   453     public Policy get_request_policy (int type){
   454         checkAccess( MID_GET_REQUEST_POLICY );
   455         // _REVISIT_ Our ORB is not policy-based at this time.
   456         throw wrapper.piOrbNotPolicyBased() ;
   457     }
   459     /**
   460      * Allows interceptors to add service contexts to the request.
   461      * <p>
   462      * There is no declaration of the order of the service contexts.  They
   463      * may or may not appear in the order they are added.
   464      */
   465     public void add_request_service_context (ServiceContext service_context,
   466                                              boolean replace)
   467     {
   468         checkAccess( MID_ADD_REQUEST_SERVICE_CONTEXT );
   470         if( cachedRequestServiceContexts == null ) {
   471             cachedRequestServiceContexts = new HashMap();
   472         }
   474         addServiceContext( cachedRequestServiceContexts,
   475                            messageMediator.getRequestServiceContexts(),
   476                            service_context, replace );
   477     }
   479     // NOTE: When adding a method, be sure to:
   480     // 1. Add a MID_* constant for that method
   481     // 2. Call checkAccess at the start of the method
   482     // 3. Define entries in the validCall[][] table for interception points.
   484     /*
   485      **********************************************************************
   486      * Public RequestInfo interfaces
   487      *
   488      * These are implemented here because they have differing
   489      * implementations depending on whether this is a client or a server
   490      * request info object.
   491      **********************************************************************/
   493     /**
   494      * See RequestInfoImpl for javadoc.
   495      */
   496     public int request_id (){
   497         // access is currently valid for all states:
   498         //checkAccess( MID_REQUEST_ID );
   499         /*
   500          * NOTE: The requestId in client interceptors is the same as the
   501          * GIOP request id.  This works because both interceptors and
   502          * request ids are scoped by the ORB on the client side.
   503          */
   504         return messageMediator.getRequestId();
   505     }
   507     /**
   508      * See RequestInfoImpl for javadoc.
   509      */
   510     public String operation (){
   511         // access is currently valid for all states:
   512         //checkAccess( MID_OPERATION );
   513         return messageMediator.getOperationName();
   514     }
   516     /**
   517      * See RequestInfoImpl for javadoc.
   518      */
   519     public Parameter[] arguments (){
   520         checkAccess( MID_ARGUMENTS );
   522         if( cachedArguments == null ) {
   523             if( request == null ) {
   524                 throw stdWrapper.piOperationNotSupported1() ;
   525             }
   527             // If it is DII request then get the arguments from the DII req
   528             // and convert that into parameters.
   529             cachedArguments = nvListToParameterArray( request.arguments() );
   530         }
   532         // Good citizen: In the interest of efficiency, we assume
   533         // interceptors will be "good citizens" in that they will not
   534         // modify the contents of the Parameter[] array.  We also assume
   535         // they will not change the values of the containing Anys.
   537         return cachedArguments;
   538     }
   540     /**
   541      * See RequestInfoImpl for javadoc.
   542      */
   543     public TypeCode[] exceptions (){
   544         checkAccess( MID_EXCEPTIONS );
   546         if( cachedExceptions == null ) {
   547             if( request == null ) {
   548                throw stdWrapper.piOperationNotSupported2() ;
   549             }
   551             // Get the list of exceptions from DII request data, If there are
   552             // no exceptions raised then this method will return null.
   553             ExceptionList excList = request.exceptions( );
   554             int count = excList.count();
   555             TypeCode[] excTCList = new TypeCode[count];
   556             try {
   557                 for( int i = 0; i < count; i++ ) {
   558                     excTCList[i] = excList.item( i );
   559                 }
   560             } catch( Exception e ) {
   561                 throw wrapper.exceptionInExceptions( e ) ;
   562             }
   564             cachedExceptions = excTCList;
   565         }
   567         // Good citizen: In the interest of efficiency, we assume
   568         // interceptors will be "good citizens" in that they will not
   569         // modify the contents of the TypeCode[] array.  We also assume
   570         // they will not change the values of the containing TypeCodes.
   572         return cachedExceptions;
   573     }
   575     /**
   576      * See RequestInfoImpl for javadoc.
   577      */
   578     public String[] contexts (){
   579         checkAccess( MID_CONTEXTS );
   581         if( cachedContexts == null ) {
   582             if( request == null ) {
   583                 throw stdWrapper.piOperationNotSupported3() ;
   584             }
   586             // Get the list of contexts from DII request data, If there are
   587             // no contexts then this method will return null.
   588             ContextList ctxList = request.contexts( );
   589             int count = ctxList.count();
   590             String[] ctxListToReturn = new String[count];
   591             try {
   592                 for( int i = 0; i < count; i++ ) {
   593                     ctxListToReturn[i] = ctxList.item( i );
   594                 }
   595             } catch( Exception e ) {
   596                 throw wrapper.exceptionInContexts( e ) ;
   597             }
   599             cachedContexts = ctxListToReturn;
   600         }
   602         // Good citizen: In the interest of efficiency, we assume
   603         // interceptors will be "good citizens" in that they will not
   604         // modify the contents of the String[] array.
   606         return cachedContexts;
   607     }
   609     /**
   610      * See RequestInfoImpl for javadoc.
   611      */
   612     public String[] operation_context (){
   613         checkAccess( MID_OPERATION_CONTEXT );
   615         if( cachedOperationContext == null ) {
   616             if( request == null ) {
   617                 throw stdWrapper.piOperationNotSupported4() ;
   618             }
   620             // Get the list of contexts from DII request data, If there are
   621             // no contexts then this method will return null.
   622             Context ctx = request.ctx( );
   623             // _REVISIT_ The API for get_values is not compliant with the spec,
   624             // Revisit this code once it's fixed.
   625             // _REVISIT_ Our ORB doesn't support Operation Context, This code
   626             // will not be excerscised until it's supported.
   627             // The first parameter in get_values is the start_scope which
   628             // if blank makes it as a global scope.
   629             // The second parameter is op_flags which is set to RESTRICT_SCOPE
   630             // As there is only one defined in the spec.
   631             // The Third param is the pattern which is '*' requiring it to
   632             // get all the contexts.
   633             NVList nvList = ctx.get_values( "", CTX_RESTRICT_SCOPE.value,"*" );
   634             String[] context = new String[(nvList.count() * 2) ];
   635             if( ( nvList != null ) &&( nvList.count() != 0 ) ) {
   636                 // The String[] array will contain Name and Value for each
   637                 // context and hence double the size in the array.
   638                 int index = 0;
   639                 for( int i = 0; i < nvList.count(); i++ ) {
   640                     NamedValue nv;
   641                     try {
   642                         nv = nvList.item( i );
   643                     }
   644                     catch (Exception e ) {
   645                         return (String[]) null;
   646                     }
   647                     context[index] = nv.name();
   648                     index++;
   649                     context[index] = nv.value().extract_string();
   650                     index++;
   651                 }
   652             }
   654             cachedOperationContext = context;
   655         }
   657         // Good citizen: In the interest of efficiency, we assume
   658         // interceptors will be "good citizens" in that they will not
   659         // modify the contents of the String[] array.
   661         return cachedOperationContext;
   662     }
   664     /**
   665      * See RequestInfoImpl for javadoc.
   666      */
   667     public Any result (){
   668         checkAccess( MID_RESULT );
   670         if( cachedResult == null ) {
   671             if( request == null ) {
   672                 throw stdWrapper.piOperationNotSupported5() ;
   673             }
   674             // Get the result from the DII request data.
   675             NamedValue nvResult = request.result( );
   677             if( nvResult == null ) {
   678                 throw wrapper.piDiiResultIsNull() ;
   679             }
   681             cachedResult = nvResult.value();
   682         }
   684         // Good citizen: In the interest of efficiency, we assume that
   685         // interceptors will not modify the contents of the result Any.
   686         // Otherwise, we would need to create a deep copy of the Any.
   688         return cachedResult;
   689     }
   691     /**
   692      * See RequestInfoImpl for javadoc.
   693      */
   694     public boolean response_expected (){
   695         // access is currently valid for all states:
   696         //checkAccess( MID_RESPONSE_EXPECTED );
   697         return ! messageMediator.isOneWay();
   698     }
   700     /**
   701      * See RequestInfoImpl for javadoc.
   702      */
   703     public Object forward_reference (){
   704         checkAccess( MID_FORWARD_REFERENCE );
   705         // Check to make sure we are in LOCATION_FORWARD
   706         // state as per ptc/00-08-06, table 21-1
   707         // footnote 2.
   708         if( replyStatus != LOCATION_FORWARD.value ) {
   709             throw stdWrapper.invalidPiCall1() ;
   710         }
   712         // Do not cache this value since if an interceptor raises
   713         // forward request then the next interceptor in the
   714         // list should see the new value.
   715         IOR ior = getLocatedIOR();
   716         return iorToObject(ior);
   717     }
   719     private IOR getLocatedIOR()
   720     {
   721         IOR ior;
   722         CorbaContactInfoList contactInfoList = (CorbaContactInfoList)
   723             messageMediator.getContactInfo().getContactInfoList();
   724         ior = contactInfoList.getEffectiveTargetIOR();
   725         return ior;
   726     }
   728     protected void setLocatedIOR(IOR ior)
   729     {
   730         ORB orb = (ORB) messageMediator.getBroker();
   732         CorbaContactInfoListIterator iterator = (CorbaContactInfoListIterator)
   733             ((CorbaInvocationInfo)orb.getInvocationInfo())
   734             .getContactInfoListIterator();
   736         // REVISIT - this most likely causes reportRedirect to happen twice.
   737         // Once here and once inside the request dispatcher.
   738         iterator.reportRedirect(
   739             (CorbaContactInfo)messageMediator.getContactInfo(),
   740             ior);
   741     }
   743     /**
   744      * See RequestInfoImpl for javadoc.
   745      */
   746     public org.omg.IOP.ServiceContext get_request_service_context( int id ) {
   747         checkAccess( MID_GET_REQUEST_SERVICE_CONTEXT );
   749         if( cachedRequestServiceContexts == null ) {
   750             cachedRequestServiceContexts = new HashMap();
   751         }
   753         return  getServiceContext(cachedRequestServiceContexts,
   754                                   messageMediator.getRequestServiceContexts(),
   755                                   id);
   756     }
   758     /**
   759      * does not contain an etry for that ID, BAD_PARAM with a minor code of
   760      * TBD_BP is raised.
   761      */
   762     public org.omg.IOP.ServiceContext get_reply_service_context( int id ) {
   763         checkAccess( MID_GET_REPLY_SERVICE_CONTEXT );
   765         if( cachedReplyServiceContexts == null ) {
   766             cachedReplyServiceContexts = new HashMap();
   767         }
   769         // In the event this is called from a oneway, we will have no
   770         // response object.
   771         //
   772         // In the event this is called after a IIOPConnection.purgeCalls,
   773         // we will have a response object, but that object will
   774         // not contain a header (which would hold the service context
   775         // container).  See bug 4624102.
   776         //
   777         // REVISIT: this is the only thing used
   778         // from response at this time.  However, a more general solution
   779         // would avoid accessing other parts of response's header.
   780         //
   781         // Instead of throwing a NullPointer, we will
   782         // "gracefully" handle these with a BAD_PARAM with minor code 25.
   784         try {
   785             ServiceContexts serviceContexts =
   786                 messageMediator.getReplyServiceContexts();
   787             if (serviceContexts == null) {
   788                 throw new NullPointerException();
   789             }
   790             return getServiceContext(cachedReplyServiceContexts,
   791                                      serviceContexts, id);
   792         } catch (NullPointerException e) {
   793             // REVISIT how this is programmed - not what it does.
   794             // See purge calls test.  The waiter is woken up by the
   795             // call to purge calls - but there is no reply containing
   796             // service contexts.
   797             throw stdWrapper.invalidServiceContextId( e ) ;
   798         }
   799     }
   801     //
   802     // REVISIT
   803     // Override RequestInfoImpl connection to work in framework.
   804     //
   806     public com.sun.corba.se.spi.legacy.connection.Connection connection()
   807     {
   808         return (com.sun.corba.se.spi.legacy.connection.Connection)
   809             messageMediator.getConnection();
   810     }
   814     /*
   815      **********************************************************************
   816      * Package-scope interfaces
   817      **********************************************************************/
   819     protected void setInfo(MessageMediator messageMediator)
   820     {
   821         this.messageMediator = (CorbaMessageMediator)messageMediator;
   822         // REVISIT - so mediator can handle DII in subcontract.
   823         this.messageMediator.setDIIInfo(request);
   824     }
   826     /**
   827      * Set or reset the retry request flag.
   828      */
   829     void setRetryRequest( RetryType retryRequest ) {
   830         this.retryRequest = retryRequest;
   831     }
   833     /**
   834      * Retrieve the current retry request status.
   835      */
   836     RetryType getRetryRequest() {
   837         // 6763340
   838         return this.retryRequest;
   839     }
   841     /**
   842      * Increases the entry count by 1.
   843      */
   844     void incrementEntryCount() {
   845         this.entryCount++;
   846     }
   848     /**
   849      * Decreases the entry count by 1.
   850      */
   851     void decrementEntryCount() {
   852         this.entryCount--;
   853     }
   855     /**
   856      * Retrieve the current entry count
   857      */
   858     int getEntryCount() {
   859         return this.entryCount;
   860     }
   862     /**
   863      * Overridden from RequestInfoImpl.  Calls the super class, then
   864      * sets the ending point call depending on the reply status.
   865      */
   866     protected void setReplyStatus( short replyStatus ) {
   867         super.setReplyStatus( replyStatus );
   868         switch( replyStatus ) {
   869         case SUCCESSFUL.value:
   870             endingPointCall = CALL_RECEIVE_REPLY;
   871             break;
   872         case SYSTEM_EXCEPTION.value:
   873         case USER_EXCEPTION.value:
   874             endingPointCall = CALL_RECEIVE_EXCEPTION;
   875             break;
   876         case LOCATION_FORWARD.value:
   877         case TRANSPORT_RETRY.value:
   878             endingPointCall = CALL_RECEIVE_OTHER;
   879             break;
   880         }
   881     }
   883     /**
   884      * Sets DII request object in the RequestInfoObject.
   885      */
   886     protected void setDIIRequest(org.omg.CORBA.Request req) {
   887          request = req;
   888     }
   890     /**
   891      * Keeps track of whether initiate was called for a DII request.  The ORB
   892      * needs to know this so it knows whether to ignore a second call to
   893      * initiateClientPIRequest or not.
   894      */
   895     protected void setDIIInitiate( boolean diiInitiate ) {
   896         this.diiInitiate = diiInitiate;
   897     }
   899     /**
   900      * See comment for setDIIInitiate
   901      */
   902     protected boolean isDIIInitiate() {
   903         return this.diiInitiate;
   904     }
   906     /**
   907      * The PICurrent stack should only be popped if it was pushed.
   908      * This is generally the case.  But exceptions which occur
   909      * after the stub's entry to _request but before the push
   910      * end up in _releaseReply which will try to pop unless told not to.
   911      */
   912     protected void setPICurrentPushed( boolean piCurrentPushed ) {
   913         this.piCurrentPushed = piCurrentPushed;
   914     }
   916     protected boolean isPICurrentPushed() {
   917         return this.piCurrentPushed;
   918     }
   920     /**
   921      * Overridden from RequestInfoImpl.
   922      */
   923     protected void setException( Exception exception ) {
   924         super.setException( exception );
   926         // Clear cached values:
   927         cachedReceivedException = null;
   928         cachedReceivedExceptionId = null;
   929     }
   931     protected boolean getIsOneWay() {
   932         return ! response_expected();
   933     }
   935     /**
   936      * See description for RequestInfoImpl.checkAccess
   937      */
   938     protected void checkAccess( int methodID )
   939         throws BAD_INV_ORDER
   940     {
   941         // Make sure currentPoint matches the appropriate index in the
   942         // validCall table:
   943         int validCallIndex = 0;
   944         switch( currentExecutionPoint ) {
   945         case EXECUTION_POINT_STARTING:
   946             switch( startingPointCall ) {
   947             case CALL_SEND_REQUEST:
   948                 validCallIndex = 0;
   949                 break;
   950             case CALL_SEND_POLL:
   951                 validCallIndex = 1;
   952                 break;
   953             }
   954             break;
   955         case EXECUTION_POINT_ENDING:
   956             switch( endingPointCall ) {
   957             case CALL_RECEIVE_REPLY:
   958                 validCallIndex = 2;
   959                 break;
   960             case CALL_RECEIVE_EXCEPTION:
   961                 validCallIndex = 3;
   962                 break;
   963             case CALL_RECEIVE_OTHER:
   964                 validCallIndex = 4;
   965                 break;
   966             }
   967             break;
   968         }
   970         // Check the validCall table:
   971         if( !validCall[methodID][validCallIndex] ) {
   972             throw stdWrapper.invalidPiCall2() ;
   973         }
   974     }
   976 }
   978 // End of file.

mercurial