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