Merge "Yang parser refactoring."
[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 java.net.URI;
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.Date;
14 import java.util.HashMap;
15 import java.util.HashSet;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Set;
19 import java.util.TreeSet;
20
21 import org.opendaylight.yangtools.yang.common.QName;
22 import org.opendaylight.yangtools.yang.model.api.*;
23 import org.opendaylight.yangtools.yang.parser.builder.api.AbstractDataNodeContainerBuilder;
24 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
25 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationTargetBuilder;
26 import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
27 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
28 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
29 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
30 import org.opendaylight.yangtools.yang.parser.util.Comparators;
31 import org.opendaylight.yangtools.yang.parser.util.ParserUtils;
32 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
33
34 public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilder implements DataSchemaNodeBuilder,
35         AugmentationTargetBuilder {
36     private boolean isBuilt;
37     private final ListSchemaNodeImpl instance;
38     // SchemaNode args
39     private SchemaPath schemaPath;
40     // DataSchemaNode args
41     private final ConstraintsBuilder constraints;
42     // AugmentationTarget args
43     private final List<AugmentationSchema> augmentations = new ArrayList<>();
44     private final List<AugmentationSchemaBuilder> augmentationBuilders = new ArrayList<>();
45
46
47     public ListSchemaNodeBuilder(final String moduleName, final int line, final QName qname, final SchemaPath path) {
48         super(moduleName, line, qname);
49         this.schemaPath = path;
50         instance = new ListSchemaNodeImpl(qname, path);
51         constraints = new ConstraintsBuilder(moduleName, line);
52     }
53
54     public ListSchemaNodeBuilder(final String moduleName, final int line, final QName qname, final SchemaPath path, final ListSchemaNode base) {
55         super(moduleName, line, qname);
56         schemaPath = path;
57         instance = new ListSchemaNodeImpl(qname, path);
58         constraints = new ConstraintsBuilder(moduleName, line, base.getConstraints());
59
60         instance.keyDefinition = base.getKeyDefinition();
61         instance.userOrdered = base.isUserOrdered();
62
63         instance.description = base.getDescription();
64         instance.reference = base.getReference();
65         instance.status = base.getStatus();
66         instance.augmenting = base.isAugmenting();
67         instance.addedByUses = base.isAddedByUses();
68         instance.configuration = base.isConfiguration();
69         instance.constraints = base.getConstraints();
70         instance.augmentations.addAll(base.getAvailableAugmentations());
71
72         URI ns = qname.getNamespace();
73         Date rev = qname.getRevision();
74         String pref = qname.getPrefix();
75         addedChildNodes.addAll(ParserUtils.wrapChildNodes(moduleName, line, base.getChildNodes(), path, ns, rev, pref));
76         addedGroupings.addAll(ParserUtils.wrapGroupings(moduleName, line, base.getGroupings(), path, ns, rev, pref));
77         addedTypedefs.addAll(ParserUtils.wrapTypedefs(moduleName, line, base, path, ns, rev, pref));
78         addedUnknownNodes.addAll(ParserUtils.wrapUnknownNodes(moduleName, line, base.getUnknownSchemaNodes(), path, ns,
79                 rev, pref));
80
81         instance.uses.addAll(base.getUses());
82     }
83
84     @Override
85     public ListSchemaNode build() {
86         if (!isBuilt) {
87             // CHILD NODES
88             for (DataSchemaNodeBuilder node : addedChildNodes) {
89                 DataSchemaNode child = node.build();
90                 childNodes.put(child.getQName(), child);
91             }
92             instance.addChildNodes(childNodes);
93
94             // TYPEDEFS
95             for (TypeDefinitionBuilder entry : addedTypedefs) {
96                 typedefs.add(entry.build());
97             }
98             instance.addTypeDefinitions(typedefs);
99
100             // USES
101             for (UsesNodeBuilder builder : addedUsesNodes) {
102                 usesNodes.add(builder.build());
103             }
104             instance.addUses(usesNodes);
105
106             // GROUPINGS
107             for (GroupingBuilder builder : addedGroupings) {
108                 groupings.add(builder.build());
109             }
110             instance.addGroupings(groupings);
111
112             // AUGMENTATIONS
113             for (AugmentationSchemaBuilder builder : augmentationBuilders) {
114                 augmentations.add(builder.build());
115             }
116             instance.addAvailableAugmentations(new HashSet<>(augmentations));
117
118             // UNKNOWN NODES
119             for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
120                 unknownNodes.add(b.build());
121             }
122             Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
123             instance.addUnknownSchemaNodes(unknownNodes);
124
125             instance.setConstraints(constraints.build());
126
127             isBuilt = true;
128         }
129         return instance;
130     }
131
132     @Override
133     public Set<TypeDefinitionBuilder> getTypeDefinitionBuilders() {
134         return addedTypedefs;
135     }
136
137     @Override
138     public void addTypedef(final TypeDefinitionBuilder type) {
139         String typeName = type.getQName().getLocalName();
140         for (TypeDefinitionBuilder addedTypedef : addedTypedefs) {
141             if (addedTypedef.getQName().getLocalName().equals(typeName)) {
142                 throw new YangParseException(moduleName, type.getLine(), "Can not add typedef '" + typeName
143                         + "': typedef with same name already declared at line " + addedTypedef.getLine());
144             }
145         }
146         addedTypedefs.add(type);
147     }
148
149     @Override
150     public SchemaPath getPath() {
151         return instance.path;
152     }
153
154     @Override
155     public void setPath(SchemaPath path) {
156         instance.path = path;
157     }
158
159     @Override
160     public String getDescription() {
161         return instance.description;
162     }
163
164     @Override
165     public void setDescription(final String description) {
166         instance.description = description;
167     }
168
169     @Override
170     public String getReference() {
171         return instance.reference;
172     }
173
174     @Override
175     public void setReference(final String reference) {
176         instance.reference = reference;
177     }
178
179     @Override
180     public Status getStatus() {
181         return instance.status;
182     }
183
184     @Override
185     public void setStatus(Status status) {
186         if (status != null) {
187             instance.status = status;
188         }
189     }
190
191     @Override
192     public void addAugmentation(AugmentationSchemaBuilder augment) {
193         augmentationBuilders.add(augment);
194     }
195
196     public List<AugmentationSchemaBuilder> getAugmentationBuilders() {
197         return augmentationBuilders;
198     }
199
200     public List<QName> getKeyDefinition() {
201         return instance.keyDefinition;
202     }
203
204     public void setKeyDefinition(final List<QName> keyDefinition) {
205         instance.keyDefinition = keyDefinition;
206     }
207
208     @Override
209     public boolean isAugmenting() {
210         return instance.augmenting;
211     }
212
213     @Override
214     public void setAugmenting(boolean augmenting) {
215         instance.augmenting = augmenting;
216     }
217
218     @Override
219     public boolean isAddedByUses() {
220         return instance.addedByUses;
221     }
222
223     @Override
224     public void setAddedByUses(final boolean addedByUses) {
225         instance.addedByUses = addedByUses;
226     }
227
228     @Override
229     public Boolean isConfiguration() {
230         return instance.configuration;
231     }
232
233     @Override
234     public void setConfiguration(Boolean configuration) {
235         instance.configuration = configuration;
236     }
237
238     @Override
239     public ConstraintsBuilder getConstraints() {
240         return constraints;
241     }
242
243     public boolean isUserOrdered() {
244         return instance.userOrdered;
245     }
246
247     public void setUserOrdered(final boolean userOrdered) {
248         instance.userOrdered = userOrdered;
249     }
250
251     @Override
252     public int hashCode() {
253         final int prime = 31;
254         int result = 1;
255         result = prime * result + ((schemaPath == null) ? 0 : schemaPath.hashCode());
256         return result;
257     }
258
259     @Override
260     public boolean equals(Object obj) {
261         if (this == obj) {
262             return true;
263         }
264         if (obj == null) {
265             return false;
266         }
267         if (getClass() != obj.getClass()) {
268             return false;
269         }
270         ListSchemaNodeBuilder other = (ListSchemaNodeBuilder) obj;
271         if (schemaPath == null) {
272             if (other.schemaPath != null) {
273                 return false;
274             }
275         } else if (!schemaPath.equals(other.schemaPath)) {
276             return false;
277         }
278         if (parentBuilder == null) {
279             if (other.parentBuilder != null) {
280                 return false;
281             }
282         } else if (!parentBuilder.equals(other.parentBuilder)) {
283             return false;
284         }
285         return true;
286     }
287
288     @Override
289     public String toString() {
290         return "list " + qname.getLocalName();
291     }
292
293     public final class ListSchemaNodeImpl implements ListSchemaNode {
294         private final QName qname;
295         private SchemaPath path;
296         private String description;
297         private String reference;
298         private Status status = Status.CURRENT;
299         private List<QName> keyDefinition = Collections.emptyList();
300         private boolean augmenting;
301         private boolean addedByUses;
302         private boolean configuration;
303         private ConstraintDefinition constraints;
304         private final Set<AugmentationSchema> augmentations = new HashSet<>();
305         private final Map<QName, DataSchemaNode> childNodes = new HashMap<>();
306         private final Set<TypeDefinition<?>> typeDefinitions = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
307         private final Set<GroupingDefinition> groupings = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
308         private final Set<UsesNode> uses = new HashSet<>();
309         private boolean userOrdered;
310         private final List<UnknownSchemaNode> unknownNodes = new ArrayList<>();
311
312         private ListSchemaNodeImpl(final QName qname, final SchemaPath path) {
313             this.qname = qname;
314             this.path = path;
315         }
316
317         @Override
318         public QName getQName() {
319             return qname;
320         }
321
322         @Override
323         public SchemaPath getPath() {
324             return path;
325         }
326
327         @Override
328         public String getDescription() {
329             return description;
330         }
331
332         @Override
333         public String getReference() {
334             return reference;
335         }
336
337         @Override
338         public Status getStatus() {
339             return status;
340         }
341
342         @Override
343         public List<QName> getKeyDefinition() {
344             return keyDefinition;
345         }
346
347         @Override
348         public boolean isAugmenting() {
349             return augmenting;
350         }
351
352         @Override
353         public boolean isAddedByUses() {
354             return addedByUses;
355         }
356
357         @Override
358         public boolean isConfiguration() {
359             return configuration;
360         }
361
362         @Override
363         public ConstraintDefinition getConstraints() {
364             return constraints;
365         }
366
367         private void setConstraints(ConstraintDefinition constraints) {
368             this.constraints = constraints;
369         }
370
371         @Override
372         public Set<AugmentationSchema> getAvailableAugmentations() {
373             return Collections.unmodifiableSet(augmentations);
374         }
375
376         private void addAvailableAugmentations(Set<AugmentationSchema> augmentations) {
377             if (augmentations != null) {
378                 this.augmentations.addAll(augmentations);
379             }
380         }
381
382         @Override
383         public Set<DataSchemaNode> getChildNodes() {
384             final Set<DataSchemaNode> result = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
385             result.addAll(childNodes.values());
386             return Collections.unmodifiableSet(result);
387         }
388
389         private void addChildNodes(Map<QName, DataSchemaNode> childNodes) {
390             if (childNodes != null) {
391                 this.childNodes.putAll(childNodes);
392             }
393         }
394
395         @Override
396         public Set<GroupingDefinition> getGroupings() {
397             return Collections.unmodifiableSet(groupings);
398         }
399
400         private void addGroupings(Set<GroupingDefinition> groupings) {
401             if (groupings != null) {
402                 this.groupings.addAll(groupings);
403             }
404         }
405
406         @Override
407         public Set<TypeDefinition<?>> getTypeDefinitions() {
408             return Collections.unmodifiableSet(typeDefinitions);
409         }
410
411         private void addTypeDefinitions(Set<TypeDefinition<?>> typeDefinitions) {
412             if (typeDefinitions != null) {
413                 this.typeDefinitions.addAll(typeDefinitions);
414             }
415         }
416
417         @Override
418         public Set<UsesNode> getUses() {
419             return Collections.unmodifiableSet(uses);
420         }
421
422         private void addUses(Set<UsesNode> uses) {
423             if (uses != null) {
424                 this.uses.addAll(uses);
425             }
426         }
427
428         @Override
429         public DataSchemaNode getDataChildByName(QName name) {
430             return childNodes.get(name);
431         }
432
433         @Override
434         public DataSchemaNode getDataChildByName(String name) {
435             DataSchemaNode result = null;
436             for (Map.Entry<QName, DataSchemaNode> entry : childNodes.entrySet()) {
437                 if (entry.getKey().getLocalName().equals(name)) {
438                     result = entry.getValue();
439                     break;
440                 }
441             }
442             return result;
443         }
444
445         @Override
446         public boolean isUserOrdered() {
447             return userOrdered;
448         }
449
450         @Override
451         public List<UnknownSchemaNode> getUnknownSchemaNodes() {
452             return Collections.unmodifiableList(unknownNodes);
453         }
454
455         private void addUnknownSchemaNodes(List<UnknownSchemaNode> unknownNodes) {
456             if (unknownNodes != null) {
457                 this.unknownNodes.addAll(unknownNodes);
458             }
459         }
460
461         @Override
462         public int hashCode() {
463             final int prime = 31;
464             int result = 1;
465             result = prime * result + ((qname == null) ? 0 : qname.hashCode());
466             result = prime * result + ((path == null) ? 0 : path.hashCode());
467             return result;
468         }
469
470         @Override
471         public boolean equals(Object obj) {
472             if (this == obj) {
473                 return true;
474             }
475             if (obj == null) {
476                 return false;
477             }
478             if (getClass() != obj.getClass()) {
479                 return false;
480             }
481             final ListSchemaNodeImpl other = (ListSchemaNodeImpl) obj;
482             if (qname == null) {
483                 if (other.qname != null) {
484                     return false;
485                 }
486             } else if (!qname.equals(other.qname)) {
487                 return false;
488             }
489             if (path == null) {
490                 if (other.path != null) {
491                     return false;
492                 }
493             } else if (!path.equals(other.path)) {
494                 return false;
495             }
496             return true;
497         }
498
499         @Override
500         public String toString() {
501             return "list " + qname.getLocalName();
502         }
503     }
504
505 }