001: package org.objectweb.celtix.systest.ws.addressing;
002:
003: import java.util.ArrayList;
004: import java.util.Iterator;
005: import java.util.List;
006: import java.util.Map;
007: import java.util.Set;
008:
009: import javax.xml.bind.JAXBContext;
010: import javax.xml.bind.JAXBElement;
011: import javax.xml.bind.JAXBException;
012: import javax.xml.bind.Marshaller;
013: import javax.xml.namespace.QName;
014: import javax.xml.soap.Name;
015: import javax.xml.soap.SOAPBody;
016: import javax.xml.soap.SOAPEnvelope;
017: import javax.xml.soap.SOAPException;
018: import javax.xml.soap.SOAPHeader;
019: import javax.xml.soap.SOAPHeaderElement;
020: import javax.xml.ws.handler.MessageContext;
021: import javax.xml.ws.handler.soap.SOAPHandler;
022: import javax.xml.ws.handler.soap.SOAPMessageContext;
023:
024: import org.objectweb.celtix.bus.ws.addressing.ContextUtils;
025: import org.objectweb.celtix.bus.ws.addressing.Names;
026: import org.objectweb.celtix.bus.ws.addressing.soap.VersionTransformer;
027: import org.objectweb.celtix.ws.addressing.AddressingProperties;
028: import org.objectweb.celtix.ws.addressing.AttributedURIType;
029: import org.objectweb.celtix.ws.addressing.v200408.AttributedURI;
030:
031: import static org.objectweb.celtix.ws.addressing.JAXWSAConstants.SERVER_ADDRESSING_PROPERTIES_OUTBOUND;
032:
033: /**
034: * Verifies presence of expected SOAP headers.
035: */
036: public class HeaderVerifier implements SOAPHandler<SOAPMessageContext> {
037: VerificationCache verificationCache;
038: String currentNamespaceURI;
039:
040: public void init(Map<String, Object> map) {
041: }
042:
043: public Set<QName> getHeaders() {
044: return null;
045: }
046:
047: public boolean handleMessage(SOAPMessageContext context) {
048: addPartialResponseHeader(context);
049: verify(context);
050: return true;
051: }
052:
053: public boolean handleFault(SOAPMessageContext context) {
054: verify(context);
055: return true;
056: }
057:
058: public void close(MessageContext context) {
059: }
060:
061: public void destroy() {
062: }
063:
064: private void addPartialResponseHeader(SOAPMessageContext context) {
065: try {
066: // add piggybacked wsa:From header to partial response
067: if (isOutgoingPartialResponse(context)) {
068: SOAPEnvelope env = context.getMessage().getSOAPPart()
069: .getEnvelope();
070: SOAPHeader header = env.getHeader() != null ? env
071: .getHeader() : env.addHeader();
072: marshallFrom("urn:piggyback_responder", header,
073: getMarshaller());
074: }
075: } catch (Exception e) {
076: verificationCache.put("SOAP header addition failed: " + e);
077: e.printStackTrace();
078: }
079: }
080:
081: private void verify(SOAPMessageContext context) {
082: try {
083: List<String> wsaHeaders = new ArrayList<String>();
084: SOAPHeader header = context.getMessage().getSOAPPart()
085: .getEnvelope().getHeader();
086: if (header != null) {
087: Iterator headerElements = header
088: .examineAllHeaderElements();
089: while (headerElements.hasNext()) {
090: Name headerName = ((SOAPHeaderElement) headerElements
091: .next()).getElementName();
092: if (isAddressingNamespace(headerName.getURI())) {
093: wsaHeaders.add(headerName.getLocalName());
094: }
095: }
096: }
097: boolean partialResponse = isIncomingPartialResponse(context)
098: || isOutgoingPartialResponse(context);
099: verificationCache.put(MAPTest.verifyHeaders(wsaHeaders,
100: partialResponse));
101: } catch (SOAPException se) {
102: verificationCache.put("SOAP header verification failed: "
103: + se);
104: }
105: }
106:
107: private boolean isAddressingNamespace(String namespace) {
108: boolean isAddressing = false;
109: if (Names.WSA_NAMESPACE_NAME.equals(namespace)
110: || VersionTransformer.Names200408.WSA_NAMESPACE_NAME
111: .equals(namespace)) {
112: currentNamespaceURI = namespace;
113: isAddressing = true;
114: }
115: return isAddressing;
116: }
117:
118: private boolean isOutgoingPartialResponse(SOAPMessageContext context) {
119: AddressingProperties maps = (AddressingProperties) context
120: .get(SERVER_ADDRESSING_PROPERTIES_OUTBOUND);
121: return ContextUtils.isOutbound(context)
122: && ContextUtils.isRequestor(context)
123: && Names.WSA_ANONYMOUS_ADDRESS.equals(maps.getTo()
124: .getValue());
125: }
126:
127: private boolean isIncomingPartialResponse(SOAPMessageContext context)
128: throws SOAPException {
129: SOAPBody body = context.getMessage().getSOAPPart()
130: .getEnvelope().getBody();
131: return !ContextUtils.isOutbound(context)
132: && ContextUtils.isRequestor(context)
133: && !body.getChildElements().hasNext();
134: }
135:
136: private Marshaller getMarshaller() throws JAXBException {
137: JAXBContext jaxbContext = VersionTransformer
138: .getExposedJAXBContext(currentNamespaceURI);
139: Marshaller marshaller = jaxbContext.createMarshaller();
140: marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
141: return marshaller;
142: }
143:
144: private void marshallFrom(String from, SOAPHeader header,
145: Marshaller marshaller) throws JAXBException {
146: if (Names.WSA_NAMESPACE_NAME.equals(currentNamespaceURI)) {
147: AttributedURIType value = ContextUtils
148: .getAttributedURI("urn:piggyback_responder");
149: marshaller.marshal(new JAXBElement<AttributedURIType>(
150: Names.WSA_FROM_QNAME, AttributedURIType.class,
151: value), header);
152: } else if (VersionTransformer.Names200408.WSA_NAMESPACE_NAME
153: .equals(currentNamespaceURI)) {
154: AttributedURI value = VersionTransformer.Names200408.WSA_OBJECT_FACTORY
155: .createAttributedURI();
156: value.setValue(from);
157: QName qname = new QName(
158: VersionTransformer.Names200408.WSA_NAMESPACE_NAME,
159: Names.WSA_FROM_NAME);
160: marshaller.marshal(new JAXBElement<AttributedURI>(qname,
161: AttributedURI.class, value), header);
162:
163: }
164:
165: }
166:
167: public void setVerificationCache(VerificationCache cache) {
168: verificationCache = cache;
169: }
170: }
|