You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by Fred Dushin <fr...@dushin.net> on 2007/03/26 16:50:30 UTC

PROPOSAL: Standard attributes on a Message to signal interceptor "mode"

This is a followup on a brief exchange on the IRC channel

I am writing a collection of interceptors, and I am finding it very  
useful to know:

   1. Whether my interceptor is servicing a request in the context of  
an inbound or outbound message
   2. Whether my interceptor is resident in the client or server side  
of an invocation

 From the sample code, I understand that to compute 1, one does  
something like:

final boolean isOutbound =
     message == message.getExchange().getOutMessage()
     || message == message.getExchange().getOutFaultMessage();

And from the discussion on #cxf, to compute 2., one does something  
semantically equivalent:

final boolean isClient =
     Boolean.TRUE.equals((tmp = msg.get(Message.REQUESTOR_ROLE)) !=  
null ? tmp : Boolean.FALSE);

All that is fine, but couldn't we do a little better?  For example, I  
found I had to write something like this in my own code, just so I  
could do a simple (and efficient) switch, to determine the context I  
live in:

      enum Mode {

         OUTBOUND_CLIENT((byte) 0x00),
         OUTBOUND_SERVER((byte) 0x10),
         INBOUND_CLIENT((byte) 0x01),
         INBOUND_SERVER((byte) 0x11);

         private static final byte DIRECTION_MASK = 0x01;
         private static final byte SIDE_MASK = 0x10;

         private final byte mode;

         Mode(byte mode) {
             this.mode = mode;
         }

         public final boolean
         isOutbound() {
             return (mode & DIRECTION_MASK) == 0;
         }

         public final boolean
         isInbound() {
             return !isOutbound();
         }

         public final boolean
         isClient() {
             return (mode & SIDE_MASK) == 0;
         }

         public final boolean
         isServer() {
             return !isClient();
         }
     }

Would this be a welcome addition to the Message interface?  We could  
modify MessageImpl to require a mode at construction time.  The only  
disadvantage to this approach is that all Message creators would need  
to know the mode in which the message is being created.  Are there  
any cases in which this is not known?

Thanks,
-Fred

RE: PROPOSAL: Standard attributes on a Message to signal interceptor "mode"

Posted by "Glynn, Eoghan" <eo...@iona.com>.

Hi Fred,

As it happens this sort of context checking is common, and the usual
approach is hive it off to a utils class. For example have a look at
org.apache.cxf.ws.addressing.ContextUtils.isRequestor()/isOutbound()/isF
ault().

The easiest thing might be to just promote these methods to a generic
ContextUtils, say in the api module.

BTW I wouldn't be too worried about the efficiency of (message ==
message.getExchange().getOutMessage()) versus bitwise AND. Unlike C++,
the Java style seems to more to code for clarity, and then let the
optimizing compiler and/or virtual machine do the rest.

Also there may be scenarios where the requestor role is not fixed from
creation, for example where a client-side interceptor decides to locally
divert the dispatch. 

Cheers,
Eoghan

> -----Original Message-----
> From: Fred Dushin [mailto:fred@dushin.net] 
> Sent: 26 March 2007 15:51
> To: cxf-dev@incubator.apache.org
> Subject: PROPOSAL: Standard attributes on a Message to signal 
> interceptor "mode"
> 
> This is a followup on a brief exchange on the IRC channel
> 
> I am writing a collection of interceptors, and I am finding 
> it very useful to know:
> 
>    1. Whether my interceptor is servicing a request in the 
> context of an inbound or outbound message
>    2. Whether my interceptor is resident in the client or 
> server side of an invocation
> 
>  From the sample code, I understand that to compute 1, one 
> does something like:
> 
> final boolean isOutbound =
>      message == message.getExchange().getOutMessage()
>      || message == message.getExchange().getOutFaultMessage();
> 
> And from the discussion on #cxf, to compute 2., one does 
> something semantically equivalent:
> 
> final boolean isClient =
>      Boolean.TRUE.equals((tmp = 
> msg.get(Message.REQUESTOR_ROLE)) != null ? tmp : Boolean.FALSE);
> 
> All that is fine, but couldn't we do a little better?  For 
> example, I found I had to write something like this in my own 
> code, just so I could do a simple (and efficient) switch, to 
> determine the context I live in:
> 
>       enum Mode {
> 
>          OUTBOUND_CLIENT((byte) 0x00),
>          OUTBOUND_SERVER((byte) 0x10),
>          INBOUND_CLIENT((byte) 0x01),
>          INBOUND_SERVER((byte) 0x11);
> 
>          private static final byte DIRECTION_MASK = 0x01;
>          private static final byte SIDE_MASK = 0x10;
> 
>          private final byte mode;
> 
>          Mode(byte mode) {
>              this.mode = mode;
>          }
> 
>          public final boolean
>          isOutbound() {
>              return (mode & DIRECTION_MASK) == 0;
>          }
> 
>          public final boolean
>          isInbound() {
>              return !isOutbound();
>          }
> 
>          public final boolean
>          isClient() {
>              return (mode & SIDE_MASK) == 0;
>          }
> 
>          public final boolean
>          isServer() {
>              return !isClient();
>          }
>      }
> 
> Would this be a welcome addition to the Message interface?  
> We could modify MessageImpl to require a mode at construction 
> time.  The only disadvantage to this approach is that all 
> Message creators would need to know the mode in which the 
> message is being created.  Are there any cases in which this 
> is not known?
> 
> Thanks,
> -Fred
>