package org.saintandreas.util;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.xml.namespace.NamespaceContext;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.DOMException;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class XPathUtil {
private static ThreadLocal<Map<String, XPathExpression>> sCache = new ThreadLocal<Map<String, XPathExpression>>();
private static XPathFactory sFactory = XPathFactory.newInstance();
private static Map<String, XPathExpression> getCache() {
Map<String, XPathExpression> mRetVal = sCache.get();
if (mRetVal == null) {
mRetVal = new HashMap<String, XPathExpression>();
sCache.set(mRetVal);
}
return mRetVal;
}
public static XPathExpression getXPath(String exp) throws XPathExpressionException {
Map<String, XPathExpression> cache = getCache();
if (!cache.containsKey(exp)) {
cache.put(exp, sFactory.newXPath().compile(exp));
}
return cache.get(exp);
}
public static XPathExpression getXPath(String exp, NamespaceContext ctx) throws XPathExpressionException {
if (ctx == null) {
return getXPath(exp);
}
XPath mRetVal = sFactory.newXPath();
mRetVal.setNamespaceContext(ctx);
return mRetVal.compile(exp);
}
public static XPathExpression getXPathNoCache(String exp) throws XPathExpressionException {
return sFactory.newXPath().compile(exp);
}
public static String[] getStrings(Object doc, XPathExpression path) throws XPathExpressionException {
Node[] mNodes = getNodes(doc, path);
String[] mRetVal = new String[mNodes.length];
for (int i = 0; i < mNodes.length; ++i) {
mRetVal[i] = mNodes[i].getTextContent().trim();
}
return mRetVal;
}
public static String[] getStrings(Object node, NamespaceContext ctx, String path) throws XPathExpressionException {
return getStrings(node, getXPath(path, ctx));
}
public static String[] getStrings(Object node, String path) throws XPathExpressionException {
return getStrings(node, null, path);
}
public static Element[] getElements(Object doc, XPathExpression path) throws XPathExpressionException {
return XmlUtil.toElementArray((NodeList) path.evaluate(doc, XPathConstants.NODESET));
}
public static Element[] getElements(Object cms, NamespaceContext ctx, String path) throws XPathExpressionException {
return getElements(cms, getXPath(path, ctx));
}
public static Element[] getElements(Object cms, String path) throws XPathExpressionException {
return getElements(cms, null, path);
}
public static Node[] getNodes(Object doc, XPathExpression path) throws XPathExpressionException {
return XmlUtil.toNodeArray((NodeList) path.evaluate(doc, XPathConstants.NODESET));
}
public static Node[] getNodes(Object cms, NamespaceContext ctx, String path) throws XPathExpressionException {
return getNodes(cms, getXPath(path, ctx));
}
public static Node[] getNodes(Object cms, String path) throws XPathExpressionException {
return getNodes(cms, null, path);
}
public static void setTextContent(Object node, XPathExpression path, String text) throws XPathExpressionException {
for (Node n : getNodes(node, path)) {
n.setTextContent(text);
}
}
public static void setTextContent(Object node, NamespaceContext ctx, String path, String text) throws XPathExpressionException {
setTextContent(node, getXPath(path, ctx), text);
}
public static void setTextContent(Object node, String path, String text) throws XPathExpressionException {
setTextContent(node, null, path, text);
}
public static Set<String> getUniqueValues(Object doc, XPathExpression path) throws Exception {
Set<String> mRetVal = new HashSet<String>();
for (String s : getStrings(doc, path)) {
mRetVal.add(s.trim());
}
return mRetVal;
}
public static Set<String> getUniqueValues(Object doc, NamespaceContext ctx, String path) throws Exception {
return getUniqueValues(doc, getXPath(path, ctx));
}
public static Set<String> getUniqueValues(Object doc, String path) throws Exception {
return getUniqueValues(doc, null, path);
}
public static String getStringValue(Object doc, XPathExpression path) throws XPathExpressionException {
return path.evaluate(doc);
}
public static String getStringValue(Object doc, NamespaceContext ctx, String path) throws XPathExpressionException {
return getStringValue(doc, getXPath(path, ctx));
}
public static String getStringValue(Object doc, String path) throws XPathExpressionException {
return getStringValue(doc, null, path);
}
public static Node getNode(Object doc, XPathExpression path) throws XPathExpressionException {
return (Node) path.evaluate(doc, XPathConstants.NODE);
}
public static Node getNode(Object doc, NamespaceContext ctx, String path) throws XPathExpressionException {
return getNode(doc, getXPath(path, ctx));
}
public static Node getNode(Object doc, String path) throws XPathExpressionException {
return getNode(doc, null, path);
}
public static void truncate(Object node, XPathExpression path, int len) throws XPathExpressionException, DOMException {
for (Node n : XPathUtil.getNodes(node, path)) {
String text = n.getTextContent();
if ((text != null) && (text.length() > len)) {
text = text.substring(0, len - 4) + "...";
}
n.setTextContent(text);
}
}
public static void truncate(Object node, NamespaceContext ctx, String path, int len) throws XPathExpressionException, DOMException {
truncate(node, getXPath(path, ctx), len);
}
public static void truncate(Object node, String path, int len) throws XPathExpressionException, DOMException {
truncate(node, null, path, len);
}
}