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. * *

* 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. *

* *
 * <ns3:Address>http://localhost:8090/app/services/isStore</ns3:Address>
 * <ns3:ReferenceParameters/>
 * <ns3:Metadata>
 *   <wsaw:InterfaceName>ns1:ISStoreService</wsaw:InterfaceName>
 *   <wsaw:ServiceName EndpointName="ISStoreServicePort">ns2:ISStoreServiceService</wsaw:ServiceName>
 *   <infrastructure:infrastructure>development</infrastructure:infrastructure>
 * </ns3:Metadata>
 * 
* * Users can easily define default system or service wide custom metadata to endpoint references by setting a * defaultMetadata property: * *
 * <bean name="cxfEndpointReferenceBuilder" class="eu.dnetlib.soap.cxf.CxfEndpointReferenceBuilder">
 *  <property name="defaultMetadata">
 *   <map>
 *    <entry key="{http://dnetlib.eu/endpointReference}infrastructure" value="${infrastructure.name}" />
 *   </map>
 *  </property>
 * </bean>
 * 
* * * @author marko * */ public class CxfEndpointReferenceBuilder extends AbstractEndpointReferenceBuilder { /** * 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 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 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 attributes) { Map 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(); for (Entry 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 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 getDefaultMetadata() { return defaultMetadata; } public void setDefaultMetadata(final Map 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; } }