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.assertEquals;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertSame;
14 import static org.junit.Assert.assertTrue;
16 import com.google.common.collect.BiMap;
17 import com.google.common.collect.HashBiMap;
18 import com.google.common.collect.ImmutableList;
19 import com.google.common.collect.ImmutableMap;
20 import com.google.common.collect.Maps;
23 import org.jaxen.Function;
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 = new JaxenSchemaContextFactory();
48 private static final QNameModule FOO_MODULE = QNameModule.create(URI.create("foo-ns"), Revision.of("2017-04-03"));
49 private static final QName MY_CONTAINER = QName.create(FOO_MODULE, "my-container");
50 private static final QName MY_INNER_CONTAINER = QName.create(FOO_MODULE, "my-inner-container");
51 private static final QName MY_LIST = QName.create(FOO_MODULE, "my-list");
52 private static final QName KEY_LEAF_A = QName.create(FOO_MODULE, "key-leaf-a");
53 private static final QName KEY_LEAF_B = QName.create(FOO_MODULE, "key-leaf-b");
54 private static final QName IID_LEAF = QName.create(FOO_MODULE, "iid-leaf");
55 private static final QName REFERENCED_LEAF = QName.create(FOO_MODULE, "referenced-leaf");
56 private static final QName REFERENCED_LEAFLIST = QName.create(FOO_MODULE, "referenced-leaf-list");
57 private static final QName ABS_LEAFREF_LEAF = QName.create(FOO_MODULE, "abs-leafref-leaf");
58 private static final QName REL_LEAFREF_LEAF = QName.create(FOO_MODULE, "rel-leafref-leaf");
59 private static final QName LEAFLIST_LEAFREF_LEAF = QName.create(FOO_MODULE, "leaf-list-leafref-leaf");
60 private static final QName ORDINARY_LEAF_A = QName.create(FOO_MODULE, "ordinary-leaf-a");
61 private static final QName ORDINARY_LEAF_B = QName.create(FOO_MODULE, "ordinary-leaf-b");
64 public void testDerefFunctionForInstanceIdentifier() throws Exception {
65 final SchemaContext schemaContext = YangParserTestUtils.parseYangResources(DerefXPathFunctionTest.class,
66 "/yang-xpath-functions-test/deref-function-iid/foo.yang");
67 assertNotNull(schemaContext);
69 final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
71 final LeafNode<?> referencedLeafNode = Builders.leafBuilder().withNodeIdentifier(
72 new NodeIdentifier(REFERENCED_LEAF)).withValue("referenced-leaf-node-value").build();
74 final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForIIdTest(
77 final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
78 converterBiMap.put("foo-prefix", FOO_MODULE);
80 final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
81 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
83 final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(
84 buildPathToIIdLeafNode());
86 final Function derefFunction = normalizedNodeContextSupport.getFunctionContext()
87 .getFunction(null, null, "deref");
88 final Object derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
89 assertNotNull(derefResult);
90 assertTrue(derefResult instanceof NormalizedNode<?, ?>);
91 assertEquals(referencedLeafNode, derefResult);
95 public void testDerefFunctionForLeafref() throws Exception {
96 // tests absolute and relative leafref that references a leaf node
97 final SchemaContext schemaContext = YangParserTestUtils.parseYangResources(DerefXPathFunctionTest.class,
98 "/yang-xpath-functions-test/deref-function-leafref/foo.yang");
99 assertNotNull(schemaContext);
101 final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
103 final LeafNode<?> referencedLeafNode = Builders.leafBuilder().withNodeIdentifier(
104 new NodeIdentifier(REFERENCED_LEAF)).withValue("referenced-leaf-node-value").build();
106 final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForLeafrefTest(
107 referencedLeafNode));
109 final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
110 converterBiMap.put("foo-prefix", FOO_MODULE);
112 final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
113 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
115 final YangInstanceIdentifier absLeafrefPath = YangInstanceIdentifier.of(MY_INNER_CONTAINER)
116 .node(ABS_LEAFREF_LEAF);
117 NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(absLeafrefPath);
119 final Function derefFunction = normalizedNodeContextSupport.getFunctionContext()
120 .getFunction(null, null, "deref");
121 Object derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
122 assertNotNull(derefResult);
123 assertTrue(derefResult instanceof NormalizedNode<?, ?>);
124 assertEquals(referencedLeafNode, derefResult);
126 final YangInstanceIdentifier relLeafrefPath = YangInstanceIdentifier.of(MY_INNER_CONTAINER)
127 .node(REL_LEAFREF_LEAF);
128 normalizedNodeContext = normalizedNodeContextSupport.createContext(relLeafrefPath);
130 derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
131 assertNotNull(derefResult);
132 assertTrue(derefResult instanceof NormalizedNode<?, ?>);
133 assertEquals(referencedLeafNode, derefResult);
137 public void testDerefFunctionForLeafref2() throws Exception {
138 // tests leafref that references a leaf-list node
139 final SchemaContext schemaContext = YangParserTestUtils.parseYangResources(DerefXPathFunctionTest.class,
140 "/yang-xpath-functions-test/deref-function-leafref/foo.yang");
141 assertNotNull(schemaContext);
143 final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
145 final LeafSetNode<?> referencedLeafListNode = Builders.leafSetBuilder().withNodeIdentifier(
146 new NodeIdentifier(REFERENCED_LEAFLIST))
147 .withChild(Builders.leafSetEntryBuilder().withNodeIdentifier(
148 new NodeWithValue<>(REFERENCED_LEAFLIST, "referenced-node-entry-value-a"))
149 .withValue("referenced-node-entry-value-a").build())
150 .withChild(Builders.leafSetEntryBuilder().withNodeIdentifier(
151 new NodeWithValue<>(REFERENCED_LEAFLIST, "referenced-node-entry-value-b"))
152 .withValue("referenced-node-entry-value-b").build())
153 .withChild(Builders.leafSetEntryBuilder().withNodeIdentifier(
154 new NodeWithValue<>(REFERENCED_LEAFLIST, "referenced-node-entry-value-c"))
155 .withValue("referenced-node-entry-value-c").build())
158 final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForLeafrefTest(
159 referencedLeafListNode));
161 final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
162 converterBiMap.put("foo-prefix", FOO_MODULE);
164 final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
165 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
167 final YangInstanceIdentifier leafListLeafrefPath = YangInstanceIdentifier.of(MY_INNER_CONTAINER)
168 .node(LEAFLIST_LEAFREF_LEAF);
169 final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport
170 .createContext(leafListLeafrefPath);
172 final Function derefFunction = normalizedNodeContextSupport.getFunctionContext()
173 .getFunction(null, null, "deref");
174 Object derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
175 assertNotNull(derefResult);
176 assertTrue(derefResult instanceof NormalizedNode<?, ?>);
178 final LeafSetEntryNode<?> referencedLeafListNodeEntry = referencedLeafListNode.getChild(
179 new NodeWithValue<>(REFERENCED_LEAFLIST, "referenced-node-entry-value-b")).get();
180 assertSame(referencedLeafListNodeEntry, derefResult);
183 private static ContainerNode buildMyContainerNodeForIIdTest(final LeafNode<?> referencedLeafNode) {
184 final Map<QName, Object> keyValues = ImmutableMap.of(KEY_LEAF_A, "key-value-a", KEY_LEAF_B, "key-value-b");
185 final YangInstanceIdentifier iidPath = YangInstanceIdentifier.of(MY_CONTAINER).node(MY_LIST)
186 .node(NodeIdentifierWithPredicates.of(MY_LIST, keyValues)).node(REFERENCED_LEAF);
188 final LeafNode<?> iidLeafNode = Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(IID_LEAF))
189 .withValue(iidPath).build();
191 final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(MY_LIST))
192 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
193 NodeIdentifierWithPredicates.of(MY_LIST, keyValues))
194 .withChild(iidLeafNode)
195 .withChild(referencedLeafNode).build())
198 final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
199 new NodeIdentifier(MY_CONTAINER)).withChild(myListNode).build();
200 return myContainerNode;
203 private static YangInstanceIdentifier buildPathToIIdLeafNode() {
204 final Map<QName, Object> keyValues = ImmutableMap.of(KEY_LEAF_A, "key-value-a", KEY_LEAF_B, "key-value-b");
205 final YangInstanceIdentifier path = YangInstanceIdentifier.of(MY_LIST)
206 .node(NodeIdentifierWithPredicates.of(MY_LIST, keyValues)).node(IID_LEAF);
210 // variant for a leafref that references a leaf
211 private static ContainerNode buildMyContainerNodeForLeafrefTest(final LeafNode<?> referencedLeafNode) {
212 final Map<QName, Object> keyValues = ImmutableMap.of(KEY_LEAF_A, "value-a", KEY_LEAF_B, "value-b");
214 final LeafNode<?> absLeafrefNode = Builders.leafBuilder()
215 .withNodeIdentifier(new NodeIdentifier(ABS_LEAFREF_LEAF))
216 .withValue("referenced-leaf-node-value").build();
217 final LeafNode<?> relLeafrefNode = Builders.leafBuilder()
218 .withNodeIdentifier(new NodeIdentifier(REL_LEAFREF_LEAF))
219 .withValue("referenced-leaf-node-value").build();
220 final LeafNode<?> ordinaryLeafANode = Builders.leafBuilder().withNodeIdentifier(
221 new NodeIdentifier(ORDINARY_LEAF_A)).withValue("value-a").build();
222 final LeafNode<?> ordinaryLeafBNode = Builders.leafBuilder().withNodeIdentifier(
223 new NodeIdentifier(ORDINARY_LEAF_B)).withValue("value-b").build();
225 final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(MY_LIST))
226 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
227 NodeIdentifierWithPredicates.of(MY_LIST, keyValues))
228 .withChild(referencedLeafNode).build())
231 final ContainerNode myInnerContainerNode = Builders.containerBuilder().withNodeIdentifier(
232 new NodeIdentifier(MY_INNER_CONTAINER))
233 .withChild(absLeafrefNode)
234 .withChild(relLeafrefNode)
235 .withChild(ordinaryLeafANode)
236 .withChild(ordinaryLeafBNode).build();
238 final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
239 new NodeIdentifier(MY_CONTAINER))
240 .withChild(myListNode)
241 .withChild(myInnerContainerNode).build();
242 return myContainerNode;
245 // variant for a leafref that references a leaf-list
246 private static ContainerNode buildMyContainerNodeForLeafrefTest(final LeafSetNode<?> referencedLeafListNode) {
247 final LeafNode<?> leafListLeafrefNode = Builders.leafBuilder().withNodeIdentifier(
248 new NodeIdentifier(LEAFLIST_LEAFREF_LEAF)).withValue("referenced-node-entry-value-b").build();
250 final LeafNode<?> ordinaryLeafANode = Builders.leafBuilder().withNodeIdentifier(
251 new NodeIdentifier(ORDINARY_LEAF_A)).withValue("value-a").build();
252 final LeafNode<?> ordinaryLeafBNode = Builders.leafBuilder().withNodeIdentifier(
253 new NodeIdentifier(ORDINARY_LEAF_B)).withValue("value-b").build();
255 final ContainerNode myInnerContainerNode = Builders.containerBuilder().withNodeIdentifier(
256 new NodeIdentifier(MY_INNER_CONTAINER))
257 .withChild(leafListLeafrefNode)
258 .withChild(ordinaryLeafANode)
259 .withChild(ordinaryLeafBNode).build();
261 final Map<QName, Object> keyValues = ImmutableMap.of(KEY_LEAF_A, "value-a", KEY_LEAF_B, "value-b");
263 final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(MY_LIST))
264 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
265 NodeIdentifierWithPredicates.of(MY_LIST, keyValues))
266 .withChild(referencedLeafListNode).build())
269 final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
270 new NodeIdentifier(MY_CONTAINER))
271 .withChild(myListNode)
272 .withChild(myInnerContainerNode).build();
273 return myContainerNode;