cb97aa4be688cf8783c0609f74b5c153a97fd2bb
[yangtools.git] / yang / yang-data-jaxen / src / test / java / org / opendaylight / yangtools / yang / data / jaxen / JaxenTest.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.yang.data.jaxen;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertTrue;
13 import static org.junit.Assert.fail;
14 import static org.mockito.Mockito.mock;
15
16 import com.google.common.base.Converter;
17 import com.google.common.base.VerifyException;
18 import com.google.common.collect.BiMap;
19 import com.google.common.collect.HashBiMap;
20 import com.google.common.collect.Maps;
21 import java.net.URI;
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.Map;
25 import java.util.Map.Entry;
26 import java.util.Optional;
27 import javax.xml.xpath.XPathExpressionException;
28 import org.jaxen.Context;
29 import org.jaxen.Function;
30 import org.jaxen.FunctionCallException;
31 import org.jaxen.UnresolvableException;
32 import org.junit.Before;
33 import org.junit.Test;
34 import org.opendaylight.yangtools.yang.common.QName;
35 import org.opendaylight.yangtools.yang.common.QNameModule;
36 import org.opendaylight.yangtools.yang.common.Revision;
37 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
38 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
39 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
40 import org.opendaylight.yangtools.yang.data.jaxen.api.XPathDocument;
41 import org.opendaylight.yangtools.yang.data.jaxen.api.XPathExpression;
42 import org.opendaylight.yangtools.yang.data.jaxen.api.XPathNodesetResult;
43 import org.opendaylight.yangtools.yang.data.jaxen.api.XPathResult;
44 import org.opendaylight.yangtools.yang.data.jaxen.api.XPathSchemaContext;
45 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
46 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
47 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
48
49 public class JaxenTest {
50     private ConverterNamespaceContext convertNctx;
51     private XPathSchemaContext xpathSchemaContext;
52     private XPathDocument xpathDocument;
53     private XPathExpression xpathExpression;
54     private NormalizedNodeNavigator navigator;
55
56     private QNameModule moduleQName;
57     private QName rootQName;
58     private QName listAQName;
59     private QName listBQName;
60     private QName leafAQName;
61     private QName leafBQName;
62     private QName leafDQName;
63     private QName containerAQName;
64     private QName containerBQName;
65
66     @Before
67     public void setup() throws XPathExpressionException {
68         final SchemaContext schemaContext = YangParserTestUtils.parseYangResourceDirectory("/test/documentTest");
69         assertNotNull(schemaContext);
70
71         initQNames();
72         xpathSchemaContext = new JaxenSchemaContextFactory().createContext(schemaContext);
73         assertNotNull(xpathSchemaContext);
74
75         xpathExpression = xpathSchemaContext.compileExpression(createSchemaPath(), createPrefixes(), createXPath(
76                     false));
77         assertNotNull(xpathExpression);
78
79         xpathDocument = xpathSchemaContext.createDocument(TestUtils.createNormalizedNodes());
80         assertNotNull(xpathDocument);
81         String rootNodeName = xpathDocument.getRootNode().getNodeType().getLocalName();
82         assertNotNull(rootNodeName);
83         assertEquals("root", rootNodeName);
84
85         Optional<? extends XPathResult<?>> resultExpressionEvaluate = xpathExpression
86                 .evaluate(xpathDocument, createYangInstanceIdentifier(false));
87         assertNotNull(resultExpressionEvaluate);
88         assertTrue(resultExpressionEvaluate.isPresent());
89         XPathResult<?> xpathResult = resultExpressionEvaluate.get();
90         assertTrue(xpathResult instanceof XPathNodesetResult);
91         XPathNodesetResult nodeset = (XPathNodesetResult) xpathResult;
92
93         Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry = nodeset.getValue().iterator().next();
94         assertNotNull(entry);
95         assertEquals("three", entry.getValue().getValue());
96
97         convertNctx = new ConverterNamespaceContext(createPrefixes());
98         navigator = new NormalizedNodeNavigator(convertNctx, (JaxenDocument) xpathDocument);
99         assertNotNull(navigator);
100     }
101
102     @Test
103     public void testConverterNamespaceContextBackFront() {
104         assertEquals("test2", convertNctx.doBackward(moduleQName));
105         assertEquals(moduleQName, convertNctx.doForward("test2"));
106     }
107
108     @Test
109     public void testConverterNamespaceContextPrefixJaxenName() {
110         assertNotNull(rootQName);
111         assertEquals("test2:root", convertNctx.jaxenQName(rootQName));
112         String prefix = convertNctx.translateNamespacePrefixToUri("test2");
113         assertNotNull(prefix);
114         assertEquals("urn:opendaylight.test2", prefix);
115     }
116
117     @Test
118     public void testCompileExpression() {
119         assertNotNull(xpathExpression.getApexPath());
120         assertEquals(createSchemaPath(), xpathExpression.getEvaluationPath());
121     }
122
123     @Test
124     public void testJaxenXpath() throws XPathExpressionException {
125         assertNotNull(xpathExpression.evaluate(xpathDocument, createYangInstanceIdentifier(false)));
126     }
127
128     @Test
129     public void testXpathWithPredicates() throws XPathExpressionException {
130         XPathExpression xpathExpressionWithPredicates = xpathSchemaContext.compileExpression(createSchemaPath(),
131                 createPrefixes(), createXPath(true));
132
133         Optional<? extends XPathResult<?>> resultExpressionEvaluate = xpathExpressionWithPredicates
134                 .evaluate(xpathDocument, createYangInstanceIdentifier(true));
135         assertTrue(resultExpressionEvaluate.isPresent());
136         XPathResult<?> xpathResult = resultExpressionEvaluate.get();
137         assertTrue(xpathResult instanceof XPathNodesetResult);
138         XPathNodesetResult nodeset = (XPathNodesetResult) xpathResult;
139
140         Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry = nodeset.getValue().iterator().next();
141         assertNotNull(entry);
142         assertEquals("two", entry.getValue().getValue());
143     }
144
145     @Test(expected = VerifyException.class)
146     public void testIsMethodsInNodeNavigator() {
147         assertTrue(navigator.isDocument("test"));
148     }
149
150     @Test(expected = XPathExpressionException.class)
151     public void testCompileExpressionException() throws XPathExpressionException {
152         assertNotNull(xpathSchemaContext.compileExpression(createSchemaPath(), createPrefixes(), "/broken-path*"));
153     }
154
155     @Test(expected = UnresolvableException.class)
156     public void testYangFunctionContext() throws UnresolvableException, FunctionCallException {
157         final YangFunctionContext yangFun = YangFunctionContext.getInstance();
158         assertNotNull(yangFun);
159         final Function function = yangFun.getFunction("urn:opendaylight.test2", null, "current");
160         assertNotNull(function);
161
162         try {
163             final Context context = mock(Context.class);
164             final ArrayList<Object> list = new ArrayList<>();
165             function.call(context, list);
166             fail();
167         } catch (VerifyException e) {
168             // Expected
169         }
170
171         yangFun.getFunction("urn:opendaylight.test2", "test2", "root");
172     }
173
174     /*
175      * container-a -> container-b -> leaf-d
176      *           list-a -> list-b -> leaf-b
177      */
178     private YangInstanceIdentifier createYangInstanceIdentifier(final boolean withPredicates) {
179         YangInstanceIdentifier testYangInstanceIdentifier = YangInstanceIdentifier.of(containerAQName).node(
180                 containerBQName).node(leafDQName);
181         if (withPredicates) {
182             final Map<QName, Object> keys1 = new HashMap<>();
183             keys1.put(leafAQName, "bar");
184
185             final NodeIdentifierWithPredicates mapEntryPath1 = NodeIdentifierWithPredicates.of(listAQName , keys1);
186
187             final Map<QName, Object> keys2 = new HashMap<>();
188             keys2.put(leafBQName, "two");
189
190             final NodeIdentifierWithPredicates mapEntryPath2 = NodeIdentifierWithPredicates.of(listBQName , keys2);
191
192             testYangInstanceIdentifier = YangInstanceIdentifier.of(listAQName).node(mapEntryPath1)
193                     .node(listBQName).node(mapEntryPath2).node(leafBQName);
194         }
195         return testYangInstanceIdentifier;
196     }
197
198     private static String createXPath(final boolean withPredicates) {
199         return withPredicates ? "/list-a[leaf-a='bar']/list-b[leaf-b='two']/leaf-b" : "/container-a/container-b/leaf-d";
200     }
201
202     private Converter<String, QNameModule> createPrefixes() {
203         BiMap<String, QNameModule> currentConverter = HashBiMap.create();
204         currentConverter.put("test2", moduleQName);
205
206         return Maps.asConverter(currentConverter);
207     }
208
209     // rootQName -> listAQName -> leafAQName
210     private  SchemaPath createSchemaPath() {
211         return SchemaPath.create(true, rootQName, listAQName, leafAQName);
212     }
213
214     private void initQNames() {
215         this.moduleQName = QNameModule.create(URI.create("urn:opendaylight.test2"), Revision.of("2015-08-08"));
216         this.rootQName = QName.create(moduleQName, "root");
217         this.listAQName = QName.create(moduleQName, "list-a");
218         this.listBQName = QName.create(moduleQName, "list-b");
219         this.leafAQName = QName.create(moduleQName, "leaf-a");
220         this.leafBQName = QName.create(moduleQName, "leaf-b");
221         this.leafDQName = QName.create(moduleQName, "leaf-d");
222         this.containerAQName = QName.create(moduleQName, "container-a");
223         this.containerBQName = QName.create(moduleQName, "container-b");
224     }
225 }