/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cxf.tools.wsdlto.frontend.jaxws.customization;
import java.util.Iterator;
import java.util.logging.Logger;
import javax.wsdl.WSDLException;
import javax.wsdl.extensions.ExtensionRegistry;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.cxf.common.i18n.Message;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.tools.common.ToolConstants;
import org.apache.cxf.tools.common.ToolException;
public class JAXWSBindingParser {
private static final Logger LOG = LogUtils.getL7dLogger(CustomizationParser.class);
private ExtensionRegistry extReg;
public JAXWSBindingParser(ExtensionRegistry ext) {
extReg = ext;
}
public JAXWSBinding parse(Class<?> parentType, Element element, String namespace) throws WSDLException {
JAXWSBinding jaxwsBinding = (JAXWSBinding)extReg.createExtension(parentType,
ToolConstants.JAXWS_BINDINGS);
jaxwsBinding.setElementType(ToolConstants.JAXWS_BINDINGS);
jaxwsBinding.setElement(element);
jaxwsBinding.setDocumentBaseURI(namespace);
parseElement(jaxwsBinding, element);
return jaxwsBinding;
}
void parseElement(JAXWSBinding jaxwsBinding, Element element) {
Node child = element.getFirstChild();
if (child == null) {
// global binding
if (isAsyncElement(element)) {
jaxwsBinding.setEnableAsyncMapping(getNodeValue(element));
}
if (isMIMEElement(element)) {
jaxwsBinding.setEnableMime(getNodeValue(element));
}
if (isPackageElement(element)) {
jaxwsBinding.setPackage(getPackageName(element));
}
if (isWrapperStyle(element)) {
jaxwsBinding.setEnableWrapperStyle(getNodeValue(element));
}
} else {
// other binding
while (child != null) {
if (isAsyncElement(child)) {
jaxwsBinding.setEnableAsyncMapping(getNodeValue(child));
} else if (isMIMEElement(child)) {
jaxwsBinding.setEnableMime(getNodeValue(child));
} else if (isWrapperStyle(child)) {
jaxwsBinding.setEnableWrapperStyle(getNodeValue(child));
} else if (isPackageElement(child)) {
jaxwsBinding.setPackage(getPackageName(child));
Node docChild = DOMUtils.getChild(child, Element.ELEMENT_NODE);
if (docChild != null && this.isJAXWSClassDoc(docChild)) {
jaxwsBinding.setPackageJavaDoc(StringEscapeUtils.escapeHtml(DOMUtils.getContent(docChild)));
}
} else if (isJAXWSMethodElement(child)) {
jaxwsBinding.setMethodName(getMethodName(child));
Node docChild = DOMUtils.getChild(child, Element.ELEMENT_NODE);
if (docChild != null && this.isJAXWSClassDoc(docChild)) {
jaxwsBinding.setMethodJavaDoc(StringEscapeUtils.escapeHtml(DOMUtils.getContent(docChild)));
}
} else if (isJAXWSParameterElement(child)) {
Element childElement = (Element)child;
String partPath = "//" + childElement.getAttribute("part");
Node node = queryXPathNode(element.getOwnerDocument().getDocumentElement(), partPath);
String messageName = "";
String partName = "";
if (node != null) {
partName = ((Element)node).getAttribute("name");
Node messageNode = node.getParentNode();
if (messageNode != null) {
Element messageEle = (Element)messageNode;
messageName = messageEle.getAttribute("name");
}
}
String name = childElement.getAttribute("name");
String elementNameString = childElement.getAttribute("childElementName");
QName elementName = null;
if (!StringUtils.isEmpty(elementNameString)) {
String ns = "";
if (elementNameString.indexOf(':') != -1) {
ns = elementNameString.substring(0, elementNameString.indexOf(':'));
ns = childElement.lookupNamespaceURI(ns);
elementNameString = elementNameString
.substring(elementNameString.indexOf(':') + 1);
}
elementName = new QName(ns, elementNameString);
}
JAXWSParameter jpara = new JAXWSParameter(messageName, partName, elementName, name);
jaxwsBinding.addJaxwsPara(jpara);
} else if (isJAXWSClass(child)) {
Element childElement = (Element)child;
String clzName = childElement.getAttribute("name");
String javadoc = "";
Node docChild = DOMUtils.getChild(child, Element.ELEMENT_NODE);
if (docChild != null && this.isJAXWSClassDoc(docChild)) {
javadoc = StringEscapeUtils.escapeHtml(DOMUtils.getContent(docChild));
}
JAXWSClass jaxwsClass = new JAXWSClass(clzName, javadoc);
jaxwsBinding.setJaxwsClass(jaxwsClass);
}
child = child.getNextSibling();
}
}
}
private boolean isJAXWSMethodElement(Node node) {
return ToolConstants.NS_JAXWS_BINDINGS.equals(node.getNamespaceURI())
&& "method".equals(node.getLocalName());
}
private String getMethodName(Node node) {
Element ele = (Element)node;
return ele.getAttribute("name");
}
private boolean isPackageElement(Node node) {
return ToolConstants.NS_JAXWS_BINDINGS.equals(node.getNamespaceURI())
&& "package".equals(node.getLocalName());
}
private boolean isJAXWSParameterElement(Node node) {
return (ToolConstants.NS_JAXWS_BINDINGS.equals(node.getNamespaceURI()))
&& "parameter".equals(node.getLocalName());
}
private boolean isJAXWSClass(Node node) {
return (ToolConstants.NS_JAXWS_BINDINGS.equals(node.getNamespaceURI()))
&& "class".equals(node.getLocalName());
}
private boolean isJAXWSClassDoc(Node node) {
return (ToolConstants.NS_JAXWS_BINDINGS.equals(node.getNamespaceURI()))
&& "javadoc".equals(node.getLocalName());
}
private String getPackageName(Node node) {
Element ele = (Element)node;
return ele.getAttribute("name");
}
private Boolean isAsyncElement(Node node) {
return "enableAsyncMapping".equals(node.getLocalName())
&& ToolConstants.NS_JAXWS_BINDINGS.equals(node.getNamespaceURI());
}
private Boolean isWrapperStyle(Node node) {
return "enableWrapperStyle".equals(node.getLocalName())
&& ToolConstants.NS_JAXWS_BINDINGS.equals(node.getNamespaceURI());
}
private Boolean getNodeValue(Node node) {
return Boolean.valueOf(node.getTextContent());
}
private Boolean isMIMEElement(Node node) {
return "enableMIMEContent".equals(node.getLocalName())
&& ToolConstants.NS_JAXWS_BINDINGS.equals(node.getNamespaceURI());
}
private Node queryXPathNode(Node target, String expression) {
NodeList nlst;
try {
ContextImpl contextImpl = new ContextImpl(target);
XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(contextImpl);
nlst = (NodeList)xpath.evaluate(expression, target, XPathConstants.NODESET);
} catch (XPathExpressionException e) {
Message msg = new Message("XPATH_ERROR", LOG, new Object[] {expression});
throw new ToolException(msg, e);
}
if (nlst.getLength() != 1) {
Message msg = new Message("ERROR_TARGETNODE_WITH_XPATH", LOG, new Object[] {expression});
throw new ToolException(msg);
}
Node rnode = nlst.item(0);
if (!(rnode instanceof Element)) {
return null;
}
return rnode;
}
static class ContextImpl implements NamespaceContext {
private Node targetNode;
ContextImpl(Node node) {
targetNode = node;
}
public String getNamespaceURI(String prefix) {
return targetNode.getOwnerDocument().lookupNamespaceURI(prefix);
}
public String getPrefix(String nsURI) {
throw new UnsupportedOperationException();
}
public Iterator<?> getPrefixes(String namespaceURI) {
throw new UnsupportedOperationException();
}
}
}