Merge "Modifications RpcResultBuilder class"
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / builder / impl / ChoiceBuilder.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.util.ArrayList;
11 import java.util.HashSet;
12 import java.util.List;
13 import java.util.Set;
14 import java.util.TreeSet;
15
16 import org.opendaylight.yangtools.yang.common.QName;
17 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
18 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
19 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
20 import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
21 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
22 import org.opendaylight.yangtools.yang.model.api.DerivableSchemaNode;
23 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
24 import org.opendaylight.yangtools.yang.model.api.Status;
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.AbstractSchemaNodeBuilder;
33 import org.opendaylight.yangtools.yang.parser.builder.util.Comparators;
34 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
35
36 import com.google.common.base.Optional;
37 import com.google.common.base.Preconditions;
38 import com.google.common.collect.ImmutableList;
39 import com.google.common.collect.ImmutableSet;
40
41 public final class ChoiceBuilder extends AbstractSchemaNodeBuilder implements DataSchemaNodeBuilder,
42 AugmentationTargetBuilder {
43     private ChoiceNodeImpl instance;
44
45     // DataSchemaNode args
46     private boolean augmenting;
47     private boolean addedByUses;
48     private boolean configuration;
49     private ChoiceNode originalNode;
50     private ChoiceBuilder originalBuilder;
51     private final ConstraintsBuilder constraints;
52     // AugmentationTarget args
53     private final Set<AugmentationSchema> augmentations = new HashSet<>();
54     private final List<AugmentationSchemaBuilder> augmentationBuilders = new ArrayList<>();
55     // ChoiceNode args
56     private final Set<ChoiceCaseBuilder> caseBuilders = new HashSet<>();
57     private String defaultCase;
58
59     public ChoiceBuilder(final String moduleName, final int line, final QName qname, final SchemaPath path) {
60         super(moduleName, line, qname);
61         this.schemaPath = path;
62         constraints = new ConstraintsBuilderImpl(moduleName, line);
63     }
64
65     public ChoiceBuilder(final String moduleName, final int line, final QName qname, final SchemaPath path,
66             final ChoiceNode base) {
67         super(moduleName, line, qname);
68         this.schemaPath = path;
69         constraints = new ConstraintsBuilderImpl(moduleName, line, base.getConstraints());
70
71         description = base.getDescription();
72         reference = base.getReference();
73         status = base.getStatus();
74         augmenting = base.isAugmenting();
75         addedByUses = base.isAddedByUses();
76         originalNode =  base;
77         configuration = base.isConfiguration();
78         augmentations.addAll(base.getAvailableAugmentations());
79
80         Set<DataSchemaNodeBuilder> wrapped = BuilderUtils.wrapChildNodes(moduleName, line, new HashSet<DataSchemaNode>(
81                 base.getCases()), path, qname);
82         for (DataSchemaNodeBuilder wrap : wrapped) {
83             if (wrap instanceof ChoiceCaseBuilder) {
84                 caseBuilders.add((ChoiceCaseBuilder) wrap);
85             }
86         }
87
88         addedUnknownNodes.addAll(BuilderUtils.wrapUnknownNodes(moduleName, line, base.getUnknownSchemaNodes(), path,
89                 qname));
90     }
91
92     @Override
93     public ChoiceNode build() {
94         if (instance != null) {
95             return instance;
96         }
97
98         instance = new ChoiceNodeImpl(qname, schemaPath);
99
100         instance.description = description;
101         instance.reference = reference;
102         instance.status = status;
103         instance.augmenting = augmenting;
104         instance.addedByUses = addedByUses;
105         instance.configuration = configuration;
106
107         instance.constraints = constraints.toInstance();
108         instance.defaultCase = defaultCase;
109
110         // ORIGINAL NODE
111         if (originalNode == null && originalBuilder != null) {
112             originalNode = originalBuilder.build();
113         }
114         instance.original = originalNode;
115
116         // CASES
117         final Set<ChoiceCaseNode> cases = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
118         for (ChoiceCaseBuilder caseBuilder : caseBuilders) {
119             cases.add(caseBuilder.build());
120         }
121         instance.cases = ImmutableSet.copyOf(cases);
122
123         // AUGMENTATIONS
124         for (AugmentationSchemaBuilder builder : augmentationBuilders) {
125             augmentations.add(builder.build());
126         }
127         instance.augmentations = ImmutableSet.copyOf(augmentations);
128
129         // UNKNOWN NODES
130         for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
131             unknownNodes.add(b.build());
132         }
133         instance.unknownNodes = ImmutableList.copyOf(unknownNodes);
134
135         return instance;
136     }
137
138     public Set<ChoiceCaseBuilder> getCases() {
139         return caseBuilders;
140     }
141
142     /**
143      * Get case by name.
144      *
145      * @param caseName
146      *            name of case to search
147      * @return case with given name if present, null otherwise
148      */
149     public ChoiceCaseBuilder getCaseNodeByName(final String caseName) {
150         for (ChoiceCaseBuilder addedCase : caseBuilders) {
151             if (addedCase.getQName().getLocalName().equals(caseName)) {
152                 return addedCase;
153             }
154         }
155         return null;
156     }
157
158     /**
159      * Add case node to this choice.
160      *
161      * If node is not declared with 'case' keyword, create new case builder and
162      * make this node child of newly created case.
163      *
164      * @param caseNode
165      *            case node
166      */
167     public void addCase(final DataSchemaNodeBuilder caseNode) {
168         QName caseQName = caseNode.getQName();
169         String caseName = caseQName.getLocalName();
170
171         for (ChoiceCaseBuilder existingCase : caseBuilders) {
172             if (existingCase.getQName().getLocalName().equals(caseName)) {
173                 throw new YangParseException(caseNode.getModuleName(), caseNode.getLine(), "Can not add '" + caseNode
174                         + "' to node '" + qname.getLocalName() + "' in module '" + getModuleName()
175                         + "': case with same name already declared at line " + existingCase.getLine());
176             }
177         }
178
179         if (caseNode instanceof ChoiceCaseBuilder) {
180             caseBuilders.add((ChoiceCaseBuilder) caseNode);
181         } else {
182             ChoiceCaseBuilder caseBuilder = new ChoiceCaseBuilder(caseNode.getModuleName(), caseNode.getLine(),
183                     caseQName, caseNode.getPath());
184             if (caseNode.isAugmenting()) {
185                 // if node is added by augmentation, set case builder augmenting
186                 // as true and node augmenting as false
187                 caseBuilder.setAugmenting(true);
188                 caseNode.setAugmenting(false);
189             }
190             SchemaPath newPath = caseNode.getPath().createChild(caseQName);
191             caseNode.setPath(newPath);
192             caseBuilder.addChildNode(caseNode);
193             caseBuilders.add(caseBuilder);
194         }
195     }
196
197     @Override
198     public boolean isAugmenting() {
199         return augmenting;
200     }
201
202     @Override
203     public void setAugmenting(final boolean augmenting) {
204         this.augmenting = augmenting;
205     }
206
207     @Override
208     public boolean isAddedByUses() {
209         return addedByUses;
210     }
211
212     @Override
213     public void setAddedByUses(final boolean addedByUses) {
214         this.addedByUses = addedByUses;
215     }
216
217     @Override
218     public ChoiceBuilder getOriginal() {
219         return originalBuilder;
220     }
221
222     @Override
223     public void setOriginal(final SchemaNodeBuilder builder) {
224         Preconditions.checkArgument(builder instanceof ChoiceBuilder, "Original of choice cannot be " + builder);
225         this.originalBuilder = (ChoiceBuilder) builder;
226     }
227
228     @Override
229     public boolean isConfiguration() {
230         return configuration;
231     }
232
233     @Override
234     public void setConfiguration(final boolean configuration) {
235         this.configuration = configuration;
236     }
237
238     @Override
239     public ConstraintsBuilder getConstraints() {
240         return constraints;
241     }
242
243     @Override
244     public void addAugmentation(final AugmentationSchemaBuilder augment) {
245         augmentationBuilders.add(augment);
246     }
247
248     public List<AugmentationSchemaBuilder> getAugmentationBuilders() {
249         return augmentationBuilders;
250     }
251
252     public String getDefaultCase() {
253         return defaultCase;
254     }
255
256     public void setDefaultCase(final String defaultCase) {
257         this.defaultCase = defaultCase;
258     }
259
260     @Override
261     public int hashCode() {
262         final int prime = 31;
263         int result = 1;
264         result = prime * result + ((schemaPath == null) ? 0 : schemaPath.hashCode());
265         return result;
266     }
267
268     @Override
269     public boolean equals(final Object obj) {
270         if (this == obj) {
271             return true;
272         }
273         if (obj == null) {
274             return false;
275         }
276         if (getClass() != obj.getClass()) {
277             return false;
278         }
279         ChoiceBuilder other = (ChoiceBuilder) obj;
280         if (schemaPath == null) {
281             if (other.schemaPath != null) {
282                 return false;
283             }
284         } else if (!schemaPath.equals(other.schemaPath)) {
285             return false;
286         }
287         if (getParent() == null) {
288             if (other.getParent() != null) {
289                 return false;
290             }
291         } else if (!getParent().equals(other.getParent())) {
292             return false;
293         }
294         return true;
295     }
296
297     @Override
298     public String toString() {
299         return "choice " + qname.getLocalName();
300     }
301
302     private static final class ChoiceNodeImpl implements ChoiceNode, DerivableSchemaNode {
303         private final QName qname;
304         private final SchemaPath path;
305         private String description;
306         private String reference;
307         private Status status;
308         private boolean augmenting;
309         private boolean addedByUses;
310         private ChoiceNode original;
311         private boolean configuration;
312         private ConstraintDefinition constraints;
313         private ImmutableSet<ChoiceCaseNode> cases;
314         private ImmutableSet<AugmentationSchema> augmentations;
315         private ImmutableList<UnknownSchemaNode> unknownNodes;
316         private String defaultCase;
317
318         private ChoiceNodeImpl(final QName qname, final SchemaPath path) {
319             this.qname = qname;
320             this.path = path;
321         }
322
323         @Override
324         public QName getQName() {
325             return qname;
326         }
327
328         @Override
329         public SchemaPath getPath() {
330             return path;
331         }
332
333         @Override
334         public String getDescription() {
335             return description;
336         }
337
338         @Override
339         public String getReference() {
340             return reference;
341         }
342
343         @Override
344         public Status getStatus() {
345             return status;
346         }
347
348         @Override
349         public boolean isAugmenting() {
350             return augmenting;
351         }
352
353         @Override
354         public boolean isAddedByUses() {
355             return addedByUses;
356         }
357
358         @Override
359         public Optional<ChoiceNode> getOriginal() {
360             return Optional.fromNullable(original);
361         }
362
363         @Override
364         public boolean isConfiguration() {
365             return configuration;
366         }
367
368         @Override
369         public ConstraintDefinition getConstraints() {
370             return constraints;
371         }
372
373         @Override
374         public Set<AugmentationSchema> getAvailableAugmentations() {
375             return augmentations;
376         }
377
378         @Override
379         public List<UnknownSchemaNode> getUnknownSchemaNodes() {
380             return unknownNodes;
381         }
382
383         @Override
384         public Set<ChoiceCaseNode> getCases() {
385             return cases;
386         }
387
388         @Override
389         public ChoiceCaseNode getCaseNodeByName(final QName name) {
390             if (name == null) {
391                 throw new IllegalArgumentException("Choice Case QName cannot be NULL!");
392             }
393             for (final ChoiceCaseNode caseNode : cases) {
394                 if (caseNode != null && name.equals(caseNode.getQName())) {
395                     return caseNode;
396                 }
397             }
398             return null;
399         }
400
401         @Override
402         public ChoiceCaseNode getCaseNodeByName(final String name) {
403             if (name == null) {
404                 throw new IllegalArgumentException("Choice Case string Name cannot be NULL!");
405             }
406             for (final ChoiceCaseNode caseNode : cases) {
407                 if (caseNode != null && (caseNode.getQName() != null)
408                         && name.equals(caseNode.getQName().getLocalName())) {
409                     return caseNode;
410                 }
411             }
412             return null;
413         }
414
415         @Override
416         public String getDefaultCase() {
417             return defaultCase;
418         }
419
420         @Override
421         public int hashCode() {
422             final int prime = 31;
423             int result = 1;
424             result = prime * result + ((qname == null) ? 0 : qname.hashCode());
425             result = prime * result + ((path == null) ? 0 : path.hashCode());
426             return result;
427         }
428
429         @Override
430         public boolean equals(final Object obj) {
431             if (this == obj) {
432                 return true;
433             }
434             if (obj == null) {
435                 return false;
436             }
437             if (getClass() != obj.getClass()) {
438                 return false;
439             }
440             ChoiceNodeImpl other = (ChoiceNodeImpl) obj;
441             if (qname == null) {
442                 if (other.qname != null) {
443                     return false;
444                 }
445             } else if (!qname.equals(other.qname)) {
446                 return false;
447             }
448             if (path == null) {
449                 if (other.path != null) {
450                     return false;
451                 }
452             } else if (!path.equals(other.path)) {
453                 return false;
454             }
455             return true;
456         }
457
458         @Override
459         public String toString() {
460             StringBuilder sb = new StringBuilder(ChoiceNodeImpl.class.getSimpleName());
461             sb.append("[");
462             sb.append("qname=").append(qname);
463             sb.append("]");
464             return sb.toString();
465         }
466
467     }
468
469 }