Added more descriptive parsing exceptions.
[controller.git] / opendaylight / sal / yang-prototype / code-generator / yang-model-parser-impl / src / main / java / org / opendaylight / controller / yang / parser / builder / impl / AugmentationSchemaBuilderImpl.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.controller.yang.parser.builder.impl;
9
10 import java.util.ArrayList;
11 import java.util.Collections;
12 import java.util.HashSet;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.Set;
16 import java.util.TreeMap;
17 import java.util.TreeSet;
18
19 import org.opendaylight.controller.yang.common.QName;
20 import org.opendaylight.controller.yang.model.api.AugmentationSchema;
21 import org.opendaylight.controller.yang.model.api.DataSchemaNode;
22 import org.opendaylight.controller.yang.model.api.GroupingDefinition;
23 import org.opendaylight.controller.yang.model.api.RevisionAwareXPath;
24 import org.opendaylight.controller.yang.model.api.SchemaPath;
25 import org.opendaylight.controller.yang.model.api.Status;
26 import org.opendaylight.controller.yang.model.api.TypeDefinition;
27 import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
28 import org.opendaylight.controller.yang.model.api.UsesNode;
29 import org.opendaylight.controller.yang.model.util.RevisionAwareXPathImpl;
30 import org.opendaylight.controller.yang.parser.builder.api.AbstractDataNodeContainerBuilder;
31 import org.opendaylight.controller.yang.parser.builder.api.AugmentationSchemaBuilder;
32 import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
33 import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder;
34 import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
35 import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
36 import org.opendaylight.controller.yang.parser.util.Comparators;
37 import org.opendaylight.controller.yang.parser.util.ParserListenerUtils;
38 import org.opendaylight.controller.yang.parser.util.YangParseException;
39
40 public final class AugmentationSchemaBuilderImpl extends AbstractDataNodeContainerBuilder implements
41         AugmentationSchemaBuilder {
42     private boolean built;
43     private final AugmentationSchemaImpl instance;
44
45     private String whenCondition;
46     private String description;
47     private String reference;
48     private Status status = Status.CURRENT;
49
50     private final String augmentTargetStr;
51     private SchemaPath dirtyAugmentTarget;
52     private SchemaPath finalAugmentTarget;
53
54     private final Set<UsesNodeBuilder> usesNodes = new HashSet<UsesNodeBuilder>();
55     private boolean resolved;
56
57     AugmentationSchemaBuilderImpl(final String moduleName, final int line, final String augmentTargetStr) {
58         super(moduleName, line, null);
59         this.augmentTargetStr = augmentTargetStr;
60         final SchemaPath targetPath = ParserListenerUtils.parseAugmentPath(augmentTargetStr);
61         dirtyAugmentTarget = targetPath;
62         instance = new AugmentationSchemaImpl(targetPath);
63     }
64
65     @Override
66     public Set<GroupingDefinition> getGroupings() {
67         return Collections.emptySet();
68     }
69
70     @Override
71     public Set<GroupingBuilder> getGroupingBuilders() {
72         return Collections.emptySet();
73     }
74
75     @Override
76     public void addGrouping(GroupingBuilder grouping) {
77         throw new YangParseException(moduleName, line, "augment can not contains grouping statement");
78     }
79
80     @Override
81     public void addUsesNode(UsesNodeBuilder usesBuilder) {
82         usesNodes.add(usesBuilder);
83     }
84
85     /**
86      * Always returns null.
87      */
88     @Override
89     public SchemaPath getPath() {
90         return null;
91     }
92
93     @Override
94     public AugmentationSchema build() {
95         if (!built) {
96             instance.setDescription(description);
97             instance.setReference(reference);
98             instance.setStatus(status);
99             instance.setTargetPath(finalAugmentTarget);
100
101             RevisionAwareXPath whenStmt;
102             if (whenCondition == null) {
103                 whenStmt = null;
104             } else {
105                 whenStmt = new RevisionAwareXPathImpl(whenCondition, false);
106             }
107             instance.setWhenCondition(whenStmt);
108
109             // CHILD NODES
110             final Map<QName, DataSchemaNode> childs = new TreeMap<QName, DataSchemaNode>(Comparators.QNAME_COMP);
111             for (DataSchemaNodeBuilder node : addedChildNodes) {
112                 childs.put(node.getQName(), node.build());
113             }
114             instance.setChildNodes(childs);
115
116             // USES
117             final Set<UsesNode> usesNodeDefinitions = new HashSet<UsesNode>();
118             for (UsesNodeBuilder builder : usesNodes) {
119                 usesNodeDefinitions.add(builder.build());
120             }
121             instance.setUses(usesNodeDefinitions);
122
123             // UNKNOWN NODES
124             List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
125             for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
126                 unknownNodes.add(b.build());
127             }
128             Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
129             instance.setUnknownSchemaNodes(unknownNodes);
130
131             built = true;
132         }
133         return instance;
134     }
135
136     @Override
137     public boolean isResolved() {
138         return resolved;
139     }
140
141     @Override
142     public void setResolved(boolean resolved) {
143         this.resolved = resolved;
144     }
145
146     public String getWhenCondition() {
147         return whenCondition;
148     }
149
150     public void addWhenCondition(String whenCondition) {
151         this.whenCondition = whenCondition;
152     }
153
154     @Override
155     public Set<TypeDefinitionBuilder> getTypeDefinitionBuilders() {
156         return Collections.emptySet();
157     }
158
159     @Override
160     public void addTypedef(TypeDefinitionBuilder type) {
161         throw new YangParseException(moduleName, line, "Augmentation can not contains typedef statement.");
162     }
163
164     @Override
165     public void setDescription(String description) {
166         this.description = description;
167     }
168
169     @Override
170     public void setReference(String reference) {
171         this.reference = reference;
172     }
173
174     @Override
175     public void setStatus(Status status) {
176         if (status != null) {
177             this.status = status;
178         }
179     }
180
181     @Override
182     public SchemaPath getTargetPath() {
183         return dirtyAugmentTarget;
184     }
185
186     @Override
187     public void setTargetPath(SchemaPath path) {
188         this.finalAugmentTarget = path;
189     }
190
191     @Override
192     public String getTargetPathAsString() {
193         return augmentTargetStr;
194     }
195
196     @Override
197     public int hashCode() {
198         final int prime = 17;
199         int result = 1;
200         result = prime * result + ((augmentTargetStr == null) ? 0 : augmentTargetStr.hashCode());
201         result = prime * result + ((whenCondition == null) ? 0 : whenCondition.hashCode());
202         result = prime * result + ((childNodes == null) ? 0 : childNodes.hashCode());
203         return result;
204     }
205
206     @Override
207     public boolean equals(Object obj) {
208         if (this == obj) {
209             return true;
210         }
211         if (obj == null) {
212             return false;
213         }
214         if (getClass() != obj.getClass()) {
215             return false;
216         }
217         AugmentationSchemaBuilderImpl other = (AugmentationSchemaBuilderImpl) obj;
218         if (augmentTargetStr == null) {
219             if (other.augmentTargetStr != null) {
220                 return false;
221             }
222         } else if (!augmentTargetStr.equals(other.augmentTargetStr)) {
223             return false;
224         }
225         if (whenCondition == null) {
226             if (other.whenCondition != null) {
227                 return false;
228             }
229         } else if (!whenCondition.equals(other.whenCondition)) {
230             return false;
231         }
232         if (childNodes == null) {
233             if (other.childNodes != null) {
234                 return false;
235             }
236         } else if (!childNodes.equals(other.childNodes)) {
237             return false;
238         }
239         return true;
240     }
241
242     public String toString() {
243         return "augment " + augmentTargetStr;
244     }
245
246     private final class AugmentationSchemaImpl implements AugmentationSchema {
247         private SchemaPath targetPath;
248         private RevisionAwareXPath whenCondition;
249         private Map<QName, DataSchemaNode> childNodes = Collections.emptyMap();
250         private Set<UsesNode> uses = Collections.emptySet();
251         private String description;
252         private String reference;
253         private Status status;
254         private List<UnknownSchemaNode> unknownNodes = Collections.emptyList();
255
256         private AugmentationSchemaImpl(SchemaPath targetPath) {
257             this.targetPath = targetPath;
258         }
259
260         @Override
261         public SchemaPath getTargetPath() {
262             return targetPath;
263         }
264
265         private void setTargetPath(SchemaPath path) {
266             this.targetPath = path;
267         }
268
269         @Override
270         public RevisionAwareXPath getWhenCondition() {
271             return whenCondition;
272         }
273
274         private void setWhenCondition(RevisionAwareXPath whenCondition) {
275             this.whenCondition = whenCondition;
276         }
277
278         @Override
279         public Set<DataSchemaNode> getChildNodes() {
280             final Set<DataSchemaNode> result = new TreeSet<DataSchemaNode>(Comparators.SCHEMA_NODE_COMP);
281             result.addAll(childNodes.values());
282             return result;
283         }
284
285         private void setChildNodes(Map<QName, DataSchemaNode> childNodes) {
286             if (childNodes != null) {
287                 this.childNodes = childNodes;
288             }
289         }
290
291         /**
292          * Always returns an empty set, because augment can not contains
293          * grouping statement.
294          */
295         @Override
296         public Set<GroupingDefinition> getGroupings() {
297             return Collections.emptySet();
298         }
299
300         @Override
301         public Set<UsesNode> getUses() {
302             return uses;
303         }
304
305         private void setUses(Set<UsesNode> uses) {
306             if (uses != null) {
307                 this.uses = uses;
308             }
309         }
310
311         /**
312          * Always returns an empty set, because augment can not contains type
313          * definitions.
314          */
315         @Override
316         public Set<TypeDefinition<?>> getTypeDefinitions() {
317             return Collections.emptySet();
318         }
319
320         @Override
321         public String getDescription() {
322             return description;
323         }
324
325         private void setDescription(String description) {
326             this.description = description;
327         }
328
329         @Override
330         public String getReference() {
331             return reference;
332         }
333
334         private void setReference(String reference) {
335             this.reference = reference;
336         }
337
338         @Override
339         public Status getStatus() {
340             return status;
341         }
342
343         private void setStatus(Status status) {
344             this.status = status;
345         }
346
347         @Override
348         public List<UnknownSchemaNode> getUnknownSchemaNodes() {
349             return unknownNodes;
350         }
351
352         private void setUnknownSchemaNodes(List<UnknownSchemaNode> unknownSchemaNodes) {
353             if (unknownSchemaNodes != null) {
354                 this.unknownNodes = unknownSchemaNodes;
355             }
356         }
357
358         @Override
359         public DataSchemaNode getDataChildByName(QName name) {
360             return childNodes.get(name);
361         }
362
363         @Override
364         public DataSchemaNode getDataChildByName(String name) {
365             DataSchemaNode result = null;
366             for (Map.Entry<QName, DataSchemaNode> entry : childNodes.entrySet()) {
367                 if (entry.getKey().getLocalName().equals(name)) {
368                     result = entry.getValue();
369                     break;
370                 }
371             }
372             return result;
373         }
374
375         @Override
376         public int hashCode() {
377             final int prime = 17;
378             int result = 1;
379             result = prime * result + ((targetPath == null) ? 0 : targetPath.hashCode());
380             result = prime * result + ((whenCondition == null) ? 0 : whenCondition.hashCode());
381             result = prime * result + ((childNodes == null) ? 0 : childNodes.hashCode());
382             return result;
383         }
384
385         @Override
386         public boolean equals(Object obj) {
387             if (this == obj) {
388                 return true;
389             }
390             if (obj == null) {
391                 return false;
392             }
393             if (getClass() != obj.getClass()) {
394                 return false;
395             }
396             AugmentationSchemaImpl other = (AugmentationSchemaImpl) obj;
397             if (targetPath == null) {
398                 if (other.targetPath != null) {
399                     return false;
400                 }
401             } else if (!targetPath.equals(other.targetPath)) {
402                 return false;
403             }
404             if (whenCondition == null) {
405                 if (other.whenCondition != null) {
406                     return false;
407                 }
408             } else if (!whenCondition.equals(other.whenCondition)) {
409                 return false;
410             }
411             if (childNodes == null) {
412                 if (other.childNodes != null) {
413                     return false;
414                 }
415             } else if (!childNodes.equals(other.childNodes)) {
416                 return false;
417             }
418             return true;
419         }
420
421         @Override
422         public String toString() {
423             StringBuilder sb = new StringBuilder(AugmentationSchemaImpl.class.getSimpleName());
424             sb.append("[");
425             sb.append("targetPath=" + targetPath);
426             sb.append(", when=" + whenCondition);
427             sb.append("]");
428             return sb.toString();
429         }
430     }
431
432 }