org.apache.cxf.ws.addressing.VersionTransformer Maven / Gradle / Ivy
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cxf.ws.addressing;
import java.util.List;
import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.dom.DOMResult;
import javax.xml.ws.EndpointReference;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
// importation convention: if the same class name is used for
// 2005/08 and 2004/08, then the former version is imported
// and the latter is fully qualified when used
import org.apache.cxf.common.util.PackageUtils;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.helpers.XMLUtils;
import org.apache.cxf.staxutils.W3CDOMStreamReader;
import org.apache.cxf.ws.addressing.v200408.AttributedQName;
import org.apache.cxf.ws.addressing.v200408.AttributedURI;
import org.apache.cxf.ws.addressing.v200408.ObjectFactory;
import org.apache.cxf.ws.addressing.v200408.Relationship;
import org.apache.cxf.ws.addressing.v200408.ServiceNameType;
import org.apache.cxf.wsdl.EndpointReferenceUtils;
/**
* This class is responsible for transforming between the native
* WS-Addressing schema version (i.e. 2005/08) and exposed
* version (currently may be 2005/08 or 2004/08).
*
* The native version is that used throughout the stack, were the
* WS-A types are represented via the JAXB generated types for the
* 2005/08 schema.
*
* The exposed version is that used when the WS-A types are
* externalized, i.e. are encoded in the headers of outgoing
* messages. For outgoing requests, the exposed version is
* determined from configuration. For outgoing responses, the
* exposed version is determined by the exposed version of
* the corresponding request.
*
* The motivation for using different native and exposed types
* is usually to facilitate a WS-* standard based on an earlier
* version of WS-Adressing (for example WS-RM depends on the
* 2004/08 version).
*/
public class VersionTransformer {
protected static final String NATIVE_VERSION = Names.WSA_NAMESPACE_NAME;
/**
* Constructor.
*/
protected VersionTransformer() {
}
/**
* @param namespace a namspace URI to consider
* @return true if th WS-Addressing version specified by the namespace
* URI is supported
*/
public static boolean isSupported(String namespace) {
return NATIVE_VERSION.equals(namespace)
|| Names200408.WSA_NAMESPACE_NAME.equals(namespace)
|| Names200403.WSA_NAMESPACE_NAME.equals(namespace);
}
/**
* Convert from 2005/08 AttributedURI to 2004/08 AttributedURI.
*
* @param internal the 2005/08 AttributedURIType
* @return an equivalent 2004/08 AttributedURI
*/
public static AttributedURI convert(AttributedURIType internal) {
AttributedURI exposed =
Names200408.WSA_OBJECT_FACTORY.createAttributedURI();
String exposedValue =
Names.WSA_ANONYMOUS_ADDRESS.equals(internal.getValue())
? Names200408.WSA_ANONYMOUS_ADDRESS
: Names.WSA_NONE_ADDRESS.equals(internal.getValue())
? Names200408.WSA_NONE_ADDRESS
: internal.getValue();
exposed.setValue(exposedValue);
putAll(exposed.getOtherAttributes(), internal.getOtherAttributes());
return exposed;
}
/**
* Convert from 2005/08 AttributedURI to 2004/03 AttributedURI.
*
* @param internal the 2005/08 AttributedURIType
* @return an equivalent 2004/08 or 2004/03 AttributedURI
*/
public static org.apache.cxf.ws.addressing.v200403.AttributedURI
convertTo200403(AttributedURIType internal) {
org.apache.cxf.ws.addressing.v200403.AttributedURI exposed = Names200403.WSA_OBJECT_FACTORY
.createAttributedURI();
String exposedValue = Names.WSA_ANONYMOUS_ADDRESS.equals(internal.getValue())
? Names200403.WSA_ANONYMOUS_ADDRESS : Names.WSA_NONE_ADDRESS.equals(internal.getValue())
? Names200403.WSA_NONE_ADDRESS : internal.getValue();
exposed.setValue(exposedValue);
putAll(exposed.getOtherAttributes(), internal.getOtherAttributes());
return exposed;
}
/**
* Convert from 2004/08 AttributedURI to 2005/08 AttributedURI.
*
* @param exposed the 2004/08 AttributedURI
* @return an equivalent 2005/08 AttributedURIType
*/
public static AttributedURIType convert(AttributedURI exposed) {
AttributedURIType internal =
ContextUtils.WSA_OBJECT_FACTORY.createAttributedURIType();
String internalValue =
Names200408.WSA_ANONYMOUS_ADDRESS.equals(exposed.getValue())
? Names.WSA_ANONYMOUS_ADDRESS
: Names200408.WSA_NONE_ADDRESS.equals(exposed.getValue())
? Names.WSA_NONE_ADDRESS
: exposed.getValue();
internal.setValue(internalValue);
putAll(internal.getOtherAttributes(), exposed.getOtherAttributes());
return internal;
}
/**
* Convert from 2004/03 AttributedURI to 2005/08 AttributedURI.
*
* @param exposed the 2004/03 AttributedURI
* @return an equivalent 2005/08 AttributedURIType
*/
public static AttributedURIType convert(org.apache.cxf.ws.addressing.v200403.AttributedURI exposed) {
AttributedURIType internal = ContextUtils.WSA_OBJECT_FACTORY.createAttributedURIType();
String internalValue = Names200403.WSA_ANONYMOUS_ADDRESS.equals(exposed.getValue())
? Names.WSA_ANONYMOUS_ADDRESS : Names200403.WSA_NONE_ADDRESS.equals(exposed.getValue())
? Names.WSA_NONE_ADDRESS : exposed.getValue();
internal.setValue(internalValue);
putAll(internal.getOtherAttributes(), exposed.getOtherAttributes());
return internal;
}
/**
* Convert from 2005/08 EndpointReferenceType to 2004/08
* EndpointReferenceType.
*
* @param internal the 2005/08 EndpointReferenceType
* @return an equivalent 2004/08 EndpointReferenceType
*/
public static org.apache.cxf.ws.addressing.v200408.EndpointReferenceType convert(
EndpointReferenceType internal) {
org.apache.cxf.ws.addressing.v200408.EndpointReferenceType exposed =
Names200408.WSA_OBJECT_FACTORY.createEndpointReferenceType();
exposed.setAddress(convert(internal.getAddress()));
exposed.setReferenceParameters(
convert(internal.getReferenceParameters()));
QName serviceQName = EndpointReferenceUtils.getServiceName(internal, null);
if (serviceQName != null) {
ServiceNameType serviceName =
Names200408.WSA_OBJECT_FACTORY.createServiceNameType();
serviceName.setValue(serviceQName);
exposed.setServiceName(serviceName);
}
String portLocalName = EndpointReferenceUtils.getPortName(internal);
if (portLocalName != null) {
String namespace = serviceQName.getNamespaceURI() != null
? serviceQName.getNamespaceURI()
: Names.WSDL_INSTANCE_NAMESPACE_NAME;
QName portQName =
new QName(namespace, portLocalName);
AttributedQName portType =
Names200408.WSA_OBJECT_FACTORY.createAttributedQName();
portType.setValue(portQName);
exposed.setPortType(portType);
}
// no direct analogue for Metadata
addAll(exposed.getAny(), internal.getAny());
putAll(exposed.getOtherAttributes(), internal.getOtherAttributes());
return exposed;
}
/**
* Convert from 2005/08 EndpointReferenceType to 2004/03 EndpointReferenceType.
*
* @param internal the 2005/08 EndpointReferenceType
* @return an equivalent 2004/03 EndpointReferenceType
*/
public static org.apache.cxf.ws.addressing.v200403.EndpointReferenceType
convertTo200403(EndpointReferenceType internal) {
org.apache.cxf.ws.addressing.v200403.EndpointReferenceType exposed = Names200403.WSA_OBJECT_FACTORY
.createEndpointReferenceType();
exposed.setAddress(convertTo200403(internal.getAddress()));
QName serviceQName = EndpointReferenceUtils.getServiceName(internal, null);
if (serviceQName != null) {
org.apache.cxf.ws.addressing.v200403.ServiceNameType serviceName = Names200403.WSA_OBJECT_FACTORY
.createServiceNameType();
serviceName.setValue(serviceQName);
exposed.setServiceName(serviceName);
}
String portLocalName = EndpointReferenceUtils.getPortName(internal);
if (portLocalName != null) {
String namespace = serviceQName.getNamespaceURI() != null
? serviceQName.getNamespaceURI() : Names.WSDL_INSTANCE_NAMESPACE_NAME;
QName portQName = new QName(namespace, portLocalName);
org.apache.cxf.ws.addressing.v200403.AttributedQName portType = Names200403.WSA_OBJECT_FACTORY
.createAttributedQName();
portType.setValue(portQName);
exposed.setPortType(portType);
}
// no direct analogue for Metadata
addAll(exposed.getAny(), internal.getAny());
putAll(exposed.getOtherAttributes(), internal.getOtherAttributes());
return exposed;
}
/**
* Convert from 2004/08 EndpointReferenceType to 2005/08
* EndpointReferenceType.
*
* @param exposed the 2004/08 EndpointReferenceType
* @return an equivalent 2005/08 EndpointReferenceType
*/
public static EndpointReferenceType convert(
org.apache.cxf.ws.addressing.v200408.EndpointReferenceType exposed) {
EndpointReferenceType internal =
ContextUtils.WSA_OBJECT_FACTORY.createEndpointReferenceType();
internal.setAddress(convert(exposed.getAddress()));
internal.setReferenceParameters(
convert(exposed.getReferenceParameters()));
ServiceNameType serviceName = exposed.getServiceName();
AttributedQName portName = exposed.getPortType();
if (serviceName != null && portName != null) {
EndpointReferenceUtils.setServiceAndPortName(internal,
serviceName.getValue(),
portName.getValue().getLocalPart());
}
// no direct analogue for ReferenceProperties
addAll(internal.getAny(), exposed.getAny());
putAll(internal.getOtherAttributes(), exposed.getOtherAttributes());
return internal;
}
/**
* Convert from 2004/03 EndpointReferenceType to 2005/08 EndpointReferenceType.
*
* @param exposed the 2004/03 EndpointReferenceType
* @return an equivalent 2005/08 EndpointReferenceType
*/
public static EndpointReferenceType
convert(org.apache.cxf.ws.addressing.v200403.EndpointReferenceType exposed) {
EndpointReferenceType internal = ContextUtils.WSA_OBJECT_FACTORY.createEndpointReferenceType();
internal.setAddress(convert(exposed.getAddress()));
// TODO ref parameters not present in 2004/03
// internal.setReferenceParameters(convert(exposed
// .getReferenceParameters()));
org.apache.cxf.ws.addressing.v200403.ServiceNameType serviceName = exposed.getServiceName();
org.apache.cxf.ws.addressing.v200403.AttributedQName portName = exposed.getPortType();
if (serviceName != null && portName != null) {
EndpointReferenceUtils.setServiceAndPortName(internal, serviceName.getValue(), portName
.getValue().getLocalPart());
}
// no direct analogue for ReferenceProperties
addAll(internal.getAny(), exposed.getAny());
putAll(internal.getOtherAttributes(), exposed.getOtherAttributes());
return internal;
}
/**
* Convert from EndpointReference to CXF internal 2005/08 EndpointReferenceType
*
* @param external the javax.xml.ws.EndpointReference
* @return CXF internal 2005/08 EndpointReferenceType
*/
public static EndpointReferenceType convertToInternal(EndpointReference external) {
if (external instanceof W3CEndpointReference) {
try {
Document doc = XMLUtils.newDocument();
DOMResult result = new DOMResult(doc);
external.writeTo(result);
W3CDOMStreamReader reader = new W3CDOMStreamReader(doc.getDocumentElement());
// CXF internal 2005/08 EndpointReferenceType should be
// compatible with W3CEndpointReference
//jaxContext = ContextUtils.getJAXBContext();
JAXBContext jaxbContext = JAXBContext
.newInstance(new Class[] {org.apache.cxf.ws.addressing.ObjectFactory.class});
EndpointReferenceType internal = jaxbContext.createUnmarshaller()
.unmarshal(reader, EndpointReferenceType.class)
.getValue();
return internal;
} catch (JAXBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
} else {
//TODO: 200408
}
return null;
}
/**
* Convert from 2005/08 ReferenceParametersType to 2004/08
* ReferenceParametersType.
*
* @param internal the 2005/08 ReferenceParametersType
* @return an equivalent 2004/08 ReferenceParametersType
*/
public static org.apache.cxf.ws.addressing.v200408.ReferenceParametersType convert(
ReferenceParametersType internal) {
org.apache.cxf.ws.addressing.v200408.ReferenceParametersType exposed =
null;
if (internal != null) {
exposed =
Names200408.WSA_OBJECT_FACTORY.createReferenceParametersType();
addAll(exposed.getAny(), internal.getAny());
}
return exposed;
}
/**
* Convert from 2004/08 ReferenceParametersType to 2005/08
* ReferenceParametersType.
*
* @param exposed the 2004/08 ReferenceParametersType
* @return an equivalent 2005/08 ReferenceParametersType
*/
public static ReferenceParametersType convert(
org.apache.cxf.ws.addressing.v200408.ReferenceParametersType exposed) {
ReferenceParametersType internal = null;
if (exposed != null) {
internal =
ContextUtils.WSA_OBJECT_FACTORY.createReferenceParametersType();
addAll(internal.getAny(), exposed.getAny());
}
return internal;
}
// THERE IS NO ReferenceParametersType for 2004/03
/**
* Convert from 2005/08 RelatesToType to 2004/08 Relationship.
*
* @param internal the 2005/08 RelatesToType
* @return an equivalent 2004/08 Relationship
*/
public static Relationship convert(RelatesToType internal) {
Relationship exposed = null;
if (internal != null) {
exposed = Names200408.WSA_OBJECT_FACTORY.createRelationship();
exposed.setValue(internal.getValue());
String internalRelationshipType = internal.getRelationshipType();
if (internalRelationshipType != null) {
QName exposedRelationshipType = null;
if (!Names.WSA_RELATIONSHIP_REPLY.equals(internalRelationshipType)) {
exposedRelationshipType = new QName(internalRelationshipType);
}
exposed.setRelationshipType(exposedRelationshipType);
}
putAll(exposed.getOtherAttributes(), internal.getOtherAttributes());
}
return exposed;
}
/**
* Convert from 2005/08 RelatesToType to 2004/03 Relationship.
*
* @param internal the 2005/08 RelatesToType
* @return an equivalent 2004/03 Relationship
*/
public static org.apache.cxf.ws.addressing.v200403.Relationship convertTo200403(RelatesToType internal) {
org.apache.cxf.ws.addressing.v200403.Relationship exposed = null;
if (internal != null) {
exposed = Names200403.WSA_OBJECT_FACTORY.createRelationship();
exposed.setValue(internal.getValue());
String internalRelationshipType = internal.getRelationshipType();
if (internalRelationshipType != null) {
QName exposedRelationshipType = null;
if (!Names.WSA_RELATIONSHIP_REPLY.equals(internalRelationshipType)) {
exposedRelationshipType = new QName(internalRelationshipType);
}
exposed.setRelationshipType(exposedRelationshipType);
}
putAll(exposed.getOtherAttributes(), internal.getOtherAttributes());
}
return exposed;
}
/** Convert from 2004/08 Relationship to 2005/08 RelatesToType.
*
* @param exposed the 2004/08 Relationship
* @return an equivalent 2005/08 RelatesToType
*/
public static RelatesToType convert(Relationship exposed) {
RelatesToType internal = null;
if (exposed != null) {
internal = ContextUtils.WSA_OBJECT_FACTORY.createRelatesToType();
internal.setValue(exposed.getValue());
QName exposedRelationshipType = exposed.getRelationshipType();
if (exposedRelationshipType != null) {
String internalRelationshipType =
Names.WSA_REPLY_NAME.equalsIgnoreCase(
exposedRelationshipType.getLocalPart())
? Names.WSA_RELATIONSHIP_REPLY
: exposedRelationshipType.toString();
internal.setRelationshipType(internalRelationshipType);
}
internal.getOtherAttributes().putAll(exposed.getOtherAttributes());
}
return internal;
}
/**
* Convert from 2004/03 Relationship to 2005/08 RelatesToType.
*
* @param exposed the 2004/03 Relationship
* @return an equivalent 2005/08 RelatesToType
*/
public static RelatesToType convert(org.apache.cxf.ws.addressing.v200403.Relationship exposed) {
RelatesToType internal = null;
if (exposed != null) {
internal = ContextUtils.WSA_OBJECT_FACTORY.createRelatesToType();
internal.setValue(exposed.getValue());
QName exposedRelationshipType = exposed.getRelationshipType();
if (exposedRelationshipType != null) {
String internalRelationshipType = Names.WSA_REPLY_NAME.equals(exposedRelationshipType
.getLocalPart()) ? Names.WSA_RELATIONSHIP_REPLY : exposedRelationshipType.toString();
internal.setRelationshipType(internalRelationshipType);
}
internal.getOtherAttributes().putAll(exposed.getOtherAttributes());
}
return internal;
}
/**
* Parse an EndpointReferenceType from a DOM element. Handles all of
* the WS-Addressing namespaces currently supported.
* @param ref
* @return
* @throws JAXBException
*/
public static EndpointReferenceType parseEndpointReference(Element ref) throws JAXBException {
Element child = DOMUtils.getFirstElement(ref);
String tns = null;
while (child != null && tns == null) {
if (isSupported(child.getNamespaceURI())) {
tns = child.getNamespaceURI();
}
child = DOMUtils.getNextElement(child);
}
if (tns == null) {
return null;
}
JAXBContext ctx = getExposedJAXBContext(tns);
Object o = ctx.createUnmarshaller().unmarshal(ref, getExposedReferenceType(tns));
if (o instanceof JAXBElement) {
o = ((JAXBElement)o).getValue();
}
return convertToNative(o);
}
/**
* Converts a version specific EndpointReferenceType to the native version
* used internally by CXF
* @param exposed
* @return
*/
public static EndpointReferenceType convertToNative(Object exposed) {
if (EndpointReferenceType.class.isInstance(exposed)) {
return (EndpointReferenceType)exposed;
} else if (Names200408.EPR_TYPE.isInstance(exposed)) {
return convert((org.apache.cxf.ws.addressing.v200408.EndpointReferenceType)exposed);
} else if (Names200403.EPR_TYPE.isInstance(exposed)) {
return convert((org.apache.cxf.ws.addressing.v200403.EndpointReferenceType)exposed);
}
return null;
}
/**
* Gets the Class representing the EndpointReferenceType that is used
* for the specific WS-Addressing version
* @param exposedURI
* @return
*/
public static Class> getExposedReferenceType(String exposedURI) {
return NATIVE_VERSION.equals(exposedURI)
? EndpointReferenceType.class
: Names200408.WSA_NAMESPACE_NAME.equals(exposedURI) ? Names200408.EPR_TYPE
: Names200403.WSA_NAMESPACE_NAME.equals(exposedURI) ? Names200403.EPR_TYPE : null;
}
/**
* @param exposedURI specifies the version WS-Addressing
* @return JABXContext for the exposed namespace URI
*/
public static JAXBContext getExposedJAXBContext(String exposedURI) throws JAXBException {
return NATIVE_VERSION.equals(exposedURI)
? ContextUtils.getJAXBContext() : Names200408.WSA_NAMESPACE_NAME.equals(exposedURI) ? Names200408
.getJAXBContext() : Names200403.WSA_NAMESPACE_NAME.equals(exposedURI) ? Names200403
.getJAXBContext() : null;
}
/**
* Put all entries from one map into another.
*
* @param to target map
* @param from source map
*/
private static void putAll(Map to, Map from) {
if (from != null) {
to.putAll(from);
}
}
/**
* Add all entries from one list into another.
*
* @param to target list
* @param from source list
*/
private static void addAll(List