Merge "Bug 865: Fixed incorrect conversion to new APIs."
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / builder / util / AbstractDocumentedDataNodeContainerBuilder.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
3  * This program and the accompanying materials are made available under the
4  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
5  * and is available at http://www.eclipse.org/legal/epl-v10.html
6  */
7 package org.opendaylight.yangtools.yang.parser.builder.util;
8
9 import java.util.HashSet;
10 import java.util.Map;
11 import java.util.Set;
12 import java.util.TreeMap;
13 import java.util.TreeSet;
14 import org.opendaylight.yangtools.yang.common.QName;
15 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
16 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
17 import org.opendaylight.yangtools.yang.model.api.DocumentedNode;
18 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
19 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
20 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
21 import org.opendaylight.yangtools.yang.model.api.UsesNode;
22 import org.opendaylight.yangtools.yang.parser.builder.api.DataNodeContainerBuilder;
23 import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
24 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
25 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
26 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
27 import org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils;
28 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
29
30 /**
31  * Basic implementation of DataNodeContainerBuilder.
32  */
33 public abstract class AbstractDocumentedDataNodeContainerBuilder extends AbstractDocumentedNodeBuilder implements DataNodeContainerBuilder {
34     protected final QName qname;
35
36     private final Map<QName, DataSchemaNode> childNodes = new TreeMap<>();
37     private final Set<DataSchemaNodeBuilder> addedChildNodes = new HashSet<>();
38
39     private final Set<GroupingDefinition> groupings = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
40     private final Set<GroupingBuilder> addedGroupings = new HashSet<>();
41
42     private final Set<TypeDefinition<?>> typedefs = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
43     private final Set<TypeDefinitionBuilder> addedTypedefs = new HashSet<>();
44
45     private final Set<UsesNode> usesNodes = new HashSet<>();
46     private final Set<UsesNodeBuilder> addedUsesNodes = new HashSet<>();
47
48     protected AbstractDocumentedDataNodeContainerBuilder(final String moduleName, final int line, final QName qname) {
49         super(moduleName, line);
50         this.qname = qname;
51     }
52
53     protected AbstractDocumentedDataNodeContainerBuilder(final String moduleName, final int line, final QName qname, final SchemaPath path, final DataNodeContainer base) {
54         super(moduleName, line);
55         this.qname = qname;
56
57         // We do copy of child nodes with namespace change
58         // FIXME: Copy should be part of builder API so impl we prevent
59         // cyclic dependencies and each builder carries its own semantic for copy.
60         addedChildNodes.addAll(BuilderUtils.wrapChildNodes(moduleName, line, base.getChildNodes(), path, qname));
61         addedGroupings.addAll(BuilderUtils.wrapGroupings(moduleName, line, base.getGroupings(), path, qname));
62         addedTypedefs.addAll(BuilderUtils.wrapTypedefs(moduleName, line, base, path, qname));
63         // FIXME: unkownSchemaNodes should be available in DataNodeContainer
64         // addedUnknownNodes.addAll(BuilderUtils.wrapUnknownNodes(moduleName,
65         // line, base.getUnknownSchemaNodes(), path, qname));
66         usesNodes.addAll(base.getUses());
67
68         if (base instanceof DocumentedNode) {
69             DocumentedNode node = (DocumentedNode) base;
70             setDescription(node.getDescription());
71             setReference(node.getReference());
72             setStatus(node.getStatus());
73         }
74     }
75
76     @Override
77     public final QName getQName() {
78         return qname;
79     }
80
81     @Override
82     public final Map<QName, DataSchemaNode> getChildNodes() {
83         return childNodes;
84     }
85
86     @Override
87     public final Set<DataSchemaNodeBuilder> getChildNodeBuilders() {
88         return addedChildNodes;
89     }
90
91     @Override
92     public final DataSchemaNodeBuilder getDataChildByName(final String name) {
93         for (DataSchemaNodeBuilder child : addedChildNodes) {
94             if (child.getQName().getLocalName().equals(name)) {
95                 return child;
96             }
97         }
98         return null;
99     }
100
101     @Override
102     public final void addChildNode(final DataSchemaNodeBuilder child) {
103         QName childName = child.getQName();
104         for (DataSchemaNodeBuilder addedChildNode : addedChildNodes) {
105             if (addedChildNode.getQName().equals(childName)) {
106                 throw new YangParseException(child.getModuleName(), child.getLine(), String.format(
107                         "Can not add '%s' to '%s' in module '%s': node with same name already declared at line %d",
108                         child, this, getModuleName(), addedChildNode.getLine()));
109             }
110         }
111         addedChildNodes.add(child);
112     }
113
114     @Override
115     public final void addChildNodeToContext(final DataSchemaNodeBuilder child) {
116         addedChildNodes.add(child);
117     }
118
119     @Override
120     public final void addChildNode(final DataSchemaNode child) {
121         checkNotSealed();
122         QName childName = child.getQName();
123         for (DataSchemaNode childNode : childNodes.values()) {
124             if (childNode.getQName().equals(childName)) {
125                 throw new YangParseException(getModuleName(), getLine(), String.format(
126                         "Can not add '%s' to '%s' in module '%s': node with same name already declared", child, this,
127                         getModuleName()));
128             }
129         }
130         childNodes.put(child.getQName(), child);
131     }
132
133     @Override
134     public final Set<GroupingDefinition> getGroupings() {
135         return groupings;
136     }
137
138     @Override
139     public final Set<GroupingBuilder> getGroupingBuilders() {
140         return addedGroupings;
141     }
142
143     @Override
144     public final void addGrouping(final GroupingBuilder grouping) {
145         checkNotSealed();
146         QName groupingName = grouping.getQName();
147         for (GroupingBuilder addedGrouping : addedGroupings) {
148             if (addedGrouping.getQName().equals(groupingName)) {
149                 throw new YangParseException(grouping.getModuleName(), grouping.getLine(), String.format(
150                         "Can not add '%s': grouping with same name already declared in module '%s' at line %d",
151                         grouping, getModuleName(), addedGrouping.getLine()));
152             }
153         }
154         addedGroupings.add(grouping);
155     }
156
157     @Override
158     public final Set<TypeDefinition<?>> getTypeDefinitions() {
159         return typedefs;
160     }
161
162     public final Set<UsesNode> getUsesNodes() {
163         return usesNodes;
164     }
165
166     @Override
167     public final Set<UsesNodeBuilder> getUsesNodeBuilders() {
168         return addedUsesNodes;
169     }
170
171     @Override
172     public final void addUsesNode(final UsesNodeBuilder usesNode) {
173         checkNotSealed();
174         addedUsesNodes.add(usesNode);
175     }
176
177
178     @Override
179     public final Set<TypeDefinitionBuilder> getTypeDefinitionBuilders() {
180         return addedTypedefs;
181     }
182
183     @Override
184     public void addTypedef(final TypeDefinitionBuilder type) {
185         checkNotSealed();
186         String typeName = type.getQName().getLocalName();
187         for (TypeDefinitionBuilder addedTypedef : addedTypedefs) {
188             if (addedTypedef.getQName().getLocalName().equals(typeName)) {
189                 throw new YangParseException(getModuleName(), type.getLine(), "Can not add typedef '" + typeName
190                         + "': typedef with same name already declared at line " + addedTypedef.getLine());
191             }
192         }
193         addedTypedefs.add(type);
194     }
195
196     protected abstract String getStatementName();
197
198     protected void buildChildren() {
199         checkNotSealed();
200         seal();
201
202         for (DataSchemaNodeBuilder node : addedChildNodes) {
203             childNodes.put(node.getQName(), node.build());
204         }
205
206         for (GroupingBuilder builder : addedGroupings) {
207             groupings.add(builder.build());
208         }
209
210         for (TypeDefinitionBuilder entry : addedTypedefs) {
211             typedefs.add(entry.build());
212         }
213
214         for (UsesNodeBuilder builder : addedUsesNodes) {
215             usesNodes.add(builder.build());
216         }
217     }
218
219     @Deprecated
220     protected static DataSchemaNode getChildNode(final Set<DataSchemaNode> childNodes, final QName name) {
221         for (DataSchemaNode node : childNodes) {
222             if (node.getQName().equals(name)) {
223                 return node;
224             }
225         }
226         return null;
227     }
228
229     @Deprecated
230     protected static DataSchemaNode getChildNode(final Set<DataSchemaNode> childNodes, final String name) {
231         for (DataSchemaNode node : childNodes) {
232             if (node.getQName().getLocalName().equals(name)) {
233                 return node;
234             }
235         }
236         return null;
237     }
238
239
240 }