/*
* SoapUI, Copyright (C) 2004-2016 SmartBear Software
*
* Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent
* versions of the EUPL (the "Licence");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://ec.europa.eu/idabc/eupl
*
* Unless required by applicable law or agreed to in writing, software distributed under the Licence is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the Licence for the specific language governing permissions and limitations
* under the Licence.
*/
package com.eviware.soapui.support;
import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContext;
import com.eviware.soapui.support.types.StringToStringMap;
import com.eviware.soapui.support.xml.XmlUtils;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.w3c.dom.Node;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
public class XmlHolder implements Map<String, Object> {
private XmlObject xmlObject;
private StringToStringMap declaredNamespaces;
private PropertyExpansionContext context;
private String propertyRef;
public XmlHolder(String xml) throws XmlException {
// xmlObject = XmlObject.Factory.parse( xml );
xmlObject = XmlUtils.createXmlObject(xml);
}
public XmlHolder(Node node) throws XmlException {
// xmlObject = XmlObject.Factory.parse( node );
xmlObject = XmlUtils.createXmlObject(node);
}
public XmlHolder(XmlObject xmlObject) throws XmlException {
this.xmlObject = xmlObject;
}
public XmlHolder(PropertyExpansionContext context, String propertyRef) throws XmlException {
this(String.valueOf(context.getProperty(propertyRef)));
this.context = context;
this.propertyRef = propertyRef;
}
public void updateProperty() {
updateProperty(false);
}
public void updateProperty(boolean prettyPrint) {
if (context != null && propertyRef != null) {
context.setProperty(propertyRef, prettyPrint ? getPrettyXml() : getXml());
}
}
public String getNodeValue(String xpath) throws XmlException {
xpath = initXPathNamespaces(xpath);
return XmlUtils.selectFirstNodeValue(xmlObject, xpath);
}
public StringToStringMap getNamespaces() {
if (declaredNamespaces == null) {
declaredNamespaces = new StringToStringMap();
}
return declaredNamespaces;
}
public void declareNamespace(String prefix, String uri) {
if (declaredNamespaces == null) {
declaredNamespaces = new StringToStringMap();
}
declaredNamespaces.put(prefix, uri);
}
public String[] getNodeValues(String xpath) throws XmlException {
xpath = initXPathNamespaces(xpath);
return XmlUtils.selectNodeValues(xmlObject, xpath);
}
private String initXPathNamespaces(String xpath) {
if (declaredNamespaces != null && !declaredNamespaces.isEmpty()) {
for (String prefix : declaredNamespaces.keySet()) {
xpath = "declare namespace " + prefix + "='" + declaredNamespaces.get(prefix) + "';\n" + xpath;
}
} else if (!xpath.trim().startsWith("declare namespace")) {
xpath = XmlUtils.declareXPathNamespaces(xmlObject) + xpath;
}
return xpath;
}
public void setNodeValue(String xpath, Object value) throws XmlException {
xpath = initXPathNamespaces(xpath);
XmlCursor cursor = xmlObject.newCursor();
try {
cursor.selectPath(xpath);
if (cursor.toNextSelection()) {
XmlUtils.setNodeValue(cursor.getDomNode(), value == null ? null : value.toString());
}
} finally {
cursor.dispose();
}
}
public XmlObject getXmlObject() {
return xmlObject;
}
public Node getDomNode(String xpath) throws XmlException {
xpath = initXPathNamespaces(xpath);
return XmlUtils.selectFirstDomNode(xmlObject, xpath);
}
public Node[] getDomNodes(String xpath) throws XmlException {
xpath = initXPathNamespaces(xpath);
return XmlUtils.selectDomNodes(xmlObject, xpath);
}
public void removeDomNodes(String xpath) throws XmlException {
xpath = initXPathNamespaces(xpath);
Node[] nodes = getDomNodes(xpath);
for (Node node : nodes) {
node.getParentNode().removeChild(node);
}
}
public String getXml() {
return xmlObject.xmlText();
}
public String getPrettyXml() {
return XmlUtils.prettyPrintXml(xmlObject);
}
public void clear() {
}
public boolean containsKey(Object key) {
try {
return getDomNode(key.toString()) != null;
} catch (XmlException e) {
e.printStackTrace();
return false;
}
}
public boolean containsValue(Object value) {
try {
return getNodeValue(value.toString()) != null;
} catch (XmlException e) {
e.printStackTrace();
return false;
}
}
public Set<java.util.Map.Entry<String, Object>> entrySet() {
return null;
}
public Object get(Object key) {
try {
String str = key.toString();
if (str.equals("prettyXml")) {
return getPrettyXml();
} else if (str.equals("xmlObject")) {
return getXmlObject();
} else if (str.equals("namespaces")) {
return getNamespaces();
} else if (str.equals("xml")) {
return getXml();
}
String[] nodeValues = getNodeValues(str);
return nodeValues != null && nodeValues.length == 1 ? nodeValues[0] : nodeValues;
} catch (XmlException e) {
e.printStackTrace();
return null;
}
}
public boolean isEmpty() {
return false;
}
public Set<String> keySet() {
return null;
}
public String put(String key, Object value) {
try {
String result = getNodeValue(key);
setNodeValue(key, value == null ? null : value.toString());
return result;
} catch (XmlException e) {
e.printStackTrace();
return null;
}
}
public void putAll(Map<? extends String, ? extends Object> t) {
if (t.keySet() == null) {
return;
}
for (Entry<? extends String, ?> entry : t.entrySet()) {
put(entry.getKey(), entry.getValue());
}
}
public Object remove(Object key) {
try {
Node node = getDomNode(key.toString());
if (node != null) {
node.getParentNode().removeChild(node);
}
} catch (XmlException e) {
e.printStackTrace();
}
return null;
}
public int size() {
return 0;
}
public Collection<Object> values() {
return null;
}
}