package jp.aonir.fuzzyxml.xpath; import java.util.Arrays; import java.util.List; import java.util.Locale; import jp.aonir.fuzzyxml.FuzzyXMLAttribute; import jp.aonir.fuzzyxml.FuzzyXMLCDATA; import jp.aonir.fuzzyxml.FuzzyXMLComment; import jp.aonir.fuzzyxml.FuzzyXMLDocument; import jp.aonir.fuzzyxml.FuzzyXMLElement; import jp.aonir.fuzzyxml.FuzzyXMLNode; import jp.aonir.fuzzyxml.FuzzyXMLText; import org.apache.commons.jxpath.ri.Compiler; import org.apache.commons.jxpath.ri.QName; import org.apache.commons.jxpath.ri.compiler.NodeNameTest; import org.apache.commons.jxpath.ri.compiler.NodeTest; import org.apache.commons.jxpath.ri.compiler.NodeTypeTest; import org.apache.commons.jxpath.ri.model.NodeIterator; import org.apache.commons.jxpath.ri.model.NodePointer; public class FuzzyXMLNodePointer extends NodePointer { private static final long serialVersionUID = 7543442288342946073L; private Object _node; public FuzzyXMLNodePointer(NodePointer parent, Object node) { super(null); this._node = node; } public FuzzyXMLNodePointer(Object node, Locale locale) { super(null, locale); this._node = node; } @Override public NodeIterator childIterator(NodeTest test, boolean reverse, NodePointer startWith) { return new FuzzyXMLNodeIterator(this, test, reverse, startWith); } @Override public NodeIterator attributeIterator(QName name) { return new FuzzyXMLAttrIterator(this, name); } @Override public boolean isLeaf() { if (_node instanceof FuzzyXMLElement) { return ((FuzzyXMLElement) _node).getChildren().length == 0; } else if (_node instanceof FuzzyXMLDocument) { return ((FuzzyXMLDocument) _node).getDocumentElement() == null; } return true; } @Override public boolean isCollection() { return false; } @Override public int getLength() { return 1; } @Override public QName getName() { // String ns = null; String ln = null; if (_node instanceof FuzzyXMLElement) { ln = ((FuzzyXMLElement) _node).getName(); } return new QName(null, ln); } @Override public Object getBaseValue() { return _node; } @Override public Object getImmediateNode() { return _node; } @Override public Object getValue() { if (_node instanceof FuzzyXMLElement) { return ((FuzzyXMLElement) _node).getValue().trim(); } else if (_node instanceof FuzzyXMLComment) { return ((FuzzyXMLComment) _node).getValue(); } else if (_node instanceof FuzzyXMLText) { return ((FuzzyXMLText) _node).getValue(); } else if (_node instanceof FuzzyXMLCDATA) { return ((FuzzyXMLCDATA) _node).getValue(); } else if (_node instanceof FuzzyXMLAttribute) { return ((FuzzyXMLAttribute) _node).getValue(); } return null; } @Override public void setValue(Object value) { } @Override public int compareChildNodePointers(NodePointer pointer1, NodePointer pointer2) { Object node1 = pointer1.getBaseValue(); Object node2 = pointer2.getBaseValue(); if (node1 == node2) { return 0; } if ((node1 instanceof FuzzyXMLAttribute) && !(node2 instanceof FuzzyXMLAttribute)) { return -1; } else if (!(node1 instanceof FuzzyXMLAttribute) && (node2 instanceof FuzzyXMLAttribute)) { return 1; } else if ((node1 instanceof FuzzyXMLAttribute) && (node2 instanceof FuzzyXMLAttribute)) { List<FuzzyXMLAttribute> list = Arrays.asList(((FuzzyXMLElement) getNode()).getAttributes()); int length = list.size(); for (int i = 0; i < length; i++) { Object n = list.get(i); if (n == node1) { return -1; } else if (n == node2) { return 1; } } return 0; // Should not happen } if (!(_node instanceof FuzzyXMLElement)) { throw new RuntimeException("JXPath internal error: " + "compareChildNodes called for " + _node); } List<FuzzyXMLNode> children = Arrays.asList(((FuzzyXMLElement) _node).getChildren()); int length = children.size(); for (int i = 0; i < length; i++) { Object n = children.get(i); if (n == node1) { return -1; } else if (n == node2) { return 1; } } return 0; } public static boolean testNode(NodePointer pointer, Object node, NodeTest test) { if (test == null) { return true; } else if (test instanceof NodeNameTest) { if (!(node instanceof FuzzyXMLElement)) { return false; } NodeNameTest nodeNameTest = (NodeNameTest) test; QName testName = nodeNameTest.getNodeName(); // String namespaceURI = nodeNameTest.getNamespaceURI(); boolean wildcard = nodeNameTest.isWildcard(); String testPrefix = testName.getPrefix(); if (wildcard && testPrefix == null) { return true; } if (wildcard || testName.getName().equals(((FuzzyXMLElement) node).getName())) { return true; } } else if (test instanceof NodeTypeTest) { switch (((NodeTypeTest) test).getNodeType()) { case Compiler.NODE_TYPE_NODE: return node instanceof FuzzyXMLElement; case Compiler.NODE_TYPE_TEXT: return (node instanceof FuzzyXMLText) || (node instanceof FuzzyXMLCDATA); case Compiler.NODE_TYPE_COMMENT: return node instanceof FuzzyXMLComment; // case Compiler.NODE_TYPE_PI : // return node instanceof ProcessingInstruction; } return false; } // else if (test instanceof ProcessingInstructionTest) { // if (node instanceof ProcessingInstruction) { // String testPI = ((ProcessingInstructionTest) test).getTarget(); // String nodePI = ((ProcessingInstruction) node).getTarget(); // return testPI.equals(nodePI); // } // } return false; } }