Skip to content

Instantly share code, notes, and snippets.

@vernetto
Last active June 20, 2024 15:03
Show Gist options
  • Save vernetto/22507acf96ce73ef0dcedd45d7e9ac5a to your computer and use it in GitHub Desktop.
Save vernetto/22507acf96ce73ef0dcedd45d7e9ac5a to your computer and use it in GitHub Desktop.
node
import org.apache.commons.configuration2.tree.ExpressionEngine;
import org.apache.commons.configuration2.tree.ImmutableNode;
import org.apache.commons.configuration2.tree.NodeHandler;
import org.apache.commons.configuration2.tree.QueryResult;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.*;
import java.util.ArrayList;
import java.util.List;
public class CustomExpressionEngine implements ExpressionEngine {
@Override
public <T> List<QueryResult<T>> query(T root, String key, NodeHandler<T> handler) {
List<QueryResult<T>> results = new ArrayList<>();
try {
// Convert root node to a DOM Node
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.newDocument();
Element rootElement = convertToElement(document, handler, root);
document.appendChild(rootElement);
// Evaluate XPath expression
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xpath = xPathFactory.newXPath();
XPathExpression expr = xpath.compile(key);
NodeList nodeList = (NodeList) expr.evaluate(document, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
results.add(new QueryResult<>(convertToImmutableNode(node), null));
}
} catch (Exception e) {
e.printStackTrace();
}
return results;
}
@Override
public <T> String nodeKey(T node, String key, NodeHandler<T> handler) {
return key;
}
private <T> Element convertToElement(Document doc, NodeHandler<T> handler, T node) {
Element element = doc.createElement(handler.nodeName(node));
// Handling attributes manually since getAttributes() does not directly return a map
for (String attrName : handler.getAttributes(node)) {
Object attrValue = handler.getAttributeValue(node, attrName);
element.setAttribute(attrName, attrValue.toString());
}
for (T child : handler.getChildren(node)) {
element.appendChild(convertToElement(doc, handler, child));
}
return element;
}
private ImmutableNode convertToImmutableNode(Node node) {
ImmutableNode.Builder builder = new ImmutableNode.Builder().name(node.getNodeName());
NamedNodeMap attributes = node.getAttributes();
for (int i = 0; i < attributes.getLength(); i++) {
Attr attr = (Attr) attributes.item(i);
builder.addAttribute(attr.getName(), attr.getValue());
}
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE) {
builder.addChild(convertToImmutableNode(child));
} else if (child.getNodeType() == Node.TEXT_NODE) {
builder.value(child.getNodeValue());
}
}
return builder.create();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment