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.wsn.jbi;
018
019 import java.util.concurrent.atomic.AtomicBoolean;
020
021 import javax.xml.namespace.QName;
022 import javax.xml.XMLConstants;
023 import javax.xml.parsers.ParserConfigurationException;
024 import javax.xml.stream.XMLStreamReader;
025 import javax.xml.stream.XMLStreamException;
026 import javax.xml.transform.Source;
027 import javax.xml.transform.TransformerException;
028 import javax.xml.transform.dom.DOMSource;
029
030 import org.w3c.dom.Document;
031 import org.w3c.dom.Element;
032
033 import org.apache.servicemix.common.util.DOMUtil;
034 import org.apache.servicemix.jbi.jaxp.StaxSource;
035 import org.apache.servicemix.jbi.jaxp.FragmentStreamReader;
036 import org.apache.servicemix.jbi.jaxp.StAXSourceTransformer;
037
038 /**
039 * Helper classes dealing with the WSDL 1.1 JBI wrapper
040 */
041 public class JbiWrapperHelper {
042
043 public static final String WSDL11_WRAPPER_NAMESPACE = "http://java.sun.com/xml/ns/jbi/wsdl-11-wrapper";
044 public static final String WSDL11_WRAPPER_PREFIX = "jbi";
045 public static final String WSDL11_WRAPPER_MESSAGE_LOCALNAME = "message";
046 public static final QName WSDL11_WRAPPER_MESSAGE = new QName(WSDL11_WRAPPER_NAMESPACE, WSDL11_WRAPPER_MESSAGE_LOCALNAME, WSDL11_WRAPPER_PREFIX);
047 public static final String WSDL11_WRAPPER_MESSAGE_PREFIX = "msg";
048 public static final String WSDL11_WRAPPER_TYPE = "type";
049 public static final String WSDL11_WRAPPER_NAME = "name";
050 public static final String WSDL11_WRAPPER_VERSION = "version";
051 public static final String WSDL11_WRAPPER_PART_LOCALNAME = "part";
052 public static final QName WSDL11_WRAPPER_PART = new QName(WSDL11_WRAPPER_NAMESPACE, WSDL11_WRAPPER_PART_LOCALNAME, WSDL11_WRAPPER_PREFIX);
053
054 private static final StAXSourceTransformer transformer = new StAXSourceTransformer();
055
056 public static Document createDocument() throws ParserConfigurationException {
057 return transformer.createDocument();
058 }
059
060 public static void wrap(Document doc) {
061 wrap(doc, null, null);
062 }
063
064 public static void wrap(Document doc, QName type, String name) {
065 Element wrapperMsg = doc.createElementNS(WSDL11_WRAPPER_NAMESPACE, WSDL11_WRAPPER_PREFIX + ":" + WSDL11_WRAPPER_MESSAGE_LOCALNAME);
066 wrapperMsg.setAttribute(WSDL11_WRAPPER_VERSION, "1.0");
067 if (type != null) {
068 if (!XMLConstants.NULL_NS_URI.equals(type.getNamespaceURI())) {
069 wrapperMsg.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, WSDL11_WRAPPER_MESSAGE_PREFIX, type.getNamespaceURI());
070 }
071 wrapperMsg.setAttribute(WSDL11_WRAPPER_TYPE, WSDL11_WRAPPER_MESSAGE_PREFIX + ":" + type.getLocalPart());
072 }
073 if (name != null) {
074 wrapperMsg.setAttribute(WSDL11_WRAPPER_NAME, name);
075 }
076 Element wrapperPart = doc.createElementNS(WSDL11_WRAPPER_NAMESPACE, WSDL11_WRAPPER_PREFIX + ":" + WSDL11_WRAPPER_PART_LOCALNAME);
077 wrapperMsg.appendChild(wrapperPart);
078 Element el = doc.getDocumentElement();
079 doc.replaceChild(wrapperMsg, el);
080 wrapperPart.appendChild(el);
081 }
082
083 public static Source unwrap(Source source, AtomicBoolean isJbiWrapped) throws XMLStreamException, TransformerException {
084 if (source instanceof DOMSource) {
085 Element el = DOMUtil.getFirstChildElement(((DOMSource) source).getNode());
086 if (el == null) {
087 throw new IllegalStateException("Unsupported DOMSource with no element");
088 }
089 if (WSDL11_WRAPPER_NAMESPACE.equals(el.getNamespaceURI()) && WSDL11_WRAPPER_MESSAGE_LOCALNAME.equals(el.getLocalName())) {
090 el = DOMUtil.getFirstChildElement(el);
091 if (el == null) {
092 throw new IllegalStateException("JBI wrapper has no child element");
093 }
094 el = DOMUtil.getFirstChildElement(el);
095 if (el == null) {
096 throw new IllegalStateException("JBI message has no child element");
097 }
098 if (!WSDL11_WRAPPER_NAMESPACE.equals(el.getNamespaceURI()) || !WSDL11_WRAPPER_PART_LOCALNAME.equals(el.getLocalName())) {
099 throw new IllegalStateException("Expected a jbi:part element");
100 }
101 isJbiWrapped.set(true);
102 source = new DOMSource(el);
103 }
104 } else {
105 XMLStreamReader reader = transformer.toXMLStreamReader(source);
106 reader.nextTag();
107 if (!reader.isStartElement()) {
108 throw new IllegalStateException("expected an element");
109 }
110 QName qname = reader.getName();
111 if (qname.equals(WSDL11_WRAPPER_MESSAGE)) {
112 reader.nextTag();
113 if (reader.getName().equals(WSDL11_WRAPPER_PART)) {
114 reader.nextTag();
115 isJbiWrapped.set(true);
116 } else {
117 throw new IllegalStateException("Expected a jbi:part element");
118 }
119 }
120 source = new StaxSource(new FragmentStreamReader(reader));
121 }
122 return source;
123 }
124
125 public static Source unwrap(Source source) throws TransformerException, XMLStreamException {
126 XMLStreamReader reader = new StAXSourceTransformer().toXMLStreamReader(source);
127 reader.nextTag();
128 if (!reader.isStartElement()) {
129 throw new IllegalStateException("expected an element");
130 }
131 QName qname = reader.getName();
132 if (qname.equals(WSDL11_WRAPPER_MESSAGE)) {
133 reader.nextTag();
134 if (reader.getName().equals(WSDL11_WRAPPER_PART)) {
135 reader.nextTag();
136 } else {
137 throw new IllegalStateException("Expected a jbi:part element");
138 }
139 }
140 source = new StaxSource(new FragmentStreamReader(reader));
141 return source;
142 }
143 }