1 package org.objectweb.celtix.bus.ws.addressing.soap; 2 3 4 import java.util.Iterator ; 5 import java.util.Map ; 6 import java.util.Set ; 7 import java.util.logging.Level ; 8 import java.util.logging.Logger ; 9 10 import javax.xml.bind.JAXBContext; 11 import javax.xml.bind.JAXBElement; 12 import javax.xml.bind.JAXBException; 13 import javax.xml.bind.Marshaller; 14 import javax.xml.bind.Unmarshaller; 15 import javax.xml.namespace.QName ; 16 import javax.xml.soap.MimeHeaders ; 17 import javax.xml.soap.Name ; 18 import javax.xml.soap.SOAPEnvelope ; 19 import javax.xml.soap.SOAPException ; 20 import javax.xml.soap.SOAPFactory ; 21 import javax.xml.soap.SOAPFault ; 22 import javax.xml.soap.SOAPHeader ; 23 import javax.xml.soap.SOAPHeaderElement ; 24 import javax.xml.soap.SOAPMessage ; 25 import javax.xml.ws.handler.MessageContext; 26 import javax.xml.ws.handler.soap.SOAPHandler; 27 import javax.xml.ws.handler.soap.SOAPMessageContext; 28 import javax.xml.ws.soap.SOAPFaultException; 29 30 import org.objectweb.celtix.bus.ws.addressing.AddressingPropertiesImpl; 31 import org.objectweb.celtix.bus.ws.addressing.ContextUtils; 32 import org.objectweb.celtix.bus.ws.addressing.Names; 33 import org.objectweb.celtix.common.logging.LogUtils; 34 import org.objectweb.celtix.ws.addressing.AddressingProperties; 35 import org.objectweb.celtix.ws.addressing.AttributedURIType; 36 import org.objectweb.celtix.ws.addressing.EndpointReferenceType; 37 import org.objectweb.celtix.ws.addressing.RelatesToType; 38 39 40 44 public class MAPCodec 45 implements SOAPHandler<SOAPMessageContext> { 46 47 private static final Logger LOG = LogUtils.getL7dLogger(MAPCodec.class); 48 private static SOAPFactory soapFactory; 49 50 private VersionTransformer transformer; 51 52 55 public MAPCodec() { 56 transformer = new VersionTransformer(this); 57 } 58 59 62 public void init(Map <String , Object > map) { 63 } 64 65 68 public Set <QName > getHeaders() { 69 return VersionTransformer.HEADERS; 70 } 71 72 77 public boolean handleMessage(SOAPMessageContext context) { 78 return mediate(context); 79 } 80 81 86 public boolean handleFault(SOAPMessageContext context) { 87 return mediate(context); 88 } 89 90 96 public void close(MessageContext context) { 97 } 98 99 102 public void destroy() { 103 } 104 105 111 private boolean mediate(SOAPMessageContext context) { 112 if (ContextUtils.isOutbound(context)) { 113 encode(context, ContextUtils.retrieveMAPs(context, false, true)); 114 } else { 115 ContextUtils.storeMAPs(decode(context), context, false); 116 } 117 return true; 118 } 119 120 126 private void encode(SOAPMessageContext context, 127 AddressingProperties maps) { 128 if (maps != null) { 129 SOAPMessage message = context.getMessage(); 130 LOG.log(Level.INFO, "encoding MAPs in SOAP headers"); 131 try { 132 SOAPEnvelope env = message.getSOAPPart().getEnvelope(); 133 SOAPHeader header = env.getHeader() != null 134 ? env.getHeader() 135 : env.addHeader(); 136 discardMAPs(header); 137 header.addNamespaceDeclaration(Names.WSA_NAMESPACE_PREFIX, 138 maps.getNamespaceURI()); 139 JAXBContext jaxbContext = 140 VersionTransformer.getExposedJAXBContext( 141 maps.getNamespaceURI()); 142 Marshaller marshaller = jaxbContext.createMarshaller(); 143 marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); 144 transformer.encodeAsExposed(maps.getNamespaceURI(), 145 maps.getMessageID(), 146 Names.WSA_MESSAGEID_NAME, 147 AttributedURIType.class, 148 header, 149 marshaller); 150 transformer.encodeAsExposed(maps.getNamespaceURI(), 151 maps.getTo(), 152 Names.WSA_TO_NAME, 153 AttributedURIType.class, 154 header, 155 marshaller); 156 transformer.encodeAsExposed(maps.getNamespaceURI(), 157 maps.getReplyTo(), 158 Names.WSA_REPLYTO_NAME, 159 EndpointReferenceType.class, 160 header, 161 marshaller); 162 transformer.encodeAsExposed(maps.getNamespaceURI(), 163 maps.getFaultTo(), 164 Names.WSA_FAULTTO_NAME, 165 EndpointReferenceType.class, 166 header, 167 marshaller); 168 transformer.encodeAsExposed(maps.getNamespaceURI(), 169 maps.getRelatesTo(), 170 Names.WSA_RELATESTO_NAME, 171 RelatesToType.class, 172 header, 173 marshaller); 174 transformer.encodeAsExposed(maps.getNamespaceURI(), 175 maps.getAction(), 176 Names.WSA_ACTION_NAME, 177 AttributedURIType.class, 178 header, 179 marshaller); 180 propogateAction(maps.getAction(), message); 181 applyMAPValidation(context); 182 } catch (SOAPException se) { 183 LOG.log(Level.WARNING, "SOAP_HEADER_ENCODE_FAILURE_MSG", se); 184 } catch (JAXBException je) { 185 LOG.log(Level.WARNING, "SOAP_HEADER_ENCODE_FAILURE_MSG", je); 186 } 187 } 188 } 189 190 197 public AddressingProperties unmarshalMAPs(SOAPMessage message) { 198 AddressingPropertiesImpl maps = null; 201 try { 202 SOAPEnvelope env = message.getSOAPPart().getEnvelope(); 203 SOAPHeader header = env.getHeader(); 204 if (header != null) { 205 Unmarshaller unmarshaller = null; 206 Iterator headerElements = header.examineAllHeaderElements(); 207 while (headerElements.hasNext()) { 208 SOAPHeaderElement headerElement = 209 (SOAPHeaderElement )headerElements.next(); 210 Name headerName = headerElement.getElementName(); 211 String headerURI = headerName.getURI(); 212 if (unmarshaller == null) { 213 JAXBContext jaxbContext = 214 VersionTransformer.getExposedJAXBContext(headerURI); 215 unmarshaller = 216 jaxbContext.createUnmarshaller(); 217 } 218 if (transformer.isSupported(headerURI)) { 219 if (maps == null) { 220 maps = new AddressingPropertiesImpl(); 221 maps.exposeAs(headerURI); 222 } 223 String localName = headerName.getLocalName(); 224 LOG.log(Level.INFO, "decoding WSA header {0}", localName); 225 if (Names.WSA_MESSAGEID_NAME.equals(localName)) { 226 maps.setMessageID(transformer.decodeAsNative( 227 headerURI, 228 AttributedURIType.class, 229 headerElement, 230 unmarshaller)); 231 } else if (Names.WSA_TO_NAME.equals(localName)) { 232 maps.setTo(transformer.decodeAsNative( 233 headerURI, 234 AttributedURIType.class, 235 headerElement, 236 unmarshaller)); 237 } else if (Names.WSA_REPLYTO_NAME.equals(localName)) { 238 maps.setReplyTo(transformer.decodeAsNative( 239 headerURI, 240 EndpointReferenceType.class, 241 headerElement, 242 unmarshaller)); 243 } else if (Names.WSA_FAULTTO_NAME.equals(localName)) { 244 maps.setFaultTo(transformer.decodeAsNative( 245 headerURI, 246 EndpointReferenceType.class, 247 headerElement, 248 unmarshaller)); 249 } else if (Names.WSA_RELATESTO_NAME.equals(localName)) { 250 maps.setRelatesTo(transformer.decodeAsNative( 251 headerURI, 252 RelatesToType.class, 253 headerElement, 254 unmarshaller)); 255 } else if (Names.WSA_ACTION_NAME.equals(localName)) { 256 maps.setAction(transformer.decodeAsNative( 257 headerURI, 258 AttributedURIType.class, 259 headerElement, 260 unmarshaller)); 261 } 262 } else if (headerURI.contains(Names.WSA_NAMESPACE_PATTERN)) { 263 LOG.log(Level.WARNING, 264 "UNSUPPORTED_VERSION_MSG", 265 headerURI); 266 } 267 } 268 } 269 } catch (SOAPException se) { 270 LOG.log(Level.WARNING, "SOAP_HEADER_DECODE_FAILURE_MSG", se); 271 } catch (JAXBException je) { 272 LOG.log(Level.WARNING, "SOAP_HEADER_DECODE_FAILURE_MSG", je); 273 } 274 return maps; 275 } 276 277 284 private AddressingProperties decode(SOAPMessageContext context) { 285 AddressingProperties maps = null; 288 boolean isRequestor = ContextUtils.isRequestor(context); 289 SOAPMessage message = context.getMessage(); 290 maps = unmarshalMAPs(message); 291 if (isRequestor && null != maps.getRelatesTo()) { 292 ContextUtils.storeCorrelationID(maps.getRelatesTo(), 293 false, 294 context); 295 } 296 return maps; 297 } 298 299 308 protected <T> void encodeMAP(T value, 309 QName qname, 310 Class <T> clz, 311 SOAPHeader header, 312 Marshaller marshaller) throws JAXBException { 313 LOG.log(Level.INFO, "encoding WSA header {0}", qname); 314 if (value != null) { 315 marshaller.marshal(new JAXBElement<T>(qname, clz, value), header); 316 } 317 } 318 319 327 protected <T> T decodeMAP(Class <T> clz, 328 SOAPHeaderElement headerElement, 329 Unmarshaller unmarshaller) throws JAXBException { 330 JAXBElement<T> element = 331 unmarshaller.unmarshal(headerElement, clz); 332 return element.getValue(); 333 } 334 335 341 private void discardMAPs(SOAPHeader header) throws SOAPException { 342 Iterator headerElements = header.examineAllHeaderElements(); 343 while (headerElements.hasNext()) { 344 SOAPHeaderElement headerElement = 345 (SOAPHeaderElement )headerElements.next(); 346 Name headerName = headerElement.getElementName(); 347 if (Names.WSA_NAMESPACE_NAME.equals(headerName.getURI())) { 348 headerElement.detachNode(); 349 } 350 } 351 } 352 353 359 private void propogateAction(AttributedURIType action, 360 SOAPMessage message) { 361 if (!(action == null || "".equals(action.getValue()))) { 362 MimeHeaders mimeHeaders = message.getMimeHeaders(); 363 String [] soapActionHeaders = 364 mimeHeaders.getHeader(Names.SOAP_ACTION_HEADER); 365 if (!(soapActionHeaders == null 367 || soapActionHeaders.length == 0 368 || "".equals(soapActionHeaders[0]))) { 369 LOG.log(Level.INFO, 370 "encoding wsa:Action in SOAPAction header {0}", 371 action.getValue()); 372 String soapAction = "\"" + action.getValue() + "\""; 373 mimeHeaders.setHeader(Names.SOAP_ACTION_HEADER, soapAction); 374 } 375 } 376 } 377 378 385 private void applyMAPValidation(SOAPMessageContext context) 386 throws SOAPException { 387 String faultName = ContextUtils.retrieveMAPFaultName(context); 388 if (faultName != null) { 389 String reason = ContextUtils.retrieveMAPFaultReason(context); 390 throw createSOAPFaultException(faultName, 391 Names.WSA_NAMESPACE_PREFIX, 392 Names.WSA_NAMESPACE_NAME, 393 reason); 394 } 395 } 396 397 400 private static synchronized SOAPFactory getSOAPFactory() throws SOAPException { 401 if (soapFactory == null) { 402 soapFactory = SOAPFactory.newInstance(); 403 } 404 return soapFactory; 405 } 406 407 416 private SOAPFaultException createSOAPFaultException(String localName, 417 String prefix, 418 String namespace, 419 String reason) 420 throws SOAPException { 421 SOAPFactory factory = getSOAPFactory(); 422 SOAPFault fault = factory.createFault(); 423 Name qname = factory.createName(localName, prefix, namespace); 424 fault.setFaultCode(qname); 425 fault.setFaultString(reason); 426 return new SOAPFaultException(fault); 427 } 428 } 429 430 431 432 433 434 435 | Popular Tags |