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