1 package org.objectweb.celtix.bus.ws.rm.soap; 2 3 4 import java.util.ArrayList ; 5 import java.util.Collection ; 6 import java.util.Iterator ; 7 import java.util.Map ; 8 import java.util.Set ; 9 import java.util.logging.Level ; 10 import java.util.logging.Logger ; 11 12 import javax.xml.bind.JAXBContext; 13 import javax.xml.bind.JAXBElement; 14 import javax.xml.bind.JAXBException; 15 import javax.xml.bind.Marshaller; 16 import javax.xml.bind.Unmarshaller; 17 import javax.xml.namespace.QName ; 18 import javax.xml.soap.Name ; 19 import javax.xml.soap.SOAPEnvelope ; 20 import javax.xml.soap.SOAPException ; 21 import javax.xml.soap.SOAPHeader ; 22 import javax.xml.soap.SOAPHeaderElement ; 23 import javax.xml.soap.SOAPMessage ; 24 import javax.xml.ws.handler.MessageContext; 25 import javax.xml.ws.handler.soap.SOAPHandler; 26 import javax.xml.ws.handler.soap.SOAPMessageContext; 27 28 29 import org.objectweb.celtix.bindings.BindingContextUtils; 30 import org.objectweb.celtix.bindings.DataBindingCallback; 31 import org.objectweb.celtix.bus.ws.addressing.ContextUtils; 32 import org.objectweb.celtix.bus.ws.rm.CreateSequenceRequest; 33 import org.objectweb.celtix.bus.ws.rm.CreateSequenceResponse; 34 import org.objectweb.celtix.bus.ws.rm.Names; 35 import org.objectweb.celtix.bus.ws.rm.RMContextUtils; 36 import org.objectweb.celtix.bus.ws.rm.RMPropertiesImpl; 37 import org.objectweb.celtix.bus.ws.rm.RMUtils; 38 import org.objectweb.celtix.bus.ws.rm.TerminateSequenceRequest; 39 import org.objectweb.celtix.common.logging.LogUtils; 40 import org.objectweb.celtix.context.ObjectMessageContext; 41 import org.objectweb.celtix.ws.addressing.AddressingProperties; 42 import org.objectweb.celtix.ws.addressing.AttributedURIType; 43 import org.objectweb.celtix.ws.rm.AckRequestedType; 44 import org.objectweb.celtix.ws.rm.RMProperties; 45 import org.objectweb.celtix.ws.rm.SequenceAcknowledgement; 46 import org.objectweb.celtix.ws.rm.SequenceType; 47 48 49 53 public class RMSoapHandler implements SOAPHandler<SOAPMessageContext> { 54 55 private static final Logger LOG = LogUtils.getL7dLogger(RMSoapHandler.class); 56 private static final String WS_RM_PACKAGE = 57 SequenceType.class.getPackage().getName(); 58 protected JAXBContext jaxbContext; 59 60 63 public RMSoapHandler() { 64 } 65 66 69 public void init(Map <String , Object > map) { 70 } 71 72 75 public Set <QName > getHeaders() { 76 return Names.HEADERS; 77 } 78 79 84 public boolean handleMessage(SOAPMessageContext context) { 85 return mediate(context); 86 } 87 88 93 public boolean handleFault(SOAPMessageContext context) { 94 return mediate(context); 95 } 96 97 103 public void close(MessageContext context) { 104 } 105 106 109 public void destroy() { 110 } 111 112 118 private boolean mediate(SOAPMessageContext context) { 119 if (ContextUtils.isOutbound(context)) { 120 encode(context); 121 } else { 122 decode(context); 123 storeBindingInfo(context); 124 } 125 return true; 126 } 127 128 133 private void encode(SOAPMessageContext context) { 134 RMProperties rmps = RMContextUtils.retrieveRMProperties(context, true); 135 if (null == rmps) { 136 return; 138 } 139 SOAPMessage message = context.getMessage(); 140 try { 141 SOAPEnvelope env = message.getSOAPPart().getEnvelope(); 142 SOAPHeader header = env.getHeader() != null 143 ? env.getHeader() 144 : env.addHeader(); 145 146 discardRMHeaders(header); 147 header.addNamespaceDeclaration(Names.WSRM_NAMESPACE_PREFIX, 148 Names.WSRM_NAMESPACE_NAME); 149 Marshaller marshaller = getJAXBContext().createMarshaller(); 150 marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); 151 152 SequenceType seq = rmps.getSequence(); 153 if (null != seq) { 154 encodeProperty(seq, 155 Names.WSRM_SEQUENCE_QNAME, 156 SequenceType.class, 157 header, 158 marshaller); 159 } 160 Collection <SequenceAcknowledgement> acks = rmps.getAcks(); 161 if (null != acks) { 162 for (SequenceAcknowledgement ack : acks) { 163 encodeProperty(ack, 164 Names.WSRM_SEQUENCE_ACK_QNAME, 165 SequenceAcknowledgement.class, 166 header, 167 marshaller); 168 } 169 } 170 Collection <AckRequestedType> requested = rmps.getAcksRequested(); 171 if (null != requested) { 172 for (AckRequestedType ar : requested) { 173 encodeProperty(ar, 174 Names.WSRM_ACK_REQUESTED_QNAME, 175 AckRequestedType.class, 176 header, 177 marshaller); 178 } 179 } 180 } catch (SOAPException se) { 181 LOG.log(Level.WARNING, "SOAP_HEADER_ENCODE_FAILURE_MSG", se); 182 } catch (JAXBException je) { 183 LOG.log(Level.WARNING, "SOAP_HEADER_ENCODE_FAILURE_MSG", je); 184 } 185 } 186 187 194 private void decode(SOAPMessageContext context) { 195 SOAPMessage message = context.getMessage(); 196 RMProperties rmps = unmarshalRMProperties(message); 197 RMContextUtils.storeRMProperties(context, rmps, false); 198 } 199 200 206 public RMProperties unmarshalRMProperties(SOAPMessage message) { 207 RMProperties rmps = new RMPropertiesImpl(); 208 209 try { 210 Collection <SequenceAcknowledgement> acks = new ArrayList <SequenceAcknowledgement>(); 211 Collection <AckRequestedType> requested = new ArrayList <AckRequestedType>(); 212 213 SOAPEnvelope env = message.getSOAPPart().getEnvelope(); 214 SOAPHeader header = env.getHeader(); 215 216 if (header != null) { 217 Unmarshaller unmarshaller = 218 getJAXBContext().createUnmarshaller(); 219 Iterator headerElements = header.examineAllHeaderElements(); 220 while (headerElements.hasNext()) { 221 SOAPHeaderElement headerElement = 222 (SOAPHeaderElement )headerElements.next(); 223 Name headerName = headerElement.getElementName(); 224 String localName = headerName.getLocalName(); 225 if (Names.WSRM_NAMESPACE_NAME.equals(headerName.getURI())) { 226 LOG.log(Level.INFO, "decoding RM header {0}", localName); 227 if (Names.WSRM_SEQUENCE_NAME.equals(localName)) { 228 SequenceType s = decodeProperty(SequenceType.class, 229 headerElement, 230 unmarshaller); 231 232 rmps.setSequence(s); 233 } else if (Names.WSRM_SEQUENCE_ACK_NAME.equals(localName)) { 234 SequenceAcknowledgement ack = decodeProperty(SequenceAcknowledgement.class, 235 headerElement, 236 unmarshaller); 237 acks.add(ack); 238 } else if (Names.WSRM_ACK_REQUESTED_NAME.equals(localName)) { 239 AckRequestedType ar = decodeProperty(AckRequestedType.class, 240 headerElement, 241 unmarshaller); 242 requested.add(ar); 243 } 244 } 245 } 246 if (acks.size() > 0) { 247 rmps.setAcks(acks); 248 } 249 if (requested.size() > 0) { 250 rmps.setAcksRequested(requested); 251 } 252 } 253 } catch (SOAPException se) { 254 LOG.log(Level.WARNING, "SOAP_HEADER_DECODE_FAILURE_MSG", se); 255 } catch (JAXBException je) { 256 LOG.log(Level.WARNING, "SOAP_HEADER_DECODE_FAILURE_MSG", je); 257 } 258 return rmps; 259 } 260 261 262 265 private synchronized JAXBContext getJAXBContext() throws JAXBException { 266 if (jaxbContext == null) { 267 jaxbContext = JAXBContext.newInstance(WS_RM_PACKAGE); 268 } 269 return jaxbContext; 270 } 271 272 281 private <T> void encodeProperty(T value, 282 QName qname, 283 Class <T> clz, 284 SOAPHeader header, 285 Marshaller marshaller) throws JAXBException { 286 if (value != null) { 287 LOG.log(Level.INFO, "encoding " + value + " into RM header {0}", qname); 288 marshaller.marshal(new JAXBElement<T>(qname, clz, value), header); 289 } 290 } 291 292 300 private <T> T decodeProperty(Class <T> clz, 301 SOAPHeaderElement headerElement, 302 Unmarshaller unmarshaller) throws JAXBException { 303 JAXBElement<T> element = 304 unmarshaller.unmarshal(headerElement, clz); 305 return element.getValue(); 306 } 307 308 309 315 private void discardRMHeaders(SOAPHeader header) throws SOAPException { 316 Iterator headerElements = header.examineAllHeaderElements(); 317 while (headerElements.hasNext()) { 318 SOAPHeaderElement headerElement = 319 (SOAPHeaderElement )headerElements.next(); 320 Name headerName = headerElement.getElementName(); 321 if (Names.WSRM_NAMESPACE_NAME.equals(headerName.getURI())) { 322 headerElement.detachNode(); 323 } 324 325 if (org.objectweb.celtix.bus.ws.addressing.Names.WSA_NAMESPACE_NAME 326 .equals(headerName.getURI()) 327 && org.objectweb.celtix.bus.ws.addressing.Names.WSA_ACTION_NAME 328 .equals(headerName.getLocalName())) { 329 headerElement.detachNode(); 330 } 331 } 332 } 333 334 343 private void storeBindingInfo(MessageContext context) { 344 assert !ContextUtils.isOutbound(context); 345 AddressingProperties maps = ContextUtils.retrieveMAPs(context, false, false); 346 AttributedURIType actionURI = null == maps ? null : maps.getAction(); 347 String action = null == actionURI ? null : actionURI.getValue(); 348 DataBindingCallback callback = null; 349 String operationName = null; 350 boolean rmProtocolMessage = true; 351 352 if (RMUtils.getRMConstants().getCreateSequenceAction().equals(action)) { 353 callback = CreateSequenceRequest.createDataBindingCallback(); 354 operationName = CreateSequenceRequest.getOperationName(); 355 } else if (RMUtils.getRMConstants().getCreateSequenceResponseAction().equals(action)) { 356 callback = CreateSequenceResponse.createDataBindingCallback(); 357 operationName = CreateSequenceResponse.getOperationName(); 358 } else if (RMUtils.getRMConstants().getTerminateSequenceAction().equals(action)) { 359 callback = TerminateSequenceRequest.createDataBindingCallback(); 360 operationName = TerminateSequenceRequest.getOperationName(); 361 } else if (RMUtils.getRMConstants().getLastMessageAction().equals(action) 362 || RMUtils.getRMConstants().getSequenceAcknowledgmentAction().equals(action)) { 363 callback = TerminateSequenceRequest.createDataBindingCallback(); 366 operationName = TerminateSequenceRequest.getOperationName(); 367 } else { 368 rmProtocolMessage = false; 369 } 370 371 if (rmProtocolMessage) { 372 BindingContextUtils.storeDispatch(context, false); 373 BindingContextUtils.storeDataBindingCallback(context, callback); 374 context.put(MessageContext.WSDL_OPERATION, new QName ("", operationName)); 375 context.put(ObjectMessageContext.MESSAGE_INPUT, Boolean.FALSE); 376 } 377 } 378 379 } 380 381 382 383 384 385 386 | Popular Tags |