Degrade DataNodeContainer.getChildNodes() from Set to Collection
[yangtools.git] / yang / yang-data-impl / src / test / java / org / opendaylight / yangtools / yang / data / impl / schema / NormalizedDataBuilderTest.java
1 /*
2  * Copyright (c) 2013 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 package org.opendaylight.yangtools.yang.data.impl.schema;
9
10 import com.google.common.base.Function;
11 import com.google.common.base.Preconditions;
12 import com.google.common.collect.Collections2;
13 import com.google.common.collect.Lists;
14 import com.google.common.collect.Sets;
15
16 import java.io.InputStream;
17 import java.net.URI;
18 import java.util.Collections;
19 import java.util.List;
20 import java.util.Set;
21
22 import org.junit.Before;
23 import org.junit.Test;
24 import org.opendaylight.yangtools.yang.common.QName;
25 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
26 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
27 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
28 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
29 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
30 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
31 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
32 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
33 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableChoiceNodeSchemaAwareBuilder;
34 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeSchemaAwareBuilder;
35 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
36 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
37 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
38 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
39 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
40 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
41 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
42 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
43 import org.opendaylight.yangtools.yang.model.api.Module;
44 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
45 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
46
47 public class NormalizedDataBuilderTest {
48
49     private ContainerSchemaNode containerNode;
50     private SchemaContext schema;
51
52     SchemaContext parseTestSchema(final String... yangPath) {
53         YangParserImpl yangParserImpl = new YangParserImpl();
54         Set<Module> modules = yangParserImpl.parseYangModelsFromStreams(getTestYangs(yangPath));
55         return yangParserImpl.resolveSchemaContext(modules);
56     }
57
58     List<InputStream> getTestYangs(final String... yangPaths) {
59
60         return Lists.newArrayList(Collections2.transform(Lists.newArrayList(yangPaths),
61                 new Function<String, InputStream>() {
62             @Override
63             public InputStream apply(final String input) {
64                 InputStream resourceAsStream = getClass().getResourceAsStream(input);
65                 Preconditions.checkNotNull(resourceAsStream, "File %s was null", resourceAsStream);
66                 return resourceAsStream;
67             }
68         }));
69     }
70
71     @Before
72     public void setUp() throws Exception {
73         schema = parseTestSchema("test.yang");
74         containerNode = (ContainerSchemaNode) getSchemaNode(schema, "test", "container");
75     }
76
77     @Test
78     public void testSchemaUnaware() throws Exception {
79         // Container
80         DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ContainerNode> builder = Builders
81                 .containerBuilder().withNodeIdentifier(getNodeIdentifier("container"));
82
83         // leaf
84         LeafNode<String> leafChild = Builders.<String> leafBuilder().withNodeIdentifier(getNodeIdentifier("leaf"))
85                 .withValue("String").build();
86         builder.withChild(leafChild);
87
88         // leafList
89         LeafSetNode<Integer> leafList = Builders
90                 .<Integer> leafSetBuilder()
91                 .withNodeIdentifier(getNodeIdentifier("leaf"))
92                 .withChildValue(1)
93                 .withChild(
94                         Builders.<Integer> leafSetEntryBuilder()
95                         .withNodeIdentifier(getNodeWithValueIdentifier("leaf", 3)).withValue(3).build())
96                         .build();
97         builder.withChild(leafList);
98
99         // list
100         MapEntryNode listChild1 = Builders
101                 .mapEntryBuilder()
102                 .withChild(
103                         Builders.<Integer> leafBuilder().withNodeIdentifier(getNodeIdentifier("uint32InList"))
104                         .withValue(1).build())
105                         .withChild(Builders.containerBuilder().withNodeIdentifier(getNodeIdentifier("containerInList")).build())
106                         .withNodeIdentifier(
107                                 new InstanceIdentifier.NodeIdentifierWithPredicates(getNodeIdentifier("list").getNodeType(),
108                                         Collections.singletonMap(getNodeIdentifier("uint32InList").getNodeType(), (Object) 1)))
109                                         .build();
110
111         MapNode list = Builders.mapBuilder().withChild(listChild1).withNodeIdentifier(getNodeIdentifier("list"))
112                 .build();
113         builder.withChild(list);
114
115         AugmentationNode augmentation = Builders
116                 .augmentationBuilder()
117                 .withNodeIdentifier(
118                         new InstanceIdentifier.AugmentationIdentifier(Sets.newHashSet(getQName("augmentUint32"))))
119                         .withChild(
120                                 Builders.<Integer> leafBuilder().withNodeIdentifier(getNodeIdentifier("augmentUint32"))
121                                 .withValue(11).build()).build();
122
123         builder.withChild(augmentation);
124
125         // This works without schema (adding child from augment as a direct
126         // child)
127         builder.withChild(Builders.<Integer> leafBuilder().withNodeIdentifier(getNodeIdentifier("augmentUint32"))
128                 .withValue(11).build());
129     }
130
131     @Test
132     public void testSchemaAware() throws Exception {
133         DataContainerNodeBuilder<InstanceIdentifier.NodeIdentifier, ContainerNode> builder = Builders
134                 .containerBuilder(containerNode);
135
136         LeafSchemaNode schemaNode = (LeafSchemaNode) getSchemaNode(schema, "test", "uint32");
137         LeafNode<String> leafChild = Builders.<String> leafBuilder(schemaNode).withValue("String").build();
138         builder.withChild(leafChild);
139
140         LeafListSchemaNode leafListSchemaNode = (LeafListSchemaNode) getSchemaNode(schema, "test", "leafList");
141         LeafSetNode<Integer> leafList = Builders.<Integer> leafSetBuilder(leafListSchemaNode).withChildValue(1)
142                 .withChild(Builders.<Integer> leafSetEntryBuilder(leafListSchemaNode).withValue(3).build()).build();
143         builder.withChild(leafList);
144
145         ListSchemaNode listSchema = (ListSchemaNode) getSchemaNode(schema, "test", "list");
146         LeafSchemaNode uint32InListSchemaNode = (LeafSchemaNode) getSchemaNode(schema, "test", "uint32InList");
147         ContainerSchemaNode containerInListSchemaNode = (ContainerSchemaNode) getSchemaNode(schema, "test",
148                 "containerInList");
149
150         MapEntryNode listChild1 = Builders.mapEntryBuilder(listSchema)
151                 .withChild(Builders.<Integer> leafBuilder(uint32InListSchemaNode).withValue(1).build())
152                 .withChild(Builders.containerBuilder(containerInListSchemaNode).build()).build();
153
154         MapNode list = ImmutableMapNodeSchemaAwareBuilder.create(listSchema).withChild(listChild1).build();
155         builder.withChild(list);
156
157         LeafSchemaNode augmentUint32SchemaNode = (LeafSchemaNode) getSchemaNode(schema, "test", "augmentUint32");
158         AugmentationSchema augmentationSchema = getAugmentationSchemaForChild(containerNode,
159                 augmentUint32SchemaNode.getQName());
160
161         AugmentationNode augmentation = Builders.augmentationBuilder(augmentationSchema)
162                 .withChild(Builders.<Integer>leafBuilder(augmentUint32SchemaNode).withValue(11).build()).build();
163
164         builder.withChild(augmentation);
165
166         // This should fail with schema, since the leaf comes from augmentation
167         // builder.withChild(ImmutableLeafNodeSchemaAwareBuilder.<Integer>get(augmentUint32SchemaNode).withValue(11).build());
168
169         LeafSchemaNode augumentString1SchemaNode = (LeafSchemaNode) getSchemaNode(schema, "test", "augmentString1");
170         LeafSchemaNode augumentString2SchemaNode = (LeafSchemaNode) getSchemaNode(schema, "test", "augmentString2");
171
172         ChoiceNode choice1SchemaNode = (ChoiceNode) getSchemaNode(schema, "test", "choice");
173         org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode choice = ImmutableChoiceNodeSchemaAwareBuilder
174                 .create(choice1SchemaNode)
175                 .withChild(Builders.<String> leafBuilder(augumentString1SchemaNode).withValue("case1").build())
176                 // This should fail, since child node belongs to different case
177                 // .withChild(Builders.<String>leafBuilder(augumentString2SchemaNode).withValue("case2")
178                 // .build())
179                 .build();
180
181         ;
182         builder.withChild(choice);
183
184         // This should fail, child from case
185         // builder.withChild(Builders.<String>leafBuilder(augumentString1SchemaNode).withValue("case1")
186         // .build());
187     }
188
189     private AugmentationSchema getAugmentationSchemaForChild(final ContainerSchemaNode containerNode, final QName qName) {
190         for (AugmentationSchema augmentationSchema : containerNode.getAvailableAugmentations()) {
191             if (augmentationSchema.getDataChildByName(qName) != null) {
192                 return augmentationSchema;
193             }
194         }
195         throw new IllegalStateException("Unable to find child augmentation in " + containerNode);
196     }
197
198     private InstanceIdentifier.NodeWithValue getNodeWithValueIdentifier(final String localName, final Object value) {
199         return new InstanceIdentifier.NodeWithValue(getQName(localName), value);
200     }
201
202     private QName getQName(final String localName) {
203         String namespace = "namespace";
204         return new QName(URI.create(namespace), localName);
205     }
206
207     private InstanceIdentifier.NodeIdentifier getNodeIdentifier(final String localName) {
208         return new InstanceIdentifier.NodeIdentifier(getQName(localName));
209     }
210
211     public static DataSchemaNode getSchemaNode(final SchemaContext context, final String moduleName, final String childNodeName) {
212         for (Module module : context.getModules()) {
213             if (module.getName().equals(moduleName)) {
214                 DataSchemaNode found = findChildNode(module.getChildNodes(), childNodeName);
215                 Preconditions.checkState(found != null, "Unable to find %s", childNodeName);
216                 return found;
217             }
218         }
219         throw new IllegalStateException("Unable to find child node " + childNodeName);
220     }
221
222     private static DataSchemaNode findChildNode(final Iterable<DataSchemaNode> children, final String name) {
223         List<DataNodeContainer> containers = Lists.newArrayList();
224
225         for (DataSchemaNode dataSchemaNode : children) {
226             if (dataSchemaNode.getQName().getLocalName().equals(name)) {
227                 return dataSchemaNode;
228             }
229             if (dataSchemaNode instanceof DataNodeContainer) {
230                 containers.add((DataNodeContainer) dataSchemaNode);
231             } else if (dataSchemaNode instanceof ChoiceNode) {
232                 containers.addAll(((ChoiceNode) dataSchemaNode).getCases());
233             }
234         }
235
236         for (DataNodeContainer container : containers) {
237             DataSchemaNode retVal = findChildNode(container.getChildNodes(), name);
238             if (retVal != null) {
239                 return retVal;
240             }
241         }
242
243         return null;
244     }
245 }