507b522b910db6bd1544d899d9f3aee4a7a7355d
[yangtools.git] / yang / yang-data-jaxen / src / test / java / org / opendaylight / yangtools / yang / data / jaxen / DerefXPathFunctionTest.java
1 /*
2  * Copyright (c) 2017 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.yangtools.yang.data.jaxen;
10
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertSame;
13 import static org.junit.Assert.assertTrue;
14
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;
20 import java.net.URI;
21 import java.text.ParseException;
22 import java.util.Map;
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;
44
45 public class DerefXPathFunctionTest {
46
47     private static JaxenSchemaContextFactory jaxenSchemaContextFactory;
48
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;
63
64     @BeforeClass
65     public static void setup() throws ParseException {
66         jaxenSchemaContextFactory = new JaxenSchemaContextFactory();
67
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");
83     }
84
85     @Test
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);
90
91         final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
92
93         final LeafNode<?> referencedLeafNode = Builders.leafBuilder().withNodeIdentifier(
94             new NodeIdentifier(referencedLeaf)).withValue("referenced-leaf-node-value").build();
95
96         final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForIIdTest(
97             referencedLeafNode));
98
99         final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
100         converterBiMap.put("foo-prefix", fooModule);
101
102         final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
103                 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
104
105         final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(
106                 buildPathToIIdLeafNode());
107
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);
114     }
115
116     @Test
117     public void testDerefFunctionForLeafref() throws Exception {
118         // tests absolute and relative leafref that references a leaf node
119         final SchemaContext schemaContext = YangParserTestUtils.parseYangSource(
120                 "/yang-xpath-functions-test/deref-function-leafref/foo.yang");
121         assertNotNull(schemaContext);
122
123         final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
124
125         final LeafNode<?> referencedLeafNode = Builders.leafBuilder().withNodeIdentifier(
126                 new NodeIdentifier(referencedLeaf)).withValue("referenced-leaf-node-value").build();
127
128         final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForLeafrefTest(
129                 referencedLeafNode));
130
131         final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
132         converterBiMap.put("foo-prefix", fooModule);
133
134         final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
135                 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
136
137         final YangInstanceIdentifier absLeafrefPath = YangInstanceIdentifier.of(myInnerContainer).node(absLeafrefLeaf);
138         NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(absLeafrefPath);
139
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);
146
147         final YangInstanceIdentifier relLeafrefPath = YangInstanceIdentifier.of(myInnerContainer).node(relLeafrefLeaf);
148         normalizedNodeContext = normalizedNodeContextSupport.createContext(relLeafrefPath);
149
150         derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
151         assertNotNull(derefResult);
152         assertTrue(derefResult instanceof NormalizedNode<?, ?>);
153         assertSame(referencedLeafNode, derefResult);
154     }
155
156     @Test
157     public void testDerefFunctionForLeafref2() throws Exception {
158         // tests leafref that references a leaf-list node
159         final SchemaContext schemaContext = YangParserTestUtils.parseYangSource(
160                 "/yang-xpath-functions-test/deref-function-leafref/foo.yang");
161         assertNotNull(schemaContext);
162
163         final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
164
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())
176                 .build();
177
178         final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForLeafrefTest(
179                 referencedLeafListNode));
180
181         final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
182         converterBiMap.put("foo-prefix", fooModule);
183
184         final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
185                 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
186
187         final YangInstanceIdentifier leafListLeafrefPath = YangInstanceIdentifier.of(myInnerContainer)
188                 .node(leafListLeafrefLeaf);
189         final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport
190                 .createContext(leafListLeafrefPath);
191
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<?, ?>);
197
198         final LeafSetEntryNode<?> referencedLeafListNodeEntry = referencedLeafListNode.getChild(
199                 new NodeWithValue<>(referencedLeafList, "referenced-node-entry-value-b")).get();
200         assertSame(referencedLeafListNodeEntry, derefResult);
201     }
202
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);
207
208         final LeafNode<?> iidLeafNode = Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(iidLeaf))
209                 .withValue(iidPath).build();
210
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())
216                 .build();
217
218         final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
219                 new NodeIdentifier(myContainer)).withChild(myListNode).build();
220         return myContainerNode;
221     }
222
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);
227         return path;
228     }
229
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");
233
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();
242
243         final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(myList))
244                 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
245                         new NodeIdentifierWithPredicates(myList, keyValues))
246                         .withChild(referencedLeafNode).build())
247                 .build();
248
249         final ContainerNode myInnerContainerNode = Builders.containerBuilder().withNodeIdentifier(
250                 new NodeIdentifier(myInnerContainer))
251                 .withChild(absLeafrefNode)
252                 .withChild(relLeafrefNode)
253                 .withChild(ordinaryLeafANode)
254                 .withChild(ordinaryLeafBNode).build();
255
256         final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
257                 new NodeIdentifier(myContainer))
258                 .withChild(myListNode)
259                 .withChild(myInnerContainerNode).build();
260         return myContainerNode;
261     }
262
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();
267
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();
272
273         final ContainerNode myInnerContainerNode = Builders.containerBuilder().withNodeIdentifier(
274                 new NodeIdentifier(myInnerContainer))
275                 .withChild(leafListLeafrefNode)
276                 .withChild(ordinaryLeafANode)
277                 .withChild(ordinaryLeafBNode).build();
278
279         final Map<QName, Object> keyValues = ImmutableMap.of(keyLeafA, "value-a", keyLeafB, "value-b");
280
281         final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(myList))
282                 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
283                         new NodeIdentifierWithPredicates(myList, keyValues))
284                         .withChild(referencedLeafListNode).build())
285                 .build();
286
287         final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
288                 new NodeIdentifier(myContainer))
289                 .withChild(myListNode)
290                 .withChild(myInnerContainerNode).build();
291         return myContainerNode;
292     }
293 }