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.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.data.api.YangInstanceIdentifier;
28 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
29 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
30 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
31 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
32 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
33 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
34 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
35 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
36 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
37 import org.opendaylight.yangtools.yang.data.api.schema.xpath.XPathDocument;
38 import org.opendaylight.yangtools.yang.data.api.schema.xpath.XPathSchemaContext;
39 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
40 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
41 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
43 public class DerefXPathFunctionTest {
45 private static JaxenSchemaContextFactory jaxenSchemaContextFactory = new JaxenSchemaContextFactory();
47 private static final QNameModule FOO_MODULE = QNameModule.create(URI.create("foo-ns"), Revision.of("2017-04-03"));
48 private static final QName MY_CONTAINER = QName.create(FOO_MODULE, "my-container");
49 private static final QName MY_INNER_CONTAINER = QName.create(FOO_MODULE, "my-inner-container");
50 private static final QName MY_LIST = QName.create(FOO_MODULE, "my-list");
51 private static final QName KEY_LEAF_A = QName.create(FOO_MODULE, "key-leaf-a");
52 private static final QName KEY_LEAF_B = QName.create(FOO_MODULE, "key-leaf-b");
53 private static final QName IID_LEAF = QName.create(FOO_MODULE, "iid-leaf");
54 private static final QName REFERENCED_LEAF = QName.create(FOO_MODULE, "referenced-leaf");
55 private static final QName REFERENCED_LEAFLIST = QName.create(FOO_MODULE, "referenced-leaf-list");
56 private static final QName ABS_LEAFREF_LEAF = QName.create(FOO_MODULE, "abs-leafref-leaf");
57 private static final QName REL_LEAFREF_LEAF = QName.create(FOO_MODULE, "rel-leafref-leaf");
58 private static final QName LEAFLIST_LEAFREF_LEAF = QName.create(FOO_MODULE, "leaf-list-leafref-leaf");
59 private static final QName ORDINARY_LEAF_A = QName.create(FOO_MODULE, "ordinary-leaf-a");
60 private static final QName ORDINARY_LEAF_B = QName.create(FOO_MODULE, "ordinary-leaf-b");
63 public void testDerefFunctionForInstanceIdentifier() throws Exception {
64 final SchemaContext schemaContext = YangParserTestUtils.parseYangResources(DerefXPathFunctionTest.class,
65 "/yang-xpath-functions-test/deref-function-iid/foo.yang");
66 assertNotNull(schemaContext);
68 final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
70 final LeafNode<?> referencedLeafNode = Builders.leafBuilder().withNodeIdentifier(
71 new NodeIdentifier(REFERENCED_LEAF)).withValue("referenced-leaf-node-value").build();
73 final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForIIdTest(
76 final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
77 converterBiMap.put("foo-prefix", FOO_MODULE);
79 final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
80 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
82 final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(
83 buildPathToIIdLeafNode());
85 final Function derefFunction = normalizedNodeContextSupport.getFunctionContext()
86 .getFunction(null, null, "deref");
87 final Object derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
88 assertNotNull(derefResult);
89 assertTrue(derefResult instanceof NormalizedNode<?, ?>);
90 assertSame(referencedLeafNode, derefResult);
94 public void testDerefFunctionForLeafref() throws Exception {
95 // tests absolute and relative leafref that references a leaf node
96 final SchemaContext schemaContext = YangParserTestUtils.parseYangResources(DerefXPathFunctionTest.class,
97 "/yang-xpath-functions-test/deref-function-leafref/foo.yang");
98 assertNotNull(schemaContext);
100 final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
102 final LeafNode<?> referencedLeafNode = Builders.leafBuilder().withNodeIdentifier(
103 new NodeIdentifier(REFERENCED_LEAF)).withValue("referenced-leaf-node-value").build();
105 final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForLeafrefTest(
106 referencedLeafNode));
108 final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
109 converterBiMap.put("foo-prefix", FOO_MODULE);
111 final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
112 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
114 final YangInstanceIdentifier absLeafrefPath = YangInstanceIdentifier.of(MY_INNER_CONTAINER)
115 .node(ABS_LEAFREF_LEAF);
116 NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(absLeafrefPath);
118 final Function derefFunction = normalizedNodeContextSupport.getFunctionContext()
119 .getFunction(null, null, "deref");
120 Object derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
121 assertNotNull(derefResult);
122 assertTrue(derefResult instanceof NormalizedNode<?, ?>);
123 assertSame(referencedLeafNode, derefResult);
125 final YangInstanceIdentifier relLeafrefPath = YangInstanceIdentifier.of(MY_INNER_CONTAINER)
126 .node(REL_LEAFREF_LEAF);
127 normalizedNodeContext = normalizedNodeContextSupport.createContext(relLeafrefPath);
129 derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
130 assertNotNull(derefResult);
131 assertTrue(derefResult instanceof NormalizedNode<?, ?>);
132 assertSame(referencedLeafNode, derefResult);
136 public void testDerefFunctionForLeafref2() throws Exception {
137 // tests leafref that references a leaf-list node
138 final SchemaContext schemaContext = YangParserTestUtils.parseYangResources(DerefXPathFunctionTest.class,
139 "/yang-xpath-functions-test/deref-function-leafref/foo.yang");
140 assertNotNull(schemaContext);
142 final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
144 final LeafSetNode<?> referencedLeafListNode = Builders.leafSetBuilder().withNodeIdentifier(
145 new NodeIdentifier(REFERENCED_LEAFLIST))
146 .withChild(Builders.leafSetEntryBuilder().withNodeIdentifier(
147 new NodeWithValue<>(REFERENCED_LEAFLIST, "referenced-node-entry-value-a"))
148 .withValue("referenced-node-entry-value-a").build())
149 .withChild(Builders.leafSetEntryBuilder().withNodeIdentifier(
150 new NodeWithValue<>(REFERENCED_LEAFLIST, "referenced-node-entry-value-b"))
151 .withValue("referenced-node-entry-value-b").build())
152 .withChild(Builders.leafSetEntryBuilder().withNodeIdentifier(
153 new NodeWithValue<>(REFERENCED_LEAFLIST, "referenced-node-entry-value-c"))
154 .withValue("referenced-node-entry-value-c").build())
157 final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForLeafrefTest(
158 referencedLeafListNode));
160 final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
161 converterBiMap.put("foo-prefix", FOO_MODULE);
163 final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
164 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
166 final YangInstanceIdentifier leafListLeafrefPath = YangInstanceIdentifier.of(MY_INNER_CONTAINER)
167 .node(LEAFLIST_LEAFREF_LEAF);
168 final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport
169 .createContext(leafListLeafrefPath);
171 final Function derefFunction = normalizedNodeContextSupport.getFunctionContext()
172 .getFunction(null, null, "deref");
173 Object derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
174 assertNotNull(derefResult);
175 assertTrue(derefResult instanceof NormalizedNode<?, ?>);
177 final LeafSetEntryNode<?> referencedLeafListNodeEntry = referencedLeafListNode.getChild(
178 new NodeWithValue<>(REFERENCED_LEAFLIST, "referenced-node-entry-value-b")).get();
179 assertSame(referencedLeafListNodeEntry, derefResult);
182 private static ContainerNode buildMyContainerNodeForIIdTest(final LeafNode<?> referencedLeafNode) {
183 final Map<QName, Object> keyValues = ImmutableMap.of(KEY_LEAF_A, "key-value-a", KEY_LEAF_B, "key-value-b");
184 final YangInstanceIdentifier iidPath = YangInstanceIdentifier.of(MY_CONTAINER).node(MY_LIST)
185 .node(NodeIdentifierWithPredicates.of(MY_LIST, keyValues)).node(REFERENCED_LEAF);
187 final LeafNode<?> iidLeafNode = Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(IID_LEAF))
188 .withValue(iidPath).build();
190 final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(MY_LIST))
191 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
192 NodeIdentifierWithPredicates.of(MY_LIST, keyValues))
193 .withChild(iidLeafNode)
194 .withChild(referencedLeafNode).build())
197 final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
198 new NodeIdentifier(MY_CONTAINER)).withChild(myListNode).build();
199 return myContainerNode;
202 private static YangInstanceIdentifier buildPathToIIdLeafNode() {
203 final Map<QName, Object> keyValues = ImmutableMap.of(KEY_LEAF_A, "key-value-a", KEY_LEAF_B, "key-value-b");
204 final YangInstanceIdentifier path = YangInstanceIdentifier.of(MY_LIST)
205 .node(NodeIdentifierWithPredicates.of(MY_LIST, keyValues)).node(IID_LEAF);
209 // variant for a leafref that references a leaf
210 private static ContainerNode buildMyContainerNodeForLeafrefTest(final LeafNode<?> referencedLeafNode) {
211 final Map<QName, Object> keyValues = ImmutableMap.of(KEY_LEAF_A, "value-a", KEY_LEAF_B, "value-b");
213 final LeafNode<?> absLeafrefNode = Builders.leafBuilder()
214 .withNodeIdentifier(new NodeIdentifier(ABS_LEAFREF_LEAF))
215 .withValue("referenced-leaf-node-value").build();
216 final LeafNode<?> relLeafrefNode = Builders.leafBuilder()
217 .withNodeIdentifier(new NodeIdentifier(REL_LEAFREF_LEAF))
218 .withValue("referenced-leaf-node-value").build();
219 final LeafNode<?> ordinaryLeafANode = Builders.leafBuilder().withNodeIdentifier(
220 new NodeIdentifier(ORDINARY_LEAF_A)).withValue("value-a").build();
221 final LeafNode<?> ordinaryLeafBNode = Builders.leafBuilder().withNodeIdentifier(
222 new NodeIdentifier(ORDINARY_LEAF_B)).withValue("value-b").build();
224 final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(MY_LIST))
225 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
226 NodeIdentifierWithPredicates.of(MY_LIST, keyValues))
227 .withChild(referencedLeafNode).build())
230 final ContainerNode myInnerContainerNode = Builders.containerBuilder().withNodeIdentifier(
231 new NodeIdentifier(MY_INNER_CONTAINER))
232 .withChild(absLeafrefNode)
233 .withChild(relLeafrefNode)
234 .withChild(ordinaryLeafANode)
235 .withChild(ordinaryLeafBNode).build();
237 final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
238 new NodeIdentifier(MY_CONTAINER))
239 .withChild(myListNode)
240 .withChild(myInnerContainerNode).build();
241 return myContainerNode;
244 // variant for a leafref that references a leaf-list
245 private static ContainerNode buildMyContainerNodeForLeafrefTest(final LeafSetNode<?> referencedLeafListNode) {
246 final LeafNode<?> leafListLeafrefNode = Builders.leafBuilder().withNodeIdentifier(
247 new NodeIdentifier(LEAFLIST_LEAFREF_LEAF)).withValue("referenced-node-entry-value-b").build();
249 final LeafNode<?> ordinaryLeafANode = Builders.leafBuilder().withNodeIdentifier(
250 new NodeIdentifier(ORDINARY_LEAF_A)).withValue("value-a").build();
251 final LeafNode<?> ordinaryLeafBNode = Builders.leafBuilder().withNodeIdentifier(
252 new NodeIdentifier(ORDINARY_LEAF_B)).withValue("value-b").build();
254 final ContainerNode myInnerContainerNode = Builders.containerBuilder().withNodeIdentifier(
255 new NodeIdentifier(MY_INNER_CONTAINER))
256 .withChild(leafListLeafrefNode)
257 .withChild(ordinaryLeafANode)
258 .withChild(ordinaryLeafBNode).build();
260 final Map<QName, Object> keyValues = ImmutableMap.of(KEY_LEAF_A, "value-a", KEY_LEAF_B, "value-b");
262 final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(MY_LIST))
263 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
264 NodeIdentifierWithPredicates.of(MY_LIST, keyValues))
265 .withChild(referencedLeafListNode).build())
268 final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
269 new NodeIdentifier(MY_CONTAINER))
270 .withChild(myListNode)
271 .withChild(myInnerContainerNode).build();
272 return myContainerNode;