blob: 52e457f22200230f49d859e90943b2f1623f9e08 [file] [log] [blame]
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.corba.se.impl.interceptors;
import java.io.IOException ;
import java.lang.reflect.Method ;
import java.lang.reflect.InvocationTargetException ;
import java.util.HashMap ;
import org.omg.PortableInterceptor.ForwardRequest;
import org.omg.PortableInterceptor.InvalidSlot;
import org.omg.PortableInterceptor.RequestInfo;
import org.omg.PortableInterceptor.LOCATION_FORWARD;
import org.omg.IOP.TaggedProfile;
import org.omg.IOP.TaggedComponent;
import org.omg.IOP.ServiceContextHelper;
import org.omg.Messaging.SYNC_WITH_TRANSPORT;
import org.omg.CORBA.ParameterMode;
import org.omg.CORBA.Any;
import org.omg.CORBA.BAD_INV_ORDER;
import org.omg.CORBA.BAD_PARAM;
import org.omg.CORBA.CompletionStatus;
import org.omg.CORBA.Context;
import org.omg.CORBA.ContextList;
import org.omg.CORBA.CTX_RESTRICT_SCOPE;
import org.omg.CORBA.ExceptionList;
import org.omg.CORBA.INTERNAL;
import org.omg.CORBA.LocalObject;
import org.omg.CORBA.NamedValue;
import org.omg.CORBA.NO_IMPLEMENT;
import org.omg.CORBA.NO_RESOURCES;
import org.omg.CORBA.NVList;
import org.omg.CORBA.Object;
import org.omg.CORBA.Policy;
import org.omg.CORBA.SystemException;
import org.omg.CORBA.TypeCode;
import org.omg.CORBA.UNKNOWN;
import org.omg.CORBA.UserException;
import org.omg.CORBA.portable.ApplicationException;
import org.omg.CORBA.portable.Delegate;
import org.omg.CORBA.portable.InputStream;
import org.omg.Dynamic.Parameter;
import com.sun.corba.se.spi.legacy.connection.Connection;
import com.sun.corba.se.spi.legacy.interceptor.RequestInfoExt;
import com.sun.corba.se.spi.ior.IOR;
import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
import com.sun.corba.se.spi.orb.ORB;
import com.sun.corba.se.spi.logging.CORBALogDomains;
import com.sun.corba.se.spi.servicecontext.ServiceContexts;
import com.sun.corba.se.spi.servicecontext.UnknownServiceContext;
import com.sun.corba.se.impl.encoding.CDRInputStream_1_0;
import com.sun.corba.se.impl.encoding.EncapsOutputStream;
import com.sun.corba.se.impl.orbutil.ORBUtility;
import com.sun.corba.se.impl.util.RepositoryId;
import com.sun.corba.se.impl.logging.InterceptorsSystemException;
import com.sun.corba.se.impl.logging.OMGSystemException;
import sun.corba.SharedSecrets;
/**
* Implementation of the RequestInfo interface as specified in
* orbos/99-12-02 section 5.4.1.
*/
public abstract class RequestInfoImpl
extends LocalObject
implements RequestInfo, RequestInfoExt
{
//////////////////////////////////////////////////////////////////////
//
// NOTE: IF AN ATTRIBUTE IS ADDED, PLEASE UPDATE RESET();
//
//////////////////////////////////////////////////////////////////////
// The ORB from which to get PICurrent and other info
protected ORB myORB;
protected InterceptorsSystemException wrapper ;
protected OMGSystemException stdWrapper ;
// The number of interceptors actually invoked for this client request.
// See setFlowStackIndex for a detailed description.
protected int flowStackIndex = 0;
// The type of starting point call to make to the interceptors
// See ClientRequestInfoImpl and ServerRequestInfoImpl for a list of
// appropriate constants.
protected int startingPointCall;
// The type of intermediate point call to make to the interceptors
// See ServerRequestInfoImpl for a list of appropriate constants.
// This does not currently apply to client request interceptors but is
// here in case intermediate points are introduced in the future.
protected int intermediatePointCall;
// The type of ending point call to make to the interceptors
// See ClientRequestInfoImpl and ServerRequestInfoImpl for a list of
// appropriate constants.
protected int endingPointCall;
// The reply status to return in reply_status. This is initialized
// to UNINITIALIZED so that we can tell if this has been set or not.
protected short replyStatus = UNINITIALIZED;
// Constant for an uninitizlied reply status.
protected static final short UNINITIALIZED = -1;
// Which points we are currently executing (so we can implement the
// validity table).
protected int currentExecutionPoint;
protected static final int EXECUTION_POINT_STARTING = 0;
protected static final int EXECUTION_POINT_INTERMEDIATE = 1;
protected static final int EXECUTION_POINT_ENDING = 2;
// Set to true if all interceptors have had all their points
// executed.
protected boolean alreadyExecuted;
// Sources of request information
protected Connection connection;
protected ServiceContexts serviceContexts;
// The ForwardRequest object if this request is being forwarded.
// Either the forwardRequest or the forwardRequestIOR field is set.
// When set, the other field is set to null initially. If the other
// field is queried, it is lazily calculated and cached. These
// two attributes are always kept in sync.
protected ForwardRequest forwardRequest;
protected IOR forwardRequestIOR;
// PICurrent's SlotTable
protected SlotTable slotTable;
// The exception to be returned by received_exception and
// received_exception_id
protected Exception exception;
//////////////////////////////////////////////////////////////////////
//
// NOTE: IF AN ATTRIBUTE IS ADDED, PLEASE UPDATE RESET();
//
//////////////////////////////////////////////////////////////////////
/**
* Reset the info object so that it can be reused for a retry,
* for example.
*/
void reset() {
// Please keep these in the same order as declared above.
flowStackIndex = 0;
startingPointCall = 0;
intermediatePointCall = 0;
endingPointCall = 0;
// 6763340
setReplyStatus( UNINITIALIZED ) ;
currentExecutionPoint = EXECUTION_POINT_STARTING;
alreadyExecuted = false;
connection = null;
serviceContexts = null;
forwardRequest = null;
forwardRequestIOR = null;
exception = null;
// We don't need to reset the Slots because they are
// already in the clean state after recieve_<point> interceptor
// are called.
}
/*
**********************************************************************
* Access protection
**********************************************************************/
// Method IDs for all methods in RequestInfo. This allows for a
// convenient O(1) lookup for checkAccess().
protected static final int MID_REQUEST_ID = 0;
protected static final int MID_OPERATION = 1;
protected static final int MID_ARGUMENTS = 2;
protected static final int MID_EXCEPTIONS = 3;
protected static final int MID_CONTEXTS = 4;
protected static final int MID_OPERATION_CONTEXT = 5;
protected static final int MID_RESULT = 6;
protected static final int MID_RESPONSE_EXPECTED = 7;
protected static final int MID_SYNC_SCOPE = 8;
protected static final int MID_REPLY_STATUS = 9;
protected static final int MID_FORWARD_REFERENCE = 10;
protected static final int MID_GET_SLOT = 11;
protected static final int MID_GET_REQUEST_SERVICE_CONTEXT = 12;
protected static final int MID_GET_REPLY_SERVICE_CONTEXT = 13;
// The last value from RequestInfo (be sure to update this):
protected static final int MID_RI_LAST = 13;
/*
**********************************************************************
* Public interfaces
**********************************************************************/
/**
* Creates a new RequestInfoImpl object.
*/
public RequestInfoImpl( ORB myORB ) {
super();
this.myORB = myORB;
wrapper = InterceptorsSystemException.get( myORB,
CORBALogDomains.RPC_PROTOCOL ) ;
stdWrapper = OMGSystemException.get( myORB,
CORBALogDomains.RPC_PROTOCOL ) ;
// Capture the current TSC and make it the RSC of this request.
PICurrent current = (PICurrent)(myORB.getPIHandler().getPICurrent());
slotTable = current.getSlotTable( );
}
/**
* Implementation for request_id() differs for client and server
* implementations.
*
* Uniquely identifies an active request/reply sequence. Once a
* request/reply sequence is concluded this ID may be reused. (this
* is NOT necessarily the same as the GIOP request_id).
*/
abstract public int request_id ();
/**
* Implementation for operation() differs for client and server
* implementations.
*
* The name of the operation being invoked.
*/
abstract public String operation ();
/**
* This method returns the list of arguments for the operation that was
* invoked. It raises NO_RESOURCES exception if the operation is not invoked
* by using DII mechanism.
*/
abstract public Parameter[] arguments ();
/**
* This method returns the list of exceptios that was raised when the
* operation was invoked. It raises NO_RESOURCES exception if the operation
* is not invoked by using DII mechanism.
*/
abstract public TypeCode[] exceptions ();
/**
* This method returns the list of contexts for the DII operation.
* It raises NO_RESOURCES exception if the operation is not invoked by
* using DII mechanism.
*/
abstract public String[] contexts ();
/**
* This method returns the list of operation_context for the DII operation.
* It raises NO_RESOURCES exception if the operation is not invoked by
* using DII mechanism.
*/
abstract public String[] operation_context ();
/**
* This method returns the result from the invoked DII operation.
* It raises NO_RESOURCES exception if the operation is not invoked by
* using DII mechanism.
*/
abstract public Any result ();
/**
* Implementation for response_expected() differs for client and server
* implementations.
*
* Indicates whether a response is expected. On the client, a reply is
* not returned when response_expected is false, so receive_reply cannot
* be called. receive_other is called unless an exception occurs, in
* which case receive_exception is called. On the client, within
* send_poll, this attribute is true.
*/
abstract public boolean response_expected ();
/**
* Defined in the Messaging specification. Pertinent only when
* response_expected is false. If response_expected is true, the value
* of sync_scope is undefined. It defines how far the request shall
* progress before control is returned to the client. This attribute may
* have one of the follwing values:
* <ul>
* <li>Messaging::SYNC_NONE</li>
* <li>Messaging::SYNC_WITH_TRANSPORT</li>
* <li>Messaging::SYNC_WITH_SERVER</li>
* <li>Messaging::SYNC_WITH_TARGET</li>
* </ul>
*/
public short sync_scope (){
checkAccess( MID_SYNC_SCOPE );
return SYNC_WITH_TRANSPORT.value; // REVISIT - get from MessageMediator
}
/**
* Describes the state of the result of the operation invocation. Its
* value can be one of the following:
* <ul>
* <li>PortableInterceptor::SUCCESSFUL</li>
* <li>PortableInterceptor::SYSTEM_EXCEPTION</li>
* <li>PortableInterceptor::USER_EXCEPTION</li>
* <li>PortableInterceptor::LOCATION_FORWARD</li>
* <li>PortableInterceptor::TRANSPORT_RETRY</li>
* </ul>
*/
public short reply_status (){
checkAccess( MID_REPLY_STATUS );
return replyStatus;
}
/**
* Implementation for forward_reference() differs for client and server
* implementations.
*
* If the reply_status attribute is LOCATION_FORWARD
* then this attribute will contain the object
* to which the request will be forwarded. It is indeterminate whether a
* forwarded request will actually occur.
*/
abstract public Object forward_reference ();
/**
* Returns the data from the given slot of the PortableInterceptor::Current
* that is in the scope of the request.
* <p>
* If the given slot has not been set, then an any containing a type code
* with a TCKind value of tk_null is returned.
* <p>
* If the ID does not define an allocated slot, InvalidSlot is raised.
*/
public Any get_slot (int id)
throws InvalidSlot
{
// access is currently valid for all states:
//checkAccess( MID_GET_SLOT );
// Delegate the call to the slotTable which was set when RequestInfo was
// created.
return slotTable.get_slot( id );
}
/**
* Implementation for get_request_service_context() differs for client
* and server implementations.
*
* This operation returns a copy of the service context with the given ID
* that is associated with the request. If the request's service context
* does not contain an etry for that ID, BAD_PARAM with a minor code of
* TBD_BP is raised.
*/
abstract public org.omg.IOP.ServiceContext
get_request_service_context(int id);
/**
* Implementation for get_reply_service_context() differs for client
* and server implementations.
*
* This operation returns a copy of the service context with the given ID
* that is associated with the reply. IF the request's service context
* does not contain an entry for that ID, BAD_PARAM with a minor code of
* TBD_BP is raised.
*/
abstract public org.omg.IOP.ServiceContext
get_reply_service_context (int id);
// NOTE: When adding a method, be sure to:
// 1. Add a MID_* constant for that method
// 2. Call checkAccess at the start of the method
// 3. Define entries in the validCall[][] table for interception points
// in both ClientRequestInfoImpl and ServerRequestInfoImpl.
/*
**********************************************************************
* Proprietary methods
**********************************************************************/
/**
* @return The connection on which the request is made.
*
* Note: we store the connection as an internal type but
* expose it here as an external type.
*/
public com.sun.corba.se.spi.legacy.connection.Connection connection()
{
return connection;
}
/*
**********************************************************************
* Private utility methods
**********************************************************************/
/**
* Inserts the UserException inside the given ApplicationException
* into the given Any. Throws an UNKNOWN with minor code
* OMGSYstemException.UNKNOWN_USER_EXCEPTION if the Helper class could not be
* found to insert it with.
*/
private void insertApplicationException( ApplicationException appException,
Any result )
throws UNKNOWN
{
try {
// Extract the UserException from the ApplicationException.
// Look up class name from repository id:
RepositoryId repId = RepositoryId.cache.getId(
appException.getId() );
String className = repId.getClassName();
// Find the read method on the helper class:
String helperClassName = className + "Helper";
Class<?> helperClass =
SharedSecrets.getJavaCorbaAccess().loadClass( helperClassName );
Class[] readParams = new Class[1];
readParams[0] = org.omg.CORBA.portable.InputStream.class;
Method readMethod = helperClass.getMethod( "read", readParams );
// Invoke the read method, passing in the input stream to
// retrieve the user exception. Mark and reset the stream
// as to not disturb it.
InputStream ueInputStream = appException.getInputStream();
ueInputStream.mark( 0 );
UserException userException = null;
try {
java.lang.Object[] readArguments = new java.lang.Object[1];
readArguments[0] = ueInputStream;
userException = (UserException)readMethod.invoke(
null, readArguments );
}
finally {
try {
ueInputStream.reset();
}
catch( IOException e ) {
throw wrapper.markAndResetFailed( e ) ;
}
}
// Insert this UserException into the provided Any using the
// helper class.
insertUserException( userException, result );
} catch( ClassNotFoundException e ) {
throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e ) ;
} catch( NoSuchMethodException e ) {
throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e ) ;
} catch( SecurityException e ) {
throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e ) ;
} catch( IllegalAccessException e ) {
throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e ) ;
} catch( IllegalArgumentException e ) {
throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e ) ;
} catch( InvocationTargetException e ) {
throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e ) ;
}
}
/**
* Inserts the UserException into the given Any.
* Throws an UNKNOWN with minor code
* OMGSYstemException.UNKNOWN_USER_EXCEPTION if the Helper class could not be
* found to insert it with.
*/
private void insertUserException( UserException userException, Any result )
throws UNKNOWN
{
try {
// Insert this UserException into the provided Any using the
// helper class.
if( userException != null ) {
Class exceptionClass = userException.getClass();
String className = exceptionClass.getName();
String helperClassName = className + "Helper";
Class<?> helperClass =
SharedSecrets.getJavaCorbaAccess().loadClass( helperClassName );
// Find insert( Any, class ) method
Class[] insertMethodParams = new Class[2];
insertMethodParams[0] = org.omg.CORBA.Any.class;
insertMethodParams[1] = exceptionClass;
Method insertMethod = helperClass.getMethod(
"insert", insertMethodParams );
// Call helper.insert( result, userException ):
java.lang.Object[] insertMethodArguments =
new java.lang.Object[2];
insertMethodArguments[0] = result;
insertMethodArguments[1] = userException;
insertMethod.invoke( null, insertMethodArguments );
}
} catch( ClassNotFoundException e ) {
throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e );
} catch( NoSuchMethodException e ) {
throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e );
} catch( SecurityException e ) {
throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e );
} catch( IllegalAccessException e ) {
throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e );
} catch( IllegalArgumentException e ) {
throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e );
} catch( InvocationTargetException e ) {
throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e );
}
}
/*
**********************************************************************
* Protected utility methods
**********************************************************************/
/**
* Internal utility method to convert an NVList into a PI Parameter[]
*/
protected Parameter[] nvListToParameterArray( NVList parNVList ) {
// _REVISIT_ This utility method should probably be doing a deep
// copy so interceptor can't accidentally change the arguments.
int count = parNVList.count();
Parameter[] plist = new Parameter[count];
try {
for( int i = 0; i < count; i++ ) {
Parameter p = new Parameter();
plist[i] = p;
NamedValue nv = parNVList.item( i );
plist[i].argument = nv.value();
// ParameterMode spec can be found in 99-10-07.pdf
// Section:10.5.22
// nv.flags spec can be found in 99-10-07.pdf
// Section 7.1.1
// nv.flags has ARG_IN as 1, ARG_OUT as 2 and ARG_INOUT as 3
// To convert this into enum PARAM_IN, PARAM_OUT and
// PARAM_INOUT the value is subtracted by 1.
plist[i].mode = ParameterMode.from_int( nv.flags() - 1 );
}
} catch ( Exception e ) {
throw wrapper.exceptionInArguments( e ) ;
}
return plist;
}
/**
* Utility to wrap the given Exception in an Any object and return it.
* If the exception is a UserException which cannot be inserted into
* an any, then this returns an Any containing the system exception
* UNKNOWN.
*/
protected Any exceptionToAny( Exception exception ){
Any result = myORB.create_any();
if( exception == null ) {
// Note: exception should never be null here since we will throw
// a BAD_INV_ORDER if this is not called from receive_exception.
throw wrapper.exceptionWasNull2() ;
} else if( exception instanceof SystemException ) {
ORBUtility.insertSystemException(
(SystemException)exception, result );
} else if( exception instanceof ApplicationException ) {
// Use the Helper class for this exception to insert it into an
// Any.
try {
// Insert the user exception inside the application exception
// into the Any result:
ApplicationException appException =
(ApplicationException)exception;
insertApplicationException( appException, result );
} catch( UNKNOWN e ) {
// As per ptc/00-08-06, 21.3.13.4. if we cannot find the
// appropriate class, then return an any containing UNKNOWN,
// with a minor code of 1. This is conveniently the same
// exception that is returned from the
// insertApplicationException utility method.
ORBUtility.insertSystemException( e, result );
}
} else if( exception instanceof UserException ) {
try {
UserException userException = (UserException)exception;
insertUserException( userException, result );
} catch( UNKNOWN e ) {
ORBUtility.insertSystemException( e, result );
}
}
return result;
}
/**
* Utility method to look up a service context with the given id and
* convert it to an IOP.ServiceContext. Uses the given HashMap as
* a cache. If not found in cache, the result is inserted in the cache.
*/
protected org.omg.IOP.ServiceContext
getServiceContext ( HashMap cachedServiceContexts,
ServiceContexts serviceContexts, int id )
{
org.omg.IOP.ServiceContext result = null;
Integer integerId = new Integer( id );
// Search cache first:
result = (org.omg.IOP.ServiceContext)
cachedServiceContexts.get( integerId );
// null could normally mean that either we cached the value null
// or it's not in the cache. However, there is no way for us to
// cache the value null in the following code.
if( result == null ) {
// Not in cache. Find it and put in cache.
// Get the desired "core" service context.
com.sun.corba.se.spi.servicecontext.ServiceContext context =
serviceContexts.get( id );
if (context == null)
throw stdWrapper.invalidServiceContextId() ;
// Convert the "core" service context to an
// "IOP" ServiceContext by writing it to a
// CDROutputStream and reading it back.
EncapsOutputStream out =
sun.corba.OutputStreamFactory.newEncapsOutputStream(myORB);
context.write( out, GIOPVersion.V1_2 );
InputStream inputStream = out.create_input_stream();
result = ServiceContextHelper.read( inputStream );
cachedServiceContexts.put( integerId, result );
}
// Good citizen: For increased efficiency, we assume that interceptors
// will not modify the returned ServiceContext. Otherwise, we would
// have to make a deep copy.
return result;
}
/**
* Utility method to add an IOP.ServiceContext to a core.ServiceContexts
* object. If replace is true, any service context with the given id
* is replaced.
* <p>
* Raises BAD_INV_ORDER if replace is false and a service context with
* the given id already exists.
* <p>
* Uses the given HashMap as a cache. If a service context is placed
* in the container, it goes in the HashMap as well.
*/
protected void addServiceContext(
HashMap cachedServiceContexts,
ServiceContexts serviceContexts,
org.omg.IOP.ServiceContext service_context,
boolean replace )
{
int id = 0 ;
// Convert IOP.service_context to core.ServiceContext:
EncapsOutputStream outputStream =
sun.corba.OutputStreamFactory.newEncapsOutputStream(myORB);
InputStream inputStream = null;
UnknownServiceContext coreServiceContext = null;
ServiceContextHelper.write( outputStream, service_context );
inputStream = outputStream.create_input_stream();
// Constructor expects id to already have been read from stream.
coreServiceContext = new UnknownServiceContext(
inputStream.read_long(),
(org.omg.CORBA_2_3.portable.InputStream)inputStream );
id = coreServiceContext.getId();
if (serviceContexts.get(id) != null)
if (replace)
serviceContexts.delete( id );
else
throw stdWrapper.serviceContextAddFailed( new Integer(id) ) ;
serviceContexts.put( coreServiceContext );
// Place IOP.ServiceContext in cache as well:
cachedServiceContexts.put( new Integer( id ), service_context );
}
/**
* Sets the number of interceptors whose starting interception
* points were successfully invoked on this client call. As specified
* in orbos/99-12-02, section 5.2.1., not all interceptors will
* be invoked if a ForwardRequest exception or a system exception
* is raised. This keeps track of how many were successfully executed
* so we know not to execute the corresponding ending interception
* points for the interceptors whose starting interception points
* were not completed. This simulates the "Flow Stack Visual Model"
* presented in section 5.1.3.*/
protected void setFlowStackIndex(int num ) {
this.flowStackIndex = num;
}
/**
* Returns the number of interceptors whose starting interception
* points were actually invoked on this client request. See
* setFlowStackIndex for more details.
*/
protected int getFlowStackIndex() {
return this.flowStackIndex;
}
/**
* Sets which ending interception point should be called
* for each interceptor in the virtual flow stack.
*/
protected void setEndingPointCall( int call ) {
this.endingPointCall = call;
}
/**
* Retrieves the current ending point call type (see
* setEndingPointCall for more details).
*/
protected int getEndingPointCall() {
return this.endingPointCall;
}
/**
* Sets which intermediate interception point should be called
* for each interceptor in the virtual flow stack.
*/
protected void setIntermediatePointCall( int call ) {
this.intermediatePointCall = call;
}
/**
* Retrieves the current intermediate point call type (see
* setEndingPointCall for more details).
*/
protected int getIntermediatePointCall() {
return this.intermediatePointCall;
}
/**
* Sets which starting interception point should be called
* for each interceptor in the virtual flow stack.
*/
protected void setStartingPointCall( int call ) {
this.startingPointCall = call;
}
/**
* Retrieves the current starting point call type (see
* setStartingPointCall for more details).
*/
protected int getStartingPointCall() {
return this.startingPointCall;
}
/**
* Returns true if all interceptors' starting and ending points
* have already executed to completion, or false if not yet.
*/
protected boolean getAlreadyExecuted() {
return this.alreadyExecuted;
}
/**
* Sets whether all interceotrs' starting and ending points
* have already been executed to completion.
*/
protected void setAlreadyExecuted( boolean alreadyExecuted ) {
this.alreadyExecuted = alreadyExecuted;
}
/**
* Sets the value to be returned by reply_status
*/
protected void setReplyStatus( short replyStatus ) {
this.replyStatus = replyStatus;
}
/**
* Gets the current reply_status without doing an access check
* (available only to package and subclasses)
*/
protected short getReplyStatus() {
return this.replyStatus;
}
/**
* Stores the given ForwardRequest object for later analysis.
* This version supplements setForwardRequest( IOR );
*/
protected void setForwardRequest( ForwardRequest forwardRequest ) {
this.forwardRequest = forwardRequest;
this.forwardRequestIOR = null;
}
/**
* Stores the given IOR for later forward request analysis.
* This version supplements setForwardRequest( ForwardRequest );
*/
protected void setForwardRequest( IOR ior ) {
this.forwardRequestIOR = ior;
this.forwardRequest = null;
}
/**
* Retrieves the ForwardRequest object as a ForwardRequest exception.
*/
protected ForwardRequest getForwardRequestException() {
if( this.forwardRequest == null ) {
if( this.forwardRequestIOR != null ) {
// Convert the internal IOR to a forward request exception
// by creating an object reference.
org.omg.CORBA.Object obj = iorToObject(this.forwardRequestIOR);
this.forwardRequest = new ForwardRequest( obj );
}
}
return this.forwardRequest;
}
/**
* Retrieves the IOR of the ForwardRequest exception.
*/
protected IOR getForwardRequestIOR() {
if( this.forwardRequestIOR == null ) {
if( this.forwardRequest != null ) {
this.forwardRequestIOR = ORBUtility.getIOR(
this.forwardRequest.forward ) ;
}
}
return this.forwardRequestIOR;
}
/**
* Sets the exception to be returned by received_exception and
* received_exception_id.
*/
protected void setException( Exception exception ) {
this.exception = exception;
}
/**
* Returns the exception to be returned by received_exception and
* received_exception_id.
*/
Exception getException() {
return this.exception;
}
/**
* Sets the execution point that we are currently executing
* (starting points, intermediate points, or ending points).
* This allows us to enforce the validity table.
*/
protected void setCurrentExecutionPoint( int executionPoint ) {
this.currentExecutionPoint = executionPoint;
}
/**
* Check whether the caller is allowed to access this method at
* this particular time. This is overridden in subclasses to implement
* the validity table specified in ptc/00-04-05, table 21-1 and 21-2.
* The currentExecutionPoint attribute is checked, and if access is
* forbidden at this time, BAD_INV_ORDER is raised with a minor code of
* TBD_BIO.
*
* @param methodID The ID of this method, one of the MID_* constants.
* This allows us to easily look up the method access in a table.
* Note that method ids may overlap between subclasses.
*/
protected abstract void checkAccess( int methodID )
throws BAD_INV_ORDER;
/**
* The server side does an explicit set rather than taking the
* current PICurrent table as is done in the general RequestInfoImpl
* constructor.
*/
void setSlotTable(SlotTable slotTable)
{
this.slotTable = slotTable;
}
protected org.omg.CORBA.Object iorToObject( IOR ior )
{
return ORBUtility.makeObjectReference( ior ) ;
}
}