001: package org.objectweb.celtix.bus.ws.addressing;
002:
003: import java.util.List;
004: import java.util.Map;
005:
006: import javax.xml.bind.JAXBContext;
007: import javax.xml.bind.JAXBException;
008: import javax.xml.namespace.QName;
009:
010: // importation convention: if the same class name is used for
011: // 2005/08 and 2004/08, then the former version is imported
012: // and the latter is fully qualified when used
013: import org.objectweb.celtix.ws.addressing.AttributedURIType;
014: import org.objectweb.celtix.ws.addressing.EndpointReferenceType;
015: import org.objectweb.celtix.ws.addressing.ReferenceParametersType;
016: import org.objectweb.celtix.ws.addressing.RelatesToType;
017: import org.objectweb.celtix.ws.addressing.v200408.AttributedQName;
018: import org.objectweb.celtix.ws.addressing.v200408.AttributedURI;
019: import org.objectweb.celtix.ws.addressing.v200408.ObjectFactory;
020: import org.objectweb.celtix.ws.addressing.v200408.Relationship;
021: import org.objectweb.celtix.ws.addressing.v200408.ServiceNameType;
022: import org.objectweb.celtix.wsdl.EndpointReferenceUtils;
023:
024: /**
025: * This class is responsible for transforming between the native
026: * WS-Addressing schema version (i.e. 2005/08) and exposed
027: * version (currently may be 2005/08 or 2004/08).
028: * <p>
029: * The native version is that used throughout the stack, were the
030: * WS-A types are represented via the JAXB generated types for the
031: * 2005/08 schema.
032: * <p>
033: * The exposed version is that used when the WS-A types are
034: * externalized, i.e. are encoded in the headers of outgoing
035: * messages. For outgoing requests, the exposed version is
036: * determined from configuration. For outgoing responses, the
037: * exposed version is determined by the exposed version of
038: * the corresponding request.
039: * <p>
040: * The motivation for using different native and exposed types
041: * is usually to facilitate a WS-* standard based on an earlier
042: * version of WS-Adressing (for example WS-RM depends on the
043: * 2004/08 version).
044: */
045: public class VersionTransformer {
046:
047: protected static final String NATIVE_VERSION = Names.WSA_NAMESPACE_NAME;
048:
049: /**
050: * Constructor.
051: */
052: public VersionTransformer() {
053: }
054:
055: /**
056: * @param namespace a namspace URI to consider
057: * @return true if th WS-Addressing version specified by the namespace
058: * URI is supported
059: */
060: public boolean isSupported(String namespace) {
061: return NATIVE_VERSION.equals(namespace)
062: || Names200408.WSA_NAMESPACE_NAME.equals(namespace);
063: }
064:
065: /**
066: * Convert from 2005/08 AttributedURI to 2004/08 AttributedURI.
067: *
068: * @param internal the 2005/08 AttributedURIType
069: * @return an equivalent 2004/08 AttributedURI
070: */
071: public static AttributedURI convert(AttributedURIType internal) {
072: AttributedURI exposed = Names200408.WSA_OBJECT_FACTORY
073: .createAttributedURI();
074: String exposedValue = Names.WSA_ANONYMOUS_ADDRESS
075: .equals(internal.getValue()) ? Names200408.WSA_ANONYMOUS_ADDRESS
076: : Names.WSA_NONE_ADDRESS.equals(internal.getValue()) ? Names200408.WSA_NONE_ADDRESS
077: : internal.getValue();
078: exposed.setValue(exposedValue);
079: putAll(exposed.getOtherAttributes(), internal
080: .getOtherAttributes());
081: return exposed;
082: }
083:
084: /**
085: * Convert from 2004/08 AttributedURI to 2005/08 AttributedURI.
086: *
087: * @param exposed the 2004/08 AttributedURI
088: * @return an equivalent 2005/08 AttributedURIType
089: */
090: public static AttributedURIType convert(AttributedURI exposed) {
091: AttributedURIType internal = ContextUtils.WSA_OBJECT_FACTORY
092: .createAttributedURIType();
093: String internalValue = Names200408.WSA_ANONYMOUS_ADDRESS
094: .equals(exposed.getValue()) ? Names.WSA_ANONYMOUS_ADDRESS
095: : Names200408.WSA_NONE_ADDRESS.equals(exposed
096: .getValue()) ? Names.WSA_NONE_ADDRESS : exposed
097: .getValue();
098: internal.setValue(internalValue);
099: putAll(internal.getOtherAttributes(), exposed
100: .getOtherAttributes());
101: return internal;
102: }
103:
104: /**
105: * Convert from 2005/08 EndpointReferenceType to 2004/08
106: * EndpointReferenceType.
107: *
108: * @param internal the 2005/08 EndpointReferenceType
109: * @return an equivalent 2004/08 EndpointReferenceType
110: */
111: public static org.objectweb.celtix.ws.addressing.v200408.EndpointReferenceType convert(
112: EndpointReferenceType internal) {
113: org.objectweb.celtix.ws.addressing.v200408.EndpointReferenceType exposed = Names200408.WSA_OBJECT_FACTORY
114: .createEndpointReferenceType();
115: exposed.setAddress(convert(internal.getAddress()));
116: exposed.setReferenceParameters(convert(internal
117: .getReferenceParameters()));
118: QName serviceQName = EndpointReferenceUtils
119: .getServiceName(internal);
120: if (serviceQName != null) {
121: ServiceNameType serviceName = Names200408.WSA_OBJECT_FACTORY
122: .createServiceNameType();
123: serviceName.setValue(serviceQName);
124: exposed.setServiceName(serviceName);
125: }
126: String portLocalName = EndpointReferenceUtils
127: .getPortName(internal);
128: if (portLocalName != null) {
129: String namespace = serviceQName.getNamespaceURI() != null ? serviceQName
130: .getNamespaceURI()
131: : Names.WSDL_INSTANCE_NAMESPACE_NAME;
132: QName portQName = new QName(namespace, portLocalName);
133: AttributedQName portType = Names200408.WSA_OBJECT_FACTORY
134: .createAttributedQName();
135: portType.setValue(portQName);
136: exposed.setPortType(portType);
137: }
138: // no direct analogue for Metadata
139: addAll(exposed.getAny(), internal.getAny());
140: putAll(exposed.getOtherAttributes(), internal
141: .getOtherAttributes());
142: return exposed;
143: }
144:
145: /**
146: * Convert from 2004/08 EndpointReferenceType to 2005/08
147: * EndpointReferenceType.
148: *
149: * @param exposed the 2004/08 EndpointReferenceType
150: * @return an equivalent 2005/08 EndpointReferenceType
151: */
152: public static EndpointReferenceType convert(
153: org.objectweb.celtix.ws.addressing.v200408.EndpointReferenceType exposed) {
154: EndpointReferenceType internal = ContextUtils.WSA_OBJECT_FACTORY
155: .createEndpointReferenceType();
156: internal.setAddress(convert(exposed.getAddress()));
157: internal.setReferenceParameters(convert(exposed
158: .getReferenceParameters()));
159: ServiceNameType serviceName = exposed.getServiceName();
160: AttributedQName portName = exposed.getPortType();
161: if (serviceName != null && portName != null) {
162: EndpointReferenceUtils.setServiceAndPortName(internal,
163: serviceName.getValue(), portName.getValue()
164: .getLocalPart());
165: }
166:
167: // no direct analogue for ReferenceProperties
168: addAll(internal.getAny(), exposed.getAny());
169: putAll(internal.getOtherAttributes(), exposed
170: .getOtherAttributes());
171: return internal;
172: }
173:
174: /**
175: * Convert from 2005/08 ReferenceParametersType to 2004/08
176: * ReferenceParametersType.
177: *
178: * @param internal the 2005/08 ReferenceParametersType
179: * @return an equivalent 2004/08 ReferenceParametersType
180: */
181: public static org.objectweb.celtix.ws.addressing.v200408.ReferenceParametersType convert(
182: ReferenceParametersType internal) {
183: org.objectweb.celtix.ws.addressing.v200408.ReferenceParametersType exposed = null;
184: if (internal != null) {
185: exposed = Names200408.WSA_OBJECT_FACTORY
186: .createReferenceParametersType();
187: addAll(exposed.getAny(), internal.getAny());
188: }
189: return exposed;
190: }
191:
192: /**
193: * Convert from 2004/08 ReferenceParametersType to 2005/08
194: * ReferenceParametersType.
195: *
196: * @param exposed the 2004/08 ReferenceParametersType
197: * @return an equivalent 2005/08 ReferenceParametersType
198: */
199: public static ReferenceParametersType convert(
200: org.objectweb.celtix.ws.addressing.v200408.ReferenceParametersType exposed) {
201: ReferenceParametersType internal = null;
202: if (exposed != null) {
203: internal = ContextUtils.WSA_OBJECT_FACTORY
204: .createReferenceParametersType();
205: addAll(internal.getAny(), exposed.getAny());
206: }
207: return internal;
208: }
209:
210: /**
211: * Convert from 2005/08 RelatesToType to 2004/08 Relationship.
212: *
213: * @param internal the 2005/08 RelatesToType
214: * @return an equivalent 2004/08 Relationship
215: */
216: public static Relationship convert(RelatesToType internal) {
217: Relationship exposed = null;
218: if (internal != null) {
219: exposed = Names200408.WSA_OBJECT_FACTORY
220: .createRelationship();
221: exposed.setValue(internal.getValue());
222: String internalRelationshipType = internal
223: .getRelationshipType();
224: if (internalRelationshipType != null) {
225: QName exposedRelationshipType = Names.WSA_RELATIONSHIP_REPLY
226: .equals(internalRelationshipType) ? new QName(
227: Names200408.WSA_NAMESPACE_NAME,
228: Names.WSA_REPLY_NAME) : new QName(
229: internalRelationshipType);
230: exposed.setRelationshipType(exposedRelationshipType);
231: }
232: putAll(exposed.getOtherAttributes(), internal
233: .getOtherAttributes());
234: }
235: return exposed;
236: }
237:
238: /**
239: * Convert from 2004/08 Relationship to 2005/08 RelatesToType.
240: *
241: * @param exposed the 2004/08 Relationship
242: * @return an equivalent 2005/08 RelatesToType
243: */
244: public static RelatesToType convert(Relationship exposed) {
245: RelatesToType internal = null;
246: if (exposed != null) {
247: internal = ContextUtils.WSA_OBJECT_FACTORY
248: .createRelatesToType();
249: internal.setValue(exposed.getValue());
250: QName exposedRelationshipType = exposed
251: .getRelationshipType();
252: if (exposedRelationshipType != null) {
253: String internalRelationshipType = Names.WSA_REPLY_NAME
254: .equals(exposedRelationshipType.getLocalPart()) ? Names.WSA_RELATIONSHIP_REPLY
255: : exposedRelationshipType.toString();
256: internal.setRelationshipType(internalRelationshipType);
257: }
258: internal.getOtherAttributes().putAll(
259: exposed.getOtherAttributes());
260: }
261: return internal;
262: }
263:
264: /**
265: * @param exposedURI specifies the version WS-Addressing
266: * @return JABXContext for the exposed namespace URI
267: */
268: public static JAXBContext getExposedJAXBContext(String exposedURI)
269: throws JAXBException {
270: return NATIVE_VERSION.equals(exposedURI) ? ContextUtils
271: .getJAXBContext() : Names200408.getJAXBContext();
272: }
273:
274: /**
275: * Put all entries from one map into another.
276: *
277: * @param to target map
278: * @param from source map
279: */
280: private static void putAll(Map<QName, String> to,
281: Map<QName, String> from) {
282: if (from != null) {
283: to.putAll(from);
284: }
285: }
286:
287: /**
288: * Add all entries from one list into another.
289: *
290: * @param to target list
291: * @param from source list
292: */
293: private static void addAll(List<Object> to, List<Object> from) {
294: if (from != null) {
295: to.addAll(from);
296: }
297: }
298:
299: /**
300: * Holder for 2004/08 Names
301: */
302: public static class Names200408 {
303: public static final String WSA_NAMESPACE_NAME = "http://schemas.xmlsoap.org/ws/2004/08/addressing";
304: public static final String WSA_ANONYMOUS_ADDRESS = WSA_NAMESPACE_NAME
305: + "/anonymous";
306: public static final String WSA_NONE_ADDRESS = WSA_NAMESPACE_NAME
307: + "/none";
308: public static final ObjectFactory WSA_OBJECT_FACTORY = new ObjectFactory();
309: public static final String WS_ADDRESSING_PACKAGE = AttributedURI.class
310: .getPackage().getName();
311: public static final Class<org.objectweb.celtix.ws.addressing.v200408.EndpointReferenceType> EPR_TYPE = org.objectweb.celtix.ws.addressing.v200408.EndpointReferenceType.class;
312:
313: private static JAXBContext jaxbContext;
314:
315: protected Names200408() {
316: }
317:
318: /**
319: * Retrieve a JAXBContext for marshalling and unmarshalling JAXB generated
320: * types for the 2004/08 version.
321: *
322: * @return a JAXBContext
323: */
324: public static JAXBContext getJAXBContext() throws JAXBException {
325: synchronized (Names200408.class) {
326: if (jaxbContext == null) {
327: jaxbContext = JAXBContext
328: .newInstance(WS_ADDRESSING_PACKAGE);
329: }
330: }
331: return jaxbContext;
332: }
333:
334: /**
335: * Set the encapsulated JAXBContext (used by unit tests).
336: *
337: * @param ctx JAXBContext
338: */
339: public static void setJAXBContext(JAXBContext ctx)
340: throws JAXBException {
341: synchronized (Names200408.class) {
342: jaxbContext = ctx;
343: }
344: }
345: }
346: }
|