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;
22 import org.jaxen.Function;
23 import org.junit.Test;
24 import org.opendaylight.yangtools.yang.common.QName;
25 import org.opendaylight.yangtools.yang.common.QNameModule;
26 import org.opendaylight.yangtools.yang.common.Revision;
27 import org.opendaylight.yangtools.yang.common.XMLNamespace;
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.NormalizedNode;
36 import org.opendaylight.yangtools.yang.data.api.schema.SystemLeafSetNode;
37 import org.opendaylight.yangtools.yang.data.api.schema.SystemMapNode;
38 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
39 import org.opendaylight.yangtools.yang.data.jaxen.api.XPathDocument;
40 import org.opendaylight.yangtools.yang.data.jaxen.api.XPathSchemaContext;
41 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
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 =
49 QNameModule.create(XMLNamespace.of("foo-ns"), Revision.of("2017-04-03"));
50 private static final QName MY_CONTAINER = QName.create(FOO_MODULE, "my-container");
51 private static final QName MY_INNER_CONTAINER = QName.create(FOO_MODULE, "my-inner-container");
52 private static final QName MY_LIST = QName.create(FOO_MODULE, "my-list");
53 private static final QName KEY_LEAF_A = QName.create(FOO_MODULE, "key-leaf-a");
54 private static final QName KEY_LEAF_B = QName.create(FOO_MODULE, "key-leaf-b");
55 private static final QName IID_LEAF = QName.create(FOO_MODULE, "iid-leaf");
56 private static final QName REFERENCED_LEAF = QName.create(FOO_MODULE, "referenced-leaf");
57 private static final QName REFERENCED_LEAFLIST = QName.create(FOO_MODULE, "referenced-leaf-list");
58 private static final QName ABS_LEAFREF_LEAF = QName.create(FOO_MODULE, "abs-leafref-leaf");
59 private static final QName REL_LEAFREF_LEAF = QName.create(FOO_MODULE, "rel-leafref-leaf");
60 private static final QName LEAFLIST_LEAFREF_LEAF = QName.create(FOO_MODULE, "leaf-list-leafref-leaf");
61 private static final QName ORDINARY_LEAF_A = QName.create(FOO_MODULE, "ordinary-leaf-a");
62 private static final QName ORDINARY_LEAF_B = QName.create(FOO_MODULE, "ordinary-leaf-b");
65 public void testDerefFunctionForInstanceIdentifier() throws Exception {
66 final EffectiveModelContext schemaContext = YangParserTestUtils.parseYangResources(DerefXPathFunctionTest.class,
67 "/yang-xpath-functions-test/deref-function-iid/foo.yang");
68 assertNotNull(schemaContext);
70 final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
72 final LeafNode<?> referencedLeafNode = Builders.leafBuilder().withNodeIdentifier(
73 new NodeIdentifier(REFERENCED_LEAF)).withValue("referenced-leaf-node-value").build();
75 final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForIIdTest(
78 final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
79 converterBiMap.put("foo-prefix", FOO_MODULE);
81 final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
82 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
84 final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(
85 buildPathToIIdLeafNode());
87 final Function derefFunction = normalizedNodeContextSupport.getFunctionContext()
88 .getFunction(null, null, "deref");
89 final Object derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
90 assertNotNull(derefResult);
91 assertTrue(derefResult instanceof LeafNode<?>);
92 assertEquals(referencedLeafNode, derefResult);
96 public void testDerefFunctionForLeafref() throws Exception {
97 // tests absolute and relative leafref that references a leaf node
98 final EffectiveModelContext schemaContext = YangParserTestUtils.parseYangResources(DerefXPathFunctionTest.class,
99 "/yang-xpath-functions-test/deref-function-leafref/foo.yang");
100 assertNotNull(schemaContext);
102 final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
104 final LeafNode<?> referencedLeafNode = Builders.leafBuilder().withNodeIdentifier(
105 new NodeIdentifier(REFERENCED_LEAF)).withValue("referenced-leaf-node-value").build();
107 final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForLeafrefTest(
108 referencedLeafNode));
110 final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
111 converterBiMap.put("foo-prefix", FOO_MODULE);
113 final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
114 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
116 final YangInstanceIdentifier absLeafrefPath = YangInstanceIdentifier.of(MY_INNER_CONTAINER)
117 .node(ABS_LEAFREF_LEAF);
118 NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(absLeafrefPath);
120 final Function derefFunction = normalizedNodeContextSupport.getFunctionContext()
121 .getFunction(null, null, "deref");
122 Object derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
123 assertNotNull(derefResult);
124 assertTrue(derefResult instanceof LeafNode<?>);
125 assertEquals(referencedLeafNode, derefResult);
127 final YangInstanceIdentifier relLeafrefPath = YangInstanceIdentifier.of(MY_INNER_CONTAINER)
128 .node(REL_LEAFREF_LEAF);
129 normalizedNodeContext = normalizedNodeContextSupport.createContext(relLeafrefPath);
131 derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
132 assertNotNull(derefResult);
133 assertTrue(derefResult instanceof LeafNode<?>);
134 assertEquals(referencedLeafNode, derefResult);
138 public void testDerefFunctionForLeafref2() throws Exception {
139 // tests leafref that references a leaf-list node
140 final EffectiveModelContext schemaContext = YangParserTestUtils.parseYangResources(DerefXPathFunctionTest.class,
141 "/yang-xpath-functions-test/deref-function-leafref/foo.yang");
142 assertNotNull(schemaContext);
144 final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
146 final SystemLeafSetNode<?> referencedLeafListNode = Builders.leafSetBuilder()
147 .withNodeIdentifier(new NodeIdentifier(REFERENCED_LEAFLIST))
148 .withChild(Builders.leafSetEntryBuilder().withNodeIdentifier(
149 new NodeWithValue<>(REFERENCED_LEAFLIST, "referenced-node-entry-value-a"))
150 .withValue("referenced-node-entry-value-a").build())
151 .withChild(Builders.leafSetEntryBuilder().withNodeIdentifier(
152 new NodeWithValue<>(REFERENCED_LEAFLIST, "referenced-node-entry-value-b"))
153 .withValue("referenced-node-entry-value-b").build())
154 .withChild(Builders.leafSetEntryBuilder().withNodeIdentifier(
155 new NodeWithValue<>(REFERENCED_LEAFLIST, "referenced-node-entry-value-c"))
156 .withValue("referenced-node-entry-value-c").build())
159 final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForLeafrefTest(
160 referencedLeafListNode));
162 final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
163 converterBiMap.put("foo-prefix", FOO_MODULE);
165 final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
166 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
168 final YangInstanceIdentifier leafListLeafrefPath = YangInstanceIdentifier.of(MY_INNER_CONTAINER)
169 .node(LEAFLIST_LEAFREF_LEAF);
170 final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport
171 .createContext(leafListLeafrefPath);
173 final Function derefFunction = normalizedNodeContextSupport.getFunctionContext()
174 .getFunction(null, null, "deref");
175 Object derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
176 assertNotNull(derefResult);
177 assertTrue(derefResult instanceof NormalizedNode);
179 final LeafSetEntryNode<?> referencedLeafListNodeEntry = referencedLeafListNode.childByArg(
180 new NodeWithValue<>(REFERENCED_LEAFLIST, "referenced-node-entry-value-b"));
181 assertSame(referencedLeafListNodeEntry, derefResult);
184 private static ContainerNode buildMyContainerNodeForIIdTest(final LeafNode<?> referencedLeafNode) {
185 final Map<QName, Object> keyValues = ImmutableMap.of(KEY_LEAF_A, "key-value-a", KEY_LEAF_B, "key-value-b");
186 final YangInstanceIdentifier iidPath = YangInstanceIdentifier.of(MY_CONTAINER).node(MY_LIST)
187 .node(NodeIdentifierWithPredicates.of(MY_LIST, keyValues)).node(REFERENCED_LEAF);
189 final LeafNode<?> iidLeafNode = Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(IID_LEAF))
190 .withValue(iidPath).build();
192 final SystemMapNode myListNode = Builders.mapBuilder()
193 .withNodeIdentifier(new NodeIdentifier(MY_LIST))
194 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
195 NodeIdentifierWithPredicates.of(MY_LIST, keyValues))
196 .withChild(iidLeafNode)
197 .withChild(referencedLeafNode).build())
200 final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
201 new NodeIdentifier(MY_CONTAINER)).withChild(myListNode).build();
202 return myContainerNode;
205 private static YangInstanceIdentifier buildPathToIIdLeafNode() {
206 final Map<QName, Object> keyValues = ImmutableMap.of(KEY_LEAF_A, "key-value-a", KEY_LEAF_B, "key-value-b");
207 final YangInstanceIdentifier path = YangInstanceIdentifier.of(MY_LIST)
208 .node(NodeIdentifierWithPredicates.of(MY_LIST, keyValues)).node(IID_LEAF);
212 // variant for a leafref that references a leaf
213 private static ContainerNode buildMyContainerNodeForLeafrefTest(final LeafNode<?> referencedLeafNode) {
214 final Map<QName, Object> keyValues = ImmutableMap.of(KEY_LEAF_A, "value-a", KEY_LEAF_B, "value-b");
216 final LeafNode<?> absLeafrefNode = Builders.leafBuilder()
217 .withNodeIdentifier(new NodeIdentifier(ABS_LEAFREF_LEAF))
218 .withValue("referenced-leaf-node-value").build();
219 final LeafNode<?> relLeafrefNode = Builders.leafBuilder()
220 .withNodeIdentifier(new NodeIdentifier(REL_LEAFREF_LEAF))
221 .withValue("referenced-leaf-node-value").build();
222 final LeafNode<?> ordinaryLeafANode = Builders.leafBuilder().withNodeIdentifier(
223 new NodeIdentifier(ORDINARY_LEAF_A)).withValue("value-a").build();
224 final LeafNode<?> ordinaryLeafBNode = Builders.leafBuilder().withNodeIdentifier(
225 new NodeIdentifier(ORDINARY_LEAF_B)).withValue("value-b").build();
227 final SystemMapNode myListNode = Builders.mapBuilder()
228 .withNodeIdentifier(new NodeIdentifier(MY_LIST))
229 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
230 NodeIdentifierWithPredicates.of(MY_LIST, keyValues))
231 .withChild(referencedLeafNode).build())
234 final ContainerNode myInnerContainerNode = Builders.containerBuilder().withNodeIdentifier(
235 new NodeIdentifier(MY_INNER_CONTAINER))
236 .withChild(absLeafrefNode)
237 .withChild(relLeafrefNode)
238 .withChild(ordinaryLeafANode)
239 .withChild(ordinaryLeafBNode).build();
241 final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
242 new NodeIdentifier(MY_CONTAINER))
243 .withChild(myListNode)
244 .withChild(myInnerContainerNode).build();
245 return myContainerNode;
248 // variant for a leafref that references a leaf-list
249 private static ContainerNode buildMyContainerNodeForLeafrefTest(final SystemLeafSetNode<?> referencedLeafListNode) {
250 final LeafNode<?> leafListLeafrefNode = Builders.leafBuilder().withNodeIdentifier(
251 new NodeIdentifier(LEAFLIST_LEAFREF_LEAF)).withValue("referenced-node-entry-value-b").build();
253 final LeafNode<?> ordinaryLeafANode = Builders.leafBuilder().withNodeIdentifier(
254 new NodeIdentifier(ORDINARY_LEAF_A)).withValue("value-a").build();
255 final LeafNode<?> ordinaryLeafBNode = Builders.leafBuilder().withNodeIdentifier(
256 new NodeIdentifier(ORDINARY_LEAF_B)).withValue("value-b").build();
258 final ContainerNode myInnerContainerNode = Builders.containerBuilder().withNodeIdentifier(
259 new NodeIdentifier(MY_INNER_CONTAINER))
260 .withChild(leafListLeafrefNode)
261 .withChild(ordinaryLeafANode)
262 .withChild(ordinaryLeafBNode).build();
264 final Map<QName, Object> keyValues = ImmutableMap.of(KEY_LEAF_A, "value-a", KEY_LEAF_B, "value-b");
265 final SystemMapNode myListNode = Builders.mapBuilder()
266 .withNodeIdentifier(new NodeIdentifier(MY_LIST))
267 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
268 NodeIdentifierWithPredicates.of(MY_LIST, keyValues))
269 .withChild(referencedLeafListNode).build())
272 final ContainerNode myContainerNode = Builders.containerBuilder()
273 .withNodeIdentifier(new NodeIdentifier(MY_CONTAINER))
274 .withChild(myListNode)
275 .withChild(myInnerContainerNode).build();
276 return myContainerNode;