001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.servicemix.soap.handlers.addressing;
018:
019: import java.util.Iterator;
020: import java.util.Map;
021:
022: import javax.xml.namespace.QName;
023:
024: import org.apache.servicemix.id.IdGenerator;
025: import org.apache.servicemix.jbi.jaxp.SourceTransformer;
026: import org.apache.servicemix.jbi.resolver.URIResolver;
027: import org.apache.servicemix.jbi.util.DOMUtil;
028: import org.apache.servicemix.jbi.util.WSAddressingConstants;
029: import org.apache.servicemix.soap.Context;
030: import org.apache.servicemix.soap.SoapFault;
031: import org.apache.servicemix.soap.handlers.AbstractHandler;
032: import org.apache.servicemix.soap.marshalers.SoapMessage;
033: import org.w3c.dom.Document;
034: import org.w3c.dom.DocumentFragment;
035: import org.w3c.dom.Element;
036:
037: /**
038: *
039: * @author Guillaume Nodet
040: * @version $Revision: 1.5 $
041: * @since 3.0
042: *
043: * @org.apache.xbean.XBean element="ws-addressing"
044: */
045: public class AddressingHandler extends AbstractHandler {
046:
047: protected final SourceTransformer sourceTransformer = new SourceTransformer();
048: protected final IdGenerator idGenerator = new IdGenerator();
049:
050: public void onReceive(Context context) throws Exception {
051: SoapMessage message = context.getInMessage();
052: String action = null;
053: String to = null;
054: String nsUri = null;
055: Map headers = message.getHeaders();
056: if (headers != null) {
057: for (Iterator it = headers.keySet().iterator(); it
058: .hasNext();) {
059: QName qname = (QName) it.next();
060: Object value = headers.get(qname);
061: if (isWSANamespace(qname.getNamespaceURI())) {
062: if (nsUri == null) {
063: nsUri = qname.getNamespaceURI();
064: } else if (!nsUri.equals(qname.getNamespaceURI())) {
065: throw new SoapFault(SoapFault.SENDER,
066: "Inconsistent use of wsa namespaces");
067: }
068: if (WSAddressingConstants.EL_ACTION.equals(qname
069: .getLocalPart())) {
070: action = getHeaderText(value);
071: String[] parts = URIResolver.split3(action);
072: context.setProperty(Context.INTERFACE,
073: new QName(parts[0], parts[1]));
074: context.setProperty(Context.OPERATION,
075: new QName(parts[0], parts[2]));
076: } else if (WSAddressingConstants.EL_TO.equals(qname
077: .getLocalPart())) {
078: to = getHeaderText(value);
079: String[] parts = URIResolver.split3(to);
080: context.setProperty(Context.SERVICE, new QName(
081: parts[0], parts[1]));
082: context.setProperty(Context.ENDPOINT, parts[2]);
083: } else {
084: // TODO: what ?
085: }
086: }
087: }
088: }
089: }
090:
091: public void onReply(Context context) throws Exception {
092: SoapMessage in = context.getInMessage();
093: SoapMessage out = context.getOutMessage();
094: Map headers = in.getHeaders();
095: if (headers != null) {
096: for (Iterator it = headers.keySet().iterator(); it
097: .hasNext();) {
098: QName qname = (QName) it.next();
099: Object value = headers.get(qname);
100: if (isWSANamespace(qname.getNamespaceURI())) {
101: if (WSAddressingConstants.EL_MESSAGE_ID
102: .equals(qname.getLocalPart())) {
103: QName name = new QName(
104: qname.getNamespaceURI(),
105: WSAddressingConstants.EL_MESSAGE_ID,
106: qname.getPrefix() != null ? qname
107: .getPrefix()
108: : WSAddressingConstants.WSA_PREFIX);
109: DocumentFragment df = createHeader(name,
110: idGenerator.generateSanitizedId());
111: out.addHeader(name, df);
112: name = new QName(
113: qname.getNamespaceURI(),
114: WSAddressingConstants.EL_RELATES_TO,
115: qname.getPrefix() != null ? qname
116: .getPrefix()
117: : WSAddressingConstants.WSA_PREFIX);
118: df = createHeader(name, getHeaderText(value));
119: out.addHeader(name, df);
120: }
121: }
122: }
123: }
124: }
125:
126: protected boolean isWSANamespace(String ns) {
127: return WSAddressingConstants.WSA_NAMESPACE_200303.equals(ns)
128: || WSAddressingConstants.WSA_NAMESPACE_200403
129: .equals(ns)
130: || WSAddressingConstants.WSA_NAMESPACE_200408
131: .equals(ns)
132: || WSAddressingConstants.WSA_NAMESPACE_200508
133: .equals(ns);
134: }
135:
136: protected String getHeaderText(Object header) {
137: Element el = (Element) ((DocumentFragment) header)
138: .getFirstChild();
139: return DOMUtil.getElementText(el);
140: }
141:
142: protected DocumentFragment createHeader(QName name, String value)
143: throws Exception {
144: Document doc = new SourceTransformer().createDocument();
145: DocumentFragment df = doc.createDocumentFragment();
146: Element el = doc.createElementNS(name.getNamespaceURI(),
147: getQualifiedName(name));
148: el.appendChild(doc.createTextNode(value));
149: df.appendChild(el);
150: return df;
151: }
152:
153: /**
154: * Gets the QName prefix. If the QName has no set prefix, the specified default prefix will be used.
155: */
156: protected String getPrefix(QName qname, String defaultPrefix) {
157: String prefix = qname.getPrefix();
158: if (null == prefix || "".equals(prefix)) {
159: prefix = defaultPrefix;
160: }
161:
162: return prefix;
163: }
164:
165: protected String getQualifiedName(QName qname) {
166: String name = qname.getLocalPart();
167:
168: String prefix = qname.getPrefix();
169: if (null != prefix && (!"".equals(prefix))) {
170: name = prefix + ":" + name;
171: }
172:
173: return name;
174: }
175:
176: }
|