Merge "Added RpcResultBuilder.buildFuture() as a convenience method"
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / builder / impl / ListSchemaNodeBuilder.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.parser.builder.impl;
9
10 import com.google.common.base.Optional;
11 import com.google.common.base.Preconditions;
12 import com.google.common.collect.ImmutableList;
13 import com.google.common.collect.ImmutableSet;
14 import java.util.ArrayList;
15 import java.util.List;
16 import java.util.Set;
17 import org.opendaylight.yangtools.yang.common.QName;
18 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
19 import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
20 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
21 import org.opendaylight.yangtools.yang.model.api.DerivableSchemaNode;
22 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
23 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
24 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
25 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
26 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
27 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationTargetBuilder;
28 import org.opendaylight.yangtools.yang.parser.builder.api.ConstraintsBuilder;
29 import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
30 import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder;
31 import org.opendaylight.yangtools.yang.parser.builder.api.UnknownSchemaNodeBuilder;
32 import org.opendaylight.yangtools.yang.parser.builder.util.AbstractDocumentedDataNodeContainer;
33 import org.opendaylight.yangtools.yang.parser.builder.util.AbstractDocumentedDataNodeContainerBuilder;
34 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
35
36 public final class ListSchemaNodeBuilder extends AbstractDocumentedDataNodeContainerBuilder implements
37         DataSchemaNodeBuilder, AugmentationTargetBuilder {
38     private ListSchemaNodeImpl instance;
39     private boolean userOrdered;
40     private Set<String> keys;
41     private List<QName> keyDefinition;
42     // SchemaNode args
43     private SchemaPath schemaPath;
44     // DataSchemaNode args
45     private boolean augmenting;
46     private boolean addedByUses;
47     private ListSchemaNodeBuilder originalBuilder;
48     private ListSchemaNode originalNode;
49     private boolean configuration;
50     private final ConstraintsBuilder constraints;
51     // AugmentationTarget args
52     private final List<AugmentationSchema> augmentations = new ArrayList<>();
53     private final List<AugmentationSchemaBuilder> augmentationBuilders = new ArrayList<>();
54
55     public ListSchemaNodeBuilder(final String moduleName, final int line, final QName qname, final SchemaPath path) {
56         super(moduleName, line, qname);
57         this.schemaPath = Preconditions.checkNotNull(path, "Schema Path must not be null");
58         constraints = new ConstraintsBuilderImpl(moduleName, line);
59     }
60
61     public ListSchemaNodeBuilder(final String moduleName, final int line, final QName qname, final SchemaPath path,
62             final ListSchemaNode base) {
63         super(moduleName, line, qname, path, base);
64         this.schemaPath = Preconditions.checkNotNull(path, "Schema Path must not be null");
65         constraints = new ConstraintsBuilderImpl(moduleName, line, base.getConstraints());
66
67         keyDefinition = ImmutableList.copyOf(base.getKeyDefinition());
68         userOrdered = base.isUserOrdered();
69
70         augmenting = base.isAugmenting();
71         addedByUses = base.isAddedByUses();
72         originalNode = base;
73         configuration = base.isConfiguration();
74
75         addedUnknownNodes.addAll(BuilderUtils.wrapUnknownNodes(moduleName, line, base.getUnknownSchemaNodes(), path,
76                 qname));
77         augmentations.addAll(base.getAvailableAugmentations());
78     }
79
80     @Override
81     public ListSchemaNode build() {
82         if (instance != null) {
83             return instance;
84         }
85         buildChildren();
86         instance = new ListSchemaNodeImpl(qname, schemaPath, this);
87
88         instance.augmenting = augmenting;
89         instance.addedByUses = addedByUses;
90         instance.configuration = configuration;
91         instance.constraints = constraints.toInstance();
92         instance.userOrdered = userOrdered;
93
94         // KEY
95         if (keys != null) {
96             keyDefinition = new ArrayList<>();
97             for (String key : keys) {
98                 DataSchemaNode keyPart = instance.getDataChildByName(key);
99                 if (keyPart == null) {
100                     throw new YangParseException(getModuleName(), getLine(), "Failed to resolve list key for name "
101                             + key);
102                 }
103
104                 if (!(keyPart instanceof LeafSchemaNode)) {
105                     throw new YangParseException(getModuleName(), getLine(), "List key : \"" + key
106                             + "\" does not reference any Leaf of the List");
107                 }
108
109                 final QName qname = keyPart.getQName();
110                 if (!keyDefinition.contains(qname)) {
111                     keyDefinition.add(qname);
112                 }
113             }
114             instance.keyDefinition = ImmutableList.copyOf(keyDefinition);
115         } else {
116             instance.keyDefinition = ImmutableList.of();
117         }
118
119         // ORIGINAL NODE
120         if (originalNode == null && originalBuilder != null) {
121             originalNode = originalBuilder.build();
122         }
123         instance.original = originalNode;
124
125         // AUGMENTATIONS
126         for (AugmentationSchemaBuilder builder : augmentationBuilders) {
127             augmentations.add(builder.build());
128         }
129         instance.augmentations = ImmutableSet.copyOf(augmentations);
130
131         // UNKNOWN NODES
132         for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
133             unknownNodes.add(b.build());
134         }
135         instance.unknownNodes = ImmutableList.copyOf(unknownNodes);
136
137         return instance;
138     }
139
140     @Override
141     protected String getStatementName() {
142         return "list";
143     }
144
145     @Override
146     public SchemaPath getPath() {
147         return schemaPath;
148     }
149
150     @Override
151     public void setPath(final SchemaPath path) {
152         this.schemaPath = path;
153     }
154
155     @Override
156     public void addAugmentation(final AugmentationSchemaBuilder augment) {
157         augmentationBuilders.add(augment);
158     }
159
160     public List<AugmentationSchemaBuilder> getAugmentationBuilders() {
161         return augmentationBuilders;
162     }
163
164     public Set<String> getKeys() {
165         return keys;
166     }
167
168     public void setKeys(final Set<String> keys) {
169         this.keys = keys;
170     }
171
172     @Override
173     public boolean isAugmenting() {
174         return augmenting;
175     }
176
177     @Override
178     public void setAugmenting(final boolean augmenting) {
179         this.augmenting = augmenting;
180     }
181
182     @Override
183     public boolean isAddedByUses() {
184         return addedByUses;
185     }
186
187     @Override
188     public void setAddedByUses(final boolean addedByUses) {
189         this.addedByUses = addedByUses;
190     }
191
192     @Override
193     public ListSchemaNodeBuilder getOriginal() {
194         return originalBuilder;
195     }
196
197     @Override
198     public void setOriginal(final SchemaNodeBuilder builder) {
199         Preconditions.checkArgument(builder instanceof ListSchemaNodeBuilder, "Original of list cannot be " + builder);
200         this.originalBuilder = (ListSchemaNodeBuilder) builder;
201     }
202
203     @Override
204     public boolean isConfiguration() {
205         return configuration;
206     }
207
208     @Override
209     public void setConfiguration(final boolean configuration) {
210         this.configuration = configuration;
211     }
212
213     @Override
214     public ConstraintsBuilder getConstraints() {
215         return constraints;
216     }
217
218     public boolean isUserOrdered() {
219         return userOrdered;
220     }
221
222     public void setUserOrdered(final boolean userOrdered) {
223         this.userOrdered = userOrdered;
224     }
225
226     @Override
227     public int hashCode() {
228         final int prime = 31;
229         int result = 1;
230         result = prime * result + ((schemaPath == null) ? 0 : schemaPath.hashCode());
231         return result;
232     }
233
234     @Override
235     public boolean equals(final Object obj) {
236         if (this == obj) {
237             return true;
238         }
239         if (obj == null) {
240             return false;
241         }
242         if (getClass() != obj.getClass()) {
243             return false;
244         }
245         ListSchemaNodeBuilder other = (ListSchemaNodeBuilder) obj;
246         if (schemaPath == null) {
247             if (other.schemaPath != null) {
248                 return false;
249             }
250         } else if (!schemaPath.equals(other.schemaPath)) {
251             return false;
252         }
253         if (getParent() == null) {
254             if (other.getParent() != null) {
255                 return false;
256             }
257         } else if (!getParent().equals(other.getParent())) {
258             return false;
259         }
260         return true;
261     }
262
263     @Override
264     public String toString() {
265         return "list " + qname.getLocalName();
266     }
267
268     private static final class ListSchemaNodeImpl extends AbstractDocumentedDataNodeContainer implements
269             ListSchemaNode, DerivableSchemaNode {
270         private final QName qname;
271         private final SchemaPath path;
272         private ImmutableList<QName> keyDefinition;
273         private boolean augmenting;
274         private boolean addedByUses;
275         private ListSchemaNode original;
276         private boolean configuration;
277         private ConstraintDefinition constraints;
278         private ImmutableSet<AugmentationSchema> augmentations;
279         private ImmutableList<UnknownSchemaNode> unknownNodes;
280         private boolean userOrdered;
281
282         private ListSchemaNodeImpl(final QName qname, final SchemaPath path, final ListSchemaNodeBuilder builder) {
283             super(builder);
284             this.qname = qname;
285             this.path = path;
286         }
287
288         @Override
289         public QName getQName() {
290             return qname;
291         }
292
293         @Override
294         public SchemaPath getPath() {
295             return path;
296         }
297
298         @Override
299         public List<QName> getKeyDefinition() {
300             return keyDefinition;
301         }
302
303         @Override
304         public boolean isAugmenting() {
305             return augmenting;
306         }
307
308         @Override
309         public boolean isAddedByUses() {
310             return addedByUses;
311         }
312
313         @Override
314         public Optional<ListSchemaNode> getOriginal() {
315             return Optional.fromNullable(original);
316         }
317
318         @Override
319         public boolean isConfiguration() {
320             return configuration;
321         }
322
323         @Override
324         public ConstraintDefinition getConstraints() {
325             return constraints;
326         }
327
328         @Override
329         public Set<AugmentationSchema> getAvailableAugmentations() {
330             return augmentations;
331         }
332
333         @Override
334         public boolean isUserOrdered() {
335             return userOrdered;
336         }
337
338         @Override
339         public List<UnknownSchemaNode> getUnknownSchemaNodes() {
340             return unknownNodes;
341         }
342
343         @Override
344         public int hashCode() {
345             final int prime = 31;
346             int result = 1;
347             result = prime * result + ((qname == null) ? 0 : qname.hashCode());
348             result = prime * result + ((path == null) ? 0 : path.hashCode());
349             return result;
350         }
351
352         @Override
353         public boolean equals(final Object obj) {
354             if (this == obj) {
355                 return true;
356             }
357             if (obj == null) {
358                 return false;
359             }
360             if (getClass() != obj.getClass()) {
361                 return false;
362             }
363             final ListSchemaNodeImpl other = (ListSchemaNodeImpl) obj;
364             if (qname == null) {
365                 if (other.qname != null) {
366                     return false;
367                 }
368             } else if (!qname.equals(other.qname)) {
369                 return false;
370             }
371             if (path == null) {
372                 if (other.path != null) {
373                     return false;
374                 }
375             } else if (!path.equals(other.path)) {
376                 return false;
377             }
378             return true;
379         }
380
381         @Override
382         public String toString() {
383             return "list " + qname.getLocalName();
384         }
385     }
386
387 }