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
7 package org.opendaylight.yangtools.yang.parser.builder.util;
9 import java.util.HashSet;
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;
31 * Basic implementation of DataNodeContainerBuilder.
33 public abstract class AbstractDocumentedDataNodeContainerBuilder extends AbstractDocumentedNodeBuilder implements DataNodeContainerBuilder {
34 protected final QName qname;
36 private final Map<QName, DataSchemaNode> childNodes = new TreeMap<>();
37 private final Set<DataSchemaNodeBuilder> addedChildNodes = new HashSet<>();
39 private final Set<GroupingDefinition> groupings = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
40 private final Set<GroupingBuilder> addedGroupings = new HashSet<>();
42 private final Set<TypeDefinition<?>> typedefs = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
43 private final Set<TypeDefinitionBuilder> addedTypedefs = new HashSet<>();
45 private final Set<UsesNode> usesNodes = new HashSet<>();
46 private final Set<UsesNodeBuilder> addedUsesNodes = new HashSet<>();
48 protected AbstractDocumentedDataNodeContainerBuilder(final String moduleName, final int line, final QName qname) {
49 super(moduleName, line);
53 protected AbstractDocumentedDataNodeContainerBuilder(final String moduleName, final int line, final QName qname, final SchemaPath path, final DataNodeContainer base) {
54 super(moduleName, line);
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());
68 if (base instanceof DocumentedNode) {
69 DocumentedNode node = (DocumentedNode) base;
70 setDescription(node.getDescription());
71 setReference(node.getReference());
72 setStatus(node.getStatus());
77 public final QName getQName() {
82 public final Map<QName, DataSchemaNode> getChildNodes() {
87 public final Set<DataSchemaNodeBuilder> getChildNodeBuilders() {
88 return addedChildNodes;
92 public final DataSchemaNodeBuilder getDataChildByName(final String name) {
93 for (DataSchemaNodeBuilder child : addedChildNodes) {
94 if (child.getQName().getLocalName().equals(name)) {
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()));
111 addedChildNodes.add(child);
115 public final void addChildNodeToContext(final DataSchemaNodeBuilder child) {
116 addedChildNodes.add(child);
120 public final void addChildNode(final DataSchemaNode child) {
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,
130 childNodes.put(child.getQName(), child);
134 public final Set<GroupingDefinition> getGroupings() {
139 public final Set<GroupingBuilder> getGroupingBuilders() {
140 return addedGroupings;
144 public final void addGrouping(final GroupingBuilder grouping) {
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()));
154 addedGroupings.add(grouping);
158 public final Set<TypeDefinition<?>> getTypeDefinitions() {
162 public final Set<UsesNode> getUsesNodes() {
167 public final Set<UsesNodeBuilder> getUsesNodeBuilders() {
168 return addedUsesNodes;
172 public final void addUsesNode(final UsesNodeBuilder usesNode) {
174 addedUsesNodes.add(usesNode);
179 public final Set<TypeDefinitionBuilder> getTypeDefinitionBuilders() {
180 return addedTypedefs;
184 public void addTypedef(final TypeDefinitionBuilder type) {
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());
193 addedTypedefs.add(type);
196 protected abstract String getStatementName();
198 protected void buildChildren() {
202 for (DataSchemaNodeBuilder node : addedChildNodes) {
203 childNodes.put(node.getQName(), node.build());
206 for (GroupingBuilder builder : addedGroupings) {
207 groupings.add(builder.build());
210 for (TypeDefinitionBuilder entry : addedTypedefs) {
211 typedefs.add(entry.build());
214 for (UsesNodeBuilder builder : addedUsesNodes) {
215 usesNodes.add(builder.build());
220 protected static DataSchemaNode getChildNode(final Set<DataSchemaNode> childNodes, final QName name) {
221 for (DataSchemaNode node : childNodes) {
222 if (node.getQName().equals(name)) {
230 protected static DataSchemaNode getChildNode(final Set<DataSchemaNode> childNodes, final String name) {
231 for (DataSchemaNode node : childNodes) {
232 if (node.getQName().getLocalName().equals(name)) {