47bc7226c17b2ae2f75d2516d6933909495abd27
[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.assertEquals;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertSame;
14 import static org.junit.Assert.assertTrue;
15
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;
21 import java.net.URI;
22 import java.util.Map;
23 import org.jaxen.Function;
24 import org.junit.Test;
25 import org.opendaylight.yangtools.yang.common.QName;
26 import org.opendaylight.yangtools.yang.common.QNameModule;
27 import org.opendaylight.yangtools.yang.common.Revision;
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.LeafSetNode;
36 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
37 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
38 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
39 import org.opendaylight.yangtools.yang.data.impl.schema.nodes.LazyLeafOperations;
40 import org.opendaylight.yangtools.yang.data.jaxen.api.XPathDocument;
41 import org.opendaylight.yangtools.yang.data.jaxen.api.XPathSchemaContext;
42 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
43 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
44
45 public class DerefXPathFunctionTest {
46
47     private static JaxenSchemaContextFactory jaxenSchemaContextFactory = new JaxenSchemaContextFactory();
48
49     private static final QNameModule FOO_MODULE = QNameModule.create(URI.create("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");
63
64     @Test
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);
69
70         final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
71
72         final LeafNode<?> referencedLeafNode = Builders.leafBuilder().withNodeIdentifier(
73             new NodeIdentifier(REFERENCED_LEAF)).withValue("referenced-leaf-node-value").build();
74
75         final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForIIdTest(
76             referencedLeafNode));
77
78         final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
79         converterBiMap.put("foo-prefix", FOO_MODULE);
80
81         final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
82                 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
83
84         final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(
85                 buildPathToIIdLeafNode());
86
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         assertLeafEquals(referencedLeafNode, (LeafNode<?>) derefResult);
93     }
94
95     @Test
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);
101
102         final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
103
104         final LeafNode<?> referencedLeafNode = Builders.leafBuilder().withNodeIdentifier(
105                 new NodeIdentifier(REFERENCED_LEAF)).withValue("referenced-leaf-node-value").build();
106
107         final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForLeafrefTest(
108                 referencedLeafNode));
109
110         final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
111         converterBiMap.put("foo-prefix", FOO_MODULE);
112
113         final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
114                 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
115
116         final YangInstanceIdentifier absLeafrefPath = YangInstanceIdentifier.of(MY_INNER_CONTAINER)
117                 .node(ABS_LEAFREF_LEAF);
118         NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(absLeafrefPath);
119
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         assertLeafEquals(referencedLeafNode, (LeafNode<?>) derefResult);
126
127         final YangInstanceIdentifier relLeafrefPath = YangInstanceIdentifier.of(MY_INNER_CONTAINER)
128                 .node(REL_LEAFREF_LEAF);
129         normalizedNodeContext = normalizedNodeContextSupport.createContext(relLeafrefPath);
130
131         derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
132         assertNotNull(derefResult);
133         assertTrue(derefResult instanceof LeafNode<?>);
134         assertLeafEquals(referencedLeafNode, (LeafNode<?>) derefResult);
135     }
136
137     @Test
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);
143
144         final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
145
146         final LeafSetNode<?> referencedLeafListNode = Builders.leafSetBuilder().withNodeIdentifier(
147                 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())
157                 .build();
158
159         final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForLeafrefTest(
160                 referencedLeafListNode));
161
162         final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
163         converterBiMap.put("foo-prefix", FOO_MODULE);
164
165         final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
166                 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
167
168         final YangInstanceIdentifier leafListLeafrefPath = YangInstanceIdentifier.of(MY_INNER_CONTAINER)
169                 .node(LEAFLIST_LEAFREF_LEAF);
170         final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport
171                 .createContext(leafListLeafrefPath);
172
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<?, ?>);
178
179         final LeafSetEntryNode<?> referencedLeafListNodeEntry = referencedLeafListNode.getChild(
180                 new NodeWithValue<>(REFERENCED_LEAFLIST, "referenced-node-entry-value-b")).get();
181         assertSame(referencedLeafListNodeEntry, derefResult);
182     }
183
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);
188
189         final LeafNode<?> iidLeafNode = Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(IID_LEAF))
190                 .withValue(iidPath).build();
191
192         final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(MY_LIST))
193                 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
194                         NodeIdentifierWithPredicates.of(MY_LIST, keyValues))
195                         .withChild(iidLeafNode)
196                         .withChild(referencedLeafNode).build())
197                 .build();
198
199         final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
200                 new NodeIdentifier(MY_CONTAINER)).withChild(myListNode).build();
201         return myContainerNode;
202     }
203
204     private static YangInstanceIdentifier buildPathToIIdLeafNode() {
205         final Map<QName, Object> keyValues = ImmutableMap.of(KEY_LEAF_A, "key-value-a", KEY_LEAF_B, "key-value-b");
206         final YangInstanceIdentifier path = YangInstanceIdentifier.of(MY_LIST)
207                 .node(NodeIdentifierWithPredicates.of(MY_LIST, keyValues)).node(IID_LEAF);
208         return path;
209     }
210
211     // variant for a leafref that references a leaf
212     private static ContainerNode buildMyContainerNodeForLeafrefTest(final LeafNode<?> referencedLeafNode) {
213         final Map<QName, Object> keyValues = ImmutableMap.of(KEY_LEAF_A, "value-a", KEY_LEAF_B, "value-b");
214
215         final LeafNode<?> absLeafrefNode = Builders.leafBuilder()
216                 .withNodeIdentifier(new NodeIdentifier(ABS_LEAFREF_LEAF))
217                 .withValue("referenced-leaf-node-value").build();
218         final LeafNode<?> relLeafrefNode = Builders.leafBuilder()
219                 .withNodeIdentifier(new NodeIdentifier(REL_LEAFREF_LEAF))
220                 .withValue("referenced-leaf-node-value").build();
221         final LeafNode<?> ordinaryLeafANode = Builders.leafBuilder().withNodeIdentifier(
222                 new NodeIdentifier(ORDINARY_LEAF_A)).withValue("value-a").build();
223         final LeafNode<?> ordinaryLeafBNode = Builders.leafBuilder().withNodeIdentifier(
224                 new NodeIdentifier(ORDINARY_LEAF_B)).withValue("value-b").build();
225
226         final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(MY_LIST))
227                 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
228                         NodeIdentifierWithPredicates.of(MY_LIST, keyValues))
229                         .withChild(referencedLeafNode).build())
230                 .build();
231
232         final ContainerNode myInnerContainerNode = Builders.containerBuilder().withNodeIdentifier(
233                 new NodeIdentifier(MY_INNER_CONTAINER))
234                 .withChild(absLeafrefNode)
235                 .withChild(relLeafrefNode)
236                 .withChild(ordinaryLeafANode)
237                 .withChild(ordinaryLeafBNode).build();
238
239         final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
240                 new NodeIdentifier(MY_CONTAINER))
241                 .withChild(myListNode)
242                 .withChild(myInnerContainerNode).build();
243         return myContainerNode;
244     }
245
246     // variant for a leafref that references a leaf-list
247     private static ContainerNode buildMyContainerNodeForLeafrefTest(final LeafSetNode<?> referencedLeafListNode) {
248         final LeafNode<?> leafListLeafrefNode = Builders.leafBuilder().withNodeIdentifier(
249                 new NodeIdentifier(LEAFLIST_LEAFREF_LEAF)).withValue("referenced-node-entry-value-b").build();
250
251         final LeafNode<?> ordinaryLeafANode = Builders.leafBuilder().withNodeIdentifier(
252                 new NodeIdentifier(ORDINARY_LEAF_A)).withValue("value-a").build();
253         final LeafNode<?> ordinaryLeafBNode = Builders.leafBuilder().withNodeIdentifier(
254                 new NodeIdentifier(ORDINARY_LEAF_B)).withValue("value-b").build();
255
256         final ContainerNode myInnerContainerNode = Builders.containerBuilder().withNodeIdentifier(
257                 new NodeIdentifier(MY_INNER_CONTAINER))
258                 .withChild(leafListLeafrefNode)
259                 .withChild(ordinaryLeafANode)
260                 .withChild(ordinaryLeafBNode).build();
261
262         final Map<QName, Object> keyValues = ImmutableMap.of(KEY_LEAF_A, "value-a", KEY_LEAF_B, "value-b");
263
264         final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(MY_LIST))
265                 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
266                         NodeIdentifierWithPredicates.of(MY_LIST, keyValues))
267                         .withChild(referencedLeafListNode).build())
268                 .build();
269
270         final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
271                 new NodeIdentifier(MY_CONTAINER))
272                 .withChild(myListNode)
273                 .withChild(myInnerContainerNode).build();
274         return myContainerNode;
275     }
276
277     private static void assertLeafEquals(final LeafNode<?> expected, final LeafNode<?> actual) {
278         if (LazyLeafOperations.isEnabled()) {
279             assertEquals(expected, actual);
280         } else {
281             assertSame(expected, actual);
282         }
283     }
284 }