1 21 package oracle.toplink.essentials.internal.ejb.cmp3.xml.parser; 23 24 import org.w3c.dom.Element ; 25 import org.w3c.dom.Node ; 26 import org.w3c.dom.NodeList ; 27 import org.w3c.dom.Text ; 28 29 33 public class XPathEngine { 34 private static final String ATTRIBUTE = "@"; 35 private static final String TEXT = "text()"; 36 private static final String ALL_CHILDREN = "child::*"; 37 private static final String NAMESPACE_URI = "http://java.sun.com/xml/ns/persistence/orm"; 38 private static XPathEngine instance = null; 39 40 private XPathEngine() { 41 super(); 42 } 43 44 47 public static XPathEngine getInstance() { 48 if (instance == null) { 49 instance = new XPathEngine(); 50 } 51 return instance; 52 } 53 54 63 public Node selectSingleNode(Node contextNode, String [] xPathFragments) { 64 if (contextNode == null) { 65 return null; 66 } 67 68 return selectSingleNode(contextNode, xPathFragments, 0); 69 } 70 71 private Node selectSingleNode(Node contextNode, String [] xPathFragments, int index) { 72 Node resultNode = getSingleNode(contextNode, xPathFragments[index]); 73 if ((resultNode == null) || (xPathFragments.length == (index + 1))) { 74 return resultNode; 75 } 76 77 return selectSingleNode(resultNode, xPathFragments, index + 1); 78 } 79 80 89 public NodeList selectNodes(Node contextNode, String [] xPathFragments) { 90 if (contextNode == null) { 91 return null; 92 } 93 94 return selectNodes(contextNode, xPathFragments, 0); 95 } 96 97 private NodeList selectNodes(Node contextNode, String [] xPathFragments, int index) { 98 99 NodeList resultNodes = getNodes(contextNode, xPathFragments[index]); 100 101 if (xPathFragments.length != index + 1) { 102 Node resultNode; 103 XMLNodeList result = new XMLNodeList(); 104 int numberOfResultNodes = resultNodes.getLength(); 105 for (int x = 0; x < numberOfResultNodes; x++) { 106 resultNode = resultNodes.item(x); 107 result.addAll(selectNodes(resultNode, xPathFragments, index + 1)); 108 } 109 return result; 110 } 111 112 return resultNodes; 113 } 114 115 private Node getSingleNode(Node contextNode, String xPathFragment) { 116 if (xPathFragment.startsWith(ATTRIBUTE)) { 117 return selectSingleAttribute(contextNode, xPathFragment); 118 } else if (TEXT.equals(xPathFragment)) { 119 return selectSingleText(contextNode); 120 } 121 return selectSingleElement(contextNode, xPathFragment); 122 } 123 124 private NodeList getNodes(Node contextNode, String xPathFragment) { 125 if (xPathFragment.startsWith(ATTRIBUTE)) { 126 return selectAttributeNodes(contextNode, xPathFragment); 127 } else if (TEXT.equals(xPathFragment)) { 128 return selectTextNodes(contextNode); 129 } else if (xPathFragment.equals(ALL_CHILDREN)) { 130 return selectChildElements(contextNode); 131 } 132 return selectElementNodes(contextNode, xPathFragment); 133 134 } 135 136 private Node selectSingleAttribute(Node contextNode, String xPathFragment) { 137 Element contextElement = (Element )contextNode; 138 return contextElement.getAttributeNode(xPathFragment.substring(1)); 139 } 140 141 private NodeList selectAttributeNodes(Node contextNode, String xPathFragment) { 142 XMLNodeList xmlNodeList = new XMLNodeList(); 143 144 Node child = selectSingleAttribute(contextNode, xPathFragment); 145 if (null != child) { 146 xmlNodeList.add(child); 147 } 148 return xmlNodeList; 149 } 150 151 private Node selectSingleElement(Node contextNode, String xPathFragment) { 152 Node child = contextNode.getFirstChild(); 153 while (null != child) { 154 if ((child.getNodeType() == Node.ELEMENT_NODE) && sameName(child, xPathFragment) && sameNamespaceURI(child, NAMESPACE_URI)) { 155 return child; 156 } 157 158 child = child.getNextSibling(); 159 } 160 return null; 161 } 162 163 private NodeList selectChildElements(Node contextNode) { 164 XMLNodeList xmlNodeList = new XMLNodeList(); 165 Node child = contextNode.getFirstChild(); 166 167 while (child != null) { 168 if (child.getNodeType() == Node.ELEMENT_NODE) { 169 xmlNodeList.add(child); 170 } 171 child = child.getNextSibling(); 172 } 173 174 return xmlNodeList; 175 } 176 177 private NodeList selectElementNodes(Node contextNode, String xPathFragment) { 178 XMLNodeList xmlNodeList = new XMLNodeList(); 179 Node child = contextNode.getFirstChild(); 180 181 while (null != child) { 182 if ((child.getNodeType() == Node.ELEMENT_NODE) && sameName(child, xPathFragment) && sameNamespaceURI(child, NAMESPACE_URI)) { 183 xmlNodeList.add(child); 184 } 185 186 child = child.getNextSibling(); 187 } 188 189 return xmlNodeList; 190 } 191 192 private Node selectSingleText(Node contextNode) { 193 NodeList childrenNodes = contextNode.getChildNodes(); 194 195 if (childrenNodes.getLength() == 0) { 196 return null; 197 } 198 199 if (childrenNodes.getLength() == 1) { 200 Node child = childrenNodes.item(0); 201 if (child.getNodeType() == Node.TEXT_NODE) { 202 return child; 203 } 204 return null; 205 } 206 207 String returnVal = null; 208 for (int i = 0; i < childrenNodes.getLength(); i++) { 209 Node next = childrenNodes.item(i); 210 if (next.getNodeType() == Node.TEXT_NODE) { 211 String val = ((Text )next).getNodeValue(); 212 if (val != null) { 213 if (returnVal == null) { 214 returnVal = new String (); 215 } 216 returnVal += val; 217 } 218 } 219 } 220 221 if (returnVal != null) { 224 return contextNode.getOwnerDocument().createTextNode(returnVal); 225 } 226 return null; 227 } 228 229 private NodeList selectTextNodes(Node contextNode) { 230 Node n = selectSingleText(contextNode); 231 232 XMLNodeList xmlNodeList = new XMLNodeList(); 233 if (n != null) { 234 xmlNodeList.add(n); 235 } 236 return xmlNodeList; 237 } 238 239 private boolean sameNamespaceURI(Node node, String namespaceURI) { 240 String nodeNamespaceURI = node.getNamespaceURI(); 242 if (nodeNamespaceURI == namespaceURI) { 243 return true; 244 } 245 246 if ((nodeNamespaceURI == null) && namespaceURI.equals("")) { 247 return true; 248 } 249 250 if ((namespaceURI == null) && nodeNamespaceURI.equals("")) { 251 return true; 252 } 253 254 return (null != nodeNamespaceURI) && nodeNamespaceURI.equals(namespaceURI); 256 } 257 258 private boolean sameName(Node node, String name) { 259 return name.equals(node.getLocalName()) || name.equals(node.getNodeName()); 260 } 261 } 262 | Popular Tags |