package org.gcube.common.clients.stubs.jaxws; import java.util.Iterator; import java.util.Set; import javax.xml.namespace.QName; import javax.xml.soap.SOAPHeader; import javax.xml.soap.SOAPHeaderElement; import javax.xml.ws.handler.MessageContext; import javax.xml.ws.handler.soap.SOAPHandler; import javax.xml.ws.handler.soap.SOAPMessageContext; import org.gcube.common.scope.api.ScopeProvider; /** * A {@link SOAPHandler} that adds gCube headers to outgoing calls. * * @author Fabio Simeoni * */ public class GCoreJAXWSHandler implements SOAPHandler { /** Namespace of scope-related headers */ public static final String SCOPE_NS = "http://gcube-system.org/namespaces/scope"; /** Name of the scope call header. */ public static final String SCOPE_HEADER_NAME = "scope"; public static final QName SCOPE_QNAME = new QName(SCOPE_NS,SCOPE_HEADER_NAME); /** Name of the service class call header. */ public static final String SERVICECLASS_HEADER_NAME = "serviceClass"; public static final QName SERVICECLASS_QNAME = new QName(SCOPE_NS,SERVICECLASS_HEADER_NAME); /** Name of the service name call header. */ public static final String SERVICENAME_HEADER_NAME = "serviceName"; public static final QName SERVICENAME_QNAME = new QName(SCOPE_NS,SERVICENAME_HEADER_NAME); /** Name of the scope call header. */ public static final String CALLER_HEADER_NAME = "caller"; /** Namespace of scope-related headers */ public static final String CALLER_NS = "http://gcube-system.org/namespaces/caller"; public static final QName CALLER_QNAME = new QName(CALLER_NS,CALLER_HEADER_NAME); private final GCoreService target; GCoreJAXWSHandler(GCoreService target) { this.target=target; } public boolean handleMessage(SOAPMessageContext context) { Boolean outbound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); if (outbound) try { SOAPHeader header = context.getMessage().getSOAPPart().getEnvelope().getHeader(); if (header == null) header = context.getMessage().getSOAPPart().getEnvelope().addHeader(); addCurrentScope(header); addTargetServiceCoordinates(header); addClientIdentity(header); correctWSAddressingHeader(header); } catch (Exception e) { throw new RuntimeException("cannot configure outgoing message", e); } return true; }; public Set getHeaders() { return null; } public boolean handleFault(SOAPMessageContext context) { return true; } public void close(MessageContext context) {} //helper private void addClientIdentity(SOAPHeader header) throws Exception { addHeader(header,CALLER_QNAME, target.clientId()); } //helper private void addTargetServiceCoordinates(SOAPHeader header) throws Exception { addHeader(header,SERVICECLASS_QNAME, target.gcubeClass()); addHeader(header,SERVICENAME_QNAME, target.gcubeName()); } //helper private void addCurrentScope(SOAPHeader header) throws Exception { String scope = ScopeProvider.instance.get(); if (scope==null) throw new IllegalStateException("no scope is defined for this call"); addHeader(header,SCOPE_QNAME, scope); } //helper: adapts ws-addressing headers to member submission's. brutal but there is no support for member submission in //jdk 1.6 private void correctWSAddressingHeader(SOAPHeader header) throws Exception { Iterator it = header.examineAllHeaderElements(); while (it.hasNext()) { SOAPHeaderElement e = (SOAPHeaderElement) it.next(); if (e.getElementQName().getNamespaceURI().equals("http://www.w3.org/2005/08/addressing")) { e.detachNode(); addHeader(header,new QName("http://schemas.xmlsoap.org/ws/2004/03/addressing",e.getElementQName().getLocalPart()), e.getTextContent()); } } } // helper private void addHeader(SOAPHeader header,QName name, String value) throws Exception { header.addHeaderElement(name).addTextNode(value); } }