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.Transport;
17  import org.codehaus.yom.Element;
18  
19  public class AddressingHandler
20      extends AbstractHandler
21  {
22      public static final Object ADRESSING_HEADERS = "xfire-ws-adressing-headers";
23  
24      public static final Object ADRESSING_FACTORY = "xfire-ws-adressing-factory";
25      
26      private List factories = new ArrayList();
27      
28      public AddressingHandler()
29      {
30          createFactories();
31      }
32      
33      public void createFactories()
34      {
35          factories.add(new AddressingHeadersFactory200502());
36          factories.add(new AddressingHeadersFactory200408());
37      }
38      
39      public String getPhase()
40      {
41          return Phase.PRE_DISPATCH;
42      }
43  
44      public void invoke(MessageContext context)
45          throws Exception
46      {
47          for (Iterator itr = factories.iterator(); itr.hasNext();)
48          {
49              AddressingHeadersFactory factory = (AddressingHeadersFactory) itr.next();
50              
51              InMessage msg = context.getInMessage();
52              Element header = msg.getHeader();
53              if (factory.hasHeaders(header))
54              {
55                  AddressingHeaders headers = factory.createHeaders(header);
56                  msg.setProperty(ADRESSING_HEADERS, headers);
57                  msg.setProperty(ADRESSING_FACTORY, factory);
58  
59                  // Dispatch the service
60                  Service service = getService(headers, context);
61                  if (service != null) context.setService(service);
62                  
63                  // Dispatch the Exchange and operation
64                  OperationInfo op = 
65                      service.getServiceInfo().getOperationByAction(headers.getAction());
66  
67                  if (op == null)
68                  {
69                      throw new XFireFault("Action '" + headers.getAction() + 
70                                               "' was not found for service " + headers.getTo(),
71                                           XFireFault.SENDER);
72                  }
73                  
74                  MessageExchange exchange = context.createMessageExchange(op);
75                  context.setExchange(exchange);
76                  
77                  EndpointReference faultTo = headers.getFaultTo();
78                  if (faultTo != null)
79                  {
80                      OutMessage outMessage = processEPR(context, faultTo);
81                      exchange.setFaultMessage(outMessage);
82                  }
83                  
84                  EndpointReference replyTo = headers.getReplyTo();
85                  if (replyTo != null)
86                  {
87                      OutMessage outMessage = processEPR(context, replyTo);
88                      exchange.setOutMessage(outMessage);
89                  }
90              }
91          }
92      }
93  
94      protected OutMessage processEPR(MessageContext context, EndpointReference epr)
95          throws XFireFault, Exception
96      {
97          String addr = epr.getAddress();
98          if (addr == null) throw new XFireFault("Invalid ReplyTo address.", XFireFault.SENDER);
99              
100         OutMessage outMessage = new OutMessage(addr);
101         outMessage.setSoapVersion(context.getExchange().getInMessage().getSoapVersion());
102         
103         // Find the correct transport for the reply message.
104         Transport t = context.getXFire().getTransportManager().getTransportForUri(addr);
105         if (t == null)
106         {
107             throw new XFireFault("URL was not recognized: " + addr, XFireFault.SENDER);
108         }
109 
110         outMessage.setChannel(t.createChannel());
111         return outMessage;
112     }
113     
114     protected Service getService(AddressingHeaders headers, MessageContext context)
115     {
116         if (headers.getTo() == null) return null;
117         
118         int i = headers.getTo().lastIndexOf('/');
119 
120         return context.getXFire().getServiceRegistry().getService(headers.getTo().substring(i+1));
121     }
122 }