2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.yang.parser.builder.util;
10 import java.util.ArrayList;
11 import java.util.HashSet;
12 import java.util.LinkedHashMap;
13 import java.util.List;
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;
34 * Basic implementation of DataNodeContainerBuilder.
36 public abstract class AbstractDocumentedDataNodeContainerBuilder extends AbstractDocumentedNodeBuilder implements DataNodeContainerBuilder {
37 protected final QName qname;
39 private final Map<QName, DataSchemaNode> childNodes = new LinkedHashMap<>();
40 private final List<DataSchemaNodeBuilder> addedChildNodes = new ArrayList<>();
42 private final Set<GroupingDefinition> groupings = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
43 private final Set<GroupingBuilder> addedGroupings = new HashSet<>();
45 private final Set<TypeDefinition<?>> typedefs = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
46 private final Set<TypeDefinitionBuilder> addedTypedefs = new HashSet<>();
48 private final Set<UsesNode> usesNodes = new HashSet<>();
49 private final List<UsesNodeBuilder> addedUsesNodes = new ArrayList<>();
51 protected AbstractDocumentedDataNodeContainerBuilder(final String moduleName, final int line, final QName qname) {
52 super(moduleName, line);
56 protected AbstractDocumentedDataNodeContainerBuilder(final String moduleName, final int line, final QName qname, final SchemaPath path, final DataNodeContainer base) {
57 super(moduleName, line);
60 // We do copy of child nodes with namespace change
61 // FIXME: Copy should be part of builder API so impl we prevent
62 // cyclic dependencies and each builder carries its own semantic for copy.
63 addedChildNodes.addAll(BuilderUtils.wrapChildNodes(moduleName, line, base.getChildNodes(), path, qname));
64 addedGroupings.addAll(BuilderUtils.wrapGroupings(moduleName, line, base.getGroupings(), path, qname));
65 addedTypedefs.addAll(BuilderUtils.wrapTypedefs(moduleName, line, base, path, qname));
66 // FIXME: unkownSchemaNodes should be available in DataNodeContainer
67 // addedUnknownNodes.addAll(BuilderUtils.wrapUnknownNodes(moduleName,
68 // line, base.getUnknownSchemaNodes(), path, qname));
69 usesNodes.addAll(base.getUses());
71 if (base instanceof DocumentedNode) {
72 DocumentedNode node = (DocumentedNode) base;
73 setDescription(node.getDescription());
74 setReference(node.getReference());
75 setStatus(node.getStatus());
80 public final QName getQName() {
85 public final Map<QName, DataSchemaNode> getChildNodes() {
90 public final List<DataSchemaNodeBuilder> getChildNodeBuilders() {
91 return addedChildNodes;
95 public final DataSchemaNodeBuilder getDataChildByName(final String name) {
96 for (DataSchemaNodeBuilder child : addedChildNodes) {
97 if (child.getQName().getLocalName().equals(name)) {
105 public final void addChildNode(final DataSchemaNodeBuilder child) {
106 checkIsPresent(child);
107 addedChildNodes.add(child);
111 public final void addChildNode(final int index, final DataSchemaNodeBuilder child) {
112 checkIsPresent(child);
113 if (index > addedChildNodes.size()) {
114 addedChildNodes.add(child);
116 addedChildNodes.add(index, child);
120 private void checkIsPresent(final DataSchemaNodeBuilder child) {
121 for (DataSchemaNodeBuilder addedChildNode : addedChildNodes) {
122 if (addedChildNode.getQName().equals(child.getQName())) {
123 throw new YangParseException(child.getModuleName(), child.getLine(), String.format(
124 "Can not add '%s' to '%s' in module '%s': node with same name already declared at line %d",
125 child, this, getModuleName(), addedChildNode.getLine()));
131 public final void addChildNodeToContext(final DataSchemaNodeBuilder child) {
132 addedChildNodes.add(child);
136 public final void addChildNode(final DataSchemaNode child) {
138 QName childName = child.getQName();
139 if (childNodes.containsKey(childName)) {
140 throw new YangParseException(getModuleName(), getLine(), String.format(
141 "Can not add '%s' to '%s' in module '%s': node with same name already declared", child, this,
144 childNodes.put(childName, child);
148 public final Set<GroupingDefinition> getGroupings() {
153 public final Set<GroupingBuilder> getGroupingBuilders() {
154 return addedGroupings;
158 public void addGrouping(final GroupingBuilder grouping) {
160 QName groupingName = grouping.getQName();
161 for (GroupingBuilder addedGrouping : addedGroupings) {
162 if (addedGrouping.getQName().equals(groupingName)) {
163 throw new YangParseException(grouping.getModuleName(), grouping.getLine(), String.format(
164 "Can not add '%s': grouping with same name already declared in module '%s' at line %d",
165 grouping, getModuleName(), addedGrouping.getLine()));
168 addedGroupings.add(grouping);
172 public final Set<TypeDefinition<?>> getTypeDefinitions() {
176 public final Set<UsesNode> getUsesNodes() {
181 public final List<UsesNodeBuilder> getUsesNodeBuilders() {
182 return addedUsesNodes;
186 public final void addUsesNode(final UsesNodeBuilder usesNode) {
188 addedUsesNodes.add(usesNode);
193 public final Set<TypeDefinitionBuilder> getTypeDefinitionBuilders() {
194 return addedTypedefs;
198 public void addTypedef(final TypeDefinitionBuilder type) {
200 String typeName = type.getQName().getLocalName();
201 for (TypeDefinitionBuilder addedTypedef : addedTypedefs) {
202 if (addedTypedef.getQName().getLocalName().equals(typeName)) {
203 throw new YangParseException(getModuleName(), type.getLine(), "Can not add typedef '" + typeName
204 + "': typedef with same name already declared at line " + addedTypedef.getLine());
207 addedTypedefs.add(type);
210 protected abstract String getStatementName();
212 protected void buildChildren() {
216 for (DataSchemaNodeBuilder node : addedChildNodes) {
217 childNodes.put(node.getQName(), node.build());
220 for (GroupingBuilder builder : addedGroupings) {
221 groupings.add(builder.build());
224 for (TypeDefinitionBuilder entry : addedTypedefs) {
225 typedefs.add(entry.build());
228 for (UsesNodeBuilder builder : addedUsesNodes) {
229 usesNodes.add(builder.build());