common-gcore-stubs/src/main/java/org/gcube/common/clients/stubs/jaxws/GCoreJAXWSHandler.java

128 lines
3.9 KiB
Java

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<SOAPMessageContext> {
/** 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<QName> 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);
}
}