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