Merge branch 'master' of ../controller
[yangtools.git] / yang / yang-parser-rfc7950 / src / main / java / org / opendaylight / yangtools / yang / parser / rfc7950 / stmt / AbstractEffectiveDocumentedDataNodeContainer.java
1 /*
2  * Copyright (c) 2015 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.rfc7950.stmt;
9
10 import static java.util.Objects.requireNonNull;
11
12 import com.google.common.collect.ImmutableMap;
13 import com.google.common.collect.ImmutableSet;
14 import java.util.HashSet;
15 import java.util.LinkedHashMap;
16 import java.util.LinkedHashSet;
17 import java.util.Map;
18 import java.util.Optional;
19 import java.util.Set;
20 import org.opendaylight.yangtools.yang.common.QName;
21 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
22 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
23 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
24 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
25 import org.opendaylight.yangtools.yang.model.api.UsesNode;
26 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
27 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
28 import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement;
29 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
30
31 public abstract class AbstractEffectiveDocumentedDataNodeContainer<A, D extends DeclaredStatement<A>>
32         extends AbstractSchemaEffectiveDocumentedNode<A, D> implements DataNodeContainer {
33
34     private final ImmutableMap<QName, DataSchemaNode> childNodes;
35     private final ImmutableSet<GroupingDefinition> groupings;
36     private final ImmutableSet<UsesNode> uses;
37     private final ImmutableSet<TypeDefinition<?>> typeDefinitions;
38     private final ImmutableSet<DataSchemaNode> publicChildNodes;
39
40     protected AbstractEffectiveDocumentedDataNodeContainer(final StmtContext<A, D, ?> ctx) {
41         super(ctx);
42
43         Map<QName, DataSchemaNode> mutableChildNodes = new LinkedHashMap<>();
44         Set<GroupingDefinition> mutableGroupings = new HashSet<>();
45         Set<UsesNode> mutableUses = new HashSet<>();
46         Set<TypeDefinition<?>> mutableTypeDefinitions = new LinkedHashSet<>();
47         Set<DataSchemaNode> mutablePublicChildNodes = new LinkedHashSet<>();
48
49         for (EffectiveStatement<?, ?> stmt : effectiveSubstatements()) {
50             if (stmt instanceof DataSchemaNode) {
51                 final DataSchemaNode dataSchemaNode = (DataSchemaNode) stmt;
52                 if (mutableChildNodes.containsKey(dataSchemaNode.getQName())) {
53                     throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, stmt);
54                 }
55
56                 mutableChildNodes.put(dataSchemaNode.getQName(), dataSchemaNode);
57                 mutablePublicChildNodes.add(dataSchemaNode);
58             }
59             if (stmt instanceof UsesNode) {
60                 UsesNode usesNode = (UsesNode) stmt;
61                 if (!mutableUses.contains(usesNode)) {
62                     mutableUses.add(usesNode);
63                 } else {
64                     throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, stmt);
65                 }
66             }
67             if (stmt instanceof TypedefEffectiveStatement) {
68                 TypedefEffectiveStatement typeDef = (TypedefEffectiveStatement) stmt;
69                 TypeDefinition<?> type = typeDef.getTypeDefinition();
70                 if (!mutableTypeDefinitions.contains(type)) {
71                     mutableTypeDefinitions.add(type);
72                 } else {
73                     throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, stmt);
74                 }
75             }
76             if (stmt instanceof GroupingDefinition) {
77                 GroupingDefinition grp = (GroupingDefinition) stmt;
78                 if (!mutableGroupings.contains(grp)) {
79                     mutableGroupings.add(grp);
80                 } else {
81                     throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, stmt);
82                 }
83             }
84         }
85
86         this.childNodes = ImmutableMap.copyOf(mutableChildNodes);
87         this.groupings = ImmutableSet.copyOf(mutableGroupings);
88         this.publicChildNodes = ImmutableSet.copyOf(mutablePublicChildNodes);
89         this.typeDefinitions = ImmutableSet.copyOf(mutableTypeDefinitions);
90         this.uses = ImmutableSet.copyOf(mutableUses);
91     }
92
93     @Override
94     public final Set<TypeDefinition<?>> getTypeDefinitions() {
95         return typeDefinitions;
96     }
97
98     @Override
99     public final Set<DataSchemaNode> getChildNodes() {
100         return publicChildNodes;
101     }
102
103     @Override
104     public final Set<GroupingDefinition> getGroupings() {
105         return groupings;
106     }
107
108     @Override
109     public final Optional<DataSchemaNode> findDataChildByName(final QName name) {
110         // Child nodes are keyed by their container name, so we can do a direct lookup
111         return Optional.ofNullable(childNodes.get(requireNonNull(name)));
112     }
113
114     @Override
115     public Set<UsesNode> getUses() {
116         return uses;
117     }
118 }