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.soap;
019:
020: import java.util.Collections;
021: import java.util.HashSet;
022: import java.util.Set;
023: import java.util.logging.Logger;
024:
025: import javax.xml.bind.JAXBException;
026: import javax.xml.bind.Marshaller;
027: import javax.xml.bind.Unmarshaller;
028: import javax.xml.namespace.QName;
029:
030: import org.w3c.dom.Element;
031:
032: import org.apache.cxf.common.logging.LogUtils;
033:
034: // importation convention: if the same class name is used for
035: // 2005/08 and 2004/08, then the former version is imported
036: // and the latter is fully qualified when used
037: import org.apache.cxf.ws.addressing.AttributedURIType;
038: import org.apache.cxf.ws.addressing.EndpointReferenceType;
039: import org.apache.cxf.ws.addressing.Names;
040: import org.apache.cxf.ws.addressing.RelatesToType;
041: import org.apache.cxf.ws.addressing.v200408.AttributedURI;
042: import org.apache.cxf.ws.addressing.v200408.Relationship;
043:
044: /**
045: * This class is responsible for transforming between the native
046: * WS-Addressing schema version (i.e. 2005/08) and exposed
047: * version (currently may be 2005/08 or 2004/08).
048: * <p>
049: * The native version is that used throughout the stack, were the
050: * WS-A types are represented via the JAXB generated types for the
051: * 2005/08 schema.
052: * <p>
053: * The exposed version is that used when the WS-A types are
054: * externalized, i.e. are encoded in the headers of outgoing
055: * messages. For outgoing requests, the exposed version is
056: * determined from configuration. For outgoing responses, the
057: * exposed version is determined by the exposed version of
058: * the corresponding request.
059: * <p>
060: * The motivation for using different native and exposed types
061: * is usually to facilitate a WS-* standard based on an earlier
062: * version of WS-Adressing (for example WS-RM depends on the
063: * 2004/08 version).
064: */
065: public class VersionTransformer extends
066: org.apache.cxf.ws.addressing.VersionTransformer {
067:
068: public static final Set<QName> HEADERS;
069: private static final Logger LOG = LogUtils
070: .getL7dLogger(VersionTransformer.class);
071:
072: protected MAPCodec codec;
073:
074: /**
075: * Constructor.
076: *
077: * @param mapCodec the MAPCodec to use
078: */
079: public VersionTransformer(MAPCodec mapCodec) {
080: codec = mapCodec;
081: }
082:
083: /**
084: * Encode message in exposed version.
085: *
086: * @param exposeAs specifies the WS-Addressing version to expose
087: * @param value the value to encode
088: * @param localName the localName for the header
089: * @param clz the class
090: * @param header the SOAP header element
091: * @param marshaller the JAXB marshaller to use
092: */
093: public <T> void encodeAsExposed(String exposeAs, T value,
094: String localName, Class<T> clz, Element header,
095: Marshaller marshaller) throws JAXBException {
096: if (value != null) {
097: if (NATIVE_VERSION.equals(exposeAs)) {
098: codec.encodeMAP(value, new QName(exposeAs, localName),
099: clz, header, marshaller);
100: } else if (Names200408.WSA_NAMESPACE_NAME.equals(exposeAs)) {
101: if (AttributedURIType.class.equals(clz)) {
102: codec.encodeMAP(convert((AttributedURIType) value),
103: new QName(exposeAs, localName),
104: AttributedURI.class, header, marshaller);
105: } else if (EndpointReferenceType.class.equals(clz)) {
106: codec.encodeMAP(
107: convert((EndpointReferenceType) value),
108: new QName(exposeAs, localName),
109: Names200408.EPR_TYPE, header, marshaller);
110: } else if (RelatesToType.class.equals(clz)) {
111: codec.encodeMAP(convert((RelatesToType) value),
112: new QName(exposeAs, localName),
113: Relationship.class, header, marshaller);
114: }
115: }
116: }
117: }
118:
119: /**
120: * Decodes a MAP from a exposed version.
121: *
122: * @param encodedAs specifies the encoded version
123: * @param clz the class
124: * @param headerElement the SOAP header element
125: * @param marshaller the JAXB marshaller to use
126: * @return the decoded value
127: */
128: public <T> T decodeAsNative(String encodedAs, Class<T> clz,
129: Element headerElement, Unmarshaller unmarshaller)
130: throws JAXBException {
131: T ret = null;
132: LOG.fine("decodeAsNative: encodedAs: " + encodedAs);
133: LOG.fine(" class: " + clz.getName());
134:
135: if (NATIVE_VERSION.equals(encodedAs)) {
136: ret = codec.decodeMAP(clz, headerElement, unmarshaller);
137: } else if (Names200408.WSA_NAMESPACE_NAME.equals(encodedAs)) {
138: if (AttributedURIType.class.equals(clz)) {
139: return clz.cast(convert(codec.decodeMAP(
140: AttributedURI.class, headerElement,
141: unmarshaller)));
142: } else if (EndpointReferenceType.class.equals(clz)) {
143: return clz.cast(convert(codec.decodeMAP(
144: Names200408.EPR_TYPE, headerElement,
145: unmarshaller)));
146: } else if (RelatesToType.class.equals(clz)) {
147: return clz.cast(convert(codec
148: .decodeMAP(Relationship.class, headerElement,
149: unmarshaller)));
150: }
151: }
152: return ret;
153: }
154:
155: /**
156: * Augment the set of headers understood by the protocol binding
157: * with the 2004/08 header QNames.
158: */
159: static {
160: Set<QName> headers = new HashSet<QName>();
161: headers.addAll(Names.HEADERS);
162: Names200408.addHeaders(headers);
163: HEADERS = Collections.unmodifiableSet(headers);
164: }
165:
166: /**
167: * Holder for 2004/08 Names
168: */
169: public static final class Names200408 extends
170: org.apache.cxf.ws.addressing.VersionTransformer.Names200408 {
171:
172: protected Names200408() {
173: }
174:
175: /**
176: * Adds 2004/08 headers to set.
177: *
178: * @param headers set of headers
179: */
180: private static void addHeaders(Set<QName> headers) {
181: headers.add(new QName(WSA_NAMESPACE_NAME,
182: Names.WSA_FROM_NAME));
183: headers
184: .add(new QName(WSA_NAMESPACE_NAME,
185: Names.WSA_TO_NAME));
186: headers.add(new QName(WSA_NAMESPACE_NAME,
187: Names.WSA_REPLYTO_NAME));
188: headers.add(new QName(WSA_NAMESPACE_NAME,
189: Names.WSA_FAULTTO_NAME));
190: headers.add(new QName(WSA_NAMESPACE_NAME,
191: Names.WSA_ACTION_NAME));
192: headers.add(new QName(WSA_NAMESPACE_NAME,
193: Names.WSA_MESSAGEID_NAME));
194: }
195: }
196: }
|