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