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