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