Merge "Memory hog: ImmutableList is appropriate here"
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / builder / impl / ChoiceCaseBuilder.java
1 /*
2  * Copyright (c) 2014 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.HashSet;
15 import java.util.List;
16 import java.util.Set;
17 import java.util.TreeSet;
18
19 import org.opendaylight.yangtools.yang.common.QName;
20 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
21 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
22 import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
23 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
24 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
25 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
26 import org.opendaylight.yangtools.yang.model.api.Status;
27 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
28 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
29 import org.opendaylight.yangtools.yang.model.api.UsesNode;
30 import org.opendaylight.yangtools.yang.parser.builder.api.AbstractDataNodeContainerBuilder;
31 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
32 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationTargetBuilder;
33 import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
34 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
35 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
36 import org.opendaylight.yangtools.yang.parser.util.Comparators;
37 import org.opendaylight.yangtools.yang.parser.util.ParserUtils;
38 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
39
40 public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder implements DataSchemaNodeBuilder,
41         AugmentationTargetBuilder {
42     private boolean isBuilt;
43     private final ChoiceCaseNodeImpl instance;
44     // SchemaNode args
45     private final SchemaPath schemaPath;
46     private final ConstraintsBuilder constraints;
47     // AugmentationTarget args
48     private final List<AugmentationSchemaBuilder> augmentationBuilders = new ArrayList<>();
49
50     public ChoiceCaseBuilder(final String moduleName, final int line, final QName qname, final SchemaPath path) {
51         super(moduleName, line, qname);
52         this.schemaPath = path;
53         instance = new ChoiceCaseNodeImpl(qname, path);
54         constraints = new ConstraintsBuilder(moduleName, line);
55     }
56
57     public ChoiceCaseBuilder(final String moduleName, final int line, final QName qname, final SchemaPath path, final ChoiceCaseNode base) {
58         super(moduleName, line, qname);
59         this.schemaPath = path;
60         instance = new ChoiceCaseNodeImpl(qname, path);
61         constraints = new ConstraintsBuilder(moduleName, line, base.getConstraints());
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.constraints = base.getConstraints();
69         instance.augmentations.addAll(base.getAvailableAugmentations());
70
71         URI ns = qname.getNamespace();
72         Date rev = qname.getRevision();
73         String pref = qname.getPrefix();
74         addedChildNodes.addAll(ParserUtils.wrapChildNodes(moduleName, line, base.getChildNodes(), path, ns, rev, pref));
75         addedGroupings.addAll(ParserUtils.wrapGroupings(moduleName, line, base.getGroupings(), path, ns, rev, pref));
76
77         instance.uses.addAll(base.getUses());
78         instance.unknownNodes.addAll(base.getUnknownSchemaNodes());
79     }
80
81     @Override
82     public ChoiceCaseNode build() {
83         if (!isBuilt) {
84             instance.setConstraints(constraints.build());
85
86             // CHILD NODES
87             for (DataSchemaNodeBuilder node : addedChildNodes) {
88                 childNodes.add(node.build());
89             }
90             instance.addChildNodes(childNodes);
91
92             // USES
93             for (UsesNodeBuilder builder : addedUsesNodes) {
94                 usesNodes.add(builder.build());
95             }
96             instance.addUses(usesNodes);
97
98             // UNKNOWN NODES
99             for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
100                 unknownNodes.add(b.build());
101             }
102             Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
103             instance.addUnknownSchemaNodes(unknownNodes);
104
105             // AUGMENTATIONS
106             final Set<AugmentationSchema> augmentations = new HashSet<>();
107             for (AugmentationSchemaBuilder builder : augmentationBuilders) {
108                 augmentations.add(builder.build());
109             }
110             instance.addAvailableAugmentations(augmentations);
111
112             isBuilt = true;
113         }
114
115         return instance;
116     }
117
118
119     @Override
120     public SchemaPath getPath() {
121         return instance.path;
122     }
123
124     @Override
125     public void setPath(final SchemaPath path) {
126         instance.path = path;
127     }
128
129     @Override
130     public String getDescription() {
131         return instance.description;
132     }
133
134     @Override
135     public void setDescription(final String description) {
136         instance.description = description;
137     }
138
139     @Override
140     public String getReference() {
141         return instance.reference;
142     }
143
144     @Override
145     public void setReference(final String reference) {
146         instance.reference = reference;
147     }
148
149     @Override
150     public Status getStatus() {
151         return instance.status;
152     }
153
154     @Override
155     public void setStatus(final Status status) {
156         if (status != null) {
157             instance.status = status;
158         }
159     }
160
161     @Override
162     public boolean isAugmenting() {
163         return instance.augmenting;
164     }
165
166     @Override
167     public void setAugmenting(final boolean augmenting) {
168         instance.augmenting = augmenting;
169     }
170
171     @Override
172     public boolean isAddedByUses() {
173         return instance.addedByUses;
174     }
175
176     @Override
177     public void setAddedByUses(final boolean addedByUses) {
178         instance.addedByUses = addedByUses;
179     }
180
181     @Override
182     public Set<TypeDefinitionBuilder> getTypeDefinitionBuilders() {
183         return Collections.emptySet();
184     }
185
186     @Override
187     public void addTypedef(final TypeDefinitionBuilder typedefBuilder) {
188         throw new YangParseException(moduleName, line, "Can not add type definition to choice case.");
189     }
190
191     @Override
192     public boolean isConfiguration() {
193         return false;
194     }
195
196     @Override
197     public void setConfiguration(final boolean configuration) {
198         throw new YangParseException(moduleName, line, "Can not add config statement to choice case.");
199     }
200
201     @Override
202     public ConstraintsBuilder getConstraints() {
203         return constraints;
204     }
205
206     @Override
207     public void addAugmentation(final AugmentationSchemaBuilder augment) {
208         augmentationBuilders.add(augment);
209     }
210
211     @Override
212     public int hashCode() {
213         final int prime = 31;
214         int result = 1;
215         result = prime * result + ((schemaPath == null) ? 0 : schemaPath.hashCode());
216         return result;
217     }
218
219     @Override
220     public boolean equals(final Object obj) {
221         if (this == obj) {
222             return true;
223         }
224         if (obj == null) {
225             return false;
226         }
227         if (getClass() != obj.getClass()) {
228             return false;
229         }
230         ChoiceCaseBuilder other = (ChoiceCaseBuilder) obj;
231         if (schemaPath == null) {
232             if (other.schemaPath != null) {
233                 return false;
234             }
235         } else if (!schemaPath.equals(other.schemaPath)) {
236             return false;
237         }
238         if (parentBuilder == null) {
239             if (other.parentBuilder != null) {
240                 return false;
241             }
242         } else if (!parentBuilder.equals(other.parentBuilder)) {
243             return false;
244         }
245         return true;
246     }
247
248     @Override
249     public String toString() {
250         return "case " + getQName().getLocalName();
251     }
252
253     private static final class ChoiceCaseNodeImpl implements ChoiceCaseNode {
254         private final QName qname;
255         private SchemaPath path;
256         private String description;
257         private String reference;
258         private Status status = Status.CURRENT;
259         private boolean augmenting;
260         private boolean addedByUses;
261         private ConstraintDefinition constraints;
262         private final Set<DataSchemaNode> childNodes = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
263         private final Set<AugmentationSchema> augmentations = new HashSet<>();
264         private final Set<UsesNode> uses = new HashSet<>();
265         private final List<UnknownSchemaNode> unknownNodes = new ArrayList<>();
266
267         private ChoiceCaseNodeImpl(final QName qname, final SchemaPath path) {
268             this.qname = qname;
269             this.path = path;
270         }
271
272         @Override
273         public QName getQName() {
274             return qname;
275         }
276
277         @Override
278         public SchemaPath getPath() {
279             return path;
280         }
281
282         @Override
283         public String getDescription() {
284             return description;
285         }
286
287         @Override
288         public String getReference() {
289             return reference;
290         }
291
292         @Override
293         public Status getStatus() {
294             return status;
295         }
296
297         @Override
298         public boolean isConfiguration() {
299             return false;
300         }
301
302         @Override
303         public ConstraintDefinition getConstraints() {
304             return constraints;
305         }
306
307         private void setConstraints(final ConstraintDefinition constraints) {
308             this.constraints = constraints;
309         }
310
311         @Override
312         public boolean isAugmenting() {
313             return augmenting;
314         }
315
316         @Override
317         public boolean isAddedByUses() {
318             return addedByUses;
319         }
320
321         @Override
322         public List<UnknownSchemaNode> getUnknownSchemaNodes() {
323             return Collections.unmodifiableList(unknownNodes);
324         }
325
326         private void addUnknownSchemaNodes(final List<UnknownSchemaNode> unknownNodes) {
327             if (unknownNodes != null) {
328                 this.unknownNodes.addAll(unknownNodes);
329             }
330         }
331
332         /**
333          * Always returns an empty set, because case node can not contains type
334          * definitions.
335          */
336         @Override
337         public Set<TypeDefinition<?>> getTypeDefinitions() {
338             return Collections.emptySet();
339         }
340
341         @Override
342         public Set<DataSchemaNode> getChildNodes() {
343             return Collections.unmodifiableSet(childNodes);
344         }
345
346         private void addChildNodes(final Set<DataSchemaNode> childNodes) {
347             if (childNodes != null) {
348                 this.childNodes.addAll(childNodes);
349             }
350         }
351
352         @Override
353         public Set<GroupingDefinition> getGroupings() {
354             return Collections.emptySet();
355         }
356
357         @Override
358         public DataSchemaNode getDataChildByName(final QName name) {
359             return getChildNode(childNodes, name);
360         }
361
362         @Override
363         public DataSchemaNode getDataChildByName(final String name) {
364             return getChildNode(childNodes, name);
365         }
366
367         @Override
368         public Set<UsesNode> getUses() {
369             return Collections.unmodifiableSet(uses);
370         }
371
372         private void addUses(final Set<UsesNode> uses) {
373             if (uses != null) {
374                 this.uses.addAll(uses);
375             }
376         }
377
378         @Override
379         public Set<AugmentationSchema> getAvailableAugmentations() {
380             return Collections.unmodifiableSet(augmentations);
381         }
382
383         private void addAvailableAugmentations(final Set<AugmentationSchema> augmentations) {
384             if (augmentations != null) {
385                 this.augmentations.addAll(augmentations);
386             }
387         }
388
389         @Override
390         public int hashCode() {
391             final int prime = 31;
392             int result = 1;
393             result = prime * result + ((qname == null) ? 0 : qname.hashCode());
394             result = prime * result + ((path == null) ? 0 : path.hashCode());
395             return result;
396         }
397
398         @Override
399         public boolean equals(final Object obj) {
400             if (this == obj) {
401                 return true;
402             }
403             if (obj == null) {
404                 return false;
405             }
406             if (getClass() != obj.getClass()) {
407                 return false;
408             }
409             ChoiceCaseNodeImpl other = (ChoiceCaseNodeImpl) obj;
410             if (qname == null) {
411                 if (other.qname != null) {
412                     return false;
413                 }
414             } else if (!qname.equals(other.qname)) {
415                 return false;
416             }
417             if (path == null) {
418                 if (other.path != null) {
419                     return false;
420                 }
421             } else if (!path.equals(other.path)) {
422                 return false;
423             }
424             return true;
425         }
426
427         @Override
428         public String toString() {
429             StringBuilder sb = new StringBuilder(ChoiceCaseNodeImpl.class.getSimpleName());
430             sb.append("[");
431             sb.append("qname=");
432             sb.append(qname);
433             sb.append("]");
434             return sb.toString();
435         }
436     }
437
438 }