Tue, 28 Dec 2010 15:52:36 -0800
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 }