Bug 6240: Entities of imported module's submodule are not visible
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / reactor / RootStatementContext.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.stmt.reactor;
9
10 import com.google.common.base.Optional;
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.Map;
14 import javax.annotation.Nullable;
15 import org.opendaylight.yangtools.yang.common.QNameModule;
16 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
17 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
18 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
19 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
20 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.NamespaceStorageNode;
21 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.Registry;
22 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType;
23 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
24 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
25 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.IncludedModuleContext;
26
27 /**
28  * root statement class for a Yang source
29  */
30 public class RootStatementContext<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>> extends
31         StatementContextBase<A, D, E> {
32
33     private final SourceSpecificContext sourceContext;
34     private final Collection<NamespaceStorageNode> includedContexts = new ArrayList<>();
35     private final A argument;
36
37     RootStatementContext(final ContextBuilder<A, D, E> builder, final SourceSpecificContext sourceContext) {
38         super(builder);
39         this.sourceContext = sourceContext;
40         this.argument = builder.getDefinition().parseArgumentValue(this, builder.getRawArgument());
41     }
42
43     RootStatementContext(final RootStatementContext<A, D, E> original, final QNameModule newQNameModule,
44         final TypeOfCopy typeOfCopy) {
45         super(original);
46
47         sourceContext = original.sourceContext;
48         this.argument = original.argument;
49
50         copyDeclaredStmts(original, newQNameModule, typeOfCopy);
51
52         copyEffectiveStmts(original, newQNameModule, typeOfCopy);
53
54     }
55
56     /**
57      * copies declared statements from original to this' substatements
58      *
59      * @param typeOfCopy
60      *            determines whether copy is used by augmentation or uses
61      * @throws org.opendaylight.yangtools.yang.parser.spi.source.SourceException
62      */
63     private void copyDeclaredStmts(final RootStatementContext<A, D, E> original, final QNameModule newQNameModule,
64             final TypeOfCopy typeOfCopy) {
65         final Collection<StatementContextBase<?, ?, ?>> originalDeclaredSubstatements = original.declaredSubstatements();
66         for (final StatementContextBase<?, ?, ?> stmtContext : originalDeclaredSubstatements) {
67             if (!StmtContextUtils.areFeaturesSupported(stmtContext)) {
68                 continue;
69             }
70             this.addEffectiveSubstatement(stmtContext.createCopy(newQNameModule, this, typeOfCopy));
71         }
72     }
73
74     /**
75      * copies effective statements from original to this' substatements
76      *
77      * @param typeOfCopy
78      *            determines whether copy is used by augmentation or uses
79      * @throws org.opendaylight.yangtools.yang.parser.spi.source.SourceException
80      */
81     private void copyEffectiveStmts(final RootStatementContext<A, D, E> original, final QNameModule newQNameModule,
82             final TypeOfCopy typeOfCopy) {
83         final Collection<? extends StmtContext<?, ?, ?>> originalEffectiveSubstatements = original.effectiveSubstatements();
84         for (final StmtContext<?, ?, ?> stmtContext : originalEffectiveSubstatements) {
85             this.addEffectiveSubstatement(stmtContext.createCopy(newQNameModule, this, typeOfCopy));
86         }
87     }
88
89     /**
90      * @return null as root cannot have parent
91      */
92     @Override
93     public StatementContextBase<?, ?, ?> getParentContext() {
94         return null;
95     }
96
97     /**
98      * @return namespace storage of source context
99      */
100     @Override
101     public NamespaceStorageNode getParentNamespaceStorage() {
102         return sourceContext;
103     }
104
105     /**
106      * @return registry of source context
107      */
108     @Override
109     public Registry getBehaviourRegistry() {
110         return sourceContext;
111     }
112
113     @Override
114     public StorageNodeType getStorageNodeType() {
115         return StorageNodeType.ROOT_STATEMENT_LOCAL;
116     }
117     /**
118      * @return this as its own root
119      */
120     @Override
121     public RootStatementContext<?, ?, ?> getRoot() {
122         return this;
123     }
124
125     SourceSpecificContext getSourceContext() {
126         return sourceContext;
127     }
128
129     @Override
130     public A getStatementArgument() {
131         return argument;
132     }
133
134     /**
135      * @return copy of this considering {@link TypeOfCopy} (augment, uses)
136      *
137      * @throws org.opendaylight.yangtools.yang.parser.spi.source.SourceException instance of SourceException
138      */
139     @Override
140     public StatementContextBase<?, ?, ?> createCopy(final StatementContextBase<?, ?, ?> newParent,
141             final TypeOfCopy typeOfCopy) {
142         return createCopy(null, newParent, typeOfCopy);
143     }
144
145     /**
146      * @return copy of this considering {@link TypeOfCopy} (augment, uses)
147      *
148      * @throws org.opendaylight.yangtools.yang.parser.spi.source.SourceException instance of SourceException
149      */
150     @Override
151     public StatementContextBase<A, D, E> createCopy(final QNameModule newQNameModule,
152             final StatementContextBase<?, ?, ?> newParent, final TypeOfCopy typeOfCopy) {
153         final RootStatementContext<A, D, E> copy = new RootStatementContext<>(this, newQNameModule, typeOfCopy);
154
155         copy.addAllToCopyHistory(this.getCopyHistory());
156         copy.addToCopyHistory(typeOfCopy);
157
158         if (this.getOriginalCtx() != null) {
159             copy.setOriginalCtx(this.getOriginalCtx());
160         } else {
161             copy.setOriginalCtx(this);
162         }
163         definition().onStatementAdded(copy);
164         return copy;
165     }
166
167     @Override
168     public Optional<SchemaPath> getSchemaPath() {
169         return Optional.of(SchemaPath.ROOT);
170     }
171
172     /**
173      * @return true
174      */
175     @Override
176     public boolean isRootContext() {
177         return true;
178     }
179
180     @Override
181     public boolean isConfiguration() {
182         return true;
183     }
184
185     @Override
186     public boolean isEnabledSemanticVersioning() {
187         return sourceContext.isEnabledSemanticVersioning();
188     }
189
190     @Override
191     public <K, V, N extends IdentifierNamespace<K, V>> void addToLocalStorage(final Class<N> type, final K key,
192             final V value) {
193         if (IncludedModuleContext.class.isAssignableFrom(type)) {
194             includedContexts.add((NamespaceStorageNode) value);
195         }
196         super.addToLocalStorage(type, key, value);
197     }
198
199     @Override
200     public <K, V, N extends IdentifierNamespace<K, V>> V getFromLocalStorage(final Class<N> type, final K key) {
201         final V potentialLocal = super.getFromLocalStorage(type, key);
202         if (potentialLocal != null) {
203             return potentialLocal;
204         }
205         for (final NamespaceStorageNode includedSource : includedContexts) {
206             final V potential = includedSource.getFromLocalStorage(type, key);
207             if (potential != null) {
208                 return potential;
209             }
210         }
211         return null;
212     }
213
214     @Nullable
215     @Override
216     public <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAllFromLocalStorage(final Class<N> type) {
217         final Map<K, V> potentialLocal = super.getAllFromLocalStorage(type);
218         if (potentialLocal != null) {
219             return potentialLocal;
220         }
221         for (final NamespaceStorageNode includedSource : includedContexts) {
222             final Map<K, V> potential = includedSource.getAllFromLocalStorage(type);
223             if (potential != null) {
224                 return potential;
225             }
226         }
227         return null;
228     }
229 }