1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package ch.elca.el4j.services.remoting.protocol.jaxws;
18
19 import java.util.HashMap;
20 import java.util.Map;
21 import java.util.Set;
22 import java.util.TreeSet;
23
24 import javax.xml.bind.JAXBContext;
25 import javax.xml.bind.JAXBElement;
26 import javax.xml.bind.JAXBException;
27 import javax.xml.bind.Marshaller;
28 import javax.xml.bind.PropertyException;
29 import javax.xml.bind.Unmarshaller;
30 import javax.xml.namespace.QName;
31 import javax.xml.soap.SOAPHeaderElement;
32 import javax.xml.soap.SOAPMessage;
33 import javax.xml.ws.handler.MessageContext;
34 import javax.xml.ws.handler.soap.SOAPMessageContext;
35
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38 import org.w3c.dom.Node;
39 import org.w3c.dom.NodeList;
40
41 import com.sun.xml.ws.util.xml.NodeListIterator;
42
43 import ch.elca.el4j.core.contextpassing.ImplicitContextPassingRegistry;
44
45
46
47
48
49
50
51
52
53 public class JaxwsContextHandler extends AbstractJaxwsJaxbContextHandler {
54
55
56
57 private static Logger s_logger = LoggerFactory.getLogger(JaxwsContextHandler.class);
58
59
60
61
62 private ImplicitContextPassingRegistry m_contextPassingRegistry;
63
64
65
66
67
68
69
70
71 public JaxwsContextHandler(ImplicitContextPassingRegistry registry,
72 JAXBContext jaxbContext) {
73 super(jaxbContext);
74 m_contextPassingRegistry = registry;
75 }
76
77
78 public boolean handleMessage(SOAPMessageContext context) {
79 Boolean outboundProperty = (Boolean) context
80 .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
81
82 if (m_contextPassingRegistry != null) {
83 SOAPMessage msg = context.getMessage();
84 if (outboundProperty.booleanValue()) {
85 handleOutgoingMessage(msg);
86 } else {
87 handleIncomingMessage(msg);
88 }
89 }
90 return true;
91 }
92
93
94
95
96
97
98
99 @SuppressWarnings("unchecked")
100 protected void handleIncomingMessage(SOAPMessage msg) {
101 Node contextElement = null;
102 try {
103 if (msg.getSOAPHeader() != null) {
104 NodeList list = msg.getSOAPHeader()
105 .getElementsByTagNameNS(CONTEXT_NAMESPACE.getURI(),
106 CONTEXT_ELEMENT_NAME);
107 if (list.getLength() > 0) {
108 contextElement = (Node) list.item(0);
109 }
110 }
111 } catch (Exception e) {
112 s_logger.error("Error getting SOAP header.");
113 return;
114 }
115
116 if (contextElement != null) {
117 Unmarshaller unmarshaller = getUnmarshaller();
118
119 Map<String, Object> map = new HashMap<String, Object>();
120 NodeList nodeList = contextElement.getChildNodes();
121 NodeListIterator it = new NodeListIterator(nodeList);
122
123 while (it.hasNext()) {
124 Node soapNode = (Node) it.next();
125
126 try {
127
128 JAXBElement element = (JAXBElement) unmarshaller
129 .unmarshal(soapNode);
130
131 map.put(soapNode.getNodeName(), element.getValue());
132 } catch (JAXBException e) {
133 s_logger.error("Unable to unmarshall context element "
134 + soapNode.getNodeName());
135 }
136 }
137 m_contextPassingRegistry.pushAssembledImplicitContext(map);
138 }
139 }
140
141
142
143
144
145
146
147 @SuppressWarnings("unchecked")
148 protected void handleOutgoingMessage(SOAPMessage msg) {
149 SOAPHeaderElement newElement = null;
150
151 try {
152 if (msg.getSOAPHeader() == null) {
153
154 msg.getSOAPPart().getEnvelope().addHeader();
155 }
156 newElement = msg.getSOAPHeader().addHeaderElement(
157 new QName(CONTEXT_NAMESPACE.getURI(),
158 CONTEXT_ELEMENT_NAME));
159 } catch (Exception e) {
160 s_logger.error("Error creating SOAP header.");
161 return;
162 }
163
164 Marshaller marshaller = getMarshaller();
165 try {
166 marshaller.setProperty(Marshaller.JAXB_FRAGMENT,
167 Boolean.TRUE);
168 } catch (PropertyException e) {
169 s_logger.error("Error setting marshaller properties.");
170 return;
171 }
172
173 Map assembledContext = m_contextPassingRegistry
174 .getAssembledImplicitContext();
175 Set<String> keys = (Set<String>) assembledContext.keySet();
176 for (String key : keys) {
177 try {
178 Object value = assembledContext.get(key);
179 marshaller.marshal(new JAXBElement(new QName("", key),
180 Object.class, value), newElement);
181 } catch (JAXBException e) {
182 s_logger.error("Unable to marshal context for " + key);
183 }
184 }
185 }
186
187
188 public boolean handleFault(SOAPMessageContext context) {
189 return true;
190 }
191
192
193 @SuppressWarnings("unchecked")
194 public Set getHeaders() {
195 return new TreeSet();
196 }
197
198
199 public void close(MessageContext context) { }
200
201
202
203 @Override
204 protected Logger getLogger() {
205 return s_logger;
206 }
207 }