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.parseYangResources(DerefXPathFunctionTest.class,
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(
94 new NodeIdentifier(referencedLeaf)).withValue("referenced-leaf-node-value").build();
96 final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForIIdTest(
99 final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
100 converterBiMap.put("foo-prefix", fooModule);
102 final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
103 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
105 final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(
106 buildPathToIIdLeafNode());
108 final Function derefFunction = normalizedNodeContextSupport.getFunctionContext()
109 .getFunction(null, null, "deref");
110 final Object derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
111 assertNotNull(derefResult);
112 assertTrue(derefResult instanceof NormalizedNode<?, ?>);
113 assertSame(referencedLeafNode, derefResult);
117 public void testDerefFunctionForLeafref() throws Exception {
118 // tests absolute and relative leafref that references a leaf node
119 final SchemaContext schemaContext = YangParserTestUtils.parseYangResources(DerefXPathFunctionTest.class,
120 "/yang-xpath-functions-test/deref-function-leafref/foo.yang");
121 assertNotNull(schemaContext);
123 final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
125 final LeafNode<?> referencedLeafNode = Builders.leafBuilder().withNodeIdentifier(
126 new NodeIdentifier(referencedLeaf)).withValue("referenced-leaf-node-value").build();
128 final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForLeafrefTest(
129 referencedLeafNode));
131 final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
132 converterBiMap.put("foo-prefix", fooModule);
134 final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
135 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
137 final YangInstanceIdentifier absLeafrefPath = YangInstanceIdentifier.of(myInnerContainer).node(absLeafrefLeaf);
138 NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(absLeafrefPath);
140 final Function derefFunction = normalizedNodeContextSupport.getFunctionContext()
141 .getFunction(null, null, "deref");
142 Object derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
143 assertNotNull(derefResult);
144 assertTrue(derefResult instanceof NormalizedNode<?, ?>);
145 assertSame(referencedLeafNode, derefResult);
147 final YangInstanceIdentifier relLeafrefPath = YangInstanceIdentifier.of(myInnerContainer).node(relLeafrefLeaf);
148 normalizedNodeContext = normalizedNodeContextSupport.createContext(relLeafrefPath);
150 derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
151 assertNotNull(derefResult);
152 assertTrue(derefResult instanceof NormalizedNode<?, ?>);
153 assertSame(referencedLeafNode, derefResult);
157 public void testDerefFunctionForLeafref2() throws Exception {
158 // tests leafref that references a leaf-list node
159 final SchemaContext schemaContext = YangParserTestUtils.parseYangResources(DerefXPathFunctionTest.class,
160 "/yang-xpath-functions-test/deref-function-leafref/foo.yang");
161 assertNotNull(schemaContext);
163 final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
165 final LeafSetNode<?> referencedLeafListNode = Builders.leafSetBuilder().withNodeIdentifier(
166 new NodeIdentifier(referencedLeafList))
167 .withChild(Builders.leafSetEntryBuilder().withNodeIdentifier(
168 new NodeWithValue<>(referencedLeafList, "referenced-node-entry-value-a"))
169 .withValue("referenced-node-entry-value-a").build())
170 .withChild(Builders.leafSetEntryBuilder().withNodeIdentifier(
171 new NodeWithValue<>(referencedLeafList, "referenced-node-entry-value-b"))
172 .withValue("referenced-node-entry-value-b").build())
173 .withChild(Builders.leafSetEntryBuilder().withNodeIdentifier(
174 new NodeWithValue<>(referencedLeafList, "referenced-node-entry-value-c"))
175 .withValue("referenced-node-entry-value-c").build())
178 final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForLeafrefTest(
179 referencedLeafListNode));
181 final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
182 converterBiMap.put("foo-prefix", fooModule);
184 final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
185 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
187 final YangInstanceIdentifier leafListLeafrefPath = YangInstanceIdentifier.of(myInnerContainer)
188 .node(leafListLeafrefLeaf);
189 final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport
190 .createContext(leafListLeafrefPath);
192 final Function derefFunction = normalizedNodeContextSupport.getFunctionContext()
193 .getFunction(null, null, "deref");
194 Object derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
195 assertNotNull(derefResult);
196 assertTrue(derefResult instanceof NormalizedNode<?, ?>);
198 final LeafSetEntryNode<?> referencedLeafListNodeEntry = referencedLeafListNode.getChild(
199 new NodeWithValue<>(referencedLeafList, "referenced-node-entry-value-b")).get();
200 assertSame(referencedLeafListNodeEntry, derefResult);
203 private static ContainerNode buildMyContainerNodeForIIdTest(final LeafNode<?> referencedLeafNode) {
204 final Map<QName, Object> keyValues = ImmutableMap.of(keyLeafA, "key-value-a", keyLeafB, "key-value-b");
205 final YangInstanceIdentifier iidPath = YangInstanceIdentifier.of(myContainer).node(myList)
206 .node(new NodeIdentifierWithPredicates(myList, keyValues)).node(referencedLeaf);
208 final LeafNode<?> iidLeafNode = Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(iidLeaf))
209 .withValue(iidPath).build();
211 final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(myList))
212 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
213 new NodeIdentifierWithPredicates(myList, keyValues))
214 .withChild(iidLeafNode)
215 .withChild(referencedLeafNode).build())
218 final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
219 new NodeIdentifier(myContainer)).withChild(myListNode).build();
220 return myContainerNode;
223 private static YangInstanceIdentifier buildPathToIIdLeafNode() {
224 final Map<QName, Object> keyValues = ImmutableMap.of(keyLeafA, "key-value-a", keyLeafB, "key-value-b");
225 final YangInstanceIdentifier path = YangInstanceIdentifier.of(myList)
226 .node(new NodeIdentifierWithPredicates(myList, keyValues)).node(iidLeaf);
230 // variant for a leafref that references a leaf
231 private static ContainerNode buildMyContainerNodeForLeafrefTest(final LeafNode<?> referencedLeafNode) {
232 final Map<QName, Object> keyValues = ImmutableMap.of(keyLeafA, "value-a", keyLeafB, "value-b");
234 final LeafNode<?> absLeafrefNode = Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(absLeafrefLeaf))
235 .withValue("referenced-leaf-node-value").build();
236 final LeafNode<?> relLeafrefNode = Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(relLeafrefLeaf))
237 .withValue("referenced-leaf-node-value").build();
238 final LeafNode<?> ordinaryLeafANode = Builders.leafBuilder().withNodeIdentifier(
239 new NodeIdentifier(ordinaryLeafA)).withValue("value-a").build();
240 final LeafNode<?> ordinaryLeafBNode = Builders.leafBuilder().withNodeIdentifier(
241 new NodeIdentifier(ordinaryLeafB)).withValue("value-b").build();
243 final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(myList))
244 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
245 new NodeIdentifierWithPredicates(myList, keyValues))
246 .withChild(referencedLeafNode).build())
249 final ContainerNode myInnerContainerNode = Builders.containerBuilder().withNodeIdentifier(
250 new NodeIdentifier(myInnerContainer))
251 .withChild(absLeafrefNode)
252 .withChild(relLeafrefNode)
253 .withChild(ordinaryLeafANode)
254 .withChild(ordinaryLeafBNode).build();
256 final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
257 new NodeIdentifier(myContainer))
258 .withChild(myListNode)
259 .withChild(myInnerContainerNode).build();
260 return myContainerNode;
263 // variant for a leafref that references a leaf-list
264 private static ContainerNode buildMyContainerNodeForLeafrefTest(final LeafSetNode<?> referencedLeafListNode) {
265 final LeafNode<?> leafListLeafrefNode = Builders.leafBuilder().withNodeIdentifier(
266 new NodeIdentifier(leafListLeafrefLeaf)).withValue("referenced-node-entry-value-b").build();
268 final LeafNode<?> ordinaryLeafANode = Builders.leafBuilder().withNodeIdentifier(
269 new NodeIdentifier(ordinaryLeafA)).withValue("value-a").build();
270 final LeafNode<?> ordinaryLeafBNode = Builders.leafBuilder().withNodeIdentifier(
271 new NodeIdentifier(ordinaryLeafB)).withValue("value-b").build();
273 final ContainerNode myInnerContainerNode = Builders.containerBuilder().withNodeIdentifier(
274 new NodeIdentifier(myInnerContainer))
275 .withChild(leafListLeafrefNode)
276 .withChild(ordinaryLeafANode)
277 .withChild(ordinaryLeafBNode).build();
279 final Map<QName, Object> keyValues = ImmutableMap.of(keyLeafA, "value-a", keyLeafB, "value-b");
281 final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(myList))
282 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
283 new NodeIdentifierWithPredicates(myList, keyValues))
284 .withChild(referencedLeafListNode).build())
287 final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
288 new NodeIdentifier(myContainer))
289 .withChild(myListNode)
290 .withChild(myInnerContainerNode).build();
291 return myContainerNode;