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