2 * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.yangtools.yang.data.jaxen;
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertSame;
13 import static org.junit.Assert.assertTrue;
15 import com.google.common.collect.BiMap;
16 import com.google.common.collect.HashBiMap;
17 import com.google.common.collect.ImmutableList;
18 import com.google.common.collect.ImmutableMap;
19 import com.google.common.collect.Maps;
22 import org.jaxen.Function;
23 import org.junit.BeforeClass;
24 import org.junit.Test;
25 import org.opendaylight.yangtools.yang.common.QName;
26 import org.opendaylight.yangtools.yang.common.QNameModule;
27 import org.opendaylight.yangtools.yang.common.Revision;
28 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
29 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
30 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
31 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
32 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
33 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
34 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
35 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
36 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
37 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
38 import org.opendaylight.yangtools.yang.data.api.schema.xpath.XPathDocument;
39 import org.opendaylight.yangtools.yang.data.api.schema.xpath.XPathSchemaContext;
40 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
41 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
42 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
44 public class DerefXPathFunctionTest {
46 private static JaxenSchemaContextFactory jaxenSchemaContextFactory;
48 private static QNameModule fooModule;
49 private static QName myContainer;
50 private static QName myInnerContainer;
51 private static QName myList;
52 private static QName keyLeafA;
53 private static QName keyLeafB;
54 private static QName iidLeaf;
55 private static QName referencedLeaf;
56 private static QName referencedLeafList;
57 private static QName absLeafrefLeaf;
58 private static QName relLeafrefLeaf;
59 private static QName leafListLeafrefLeaf;
60 private static QName ordinaryLeafA;
61 private static QName ordinaryLeafB;
64 public static void setup() {
65 jaxenSchemaContextFactory = new JaxenSchemaContextFactory();
67 fooModule = QNameModule.create(URI.create("foo-ns"), Revision.valueOf("2017-04-03"));
68 myContainer = QName.create(fooModule, "my-container");
69 myInnerContainer = QName.create(fooModule, "my-inner-container");
70 myList = QName.create(fooModule, "my-list");
71 keyLeafA = QName.create(fooModule, "key-leaf-a");
72 keyLeafB = QName.create(fooModule, "key-leaf-b");
73 iidLeaf = QName.create(fooModule, "iid-leaf");
74 referencedLeaf = QName.create(fooModule, "referenced-leaf");
75 referencedLeafList = QName.create(fooModule, "referenced-leaf-list");
76 absLeafrefLeaf = QName.create(fooModule, "abs-leafref-leaf");
77 relLeafrefLeaf = QName.create(fooModule, "rel-leafref-leaf");
78 leafListLeafrefLeaf = QName.create(fooModule, "leaf-list-leafref-leaf");
79 ordinaryLeafA = QName.create(fooModule, "ordinary-leaf-a");
80 ordinaryLeafB = QName.create(fooModule, "ordinary-leaf-b");
84 public void testDerefFunctionForInstanceIdentifier() throws Exception {
85 final SchemaContext schemaContext = YangParserTestUtils.parseYangResources(DerefXPathFunctionTest.class,
86 "/yang-xpath-functions-test/deref-function-iid/foo.yang");
87 assertNotNull(schemaContext);
89 final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
91 final LeafNode<?> referencedLeafNode = Builders.leafBuilder().withNodeIdentifier(
92 new NodeIdentifier(referencedLeaf)).withValue("referenced-leaf-node-value").build();
94 final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForIIdTest(
97 final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
98 converterBiMap.put("foo-prefix", fooModule);
100 final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
101 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
103 final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(
104 buildPathToIIdLeafNode());
106 final Function derefFunction = normalizedNodeContextSupport.getFunctionContext()
107 .getFunction(null, null, "deref");
108 final Object derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
109 assertNotNull(derefResult);
110 assertTrue(derefResult instanceof NormalizedNode<?, ?>);
111 assertSame(referencedLeafNode, derefResult);
115 public void testDerefFunctionForLeafref() throws Exception {
116 // tests absolute and relative leafref that references a leaf node
117 final SchemaContext schemaContext = YangParserTestUtils.parseYangResources(DerefXPathFunctionTest.class,
118 "/yang-xpath-functions-test/deref-function-leafref/foo.yang");
119 assertNotNull(schemaContext);
121 final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
123 final LeafNode<?> referencedLeafNode = Builders.leafBuilder().withNodeIdentifier(
124 new NodeIdentifier(referencedLeaf)).withValue("referenced-leaf-node-value").build();
126 final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForLeafrefTest(
127 referencedLeafNode));
129 final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
130 converterBiMap.put("foo-prefix", fooModule);
132 final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
133 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
135 final YangInstanceIdentifier absLeafrefPath = YangInstanceIdentifier.of(myInnerContainer).node(absLeafrefLeaf);
136 NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(absLeafrefPath);
138 final Function derefFunction = normalizedNodeContextSupport.getFunctionContext()
139 .getFunction(null, null, "deref");
140 Object derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
141 assertNotNull(derefResult);
142 assertTrue(derefResult instanceof NormalizedNode<?, ?>);
143 assertSame(referencedLeafNode, derefResult);
145 final YangInstanceIdentifier relLeafrefPath = YangInstanceIdentifier.of(myInnerContainer).node(relLeafrefLeaf);
146 normalizedNodeContext = normalizedNodeContextSupport.createContext(relLeafrefPath);
148 derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
149 assertNotNull(derefResult);
150 assertTrue(derefResult instanceof NormalizedNode<?, ?>);
151 assertSame(referencedLeafNode, derefResult);
155 public void testDerefFunctionForLeafref2() throws Exception {
156 // tests leafref that references a leaf-list node
157 final SchemaContext schemaContext = YangParserTestUtils.parseYangResources(DerefXPathFunctionTest.class,
158 "/yang-xpath-functions-test/deref-function-leafref/foo.yang");
159 assertNotNull(schemaContext);
161 final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
163 final LeafSetNode<?> referencedLeafListNode = Builders.leafSetBuilder().withNodeIdentifier(
164 new NodeIdentifier(referencedLeafList))
165 .withChild(Builders.leafSetEntryBuilder().withNodeIdentifier(
166 new NodeWithValue<>(referencedLeafList, "referenced-node-entry-value-a"))
167 .withValue("referenced-node-entry-value-a").build())
168 .withChild(Builders.leafSetEntryBuilder().withNodeIdentifier(
169 new NodeWithValue<>(referencedLeafList, "referenced-node-entry-value-b"))
170 .withValue("referenced-node-entry-value-b").build())
171 .withChild(Builders.leafSetEntryBuilder().withNodeIdentifier(
172 new NodeWithValue<>(referencedLeafList, "referenced-node-entry-value-c"))
173 .withValue("referenced-node-entry-value-c").build())
176 final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForLeafrefTest(
177 referencedLeafListNode));
179 final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
180 converterBiMap.put("foo-prefix", fooModule);
182 final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
183 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
185 final YangInstanceIdentifier leafListLeafrefPath = YangInstanceIdentifier.of(myInnerContainer)
186 .node(leafListLeafrefLeaf);
187 final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport
188 .createContext(leafListLeafrefPath);
190 final Function derefFunction = normalizedNodeContextSupport.getFunctionContext()
191 .getFunction(null, null, "deref");
192 Object derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
193 assertNotNull(derefResult);
194 assertTrue(derefResult instanceof NormalizedNode<?, ?>);
196 final LeafSetEntryNode<?> referencedLeafListNodeEntry = referencedLeafListNode.getChild(
197 new NodeWithValue<>(referencedLeafList, "referenced-node-entry-value-b")).get();
198 assertSame(referencedLeafListNodeEntry, derefResult);
201 private static ContainerNode buildMyContainerNodeForIIdTest(final LeafNode<?> referencedLeafNode) {
202 final Map<QName, Object> keyValues = ImmutableMap.of(keyLeafA, "key-value-a", keyLeafB, "key-value-b");
203 final YangInstanceIdentifier iidPath = YangInstanceIdentifier.of(myContainer).node(myList)
204 .node(new NodeIdentifierWithPredicates(myList, keyValues)).node(referencedLeaf);
206 final LeafNode<?> iidLeafNode = Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(iidLeaf))
207 .withValue(iidPath).build();
209 final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(myList))
210 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
211 new NodeIdentifierWithPredicates(myList, keyValues))
212 .withChild(iidLeafNode)
213 .withChild(referencedLeafNode).build())
216 final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
217 new NodeIdentifier(myContainer)).withChild(myListNode).build();
218 return myContainerNode;
221 private static YangInstanceIdentifier buildPathToIIdLeafNode() {
222 final Map<QName, Object> keyValues = ImmutableMap.of(keyLeafA, "key-value-a", keyLeafB, "key-value-b");
223 final YangInstanceIdentifier path = YangInstanceIdentifier.of(myList)
224 .node(new NodeIdentifierWithPredicates(myList, keyValues)).node(iidLeaf);
228 // variant for a leafref that references a leaf
229 private static ContainerNode buildMyContainerNodeForLeafrefTest(final LeafNode<?> referencedLeafNode) {
230 final Map<QName, Object> keyValues = ImmutableMap.of(keyLeafA, "value-a", keyLeafB, "value-b");
232 final LeafNode<?> absLeafrefNode = Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(absLeafrefLeaf))
233 .withValue("referenced-leaf-node-value").build();
234 final LeafNode<?> relLeafrefNode = Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(relLeafrefLeaf))
235 .withValue("referenced-leaf-node-value").build();
236 final LeafNode<?> ordinaryLeafANode = Builders.leafBuilder().withNodeIdentifier(
237 new NodeIdentifier(ordinaryLeafA)).withValue("value-a").build();
238 final LeafNode<?> ordinaryLeafBNode = Builders.leafBuilder().withNodeIdentifier(
239 new NodeIdentifier(ordinaryLeafB)).withValue("value-b").build();
241 final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(myList))
242 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
243 new NodeIdentifierWithPredicates(myList, keyValues))
244 .withChild(referencedLeafNode).build())
247 final ContainerNode myInnerContainerNode = Builders.containerBuilder().withNodeIdentifier(
248 new NodeIdentifier(myInnerContainer))
249 .withChild(absLeafrefNode)
250 .withChild(relLeafrefNode)
251 .withChild(ordinaryLeafANode)
252 .withChild(ordinaryLeafBNode).build();
254 final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
255 new NodeIdentifier(myContainer))
256 .withChild(myListNode)
257 .withChild(myInnerContainerNode).build();
258 return myContainerNode;
261 // variant for a leafref that references a leaf-list
262 private static ContainerNode buildMyContainerNodeForLeafrefTest(final LeafSetNode<?> referencedLeafListNode) {
263 final LeafNode<?> leafListLeafrefNode = Builders.leafBuilder().withNodeIdentifier(
264 new NodeIdentifier(leafListLeafrefLeaf)).withValue("referenced-node-entry-value-b").build();
266 final LeafNode<?> ordinaryLeafANode = Builders.leafBuilder().withNodeIdentifier(
267 new NodeIdentifier(ordinaryLeafA)).withValue("value-a").build();
268 final LeafNode<?> ordinaryLeafBNode = Builders.leafBuilder().withNodeIdentifier(
269 new NodeIdentifier(ordinaryLeafB)).withValue("value-b").build();
271 final ContainerNode myInnerContainerNode = Builders.containerBuilder().withNodeIdentifier(
272 new NodeIdentifier(myInnerContainer))
273 .withChild(leafListLeafrefNode)
274 .withChild(ordinaryLeafANode)
275 .withChild(ordinaryLeafBNode).build();
277 final Map<QName, Object> keyValues = ImmutableMap.of(keyLeafA, "value-a", keyLeafB, "value-b");
279 final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(myList))
280 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
281 new NodeIdentifierWithPredicates(myList, keyValues))
282 .withChild(referencedLeafListNode).build())
285 final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
286 new NodeIdentifier(myContainer))
287 .withChild(myListNode)
288 .withChild(myInnerContainerNode).build();
289 return myContainerNode;