24a08803a13eafbb3f1c7b4773de8fcc94cb0cad
[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.util.Map;
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;
42
43 public class DerefXPathFunctionTest {
44
45     private static JaxenSchemaContextFactory jaxenSchemaContextFactory = new JaxenSchemaContextFactory();
46
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");
61
62     @Test
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);
67
68         final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
69
70         final LeafNode<?> referencedLeafNode = Builders.leafBuilder().withNodeIdentifier(
71             new NodeIdentifier(REFERENCED_LEAF)).withValue("referenced-leaf-node-value").build();
72
73         final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForIIdTest(
74             referencedLeafNode));
75
76         final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
77         converterBiMap.put("foo-prefix", FOO_MODULE);
78
79         final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
80                 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
81
82         final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(
83                 buildPathToIIdLeafNode());
84
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);
91     }
92
93     @Test
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);
99
100         final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
101
102         final LeafNode<?> referencedLeafNode = Builders.leafBuilder().withNodeIdentifier(
103                 new NodeIdentifier(REFERENCED_LEAF)).withValue("referenced-leaf-node-value").build();
104
105         final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForLeafrefTest(
106                 referencedLeafNode));
107
108         final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
109         converterBiMap.put("foo-prefix", FOO_MODULE);
110
111         final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
112                 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
113
114         final YangInstanceIdentifier absLeafrefPath = YangInstanceIdentifier.of(MY_INNER_CONTAINER)
115                 .node(ABS_LEAFREF_LEAF);
116         NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(absLeafrefPath);
117
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);
124
125         final YangInstanceIdentifier relLeafrefPath = YangInstanceIdentifier.of(MY_INNER_CONTAINER)
126                 .node(REL_LEAFREF_LEAF);
127         normalizedNodeContext = normalizedNodeContextSupport.createContext(relLeafrefPath);
128
129         derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
130         assertNotNull(derefResult);
131         assertTrue(derefResult instanceof NormalizedNode<?, ?>);
132         assertSame(referencedLeafNode, derefResult);
133     }
134
135     @Test
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);
141
142         final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
143
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())
155                 .build();
156
157         final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNodeForLeafrefTest(
158                 referencedLeafListNode));
159
160         final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
161         converterBiMap.put("foo-prefix", FOO_MODULE);
162
163         final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
164                 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
165
166         final YangInstanceIdentifier leafListLeafrefPath = YangInstanceIdentifier.of(MY_INNER_CONTAINER)
167                 .node(LEAFLIST_LEAFREF_LEAF);
168         final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport
169                 .createContext(leafListLeafrefPath);
170
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<?, ?>);
176
177         final LeafSetEntryNode<?> referencedLeafListNodeEntry = referencedLeafListNode.getChild(
178                 new NodeWithValue<>(REFERENCED_LEAFLIST, "referenced-node-entry-value-b")).get();
179         assertSame(referencedLeafListNodeEntry, derefResult);
180     }
181
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);
186
187         final LeafNode<?> iidLeafNode = Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(IID_LEAF))
188                 .withValue(iidPath).build();
189
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())
195                 .build();
196
197         final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
198                 new NodeIdentifier(MY_CONTAINER)).withChild(myListNode).build();
199         return myContainerNode;
200     }
201
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);
206         return path;
207     }
208
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");
212
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();
223
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())
228                 .build();
229
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();
236
237         final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
238                 new NodeIdentifier(MY_CONTAINER))
239                 .withChild(myListNode)
240                 .withChild(myInnerContainerNode).build();
241         return myContainerNode;
242     }
243
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();
248
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();
253
254         final ContainerNode myInnerContainerNode = Builders.containerBuilder().withNodeIdentifier(
255                 new NodeIdentifier(MY_INNER_CONTAINER))
256                 .withChild(leafListLeafrefNode)
257                 .withChild(ordinaryLeafANode)
258                 .withChild(ordinaryLeafBNode).build();
259
260         final Map<QName, Object> keyValues = ImmutableMap.of(KEY_LEAF_A, "value-a", KEY_LEAF_B, "value-b");
261
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())
266                 .build();
267
268         final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
269                 new NodeIdentifier(MY_CONTAINER))
270                 .withChild(myListNode)
271                 .withChild(myInnerContainerNode).build();
272         return myContainerNode;
273     }
274 }