serverrequestinfoimpl.java
来自「java jdk 1.4的源码」· Java 代码 · 共 874 行 · 第 1/2 页
JAVA
874 行
/* * @(#)ServerRequestInfoImpl.java 1.37 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.corba.se.internal.Interceptors; import org.omg.CORBA.Any;import org.omg.CORBA.BAD_INV_ORDER;import org.omg.CORBA.CompletionStatus;import org.omg.CORBA.INTERNAL;import org.omg.CORBA.LocalObject;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.TypeCode;import org.omg.CORBA.portable.ObjectImpl;import org.omg.PortableServer.Servant;import org.omg.IOP.TaggedProfile;import org.omg.IOP.ServiceContext;import com.sun.corba.se.internal.iiop.messages.ReplyMessage;import org.omg.Dynamic.Parameter;import org.omg.PortableInterceptor.InvalidSlot;import org.omg.PortableInterceptor.ServerRequestInfo;import org.omg.PortableInterceptor.LOCATION_FORWARD;import org.omg.PortableInterceptor.SUCCESSFUL;import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;import org.omg.PortableInterceptor.TRANSPORT_RETRY;import org.omg.PortableInterceptor.USER_EXCEPTION;import com.sun.corba.se.internal.core.ServerRequest;import com.sun.corba.se.internal.core.ServiceContexts;import com.sun.corba.se.internal.POA.POAImpl;import java.util.*;/** * Implementation of the ServerRequestInfo interface as specified in * orbos/99-12-02 section 5.4.3. */public final class ServerRequestInfoImpl extends RequestInfoImpl implements ServerRequestInfo { // The available constants for startingPointCall static final int CALL_RECEIVE_REQUEST_SERVICE_CONTEXT = 0; // The available constants for intermediatePointCall. The default (0) // is receive_request, but can be set to none on demand. static final int CALL_RECEIVE_REQUEST = 0; static final int CALL_INTERMEDIATE_NONE = 1; // The available constants for endingPointCall static final int CALL_SEND_REPLY = 0; static final int CALL_SEND_EXCEPTION = 1; static final int CALL_SEND_OTHER = 2; ////////////////////////////////////////////////////////////////////// // // NOTE: IF AN ATTRIBUTE IS ADDED, PLEASE UPDATE RESET(); // ////////////////////////////////////////////////////////////////////// // Set to true if the server ending point raised ForwardRequest at some // point in the ending point. private boolean forwardRequestRaisedInEnding; // Sources of server request information: private ServerRequest request; private java.lang.Object servant; private byte[] objectId; private byte[] adapterId; private ArrayList addReplyServiceContextQueue; private ReplyMessage replyMessage; private String targetMostDerivedInterface; private NVList dsiArguments; private Any dsiResult; private Any dsiException; private boolean isDynamic; private POAImpl poaimpl; private int serverRequestId; // Cached information: private Parameter[] cachedArguments; private Any cachedSendingException; // key = Integer, value = IOP.ServiceContext. private HashMap cachedRequestServiceContexts; // key = Integer, value = IOP.ServiceContext. private HashMap cachedReplyServiceContexts; ////////////////////////////////////////////////////////////////////// // // 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() { super.reset(); // Please keep these in the same order as declared above. forwardRequestRaisedInEnding = false; request = null; servant = null; objectId = null; adapterId = null; addReplyServiceContextQueue = null; replyMessage = null; targetMostDerivedInterface = null; dsiArguments = null; dsiResult = null; dsiException = null; isDynamic = false; poaimpl = null; serverRequestId = piOrb.allocateServerRequestId(); // reset cached attributes: cachedArguments = null; cachedSendingException = null; cachedRequestServiceContexts = null; cachedReplyServiceContexts = null; startingPointCall = CALL_RECEIVE_REQUEST_SERVICE_CONTEXT; intermediatePointCall = CALL_RECEIVE_REQUEST; endingPointCall = CALL_SEND_REPLY; } /* ********************************************************************** * Access protection **********************************************************************/ // Method IDs for all methods in ServerRequestInfo. This allows for a // convenient O(1) lookup for checkAccess(). protected static final int MID_SENDING_EXCEPTION = MID_RI_LAST + 1; protected static final int MID_OBJECT_ID = MID_RI_LAST + 2; protected static final int MID_ADAPTER_ID = MID_RI_LAST + 3; protected static final int MID_TARGET_MOST_DERIVED_INTERFACE = MID_RI_LAST + 4; protected static final int MID_GET_SERVER_POLICY = MID_RI_LAST + 5; protected static final int MID_SET_SLOT = MID_RI_LAST + 6; protected static final int MID_TARGET_IS_A = MID_RI_LAST + 7; protected static final int MID_ADD_REPLY_SERVICE_CONTEXT = MID_RI_LAST + 8; // ServerRequestInfo validity table (see ptc/00-08-06 table 21-2). // Note: These must be in the same order as specified in contants. protected static final boolean validCall[][] = { // LEGEND: // r_rsc = receive_request_service_contexts // r_req = receive_request // s_rep = send_reply // s_exc = send_exception // s_oth = send_other // // A true value indicates call is valid at specified point. // A false value indicates the call is invalid. // // NOTE: If the order or number of columns change, update // checkAccess() accordingly. // // { r_rsc, r_req, s_rep, s_exc, s_oth } // RequestInfo methods: /*request_id*/ { true , true , true , true , true }, /*operation*/ { true , true , true , true , true }, /*arguments*/ { false, true , true , false, false }, /*exceptions*/ { false, true , true , true , true }, /*contexts*/ { false, true , true , true , true }, /*operation_context*/ { false, true , true , false, false }, /*result*/ { false, false, true , false, false }, /*response_expected*/ { true , true , true , true , true }, /*sync_scope*/ { true , true , true , true , true }, /*reply_status*/ { false, false, true , true , true }, /*forward_reference*/ { false, false, false, false, true }, /*get_slot*/ { true , true , true , true , true }, /*get_request_service_context*/ { true , true , true , true , true }, /*get_reply_service_context*/ { false, false, true , true , true }, // // ServerRequestInfo methods:: /*sending_exception*/ { false, false, false, true , false }, /*object_id*/ { false, true , true , true , true }, /*adapter_id*/ { false, true , true , true , true }, /*target_most_derived_inte...*/ { false, true , false, false, false }, /*get_server_policy*/ { true , true , true , true , true }, /*set_slot*/ { true , true , true , true , true }, /*target_is_a*/ { false, true , false, false, false }, /*add_reply_service_context*/ { true , true , true , true , true } }; /* ********************************************************************** * Public interfaces **********************************************************************/ /** * Creates a new ServerRequestInfo implementation. * The constructor is package scope since no other package need create * an instance of this class. */ ServerRequestInfoImpl( PIORB piOrb ) { super( piOrb ); startingPointCall = CALL_RECEIVE_REQUEST_SERVICE_CONTEXT; intermediatePointCall = CALL_RECEIVE_REQUEST; endingPointCall = CALL_SEND_REPLY; serverRequestId = piOrb.allocateServerRequestId(); } /** * Any containing the exception to be returned to the client. */ public Any sending_exception () { checkAccess( MID_SENDING_EXCEPTION ); if( cachedSendingException == null ) { Any result; if( dsiException != null ) { result = dsiException; } else if( exception != null ) { result = exceptionToAny( exception ); } else { // sending_exception should not be callable if both dsiException // and exception are null. throw new INTERNAL( "Exception not available in sending_exception.", MinorCodes.EXCEPTION_UNAVAILABLE, CompletionStatus.COMPLETED_NO ); } cachedSendingException = result; } return cachedSendingException; } /** * The opaque object_id describing the target of the operation invocation. */ public byte[] object_id () { checkAccess( MID_OBJECT_ID ); if( objectId == null ) { // For some reason, we never set object id. This could be // because a servant locator caused a location forward or // raised an exception. As per ptc/00-08-06, section 21.3.14, // we throw NO_RESOURCES throw new NO_RESOURCES( "object id never set.", MinorCodes.PI_OPERATION_NOT_SUPPORTED, CompletionStatus.COMPLETED_NO ); } // Good citizen: In the interest of efficiency, we will assume // interceptors will not change the resulting byte[] array. // Otherwise, we would need to make a clone of this array. return objectId; } /** * The opaque identifier for the object adapter. */ public byte[] adapter_id () { checkAccess( MID_ADAPTER_ID ); if( adapterId == null ) { // For some reason, we never set the adapter id. This could be // because a servant locator caused a location forward or // raised an exception. As per ptc/00-08-06, section 21.3.14, // we throw NO_RESOURCES throw new NO_RESOURCES( "adapter id never set.", MinorCodes.PI_OPERATION_NOT_SUPPORTED, CompletionStatus.COMPLETED_NO ); } // Good citizen: In the interest of efficiency, we will assume // interceptors will not change the resulting byte[] array. // Otherwise, we would need to make a clone of this array. return adapterId; } /** * The RepositoryID for the most derived interface of the servant. */ public String target_most_derived_interface () { checkAccess( MID_TARGET_MOST_DERIVED_INTERFACE ); return targetMostDerivedInterface; } /** * Returns the policy in effect for this operation for the given policy * type. */ public Policy get_server_policy (int type) { // access is currently valid for all states: //checkAccess( MID_GET_SERVER_POLICY ); Policy result = null; if( poaimpl != null ) { result = poaimpl.get_effective_policy( type ); } // _REVISIT_ RTF Issue: get_server_policy spec not in sync with // get_effective_policy spec. return result; } /** * Allows an Interceptor to set a slot in the Current that is in the scope * of the request. If data already exists in that slot, it will be * overwritten. If the ID does not define an allocated slot, InvalidSlot * is raised. */ public void set_slot (int id, Any data) throws InvalidSlot { // access is currently valid for all states: //checkAccess( MID_SET_SLOT ); slotTable.set_slot( id, data ); } /** * Returns true if the servant is the given RepositoryId, false if it is * not. */ public boolean target_is_a (String id) { checkAccess( MID_TARGET_IS_A ); boolean result; if( servant instanceof Servant ) { result = ((Servant)servant)._is_a( id ); } else if( servant instanceof ObjectImpl ) { result = ((ObjectImpl)servant)._is_a( id ); } else { throw new INTERNAL( "During target_is_a, servant was not a Servant or ObjectImpl", MinorCodes.SERVANT_INVALID, CompletionStatus.COMPLETED_NO ); } return result; } /** * Allows Interceptors to add service contexts to the request. */ public void add_reply_service_context ( ServiceContext service_context, boolean replace ) { // access is currently valid for all states: //checkAccess( MID_ADD_REPLY_SERVICE_CONTEXT ); if( currentExecutionPoint == EXECUTION_POINT_ENDING ) { ServiceContexts scs = replyMessage.getServiceContexts(); // May be null. If this is null, create a new one in its place. if( scs == null ) { scs = new ServiceContexts( piOrb ); replyMessage.setServiceContexts( scs ); } if( cachedReplyServiceContexts == null ) { cachedReplyServiceContexts = new HashMap(); } // This is during and ending point, so we now have enough // information to add the reply service context. addServiceContext( cachedReplyServiceContexts, scs, service_context, replace ); } // We enqueue all adds for the following reasons: // // If we are not in the ending point then we do not yet have a // pointer to the ServiceContexts object so we cannot access the // service contexts until we get to the ending point. // So we enqueue this add reply service context request. // It is added when we do have a handle on the service contexts object. // // If we are in the ending point and we just add directly to the // SC container but then an interceptor raises a SystemException // then that add will be lost since a new container is created // for the SystemException response. // // Therefore we always enqueue and never dequeue (per request) so // that all adds will be completed. AddReplyServiceContextCommand addReply = new AddReplyServiceContextCommand(); addReply.service_context = service_context; addReply.replace = replace; if( addReplyServiceContextQueue == null ) { addReplyServiceContextQueue = new ArrayList(); } // REVISIT: this does not add to the cache. enqueue( addReply ); } // 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. /* ********************************************************************** * Public RequestInfo interfaces * * These are implemented here because they have differing * implementations depending on whether this is a client or a server * request info object. **********************************************************************/ /** * See ServerRequestInfo for javadocs. */ public int request_id (){ // access is currently valid for all states: //checkAccess( MID_REQUEST_ID ); /*
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?