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;
21 import java.text.ParseException;
23 import org.jaxen.Function;
24 import org.junit.BeforeClass;
25 import org.junit.Test;
26 import org.opendaylight.yangtools.yang.common.QName;
27 import org.opendaylight.yangtools.yang.common.QNameModule;
28 import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
29 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
30 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
31 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
32 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
33 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
34 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
35 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
36 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
37 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
38 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
39 import org.opendaylight.yangtools.yang.data.api.schema.xpath.XPathDocument;
40 import org.opendaylight.yangtools.yang.data.api.schema.xpath.XPathSchemaContext;
41 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
42 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
43 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
45 public class DerefXPathFunctionTest {
47 private static JaxenSchemaContextFactory jaxenSchemaContextFactory;
49 private static QNameModule fooModule;
50 private static QName myContainer;
51 private static QName myInnerContainer;
52 private static QName myList;
53 private static QName keyLeafA;
54 private static QName keyLeafB;
55 private static QName iidLeaf;
56 private static QName referencedLeaf;
57 private static QName referencedLeafList;
58 private static QName absLeafrefLeaf;
59 private static QName relLeafrefLeaf;
60 private static QName leafListLeafrefLeaf;
61 private static QName ordinaryLeafA;
62 private static QName ordinaryLeafB;
65 public static void setup() throws ParseException {
66 jaxenSchemaContextFactory = new JaxenSchemaContextFactory();
68 fooModule = QNameModule.create(URI.create("foo-ns"),
69 SimpleDateFormatUtil.getRevisionFormat().parse("2017-04-03"));
70 myContainer = QName.create(fooModule, "my-container");
71 myInnerContainer = QName.create(fooModule, "my-inner-container");
72 myList = QName.create(fooModule, "my-list");
73 keyLeafA = QName.create(fooModule, "key-leaf-a");
74 keyLeafB = QName.create(fooModule, "key-leaf-b");
75 iidLeaf = QName.create(fooModule, "iid-leaf");
76 referencedLeaf = QName.create(fooModule, "referenced-leaf");
77 referencedLeafList = QName.create(fooModule, "referenced-leaf-list");
78 absLeafrefLeaf = QName.create(fooModule, "abs-leafref-leaf");
79 relLeafrefLeaf = QName.create(fooModule, "rel-leafref-leaf");
80 leafListLeafrefLeaf = QName.create(fooModule, "leaf-list-leafref-leaf");
81 ordinaryLeafA = QName.create(fooModule, "ordinary-leaf-a");
82 ordinaryLeafB = QName.create(fooModule, "ordinary-leaf-b");
86 public void testDerefFunctionForInstanceIdentifier() throws Exception {
87 final SchemaContext schemaContext = YangParserTestUtils.parseYangSource(
88 "/yang-xpath-functions-test/deref-function-iid/foo.yang");
89 assertNotNull(schemaContext);
91 final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
93 final LeafNode<?> referencedLeafNode = Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(referencedLeaf))
94 .withValue("referenced-leaf-node-value").build();
96 final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForIIdTest(referencedLeafNode));
98 final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
99 converterBiMap.put("foo-prefix", fooModule);
101 final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
102 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
104 final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(
105 buildPathToIIdLeafNode());
107 final Function derefFunction = normalizedNodeContextSupport.getFunctionContext()
108 .getFunction(null, null, "deref");
109 final Object derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
110 assertNotNull(derefResult);
111 assertTrue(derefResult instanceof NormalizedNode<?, ?>);
112 assertSame(referencedLeafNode, derefResult);
116 public void testDerefFunctionForLeafref() throws Exception {
117 // tests absolute and relative leafref that references a leaf node
118 final SchemaContext schemaContext = YangParserTestUtils.parseYangSource(
119 "/yang-xpath-functions-test/deref-function-leafref/foo.yang");
120 assertNotNull(schemaContext);
122 final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
124 final LeafNode<?> referencedLeafNode = Builders.leafBuilder().withNodeIdentifier(
125 new NodeIdentifier(referencedLeaf)).withValue("referenced-leaf-node-value").build();
127 final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForLeafrefTest(
128 referencedLeafNode));
130 final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
131 converterBiMap.put("foo-prefix", fooModule);
133 final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
134 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
136 final YangInstanceIdentifier absLeafrefPath = YangInstanceIdentifier.of(myInnerContainer).node(absLeafrefLeaf);
137 NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(absLeafrefPath);
139 final Function derefFunction = normalizedNodeContextSupport.getFunctionContext()
140 .getFunction(null, null, "deref");
141 Object derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
142 assertNotNull(derefResult);
143 assertTrue(derefResult instanceof NormalizedNode<?, ?>);
144 assertSame(referencedLeafNode, derefResult);
146 final YangInstanceIdentifier relLeafrefPath = YangInstanceIdentifier.of(myInnerContainer).node(relLeafrefLeaf);
147 normalizedNodeContext = normalizedNodeContextSupport.createContext(relLeafrefPath);
149 derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
150 assertNotNull(derefResult);
151 assertTrue(derefResult instanceof NormalizedNode<?, ?>);
152 assertSame(referencedLeafNode, derefResult);
156 public void testDerefFunctionForLeafref2() throws Exception {
157 // tests leafref that references a leaf-list node
158 final SchemaContext schemaContext = YangParserTestUtils.parseYangSource(
159 "/yang-xpath-functions-test/deref-function-leafref/foo.yang");
160 assertNotNull(schemaContext);
162 final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
164 final LeafSetNode<?> referencedLeafListNode = Builders.leafSetBuilder().withNodeIdentifier(
165 new NodeIdentifier(referencedLeafList))
166 .withChild(Builders.leafSetEntryBuilder().withNodeIdentifier(
167 new NodeWithValue<>(referencedLeafList, "referenced-node-entry-value-a"))
168 .withValue("referenced-node-entry-value-a").build())
169 .withChild(Builders.leafSetEntryBuilder().withNodeIdentifier(
170 new NodeWithValue<>(referencedLeafList, "referenced-node-entry-value-b"))
171 .withValue("referenced-node-entry-value-b").build())
172 .withChild(Builders.leafSetEntryBuilder().withNodeIdentifier(
173 new NodeWithValue<>(referencedLeafList, "referenced-node-entry-value-c"))
174 .withValue("referenced-node-entry-value-c").build())
177 final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForLeafrefTest(
178 referencedLeafListNode));
180 final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
181 converterBiMap.put("foo-prefix", fooModule);
183 final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
184 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
186 final YangInstanceIdentifier leafListLeafrefPath = YangInstanceIdentifier.of(myInnerContainer)
187 .node(leafListLeafrefLeaf);
188 final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport
189 .createContext(leafListLeafrefPath);
191 final Function derefFunction = normalizedNodeContextSupport.getFunctionContext()
192 .getFunction(null, null, "deref");
193 Object derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
194 assertNotNull(derefResult);
195 assertTrue(derefResult instanceof NormalizedNode<?, ?>);
197 final LeafSetEntryNode<?> referencedLeafListNodeEntry = referencedLeafListNode.getChild(
198 new NodeWithValue<>(referencedLeafList, "referenced-node-entry-value-b")).get();
199 assertSame(referencedLeafListNodeEntry, derefResult);
202 private static ContainerNode buildMyContainerNodeForIIdTest(final LeafNode<?> referencedLeafNode) {
203 final Map<QName, Object> keyValues = ImmutableMap.of(keyLeafA, "key-value-a", keyLeafB, "key-value-b");
204 final YangInstanceIdentifier iidPath = YangInstanceIdentifier.of(myContainer).node(myList)
205 .node(new NodeIdentifierWithPredicates(myList, keyValues)).node(referencedLeaf);
207 final LeafNode<?> iidLeafNode = Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(iidLeaf))
208 .withValue(iidPath).build();
210 final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(myList))
211 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
212 new NodeIdentifierWithPredicates(myList, keyValues))
213 .withChild(iidLeafNode)
214 .withChild(referencedLeafNode).build())
217 final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
218 new NodeIdentifier(myContainer)).withChild(myListNode).build();
219 return myContainerNode;
222 private static YangInstanceIdentifier buildPathToIIdLeafNode() {
223 final Map<QName, Object> keyValues = ImmutableMap.of(keyLeafA, "key-value-a", keyLeafB, "key-value-b");
224 final YangInstanceIdentifier path = YangInstanceIdentifier.of(myList)
225 .node(new NodeIdentifierWithPredicates(myList, keyValues)).node(iidLeaf);
229 // variant for a leafref that references a leaf
230 private static ContainerNode buildMyContainerNodeForLeafrefTest(final LeafNode<?> referencedLeafNode) {
231 final Map<QName, Object> keyValues = ImmutableMap.of(keyLeafA, "value-a", keyLeafB, "value-b");
233 final LeafNode<?> absLeafrefNode = Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(absLeafrefLeaf))
234 .withValue("referenced-leaf-node-value").build();
235 final LeafNode<?> relLeafrefNode = Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(relLeafrefLeaf))
236 .withValue("referenced-leaf-node-value").build();
237 final LeafNode<?> ordinaryLeafANode = Builders.leafBuilder().withNodeIdentifier(
238 new NodeIdentifier(ordinaryLeafA)).withValue("value-a").build();
239 final LeafNode<?> ordinaryLeafBNode = Builders.leafBuilder().withNodeIdentifier(
240 new NodeIdentifier(ordinaryLeafB)).withValue("value-b").build();
242 final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(myList))
243 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
244 new NodeIdentifierWithPredicates(myList, keyValues))
245 .withChild(referencedLeafNode).build())
248 final ContainerNode myInnerContainerNode = Builders.containerBuilder().withNodeIdentifier(
249 new NodeIdentifier(myInnerContainer))
250 .withChild(absLeafrefNode)
251 .withChild(relLeafrefNode)
252 .withChild(ordinaryLeafANode)
253 .withChild(ordinaryLeafBNode).build();
255 final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
256 new NodeIdentifier(myContainer))
257 .withChild(myListNode)
258 .withChild(myInnerContainerNode).build();
259 return myContainerNode;
262 // variant for a leafref that references a leaf-list
263 private static ContainerNode buildMyContainerNodeForLeafrefTest(final LeafSetNode<?> referencedLeafListNode) {
264 final LeafNode<?> leafListLeafrefNode = Builders.leafBuilder().withNodeIdentifier(
265 new NodeIdentifier(leafListLeafrefLeaf)).withValue("referenced-node-entry-value-b").build();
267 final LeafNode<?> ordinaryLeafANode = Builders.leafBuilder().withNodeIdentifier(
268 new NodeIdentifier(ordinaryLeafA)).withValue("value-a").build();
269 final LeafNode<?> ordinaryLeafBNode = Builders.leafBuilder().withNodeIdentifier(
270 new NodeIdentifier(ordinaryLeafB)).withValue("value-b").build();
272 final ContainerNode myInnerContainerNode = Builders.containerBuilder().withNodeIdentifier(
273 new NodeIdentifier(myInnerContainer))
274 .withChild(leafListLeafrefNode)
275 .withChild(ordinaryLeafANode)
276 .withChild(ordinaryLeafBNode).build();
278 final Map<QName, Object> keyValues = ImmutableMap.of(keyLeafA, "value-a", keyLeafB, "value-b");
280 final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(myList))
281 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
282 new NodeIdentifierWithPredicates(myList, keyValues))
283 .withChild(referencedLeafListNode).build())
286 final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
287 new NodeIdentifier(myContainer))
288 .withChild(myListNode)
289 .withChild(myInnerContainerNode).build();
290 return myContainerNode;