View Javadoc

    1   package org.codehaus.xfire.addressing;
    2
    3   import java.util.ArrayList;
    4   import java.util.Iterator;
    5   import java.util.List;
    6
    7   import org.codehaus.xfire.MessageContext;
    8   import org.codehaus.xfire.exchange.InMessage;
    9   import org.codehaus.xfire.exchange.MessageExchange;
    10  import org.codehaus.xfire.exchange.OutMessage;
    11  import org.codehaus.xfire.fault.XFireFault;
    12  import org.codehaus.xfire.handler.AbstractHandler;
    13  import org.codehaus.xfire.handler.Phase;
    14  import org.codehaus.xfire.service.OperationInfo;
    15  import org.codehaus.xfire.service.Service;
    16  import org.codehaus.xfire.transport.Channel;
    17  import org.codehaus.xfire.transport.Transport;
    18  import org.codehaus.yom.Element;
    19
    20  public class AddressingInHandler
    21      extends AbstractHandler
    22  {
    23      public static final Object ADRESSING_HEADERS = "xfire-ws-adressing-headers";
    24
    25      public static final Object ADRESSING_FACTORY = "xfire-ws-adressing-factory";
    26
    27      private List factories = new ArrayList();
    28
    29      public AddressingInHandler()
    30      {
    31          createFactories();
    32      }
    33
    34      public void createFactories()
    35      {
    36          factories.add(new AddressingHeadersFactory200502());
    37          factories.add(new AddressingHeadersFactory200408());
    38      }
    39
    40      public String getPhase()
    41      {
    42          return Phase.PRE_DISPATCH;
    43      }
    44
    45      public void invoke(MessageContext context)
    46          throws Exception
    47      {
    48          for (Iterator itr = factories.iterator(); itr.hasNext();)
    49          {
    50              AddressingHeadersFactory factory = (AddressingHeadersFactory) itr.next();
    51
    52              InMessage msg = context.getInMessage();
    53              Element header = msg.getHeader();
    54              if (factory.hasHeaders(header))
    55              {
    56                  AddressingHeaders headers = factory.createHeaders(header);
    57                  msg.setProperty(ADRESSING_HEADERS, headers);
    58                  msg.setProperty(ADRESSING_FACTORY, factory);
    59
    60                  // Dispatch the service
    61                  Service service = getService(headers, context);
    62                  if (service != null) context.setService(service);
    63
    64                  // Dispatch the Exchange and operation
    65                  OperationInfo op =
    66                      service.getServiceInfo().getOperationByAction(headers.getAction());
    67
    68                  if (op == null)
    69                  {
    70                      throw new XFireFault("Action '" + headers.getAction() +
    71                                               "' was not found for service " + headers.getTo(),
    72                                           XFireFault.SENDER);
    73                  }
    74
    75                  MessageExchange exchange = context.createMessageExchange(op);
    76                  context.setExchange(exchange);
    77
    78                  EndpointReference faultTo = headers.getFaultTo();
    79                  OutMessage faultMsg = null;
    80                  if (faultTo != null)
    81                  {
    82                      faultMsg = processEPR(context, faultTo, headers, factory);
    83                  }
    84                  else
    85                  {
    86                      faultMsg = createDefaultMessage(context, headers, factory);
    87                  }
    88                  exchange.setFaultMessage(faultMsg);
    89
    90                  EndpointReference replyTo = headers.getReplyTo();
    91                  OutMessage outMessage = null;
    92                  if (replyTo != null)
    93                  {
    94                      outMessage = processEPR(context, replyTo, headers, factory);
    95                  }
    96                  else
    97                  {
    98                      outMessage = createDefaultMessage(context, headers, factory);
    99                  }
    100                 exchange.setOutMessage(outMessage);
    101             }
    102         }
    103     }
    104
    105     private OutMessage createDefaultMessage(MessageContext context,
    106                                             AddressingHeaders inHeaders,
    107                                             AddressingHeadersFactory factory)
    108     {
    109         OutMessage outMessage = context.getOutMessage();
    110
    111         AddressingHeaders headers = new AddressingHeaders();
    112         headers.setTo(factory.getAnonymousUri());
    113
    114         // TODO: need way to set out action
    115         headers.setAction(inHeaders.getAction() + "Ack");
    116         outMessage.setProperty(ADRESSING_HEADERS, headers);
    117         outMessage.setProperty(ADRESSING_FACTORY, factory);
    118
    119         return outMessage;
    120     }
    121
    122     protected OutMessage processEPR(MessageContext context,
    123                                     EndpointReference epr,
    124                                     AddressingHeaders inHeaders,
    125                                     AddressingHeadersFactory factory)
    126         throws XFireFault, Exception
    127     {
    128         String addr = epr.getAddress();
    129         OutMessage outMessage;
    130         if (addr == null)
    131         {
    132             throw new XFireFault("Invalid ReplyTo address.", XFireFault.SENDER);
    133         }
    134         if (addr.equals(factory.getAnonymousUri()))
    135         {
    136             outMessage = new OutMessage(Channel.BACKCHANNEL_URI);
    137         }
    138         else
    139         {
    140             outMessage = new OutMessage(addr);
    141         }
    142
    143         outMessage.setSoapVersion(context.getExchange().getInMessage().getSoapVersion());
    144
    145         // Find the correct transport for the reply message.
    146         Transport t = context.getXFire().getTransportManager().getTransportForUri(addr);
    147         if (t == null)
    148         {
    149             throw new XFireFault("URL was not recognized: " + addr, XFireFault.SENDER);
    150         }
    151
    152         outMessage.setChannel(t.createChannel());
    153
    154         AddressingHeaders headers = new AddressingHeaders();
    155         headers.setTo(addr);
    156
    157         headers.setAction(inHeaders.getAction() + "Ack");
    158         outMessage.setProperty(ADRESSING_HEADERS, headers);
    159         outMessage.setProperty(ADRESSING_FACTORY, factory);
    160
    161         return outMessage;
    162     }
    163
    164     protected Service getService(AddressingHeaders headers, MessageContext context)
    165     {
    166         if (headers.getTo() == null) return null;
    167
    168         int i = headers.getTo().lastIndexOf('/');
    169
    170         return context.getXFire().getServiceRegistry().getService(headers.getTo().substring(i+1));
    171     }
    172 }