dnet-core/dnet-core-components/src/main/java/eu/dnetlib/enabling/soap/cxf/CxfEndpointReferenceBuilder...

207 lines
6.2 KiB
Java

package eu.dnetlib.soap.cxf;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import javax.xml.ws.wsaddressing.W3CEndpointReferenceBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.oro.text.perl.Perl5Util;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import eu.dnetlib.soap.AbstractEndpointReferenceBuilder;
/**
* The cxf endpoint is an internal cross-toolkit implementation of the messaging endpoint.
*
* <p>
* End users will normally access jaxws endpoints, since jaxws is the mostly used cxf frontend. However, generic code,
* like interceptors, will handle cxf endpoints, so sometimes you may need to construct endpoint references from them.
* </p>
*
* <pre>
* &lt;ns3:Address&gt;http://localhost:8090/app/services/isStore&lt;/ns3:Address&gt;
* &lt;ns3:ReferenceParameters/&gt;
* &lt;ns3:Metadata&gt;
* &lt;wsaw:InterfaceName&gt;ns1:ISStoreService&lt;/wsaw:InterfaceName&gt;
* &lt;wsaw:ServiceName EndpointName=&quot;ISStoreServicePort&quot;&gt;ns2:ISStoreServiceService&lt;/wsaw:ServiceName&gt;
* &lt;infrastructure:infrastructure&gt;development&lt;/infrastructure:infrastructure&gt;
* &lt;/ns3:Metadata&gt;
* </pre>
*
* Users can easily define default system or service wide custom metadata to endpoint references by setting a
* defaultMetadata property:
*
* <pre>
* &lt;bean name=&quot;cxfEndpointReferenceBuilder&quot; class=&quot;eu.dnetlib.soap.cxf.CxfEndpointReferenceBuilder&quot;&gt;
* &lt;property name=&quot;defaultMetadata&quot;&gt;
* &lt;map&gt;
* &lt;entry key=&quot;{http://dnetlib.eu/endpointReference}infrastructure&quot; value=&quot;${infrastructure.name}&quot; /&gt;
* &lt;/map&gt;
* &lt;/property&gt;
* &lt;/bean&gt;
* </pre>
*
*
* @author marko
*
*/
public class CxfEndpointReferenceBuilder extends AbstractEndpointReferenceBuilder<Endpoint> {
/**
* logger.
*/
private static final Log log = LogFactory.getLog(CxfEndpointReferenceBuilder.class); // NOPMD by marko on 11/24/08 4:55
/**
* users can put some default metadata elements into all EPRs.
*/
private Map<String, Object> defaultMetadata;
/**
* regexp utility.
*/
private final transient Perl5Util matcher = new Perl5Util();
/**
* namespace of the ResourceIdentifier reference parameter.
*/
private String riNamespace = "http://www.driver.org";
/**
* element name of the ResourceIdentifier reference parameter.
*/
private String riElementName = "ResourceIdentifier";
/**
* {@inheritDoc}
*
* TODO: refactor.
*
* @see eu.dnetlib.soap.EndpointReferenceBuilder#getEndpointReference(java.lang.Object, java.util.Map)
*/
@Override
public W3CEndpointReference getEndpointReference(final Endpoint endpoint, final String referenceParam, final Map<QName, Object> attributes) {
final String address = getAddress(endpoint);
return getEndpointReference(address, endpoint.getService().getName(), endpoint.getEndpointInfo().getName(), null, referenceParam,
attributes);
}
/**
* low level method which allows the construction of a endpoint reference knowing all basic data as the address, service name etc.
*
* @param address
* @param serviceName
* @param endpointName
* @param wsdl
* @param referenceParam
* @param attributes
* @return
*/
public W3CEndpointReference getEndpointReference(
final String address,
final QName serviceName,
final QName endpointName,
final String wsdl,
final String referenceParam,
final Map<QName, Object> attributes) {
Map<QName, Object> attrs = attributes;
final W3CEndpointReferenceBuilder builder = new W3CEndpointReferenceBuilder();
builder.address(address);
if(serviceName != null)
builder.serviceName(serviceName);
if(endpointName != null)
builder.endpointName(endpointName);
builder.wsdlDocumentLocation(wsdl);
if (defaultMetadata != null) {
if (attrs == null)
attrs = new HashMap<QName, Object>();
for (Entry<String, Object> entry : defaultMetadata.entrySet())
attrs.put(splitQNameString(entry.getKey()), entry.getValue());
}
try {
final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); // NOPMD
if (referenceParam != null) {
final Element referenceElement = doc.createElementNS(getRiNamespace(), getRiElementName());
referenceElement.setTextContent(referenceParam);
builder.referenceParameter(referenceElement);
}
if (attrs != null && !attrs.isEmpty()) {
for (Entry<QName, Object> entry : attrs.entrySet()) {
final QName qname = entry.getKey();
final Element element = doc.createElementNS(qname.getNamespaceURI(), qname.getLocalPart());
element.setTextContent((String) entry.getValue());
builder.metadata(element);
}
}
} catch (ParserConfigurationException e) {
log.fatal("cannot extend EPR", e);
throw new IllegalStateException("cannot extend EPR", e);
}
return builder.build();
}
/**
* compute an endpoint address.
*
* @param endpoint
* endpoint
* @return url as string
*/
@Override
public String getAddress(final Endpoint endpoint) {
return endpoint.getEndpointInfo().getAddress();
}
/**
* helper method for converting "{namespace}elementName" strings to QNames.
*
* @param key
* "{namespace}elementName" string
* @return qname
*/
private QName splitQNameString(final String key) {
matcher.match("m/{(.*)}(.*)/", key);
return new QName(matcher.group(1), matcher.group(2));
}
public Map<String, Object> getDefaultMetadata() {
return defaultMetadata;
}
public void setDefaultMetadata(final Map<String, Object> defaultMetadata) {
this.defaultMetadata = defaultMetadata;
}
public String getRiNamespace() {
return riNamespace;
}
public void setRiNamespace(final String riNamespace) {
this.riNamespace = riNamespace;
}
public String getRiElementName() {
return riElementName;
}
public void setRiElementName(final String riElementName) {
this.riElementName = riElementName;
}
}