
Since revision 1.1 JacORB provides support for Portable Interceptors These
interceptors are compliant to the standard CORBA specification.  Therefore we
don't provide any documentation on how to program interceptors but supply a
few (hopefully helpful) hints and tips on JacORB specific solutions.

The first  step to have an  interceptor integrated into the  ORB is to
register an {\em  ORBInitializer}. This is done by  setting a property
the following way:
\begin{verbatim}org.omg.PortableInterceptor.ORBInitializerClass.<any_suffix>=
   <orb initializer classname>
\end{verbatim}

For compatibility reasons with the spec, the properties format may also be
like this:

\begin{verbatim}org.omg.PortableInterceptor.ORBInitializerClass.<orb initializer classname>
\end{verbatim}

The suffix  is just to distinguish between  different initializers and
doesn't have to  have any meaningful value. The  value of the property
however has to be the fully qualified classname of the initializer. If
the  verbosity  is  set  to  $\geq  2$  JacORB  will  display  a  {\tt
ClassNotFoundException} in  case the initializers class is  not in the
class path.

An example line might look like:
\begin{verbatim}org.omg.PortableInterceptor.ORBInitializerClass.my_init=
   test.MyInterceptorInitializer
\end{verbatim}

Unfortunately the  interfaces of  the specification don't  provide any
access to  the ORB.  If  you need  access to the  ORB from out  of the
initializer  you  can  cast  the  {\tt  ORBInitInfo}  object  to  {\tt
jacorb. orb.portableInterceptor.ORBInitInfoImpl}   and   call  {\tt
getORB()}  to  get  a  reference  to the  ORB  that  instantiated  the
initializer.

When working with service contexts please make sure that you don't use {\tt
  0x4A414301} as an id because a service context with that id is used
internally.  Otherwise you will end up with either your data not transfered or
unexpected internal exceptions.

\section{Interceptor ForwardRequest Exceptions}
Several of the interceptor types may throw a ForwardException such as
{\tt ClientRequestInterceptor send\_request}. A developer may wish to do
this if, for instance, a new policy is being applied to the object to switch
to a SSL connection type as suggested within chapter \ref{ch:etf}.

A current limitation of the specification (CORBA 3; 02-06-33) is that it is
impossible to detect whether the call has previously been thrown for the same
client request. Thus it is possible to enter an infinite loop throwing
ForwardRequest at this point. This issue was first submitted to the OMG in
May 2002 under number 5266.

In order to allow developers more flexibility when writing their interceptors
PrismTech have enhanced the exception handling as follows. We have chosen one of
the solutions proposed within issue 5266; namely to allow forward\_reference()
to be accessed in send\_request() as well as in receive\_other(). i.e. returning
the object from the previous ForwardRequest if that has been thrown and null
otherwise.

A typical use of this might be
\begin{verbatim}
   public void send_request( ClientRequestInfo ri )
   {
      if (ri.effective_profile().tag == TAG_INTERNET_IOP.value &&
          ri.forward_reference() == null)
      {
         // Do some processing, throw a forward request.
      }
   }
\end{verbatim}
This allows the developer to conditionally throw a forward request while using
forward\_reference() to prevent infinite loops.

\section{Public API}
Some users may find it useful to access internal data on the ClientRequestInfo and ServerRequestInfo. The following API is available. Note that it may be possible to corrupt the call chain so use these at your own risk.

{\tt isLocalInterceptors} returns true if the interceptors are running locally (i.e. no TCP
connection is being used and therefore {\tt getConnection} will return null).

\subsubsection{org.jacorb.orb.portableInterceptor.ServerRequestInfoImpl}
\begin{verbatim}
   public boolean isLocalInterceptors()
   public GIOPConnection getConnection()
   public ReplyOutputStream getReplyStream ()
   public RequestInputStream getRequestStream ()
   public ORB orb()
\end{verbatim}

\subsubsection{org.jacorb.orb.portableInterceptor.ClientRequestInfoImpl}
\begin{verbatim}
   public boolean isLocalInterceptors()
   public ClientConnection getConnection()
   public ReplyInputStream getReplyStream ()
   public RequestOutputStream getRequestStream ()
   public Delegate getDelegate ()
   public ORB orb()
\end{verbatim}


%%% Local Variables:
%%% mode: latex
%%% TeX-master: "../ProgrammingGuide"
%%% End:
