Merge "Fix for Bug 308."
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / builder / impl / NotificationBuilder.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.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.NotificationDefinition;
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.parser.builder.api.AbstractDataNodeContainerBuilder;
30 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
31 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationTargetBuilder;
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.SchemaNodeBuilder;
35 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
36 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
37 import org.opendaylight.yangtools.yang.parser.util.Comparators;
38 import org.opendaylight.yangtools.yang.parser.util.ParserUtils;
39 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
40
41 public final class NotificationBuilder extends AbstractDataNodeContainerBuilder implements SchemaNodeBuilder,
42         AugmentationTargetBuilder {
43     private boolean isBuilt;
44     private final NotificationDefinitionImpl instance;
45     private SchemaPath schemaPath;
46     private final List<AugmentationSchema> augmentations = new ArrayList<>();
47     private final List<AugmentationSchemaBuilder> augmentationBuilders = new ArrayList<>();
48
49     NotificationBuilder(final String moduleName, final int line, final QName qname, final SchemaPath path) {
50         super(moduleName, line, qname);
51         this.schemaPath = path;
52         instance = new NotificationDefinitionImpl(qname, path);
53     }
54
55     NotificationBuilder(final String moduleName, final int line, final QName qname, final SchemaPath path, NotificationDefinition base) {
56         super(moduleName, line, qname);
57         this.schemaPath = path;
58         instance = new NotificationDefinitionImpl(qname, path);
59
60         instance.description = base.getDescription();
61         instance.reference = base.getReference();
62         instance.status = base.getStatus();
63         instance.augmentations.addAll(base.getAvailableAugmentations());
64
65         URI ns = qname.getNamespace();
66         Date rev = qname.getRevision();
67         String pref = qname.getPrefix();
68         addedChildNodes.addAll(ParserUtils.wrapChildNodes(moduleName, line, base.getChildNodes(), path, ns, rev, pref));
69         addedGroupings.addAll(ParserUtils.wrapGroupings(moduleName, line, base.getGroupings(), path, ns, rev, pref));
70
71         instance.groupings.addAll(base.getGroupings());
72         instance.typeDefinitions.addAll(base.getTypeDefinitions());
73         instance.uses.addAll(base.getUses());
74         instance.unknownNodes.addAll(base.getUnknownSchemaNodes());
75     }
76
77     @Override
78     public NotificationDefinition build() {
79         if (!(parentBuilder instanceof ModuleBuilder)) {
80             throw new YangParseException(moduleName, line, "Notification can be defined only under module (was " + parentBuilder + ")");
81         }
82         if (!isBuilt) {
83             // CHILD NODES
84             for (DataSchemaNodeBuilder node : addedChildNodes) {
85                 childNodes.add(node.build());
86             }
87             instance.setChildNodes(childNodes);
88
89             // GROUPINGS
90             for (GroupingBuilder builder : addedGroupings) {
91                 groupings.add(builder.build());
92             }
93             instance.setGroupings(groupings);
94
95             // TYPEDEFS
96             for (TypeDefinitionBuilder entry : addedTypedefs) {
97                 typedefs.add(entry.build());
98             }
99             instance.setTypeDefinitions(typedefs);
100
101             // USES
102             for (UsesNodeBuilder builder : addedUsesNodes) {
103                 usesNodes.add(builder.build());
104             }
105             instance.setUses(usesNodes);
106
107             // AUGMENTATIONS
108             for (AugmentationSchemaBuilder builder : augmentationBuilders) {
109                 augmentations.add(builder.build());
110             }
111             instance.setAvailableAugmentations(new HashSet<>(augmentations));
112
113             // UNKNOWN NODES
114             for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
115                 unknownNodes.add(b.build());
116             }
117             Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
118             instance.setUnknownSchemaNodes(unknownNodes);
119
120             isBuilt = true;
121         }
122
123         return instance;
124     }
125
126
127     @Override
128     public Set<TypeDefinitionBuilder> getTypeDefinitionBuilders() {
129         return addedTypedefs;
130     }
131
132     @Override
133     public void addTypedef(final TypeDefinitionBuilder type) {
134         addedTypedefs.add(type);
135     }
136
137     @Override
138     public SchemaPath getPath() {
139         return schemaPath;
140     }
141
142     @Override
143     public String getDescription() {
144         return instance.description;
145     }
146
147     @Override
148     public void setDescription(final String description) {
149         instance.description = description;
150     }
151
152     @Override
153     public String getReference() {
154         return instance.reference;
155     }
156
157     @Override
158     public void setReference(final String reference) {
159         instance.reference = reference;
160     }
161
162     @Override
163     public Status getStatus() {
164         return instance.status;
165     }
166
167     @Override
168     public void setStatus(Status status) {
169         if (status != null) {
170             instance.status = status;
171         }
172     }
173
174     @Override
175     public void addAugmentation(AugmentationSchemaBuilder augment) {
176         augmentationBuilders.add(augment);
177     }
178
179     @Override
180     public String toString() {
181         return "notification " + getQName().getLocalName();
182     }
183
184     public final class NotificationDefinitionImpl implements NotificationDefinition {
185         private final QName qname;
186         private final SchemaPath path;
187         private String description;
188         private String reference;
189         private Status status = Status.CURRENT;
190         private final Set<DataSchemaNode> childNodes = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
191         private final Set<GroupingDefinition> groupings = new HashSet<>();
192         private final Set<TypeDefinition<?>> typeDefinitions = new HashSet<>();
193         private final Set<UsesNode> uses = new HashSet<>();
194         private final Set<AugmentationSchema> augmentations = new HashSet<>();
195         private final List<UnknownSchemaNode> unknownNodes = new ArrayList<>();
196
197         private NotificationDefinitionImpl(final QName qname, final SchemaPath path) {
198             this.qname = qname;
199             this.path = path;
200         }
201
202         @Override
203         public QName getQName() {
204             return qname;
205         }
206
207         @Override
208         public SchemaPath getPath() {
209             return path;
210         }
211
212         @Override
213         public String getDescription() {
214             return description;
215         }
216
217         @Override
218         public String getReference() {
219             return reference;
220         }
221
222         @Override
223         public Status getStatus() {
224             return status;
225         }
226
227         @Override
228         public Set<DataSchemaNode> getChildNodes() {
229             return Collections.unmodifiableSet(childNodes);
230         }
231
232         private void setChildNodes(Set<DataSchemaNode> childNodes) {
233             if (childNodes != null) {
234                 this.childNodes.addAll(childNodes);
235             }
236         }
237
238         @Override
239         public Set<GroupingDefinition> getGroupings() {
240             return Collections.unmodifiableSet(groupings);
241         }
242
243         private void setGroupings(Set<GroupingDefinition> groupings) {
244             if (groupings != null) {
245                 this.groupings.addAll(groupings);
246             }
247         }
248
249         @Override
250         public Set<UsesNode> getUses() {
251             return Collections.unmodifiableSet(uses);
252         }
253
254         private void setUses(Set<UsesNode> uses) {
255             if (uses != null) {
256                 this.uses.addAll(uses);
257             }
258         }
259
260         @Override
261         public Set<TypeDefinition<?>> getTypeDefinitions() {
262             return Collections.unmodifiableSet(typeDefinitions);
263         }
264
265         private void setTypeDefinitions(final Set<TypeDefinition<?>> typeDefinitions) {
266             if (typeDefinitions != null) {
267                 this.typeDefinitions.addAll(typeDefinitions);
268             }
269         }
270
271         @Override
272         public Set<AugmentationSchema> getAvailableAugmentations() {
273             return Collections.unmodifiableSet(augmentations);
274         }
275
276         private void setAvailableAugmentations(Set<AugmentationSchema> augmentations) {
277             if (augmentations != null) {
278                 this.augmentations.addAll(augmentations);
279             }
280         }
281
282         @Override
283         public List<UnknownSchemaNode> getUnknownSchemaNodes() {
284             return Collections.unmodifiableList(unknownNodes);
285         }
286
287         private void setUnknownSchemaNodes(final List<UnknownSchemaNode> unknownNodes) {
288             if (unknownNodes != null) {
289                 this.unknownNodes.addAll(unknownNodes);
290             }
291         }
292
293         @Override
294         public DataSchemaNode getDataChildByName(QName name) {
295             return getChildNode(childNodes, name);
296         }
297
298         @Override
299         public DataSchemaNode getDataChildByName(String name) {
300             return getChildNode(childNodes, name);
301         }
302
303         @Override
304         public int hashCode() {
305             final int prime = 31;
306             int result = 1;
307             result = prime * result + ((qname == null) ? 0 : qname.hashCode());
308             result = prime * result + ((path == null) ? 0 : path.hashCode());
309             return result;
310         }
311
312         @Override
313         public boolean equals(Object obj) {
314             if (this == obj) {
315                 return true;
316             }
317             if (obj == null) {
318                 return false;
319             }
320             if (getClass() != obj.getClass()) {
321                 return false;
322             }
323             final NotificationDefinitionImpl other = (NotificationDefinitionImpl) obj;
324             if (qname == null) {
325                 if (other.qname != null) {
326                     return false;
327                 }
328             } else if (!qname.equals(other.qname)) {
329                 return false;
330             }
331             if (path == null) {
332                 if (other.path != null) {
333                     return false;
334                 }
335             } else if (!path.equals(other.path)) {
336                 return false;
337             }
338             return true;
339         }
340
341         @Override
342         public String toString() {
343             StringBuilder sb = new StringBuilder(NotificationDefinitionImpl.class.getSimpleName());
344             sb.append("[qname=" + qname + ", path=" + path + "]");
345             return sb.toString();
346         }
347     }
348
349 }