1 /* 2 * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package test.astro; 24 25 import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; 26 import static javax.xml.xpath.XPathConstants.DOM_OBJECT_MODEL; 27 import static javax.xml.xpath.XPathConstants.NODESET; 28 import static jaxp.library.JAXPTestUtilities.filenameToURL; 29 import static org.testng.Assert.assertEquals; 30 import static test.astro.AstroConstants.ASTROCAT; 31 import static test.astro.AstroConstants.JAXP_SCHEMA_LANGUAGE; 32 import static test.astro.AstroConstants.JAXP_SCHEMA_SOURCE; 33 34 import java.net.MalformedURLException; 35 import java.util.ArrayList; 36 import java.util.Iterator; 37 38 import javax.xml.namespace.NamespaceContext; 39 import javax.xml.namespace.QName; 40 import javax.xml.parsers.DocumentBuilder; 41 import javax.xml.parsers.DocumentBuilderFactory; 42 import javax.xml.xpath.XPath; 43 import javax.xml.xpath.XPathExpression; 44 import javax.xml.xpath.XPathExpressionException; 45 import javax.xml.xpath.XPathFactory; 46 import javax.xml.xpath.XPathVariableResolver; 47 48 import jaxp.library.JAXPFileBaseTest; 49 50 import org.testng.annotations.BeforeClass; 51 import org.testng.annotations.DataProvider; 52 import org.testng.annotations.Test; 53 import org.w3c.dom.Document; 54 import org.w3c.dom.NodeList; 55 import org.xml.sax.InputSource; 56 57 /* 58 * @summary test XPath API 59 */ 60 @Test(singleThreaded = true) 61 public class XPathAPITest extends JAXPFileBaseTest { 62 private static final String STARDB_STAR_3_CONSTELLATION = "//astro:stardb/astro:star[3]/astro:constellation"; 63 private static final String STARDB_STAR = "//astro:stardb/astro:star"; 64 private Document doc; 65 private XPathFactory xpf; 66 private NamespaceContext nsContext; 67 68 @BeforeClass 69 public void setup() throws Exception { 70 DocumentBuilderFactory df = DocumentBuilderFactory.newInstance(); 71 df.setNamespaceAware(true); 72 df.setValidating(true); 73 df.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); 74 df.setAttribute(JAXP_SCHEMA_SOURCE, "catalog.xsd"); 75 DocumentBuilder bldr = df.newDocumentBuilder(); 76 doc = bldr.parse(ASTROCAT); 77 78 xpf = XPathFactory.newInstance(DOM_OBJECT_MODEL); 79 80 nsContext = new MyNamespaceContext(); 81 } 82 83 @DataProvider(name = "nodelist-evaluator") 84 public Object[][] getNodeListEvaluator() throws MalformedURLException { 85 return new Object[][] { { (XPathEvaluator) expression -> getXPath().evaluate(expression, doc.getDocumentElement(), NODESET) }, 86 { (XPathEvaluator) expression -> getXPath().evaluate(expression, createXMLInputSource(), NODESET) }, 87 { (XPathEvaluator) expression -> getXPathExpression(expression).evaluate(doc.getDocumentElement(), NODESET) }, 88 { (XPathEvaluator) expression -> getXPathExpression(expression).evaluate(createXMLInputSource(), NODESET) } }; 89 } 90 91 /* 92 * Test xpath expression evaluations method that returns type indicated by 93 * QName 94 */ 95 @Test(dataProvider = "nodelist-evaluator") 96 public void testEvaluateNodeList(XPathEvaluator evaluator) throws Exception { 97 NodeList o = (NodeList) evaluator.evaluate(STARDB_STAR); 98 assertEquals(o.getLength(), 10); 99 } 100 101 @DataProvider(name = "string-evaluator") 102 public Object[][] getStringEvaluator() throws MalformedURLException { 103 return new Object[][] { { (XPathEvaluator) expression -> getXPath().evaluate(expression, doc.getDocumentElement()) }, 104 { (XPathEvaluator) expression -> getXPath().evaluate(expression, createXMLInputSource()) }, 105 { (XPathEvaluator) expression -> getXPathExpression(expression).evaluate(doc.getDocumentElement()) }, 106 { (XPathEvaluator) expression -> getXPathExpression(expression).evaluate(createXMLInputSource()) } }; 107 } 108 109 /* 110 * Test xpath expression evaluations method that returns String 111 */ 112 @Test(dataProvider = "string-evaluator") 113 public void testEvaluateString(XPathEvaluator evaluator) throws Exception { 114 assertEquals(evaluator.evaluate(STARDB_STAR_3_CONSTELLATION), "Psc"); 115 } 116 117 @Test 118 public void testXPathVariableResolver() throws Exception { 119 XPath xpath = getXPath(); 120 xpath.setXPathVariableResolver(new MyXPathVariableResolver()); 121 assertEquals(xpath.evaluate("//astro:stardb/astro:star[astro:hr=$id]/astro:constellation", doc.getDocumentElement()), "Peg"); 122 123 } 124 125 private static class MyXPathVariableResolver implements XPathVariableResolver { 126 public Object resolveVariable(QName vname) { 127 return "4"; // resolve $id as 4, xpath will locate to star[hr=4] 128 } 129 } 130 131 /* 132 * Implementation of a NamespaceContext interface for the Xpath api tests. 133 * Used in xpath.setNamespaceContext(...) 134 */ 135 private static class MyNamespaceContext implements NamespaceContext { 136 public String getNamespaceURI(String prefix) { 137 return "astro".equals(prefix) ? "http://www.astro.com/astro" : ""; 138 } 139 140 public String getPrefix(String nsURI) { 141 return "http://www.astro.com/astro".equals(nsURI) ? "astro" : ""; 142 } 143 144 public Iterator getPrefixes(String nsURI) { 145 ArrayList list = new ArrayList(); 146 list.add("astro"); 147 return list.iterator(); 148 } 149 } 150 151 @FunctionalInterface 152 private interface XPathEvaluator { 153 Object evaluate(String expression) throws XPathExpressionException; 154 } 155 156 private XPath getXPath() { 157 XPath xpath = xpf.newXPath(); 158 xpath.setNamespaceContext(nsContext); 159 return xpath; 160 } 161 162 private XPathExpression getXPathExpression(String expression) throws XPathExpressionException { 163 return getXPath().compile(expression); 164 } 165 166 private InputSource createXMLInputSource() { 167 return new InputSource(filenameToURL(ASTROCAT)); 168 } 169 }