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