src/share/classes/com/sun/corba/se/impl/interceptors/PIHandlerImpl.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 380
47adb42076f1
permissions
-rw-r--r--

6962318: Update copyright year
Reviewed-by: xdono

     1 /*
     2  * Copyright (c) 2002, 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.util.*;
    28 import java.io.IOException;
    30 import org.omg.CORBA.Any;
    31 import org.omg.CORBA.BAD_PARAM;
    32 import org.omg.CORBA.BAD_POLICY;
    33 import org.omg.CORBA.BAD_INV_ORDER;
    34 import org.omg.CORBA.COMM_FAILURE;
    35 import org.omg.CORBA.CompletionStatus;
    36 import org.omg.CORBA.INTERNAL;
    37 import org.omg.CORBA.NVList;
    38 import org.omg.CORBA.OBJECT_NOT_EXIST;
    39 import org.omg.CORBA.ORBPackage.InvalidName;
    40 import org.omg.CORBA.SystemException;
    41 import org.omg.CORBA.UserException;
    42 import org.omg.CORBA.UNKNOWN;
    44 import org.omg.CORBA.portable.ApplicationException;
    45 import org.omg.CORBA.portable.RemarshalException;
    47 import org.omg.IOP.CodecFactory;
    49 import org.omg.PortableInterceptor.ForwardRequest;
    50 import org.omg.PortableInterceptor.Current;
    51 import org.omg.PortableInterceptor.Interceptor;
    52 import org.omg.PortableInterceptor.LOCATION_FORWARD;
    53 import org.omg.PortableInterceptor.ORBInitializer;
    54 import org.omg.PortableInterceptor.ORBInitInfo;
    55 import org.omg.PortableInterceptor.ORBInitInfoPackage.DuplicateName;
    56 import org.omg.PortableInterceptor.SUCCESSFUL;
    57 import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
    58 import org.omg.PortableInterceptor.TRANSPORT_RETRY;
    59 import org.omg.PortableInterceptor.USER_EXCEPTION;
    60 import org.omg.PortableInterceptor.PolicyFactory;
    61 import org.omg.PortableInterceptor.ObjectReferenceTemplate ;
    63 import com.sun.corba.se.pept.encoding.OutputObject;
    65 import com.sun.corba.se.spi.ior.IOR;
    66 import com.sun.corba.se.spi.ior.ObjectKeyTemplate;
    67 import com.sun.corba.se.spi.oa.ObjectAdapter;
    68 import com.sun.corba.se.spi.orb.ORB;
    69 import com.sun.corba.se.spi.orbutil.closure.ClosureFactory;
    70 import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
    71 import com.sun.corba.se.spi.protocol.ForwardException;
    72 import com.sun.corba.se.spi.protocol.PIHandler;
    73 import com.sun.corba.se.spi.protocol.RetryType;
    74 import com.sun.corba.se.spi.logging.CORBALogDomains;
    76 import com.sun.corba.se.impl.logging.InterceptorsSystemException;
    77 import com.sun.corba.se.impl.logging.ORBUtilSystemException;
    78 import com.sun.corba.se.impl.logging.OMGSystemException;
    79 import com.sun.corba.se.impl.corba.RequestImpl;
    80 import com.sun.corba.se.impl.orbutil.ORBClassLoader;
    81 import com.sun.corba.se.impl.orbutil.ORBConstants;
    82 import com.sun.corba.se.impl.orbutil.ORBUtility;
    83 import com.sun.corba.se.impl.orbutil.StackImpl;
    84 import com.sun.corba.se.impl.protocol.giopmsgheaders.ReplyMessage;
    86 /**
    87  * Provides portable interceptor functionality.
    88  */
    89 public class PIHandlerImpl implements PIHandler
    90 {
    91     // REVISIT - delete these after framework merging.
    92     boolean printPushPopEnabled = false;
    93     int pushLevel = 0;
    94     private void printPush()
    95     {
    96         if (! printPushPopEnabled) return;
    97         printSpaces(pushLevel);
    98         pushLevel++;
    99         System.out.println("PUSH");
   100     }
   101     private void printPop()
   102     {
   103         if (! printPushPopEnabled) return;
   104         pushLevel--;
   105         printSpaces(pushLevel);
   106         System.out.println("POP");
   107     }
   108     private void printSpaces(int n)
   109     {
   110         for (int i = 0; i < n; i++) {
   111             System.out.print(" ");
   112         }
   113     }
   115     private ORB orb ;
   116     InterceptorsSystemException wrapper ;
   117     ORBUtilSystemException orbutilWrapper ;
   118     OMGSystemException omgWrapper ;
   120     // A unique id used in ServerRequestInfo.
   121     // This does not correspond to the GIOP request id.
   122     private int serverRequestIdCounter = 0;
   124     // Stores the codec factory for producing codecs
   125     CodecFactory codecFactory = null;
   127     // The arguments passed to the application's main method.  May be null.
   128     // This is used for ORBInitializers and set from set_parameters.
   129     String[] arguments = null;
   131     // The list of portable interceptors, organized by type:
   132     private InterceptorList interceptorList;
   134     // Cached information for optimization - do we have any interceptors
   135     // registered of the given types?  Set during ORB initialization.
   136     private boolean hasIORInterceptors;
   137     private boolean hasClientInterceptors;  // temp always true
   138     private boolean hasServerInterceptors;
   140     // The class responsible for invoking interceptors
   141     private InterceptorInvoker interceptorInvoker;
   143     // There will be one PICurrent instantiated for every ORB.
   144     private PICurrent current;
   146     // This table contains a list of PolicyFactories registered using
   147     // ORBInitInfo.registerPolicyFactory() method.
   148     // Key for the table is PolicyType which is an Integer
   149     // Value is PolicyFactory.
   150     private HashMap policyFactoryTable;
   152     // Table to convert from a ReplyMessage.? to a PI replyStatus short.
   153     // Note that this table relies on the order and constants of
   154     // ReplyMessage not to change.
   155     private final static short REPLY_MESSAGE_TO_PI_REPLY_STATUS[] = {
   156         SUCCESSFUL.value,       // = ReplyMessage.NO_EXCEPTION
   157         USER_EXCEPTION.value,   // = ReplyMessage.USER_EXCEPTION
   158         SYSTEM_EXCEPTION.value, // = ReplyMessage.SYSTEM_EXCEPTION
   159         LOCATION_FORWARD.value, // = ReplyMessage.LOCATION_FORWARD
   160         LOCATION_FORWARD.value, // = ReplyMessage.LOCATION_FORWARD_PERM
   161         TRANSPORT_RETRY.value   // = ReplyMessage.NEEDS_ADDRESSING_MODE
   162     };
   164     // ThreadLocal containing a stack to store client request info objects
   165     // and a disable count.
   166     private ThreadLocal threadLocalClientRequestInfoStack =
   167         new ThreadLocal() {
   168             protected Object initialValue() {
   169                 return new RequestInfoStack();
   170             }
   171         };
   173     // ThreadLocal containing the current server request info object.
   174     private ThreadLocal threadLocalServerRequestInfoStack =
   175         new ThreadLocal() {
   176             protected Object initialValue() {
   177                 return new RequestInfoStack();
   178             }
   179         };
   181     // Class to contain all ThreadLocal data for ClientRequestInfo
   182     // maintenance.
   183     //
   184     // We use an ArrayList instead since it is not thread-safe.
   185     // RequestInfoStack is used quite frequently.
   186     private final class RequestInfoStack extends Stack {
   187         // Number of times a request has been made to disable interceptors.
   188         // When this reaches 0, interception hooks are disabled.  Any higher
   189         // value indicates they are enabled.
   190         // NOTE: The is only currently used on the client side.
   191         public int disableCount = 0;
   192     }
   194     public PIHandlerImpl( ORB orb, String[] args ) {
   195         this.orb = orb ;
   196         wrapper = InterceptorsSystemException.get( orb,
   197             CORBALogDomains.RPC_PROTOCOL ) ;
   198         orbutilWrapper = ORBUtilSystemException.get( orb,
   199             CORBALogDomains.RPC_PROTOCOL ) ;
   200         omgWrapper = OMGSystemException.get( orb,
   201             CORBALogDomains.RPC_PROTOCOL ) ;
   202         arguments = args ;
   204         // Create codec factory:
   205         codecFactory = new CodecFactoryImpl( orb );
   207         // Create new interceptor list:
   208         interceptorList = new InterceptorList( wrapper );
   210         // Create a new PICurrent.
   211         current = new PICurrent( orb );
   213         // Create new interceptor invoker, initially disabled:
   214         interceptorInvoker = new InterceptorInvoker( orb, interceptorList,
   215                                                      current );
   217         // Register the PI current and Codec factory objects
   218         orb.getLocalResolver().register( ORBConstants.PI_CURRENT_NAME,
   219             ClosureFactory.makeConstant( current ) ) ;
   220         orb.getLocalResolver().register( ORBConstants.CODEC_FACTORY_NAME,
   221             ClosureFactory.makeConstant( codecFactory ) ) ;
   222     }
   224     public void initialize() {
   225         // If we have any orb initializers, make use of them:
   226         if( orb.getORBData().getORBInitializers() != null ) {
   227             // Create the ORBInitInfo object to pass to ORB intializers:
   228             ORBInitInfoImpl orbInitInfo = createORBInitInfo();
   230             // Make sure get_slot and set_slot are not called from within
   231             // ORB initializers:
   232             current.setORBInitializing( true );
   234             // Call pre_init on all ORB initializers:
   235             preInitORBInitializers( orbInitInfo );
   237             // Call post_init on all ORB initializers:
   238             postInitORBInitializers( orbInitInfo );
   240             // Proprietary: sort interceptors:
   241             interceptorList.sortInterceptors();
   243             // Re-enable get_slot and set_slot to be called from within
   244             // ORB initializers:
   245             current.setORBInitializing( false );
   247             // Ensure nobody makes any more calls on this object.
   248             orbInitInfo.setStage( ORBInitInfoImpl.STAGE_CLOSED );
   250             // Set cached flags indicating whether we have interceptors
   251             // registered of a given type.
   252             hasIORInterceptors = interceptorList.hasInterceptorsOfType(
   253                 InterceptorList.INTERCEPTOR_TYPE_IOR );
   254             // XXX This must always be true, so that using the new generic
   255             // RPC framework can pass info between the PI stack and the
   256             // framework invocation stack.  Temporary until Harold fixes
   257             // this.  Note that this must never be true until after the
   258             // ORBInitializer instances complete executing.
   259             //hasClientInterceptors = interceptorList.hasInterceptorsOfType(
   260                 //InterceptorList.INTERCEPTOR_TYPE_CLIENT );
   261             hasClientInterceptors = true;
   262             hasServerInterceptors = interceptorList.hasInterceptorsOfType(
   263                 InterceptorList.INTERCEPTOR_TYPE_SERVER );
   265             // Enable interceptor invoker (not necessary if no interceptors
   266             // are registered).  This should be the last stage of ORB
   267             // initialization.
   268             interceptorInvoker.setEnabled( true );
   269         }
   270     }
   272     /**
   273      *  ptc/00-08-06 p 205: "When an application calls ORB::destroy, the ORB
   274      *  1) waits for all requests in progress to complete
   275      *  2) calls the Interceptor::destroy operation for each interceptor
   276      *  3) completes destruction of the ORB"
   277      *
   278      * This must be called at the end of ORB.destroy.  Note that this is not
   279      * part of the PIHandler interface, since ORBImpl implements the ORB interface.
   280      */
   281     public void destroyInterceptors() {
   282         interceptorList.destroyAll();
   283     }
   285     public void objectAdapterCreated( ObjectAdapter oa )
   286     {
   287         if (!hasIORInterceptors)
   288             return ;
   290         interceptorInvoker.objectAdapterCreated( oa ) ;
   291     }
   293     public void adapterManagerStateChanged( int managerId,
   294         short newState )
   295     {
   296         if (!hasIORInterceptors)
   297             return ;
   299         interceptorInvoker.adapterManagerStateChanged( managerId, newState ) ;
   300     }
   302     public void adapterStateChanged( ObjectReferenceTemplate[]
   303         templates, short newState )
   304     {
   305         if (!hasIORInterceptors)
   306             return ;
   308         interceptorInvoker.adapterStateChanged( templates, newState ) ;
   309     }
   311     /*
   312      *****************
   313      * Client PI hooks
   314      *****************/
   316     public void disableInterceptorsThisThread() {
   317         if( !hasClientInterceptors ) return;
   319         RequestInfoStack infoStack =
   320             (RequestInfoStack)threadLocalClientRequestInfoStack.get();
   321         infoStack.disableCount++;
   322     }
   324     public void enableInterceptorsThisThread() {
   325         if( !hasClientInterceptors ) return;
   327         RequestInfoStack infoStack =
   328             (RequestInfoStack)threadLocalClientRequestInfoStack.get();
   329         infoStack.disableCount--;
   330     }
   332     public void invokeClientPIStartingPoint()
   333         throws RemarshalException
   334     {
   335         if( !hasClientInterceptors ) return;
   336         if( !isClientPIEnabledForThisThread() ) return;
   338         // Invoke the starting interception points and record exception
   339         // and reply status info in the info object:
   340         ClientRequestInfoImpl info = peekClientRequestInfoImplStack();
   341         interceptorInvoker.invokeClientInterceptorStartingPoint( info );
   343         // Check reply status.  If we will not have another chance later
   344         // to invoke the client ending points, do it now.
   345         short replyStatus = info.getReplyStatus();
   346         if( (replyStatus == SYSTEM_EXCEPTION.value) ||
   347             (replyStatus == LOCATION_FORWARD.value) )
   348         {
   349             // Note: Transport retry cannot happen here since this happens
   350             // before the request hits the wire.
   352             Exception exception = invokeClientPIEndingPoint(
   353                 convertPIReplyStatusToReplyMessage( replyStatus ),
   354                 info.getException() );
   355             if( exception == null ) {
   356                 // Do not throw anything.  Otherwise, it must be a
   357                 // SystemException, UserException or RemarshalException.
   358             } if( exception instanceof SystemException ) {
   359                 throw (SystemException)exception;
   360             } else if( exception instanceof RemarshalException ) {
   361                 throw (RemarshalException)exception;
   362             } else if( (exception instanceof UserException) ||
   363                      (exception instanceof ApplicationException) ) {
   364                 // It should not be possible for an interceptor to throw
   365                 // a UserException.  By asserting instead of throwing the
   366                 // UserException, we need not declare anything but
   367                 // RemarshalException in the throws clause.
   368                 throw wrapper.exceptionInvalid() ;
   369             }
   370         }
   371         else if( replyStatus != ClientRequestInfoImpl.UNINITIALIZED ) {
   372             throw wrapper.replyStatusNotInit() ;
   373         }
   374     }
   376     // Needed when an error forces a retry AFTER initiateClientPIRequest
   377     // but BEFORE invokeClientPIStartingPoint.
   378     public Exception makeCompletedClientRequest( int replyStatus,
   379         Exception exception ) {
   381         // 6763340
   382         return handleClientPIEndingPoint( replyStatus, exception, false ) ;
   383     }
   385     public Exception invokeClientPIEndingPoint( int replyStatus,
   386         Exception exception ) {
   388         // 6763340
   389         return handleClientPIEndingPoint( replyStatus, exception, true ) ;
   390     }
   392     public Exception handleClientPIEndingPoint(
   393         int replyStatus, Exception exception, boolean invokeEndingPoint ) {
   394         if( !hasClientInterceptors ) return exception;
   395         if( !isClientPIEnabledForThisThread() ) return exception;
   397         // Translate ReplyMessage.replyStatus into PI replyStatus:
   398         // Note: this is also an assertion to make sure a valid replyStatus
   399         // is passed in (IndexOutOfBoundsException will be thrown otherwise)
   400         short piReplyStatus = REPLY_MESSAGE_TO_PI_REPLY_STATUS[replyStatus];
   402         // Invoke the ending interception points and record exception
   403         // and reply status info in the info object:
   404         ClientRequestInfoImpl info = peekClientRequestInfoImplStack();
   405         info.setReplyStatus( piReplyStatus );
   406         info.setException( exception );
   408         if (invokeEndingPoint) {
   409             // 6763340
   410             interceptorInvoker.invokeClientInterceptorEndingPoint( info );
   411             piReplyStatus = info.getReplyStatus();
   412         }
   414         // Check reply status:
   415         if( (piReplyStatus == LOCATION_FORWARD.value) ||
   416             (piReplyStatus == TRANSPORT_RETRY.value) ) {
   417             // If this is a forward or a retry, reset and reuse
   418             // info object:
   419             info.reset();
   421             // fix for 6763340:
   422             if (invokeEndingPoint) {
   423                 info.setRetryRequest( RetryType.AFTER_RESPONSE ) ;
   424             } else {
   425                 info.setRetryRequest( RetryType.BEFORE_RESPONSE ) ;
   426             }
   428             // ... and return a RemarshalException so the orb internals know
   429             exception = new RemarshalException();
   430         } else if( (piReplyStatus == SYSTEM_EXCEPTION.value) ||
   431                  (piReplyStatus == USER_EXCEPTION.value) ) {
   432             exception = info.getException();
   433         }
   435         return exception;
   436     }
   438     public void initiateClientPIRequest( boolean diiRequest ) {
   439         if( !hasClientInterceptors ) return;
   440         if( !isClientPIEnabledForThisThread() ) return;
   442         // Get the most recent info object from the thread local
   443         // ClientRequestInfoImpl stack:
   444         RequestInfoStack infoStack =
   445             (RequestInfoStack)threadLocalClientRequestInfoStack.get();
   446         ClientRequestInfoImpl info = null;
   448         if (!infoStack.empty() ) {
   449             info = (ClientRequestInfoImpl)infoStack.peek();
   450         }
   452         if (!diiRequest && (info != null) && info.isDIIInitiate() ) {
   453             // In RequestImpl.doInvocation we already called
   454             // initiateClientPIRequest( true ), so ignore this initiate.
   455             info.setDIIInitiate( false );
   456         } else {
   457             // If there is no info object or if we are not retrying a request,
   458             // push a new ClientRequestInfoImpl on the stack:
   460             // 6763340: don't push unless this is not a retry
   461             if( (info == null) || !info.getRetryRequest().isRetry() ) {
   462                 info = new ClientRequestInfoImpl( orb );
   463                 infoStack.push( info );
   464                 printPush();
   465                 // Note: the entry count is automatically initialized to 0.
   466             }
   468             // Reset the retry request flag so that recursive calls will
   469             // push a new info object, and bump up entry count so we know
   470             // when to pop this info object:
   471             info.setRetryRequest( RetryType.NONE );
   472             info.incrementEntryCount();
   474             // KMC 6763340: I don't know why this wasn't set earlier,
   475             // but we do not want a retry to pick up the previous
   476             // reply status, so clear it here.  Most likely a new
   477             // info was pushed before, so that this was not a problem.
   478             info.setReplyStatus( RequestInfoImpl.UNINITIALIZED ) ;
   480             // If this is a DII request, make sure we ignore the next initiate.
   481             if( diiRequest ) {
   482                 info.setDIIInitiate( true );
   483             }
   484         }
   485     }
   487     public void cleanupClientPIRequest() {
   488         if( !hasClientInterceptors ) return;
   489         if( !isClientPIEnabledForThisThread() ) return;
   491         ClientRequestInfoImpl info = peekClientRequestInfoImplStack();
   492         RetryType rt = info.getRetryRequest() ;
   494         // fix for 6763340
   495         if (!rt.equals( RetryType.BEFORE_RESPONSE )) {
   497             // If the replyStatus has not yet been set, this is an indication
   498             // that the ORB threw an exception before we had a chance to
   499             // invoke the client interceptor ending points.
   500             //
   501             // _REVISIT_ We cannot handle any exceptions or ForwardRequests
   502             // flagged by the ending points here because there is no way
   503             // to gracefully handle this in any of the calling code.
   504             // This is a rare corner case, so we will ignore this for now.
   505             short replyStatus = info.getReplyStatus();
   506             if (replyStatus == info.UNINITIALIZED ) {
   507                 invokeClientPIEndingPoint( ReplyMessage.SYSTEM_EXCEPTION,
   508                     wrapper.unknownRequestInvoke(
   509                         CompletionStatus.COMPLETED_MAYBE ) ) ;
   510             }
   511         }
   513         // Decrement entry count, and if it is zero, pop it from the stack.
   514         info.decrementEntryCount();
   516         // fix for 6763340, and probably other cases (non-recursive retry)
   517         if (info.getEntryCount() == 0 && !info.getRetryRequest().isRetry()) {
   518             // RequestInfoStack<ClientRequestInfoImpl> infoStack =
   519             //     threadLocalClientRequestInfoStack.get();
   520             RequestInfoStack infoStack =
   521                 (RequestInfoStack)threadLocalClientRequestInfoStack.get();
   522             infoStack.pop();
   523             printPop();
   524         }
   525     }
   527     public void setClientPIInfo(CorbaMessageMediator messageMediator)
   528     {
   529         if( !hasClientInterceptors ) return;
   530         if( !isClientPIEnabledForThisThread() ) return;
   532         peekClientRequestInfoImplStack().setInfo(messageMediator);
   533     }
   535     public void setClientPIInfo( RequestImpl requestImpl ) {
   536         if( !hasClientInterceptors ) return;
   537         if( !isClientPIEnabledForThisThread() ) return;
   539         peekClientRequestInfoImplStack().setDIIRequest( requestImpl );
   540     }
   542     /*
   543      *****************
   544      * Server PI hooks
   545      *****************/
   547     public void invokeServerPIStartingPoint()
   548     {
   549         if( !hasServerInterceptors ) return;
   551         ServerRequestInfoImpl info = peekServerRequestInfoImplStack();
   552         interceptorInvoker.invokeServerInterceptorStartingPoint( info );
   554         // Handle SystemException or ForwardRequest:
   555         serverPIHandleExceptions( info );
   556     }
   558     public void invokeServerPIIntermediatePoint()
   559     {
   560         if( !hasServerInterceptors ) return;
   562         ServerRequestInfoImpl info = peekServerRequestInfoImplStack();
   563         interceptorInvoker.invokeServerInterceptorIntermediatePoint( info );
   565         // Clear servant from info object so that the user has control over
   566         // its lifetime:
   567         info.releaseServant();
   569         // Handle SystemException or ForwardRequest:
   570         serverPIHandleExceptions( info );
   571     }
   573     public void invokeServerPIEndingPoint( ReplyMessage replyMessage )
   574     {
   575         if( !hasServerInterceptors ) return;
   576         ServerRequestInfoImpl info = peekServerRequestInfoImplStack();
   578         // REVISIT: This needs to be done "early" for the following workaround.
   579         info.setReplyMessage( replyMessage );
   581         // REVISIT: This was done inside of invokeServerInterceptorEndingPoint
   582         // but needs to be here for now.  See comment in that method for why.
   583         info.setCurrentExecutionPoint( info.EXECUTION_POINT_ENDING );
   585         // It is possible we might have entered this method more than
   586         // once (e.g. if an ending point threw a SystemException, then
   587         // a new ServerResponseImpl is created).
   588         if( !info.getAlreadyExecuted() ) {
   589             int replyStatus = replyMessage.getReplyStatus();
   591             // Translate ReplyMessage.replyStatus into PI replyStatus:
   592             // Note: this is also an assertion to make sure a valid
   593             // replyStatus is passed in (IndexOutOfBoundsException will be
   594             // thrown otherwise)
   595             short piReplyStatus =
   596                 REPLY_MESSAGE_TO_PI_REPLY_STATUS[replyStatus];
   598             // Make forwarded IOR available to interceptors, if applicable:
   599             if( ( piReplyStatus == LOCATION_FORWARD.value ) ||
   600                 ( piReplyStatus == TRANSPORT_RETRY.value ) )
   601             {
   602                 info.setForwardRequest( replyMessage.getIOR() );
   603             }
   605             // REVISIT: Do early above for now.
   606             // Make reply message available to interceptors:
   607             //info.setReplyMessage( replyMessage );
   609             // Remember exception so we can tell if an interceptor changed it.
   610             Exception prevException = info.getException();
   612             // _REVISIT_ We do not have access to the User Exception at
   613             // this point, so treat it as an UNKNOWN for now.
   614             // Note that if this is a DSI call, we do have the user exception.
   615             if( !info.isDynamic() &&
   616                 (piReplyStatus == USER_EXCEPTION.value) )
   617             {
   618                 info.setException( omgWrapper.unknownUserException(
   619                     CompletionStatus.COMPLETED_MAYBE ) ) ;
   620             }
   622             // Invoke the ending interception points:
   623             info.setReplyStatus( piReplyStatus );
   624             interceptorInvoker.invokeServerInterceptorEndingPoint( info );
   625             short newPIReplyStatus = info.getReplyStatus();
   626             Exception newException = info.getException();
   628             // Check reply status.  If an interceptor threw a SystemException
   629             // and it is different than the one that we came in with,
   630             // rethrow it so the proper response can be constructed:
   631             if( ( newPIReplyStatus == SYSTEM_EXCEPTION.value ) &&
   632                 ( newException != prevException ) )
   633             {
   634                 throw (SystemException)newException;
   635             }
   637             // If we are to forward the location:
   638             if( newPIReplyStatus == LOCATION_FORWARD.value ) {
   639                 if( piReplyStatus != LOCATION_FORWARD.value ) {
   640                     // Treat a ForwardRequest as a ForwardException.
   641                     IOR ior = info.getForwardRequestIOR();
   642                     throw new ForwardException( orb, ior ) ;
   643                 }
   644                 else if( info.isForwardRequestRaisedInEnding() ) {
   645                     // Treat a ForwardRequest by changing the IOR.
   646                     replyMessage.setIOR( info.getForwardRequestIOR() );
   647                 }
   648             }
   649         }
   650     }
   652     public void setServerPIInfo( Exception exception ) {
   653         if( !hasServerInterceptors ) return;
   655         ServerRequestInfoImpl info = peekServerRequestInfoImplStack();
   656         info.setException( exception );
   657     }
   659     public void setServerPIInfo( NVList arguments )
   660     {
   661         if( !hasServerInterceptors ) return;
   663         ServerRequestInfoImpl info = peekServerRequestInfoImplStack();
   664         info.setDSIArguments( arguments );
   665     }
   667     public void setServerPIExceptionInfo( Any exception )
   668     {
   669         if( !hasServerInterceptors ) return;
   671         ServerRequestInfoImpl info = peekServerRequestInfoImplStack();
   672         info.setDSIException( exception );
   673     }
   675     public void setServerPIInfo( Any result )
   676     {
   677         if( !hasServerInterceptors ) return;
   679         ServerRequestInfoImpl info = peekServerRequestInfoImplStack();
   680         info.setDSIResult( result );
   681     }
   683     public void initializeServerPIInfo( CorbaMessageMediator request,
   684         ObjectAdapter oa, byte[] objectId, ObjectKeyTemplate oktemp )
   685     {
   686         if( !hasServerInterceptors ) return;
   688         RequestInfoStack infoStack =
   689             (RequestInfoStack)threadLocalServerRequestInfoStack.get();
   690         ServerRequestInfoImpl info = new ServerRequestInfoImpl( orb );
   691         infoStack.push( info );
   692         printPush();
   694         // Notify request object that once response is constructed, make
   695         // sure we execute ending points.
   696         request.setExecutePIInResponseConstructor( true );
   698         info.setInfo( request, oa, objectId, oktemp );
   699     }
   701     public void setServerPIInfo( java.lang.Object servant,
   702                                           String targetMostDerivedInterface )
   703     {
   704         if( !hasServerInterceptors ) return;
   706         ServerRequestInfoImpl info = peekServerRequestInfoImplStack();
   707         info.setInfo( servant, targetMostDerivedInterface );
   708     }
   710     public void cleanupServerPIRequest() {
   711         if( !hasServerInterceptors ) return;
   713         RequestInfoStack infoStack =
   714             (RequestInfoStack)threadLocalServerRequestInfoStack.get();
   715         infoStack.pop();
   716         printPop();
   717     }
   719     /*
   720      **********************************************************************
   721      *  The following methods are private utility methods.
   722      ************************************************************************/
   724     /**
   725      * Handles exceptions for the starting and intermediate points for
   726      * server request interceptors.  This is common code that has been
   727      * factored out into this utility method.
   728      * <p>
   729      * This method will NOT work for ending points.
   730      */
   731     private void serverPIHandleExceptions( ServerRequestInfoImpl info )
   732     {
   733         int endingPointCall = info.getEndingPointCall();
   734         if(endingPointCall == ServerRequestInfoImpl.CALL_SEND_EXCEPTION) {
   735             // If a system exception was thrown, throw it to caller:
   736             throw (SystemException)info.getException();
   737         }
   738         else if( (endingPointCall == ServerRequestInfoImpl.CALL_SEND_OTHER) &&
   739                  (info.getForwardRequestException() != null) )
   740         {
   741             // If an interceptor throws a forward request, convert it
   742             // into a ForwardException for easier handling:
   743             IOR ior = info.getForwardRequestIOR();
   744             throw new ForwardException( orb, ior );
   745         }
   746     }
   748     /**
   749      * Utility method to convert a PI reply status short to a ReplyMessage
   750      * constant.  This is a reverse lookup on the table defined in
   751      * REPLY_MESSAGE_TO_PI_REPLY_STATUS.  The reverse lookup need not be
   752      * performed as quickly since it is only executed in exception
   753      * conditions.
   754      */
   755     private int convertPIReplyStatusToReplyMessage( short replyStatus ) {
   756         int result = 0;
   757         for( int i = 0; i < REPLY_MESSAGE_TO_PI_REPLY_STATUS.length; i++ ) {
   758             if( REPLY_MESSAGE_TO_PI_REPLY_STATUS[i] == replyStatus ) {
   759                 result = i;
   760                 break;
   761             }
   762         }
   763         return result;
   764     }
   766     /**
   767      * Convenience method to get the ClientRequestInfoImpl object off the
   768      * top of the ThreadLocal stack.  Throws an INTERNAL exception if
   769      * the Info stack is empty.
   770      */
   771     private ClientRequestInfoImpl peekClientRequestInfoImplStack() {
   772         RequestInfoStack infoStack =
   773             (RequestInfoStack)threadLocalClientRequestInfoStack.get();
   774         ClientRequestInfoImpl info = null;
   775         if( !infoStack.empty() ) {
   776             info = (ClientRequestInfoImpl)infoStack.peek();
   777         } else {
   778             throw wrapper.clientInfoStackNull() ;
   779         }
   781         return info;
   782     }
   784     /**
   785      * Convenience method to get the ServerRequestInfoImpl object off the
   786      * top of the ThreadLocal stack.  Returns null if there are none.
   787      */
   788     private ServerRequestInfoImpl peekServerRequestInfoImplStack() {
   789         RequestInfoStack infoStack =
   790             (RequestInfoStack)threadLocalServerRequestInfoStack.get();
   791         ServerRequestInfoImpl info = null;
   793         if( !infoStack.empty() ) {
   794             info = (ServerRequestInfoImpl)infoStack.peek();
   795         } else {
   796             throw wrapper.serverInfoStackNull() ;
   797         }
   799         return info;
   800     }
   802     /**
   803      * Convenience method to determine whether Client PI is enabled
   804      * for requests on this thread.
   805      */
   806     private boolean isClientPIEnabledForThisThread() {
   807         RequestInfoStack infoStack =
   808             (RequestInfoStack)threadLocalClientRequestInfoStack.get();
   809         return (infoStack.disableCount == 0);
   810     }
   812     /**
   813      * Call pre_init on all ORB initializers
   814      */
   815     private void preInitORBInitializers( ORBInitInfoImpl info ) {
   817         // Inform ORBInitInfo we are in pre_init stage
   818         info.setStage( ORBInitInfoImpl.STAGE_PRE_INIT );
   820         // Step through each initializer instantiation and call its
   821         // pre_init.  Ignore any exceptions.
   822         for( int i = 0; i < orb.getORBData().getORBInitializers().length;
   823             i++ ) {
   824             ORBInitializer init = orb.getORBData().getORBInitializers()[i];
   825             if( init != null ) {
   826                 try {
   827                     init.pre_init( info );
   828                 }
   829                 catch( Exception e ) {
   830                     // As per orbos/99-12-02, section 9.3.1.2, "If there are
   831                     // any exceptions, the ORB shall ignore them and proceed."
   832                 }
   833             }
   834         }
   835     }
   837     /**
   838      * Call post_init on all ORB initializers
   839      */
   840     private void postInitORBInitializers( ORBInitInfoImpl info ) {
   842         // Inform ORBInitInfo we are in post_init stage
   843         info.setStage( ORBInitInfoImpl.STAGE_POST_INIT );
   845         // Step through each initializer instantiation and call its post_init.
   846         // Ignore any exceptions.
   847         for( int i = 0; i < orb.getORBData().getORBInitializers().length;
   848             i++ ) {
   849             ORBInitializer init = orb.getORBData().getORBInitializers()[i];
   850             if( init != null ) {
   851                 try {
   852                     init.post_init( info );
   853                 }
   854                 catch( Exception e ) {
   855                     // As per orbos/99-12-02, section 9.3.1.2, "If there are
   856                     // any exceptions, the ORB shall ignore them and proceed."
   857                 }
   858             }
   859         }
   860     }
   862     /**
   863      * Creates the ORBInitInfo object to be passed to ORB intializers'
   864      * pre_init and post_init methods
   865      */
   866     private ORBInitInfoImpl createORBInitInfo() {
   867         ORBInitInfoImpl result = null;
   869         // arguments comes from set_parameters.  May be null.
   871         // _REVISIT_ The spec does not specify which ID this is to be.
   872         // We currently get this from the corba.ORB, which reads it from
   873         // the ORB_ID_PROPERTY property.
   874         String orbId = orb.getORBData().getORBId() ;
   876         result = new ORBInitInfoImpl( orb, arguments, orbId, codecFactory );
   878         return result;
   879     }
   881     /**
   882      * Called by ORBInitInfo when an interceptor needs to be registered.
   883      * The type is one of:
   884      * <ul>
   885      *   <li>INTERCEPTOR_TYPE_CLIENT - ClientRequestInterceptor
   886      *   <li>INTERCEPTOR_TYPE_SERVER - ServerRequestInterceptor
   887      *   <li>INTERCEPTOR_TYPE_IOR - IORInterceptor
   888      * </ul>
   889      *
   890      * @exception DuplicateName Thrown if an interceptor of the given
   891      *     name already exists for the given type.
   892      */
   893     public void register_interceptor( Interceptor interceptor, int type )
   894         throws DuplicateName
   895     {
   896         // We will assume interceptor is not null, since it is called
   897         // internally.
   898         if( (type >= InterceptorList.NUM_INTERCEPTOR_TYPES) || (type < 0) ) {
   899             throw wrapper.typeOutOfRange( new Integer( type ) ) ;
   900         }
   902         String interceptorName = interceptor.name();
   904         if( interceptorName == null ) {
   905             throw wrapper.nameNull() ;
   906         }
   908         // Register with interceptor list:
   909         interceptorList.register_interceptor( interceptor, type );
   910     }
   912     public Current getPICurrent( ) {
   913         return current;
   914     }
   916     /**
   917      * Called when an invalid null parameter was passed.  Throws a
   918      * BAD_PARAM with a minor code of 1
   919      */
   920     private void nullParam()
   921         throws BAD_PARAM
   922     {
   923         throw orbutilWrapper.nullParam() ;
   924     }
   926     /** This is the implementation of standard API defined in org.omg.CORBA.ORB
   927      *  class. This method finds the Policy Factory for the given Policy Type
   928      *  and instantiates the Policy object from the Factory. It will throw
   929      *  PolicyError exception, If the PolicyFactory for the given type is
   930      *  not registered.
   931      *  _REVISIT_, Once Policy Framework work is completed, Reorganize
   932      *  this method to com.sun.corba.se.spi.orb.ORB.
   933      */
   934     public org.omg.CORBA.Policy create_policy(int type, org.omg.CORBA.Any val)
   935         throws org.omg.CORBA.PolicyError
   936     {
   937         if( val == null ) {
   938             nullParam( );
   939         }
   940         if( policyFactoryTable == null ) {
   941             throw new org.omg.CORBA.PolicyError(
   942                 "There is no PolicyFactory Registered for type " + type,
   943                 BAD_POLICY.value );
   944         }
   945         PolicyFactory factory = (PolicyFactory)policyFactoryTable.get(
   946             new Integer(type) );
   947         if( factory == null ) {
   948             throw new org.omg.CORBA.PolicyError(
   949                 " Could Not Find PolicyFactory for the Type " + type,
   950                 BAD_POLICY.value);
   951         }
   952         org.omg.CORBA.Policy policy = factory.create_policy( type, val );
   953         return policy;
   954     }
   956     /** This method registers the Policy Factory in the policyFactoryTable,
   957      *  which is a HashMap. This method is made package private, because
   958      *  it is used internally by the  Interceptors.
   959      */
   960     public void registerPolicyFactory( int type, PolicyFactory factory ) {
   961         if( policyFactoryTable == null ) {
   962             policyFactoryTable = new HashMap();
   963         }
   964         Integer key = new Integer( type );
   965         java.lang.Object val = policyFactoryTable.get( key );
   966         if( val == null ) {
   967             policyFactoryTable.put( key, factory );
   968         }
   969         else {
   970             throw omgWrapper.policyFactoryRegFailed( new Integer( type ) ) ;
   971         }
   972     }
   974     public synchronized int allocateServerRequestId ()
   975     {
   976         return serverRequestIdCounter++;
   977     }
   978 }

mercurial