package org.jacorb.orb;
import org.jacorb.orb.portableInterceptor.DefaultClientInterceptorHandler;
import org.jacorb.orb.portableInterceptor.InterceptorManager;
import org.jacorb.orb.portableInterceptor.ServerInterceptorIterator;
import org.jacorb.orb.portableInterceptor.ServerRequestInfoImpl;
import org.omg.CORBA.UserException;
import org.omg.CORBA.portable.ServantObjectExt;
import org.omg.PortableInterceptor.SUCCESSFUL;
import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
import org.omg.PortableInterceptor.USER_EXCEPTION;
public class ServantObjectImpl extends ServantObjectExt
{
/**
* The Server request info associated with this servant
*/
private ServerRequestInfoImpl sinfo = null;
/**
* The client interceptors associated with this servant
*/
private DefaultClientInterceptorHandler interceptors = null;
/**
* The interceptor manager associated with this call
*/
private InterceptorManager manager = null;
/**
* The server interceptor iterator
*/
private ServerInterceptorIterator interceptorIterator = null;
/**
* Prevent call to sendException if an exception occurs during handling
* of the reply in normalCompletion
*/
private boolean normalCompletionCalled = false;
/**
* Reference to the orb for this servant
*/
private org.jacorb.orb.ORB orb = null;
/**
* This method is called if a call to the local server is successful.
* The call to SEND_EXCEPTION can result in further exceptions being
* thrown, including a ForwardRequest
*/
public void normalCompletion()
{
if (orb.hasServerRequestInterceptors())
{
manager = orb.getInterceptorManager();
interceptorIterator = manager.getServerIterator();
try
{
/**
* Setting this flag here to prevent a duplicate call to SEND_EXCEPTION
* if an error occurs during the call to SEND_REPLY.
*
* If an exception occurs during SEND_REPLY any necessary SEND_EXCEPTION
* points will already have been called
*/
normalCompletionCalled = true;
interceptorIterator.iterate (sinfo,
ServerInterceptorIterator.SEND_REPLY);
sinfo.setReplyStatus (SUCCESSFUL.value);
}
catch (RuntimeException ex)
{
sinfo.setReplyStatus (SYSTEM_EXCEPTION.value);
sinfo.updateException (ex);
throw ex;
}
catch (UserException ue)
{
sinfo.setReplyStatus (USER_EXCEPTION.value);
sinfo.updateException (ue);
throw new RuntimeException (ue);
}
}
}
/**
* This method is called if the exception thrown is a RuntimeException
* @param re the RuntimeException
*/
public void exceptionalCompletion (RuntimeException re)
{
exceptionalCompletion ( (Throwable) re);
}
/**
* This method is called if the exception thrown is an Error
* @param err the RuntimeException
*/
public void exceptionalCompletion (Error err)
{
exceptionalCompletion ( (Throwable) err);
}
/**
* Generic method to handle whatever is thrown
*/
public void exceptionalCompletion (Throwable t)
{
/**
* If we haven't come from SEND_REPLY and there are interceptors
* then we need to call SEND_EXCEPTION
*/
if (!normalCompletionCalled && orb.hasServerRequestInterceptors())
{
manager = orb.getInterceptorManager();
interceptorIterator = manager.getServerIterator();
sinfo.updateException (t);
try
{
interceptorIterator.iterate (sinfo,
ServerInterceptorIterator.SEND_EXCEPTION);
}
catch (UserException ue)
{
sinfo.setReplyStatus (USER_EXCEPTION.value);
sinfo.updateException (ue);
throw new RuntimeException (ue);
}
}
}
/**
* Set a reference to the ORB to be used in subsequent processing
* @param orb the orb reference
*/
public void setORB (org.jacorb.orb.ORB orb)
{
this.orb = orb;
}
/**
* Set the server request info associated with this Servant
* @param sinfo the ServerRequestInfoImpl
*/
public void setServerRequestInfo (ServerRequestInfoImpl sinfo)
{
this.sinfo = sinfo;
}
/**
* Set the local client interceptor handler that was instantiated
* during servant_preinvoke, we need this to handle any necessary
* interception points if an exception occurs
* @param interceptors the ClientInterceptorHandler
*/
public void setClientInterceptorHandler (DefaultClientInterceptorHandler interceptors)
{
this.interceptors = interceptors;
}
/**
* Accessor method to get the ServerRequestInfoImpl.
*
* @return the server request info
*/
public ServerRequestInfoImpl getServerRequestInfo()
{
return sinfo;
}
/**
* Accessor method to get the ClientInterceptorHandler - required
* in servant_postinvoke
* @return the DefaultClientInterceptorHandler
*/
public DefaultClientInterceptorHandler getClientInterceptorHandler()
{
return interceptors;
}
}