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