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
61 Service service = getService(headers, context);
62 if (service != null) context.setService(service);
63
64
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
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
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 }