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 }