Merge "Bug 2983 - Throws ResultAlreadySet instead of IllegalStateException"
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / rfc6020 / effective / EffectiveStatementBase.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.rfc6020.effective;
9
10 import java.util.Collections;
11
12 import java.util.NoSuchElementException;
13 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
14 import com.google.common.collect.Collections2;
15 import com.google.common.base.Predicates;
16 import com.google.common.collect.Iterables;
17 import java.util.LinkedList;
18 import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase;
19 import com.google.common.collect.FluentIterable;
20 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
21 import com.google.common.collect.ImmutableList;
22 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
23 import java.util.Collection;
24 import java.util.Map;
25 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
26 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
27 import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
28 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
29 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
30
31 abstract public class EffectiveStatementBase<A, D extends DeclaredStatement<A>>
32         implements EffectiveStatement<A, D> {
33
34     private final StmtContext<A, D, ?> stmtCtx;
35     private final ImmutableList<? extends EffectiveStatement<?, ?>> substatements;
36     private final StatementSource statementSource;
37     private final StatementDefinition statementDefinition;
38     private D declaredInstance;
39
40     private final A argument;
41
42     public EffectiveStatementBase(StmtContext<A, D, ?> ctx) {
43
44         this.stmtCtx = ctx;
45         this.statementDefinition = ctx.getPublicDefinition();
46         this.argument = ctx.getStatementArgument();
47         this.statementSource = ctx.getStatementSource();
48
49         Collection<StatementContextBase<?, ?, ?>> declaredSubstatements = ctx
50                 .declaredSubstatements();
51         Collection<StatementContextBase<?, ?, ?>> effectiveSubstatements = ctx
52                 .effectiveSubstatements();
53
54         Collection<StatementContextBase<?, ?, ?>> substatementsInit = new LinkedList<>();
55         substatementsInit.addAll(declaredSubstatements);
56         substatementsInit.addAll(effectiveSubstatements);
57
58         this.substatements = FluentIterable.from(substatementsInit)
59                 .transform(StmtContextUtils.buildEffective()).toList();
60     }
61
62     @Override
63     public StatementDefinition statementDefinition() {
64         return statementDefinition;
65     }
66
67     @Override
68     public A argument() {
69         return argument;
70     }
71
72     @Override
73     public StatementSource getStatementSource() {
74         return statementSource;
75     }
76
77     @Override
78     public D getDeclared() {
79         if (declaredInstance == null) {
80             declaredInstance = stmtCtx.buildDeclared();
81         }
82
83         return declaredInstance;
84     }
85
86     // public <K, V, N extends IdentifierNamespace<? super K, ? extends V>> V
87     // get(
88     @Override
89     public <K, V, N extends IdentifierNamespace<K, V>> V get(
90             Class<N> namespace, K identifier) {
91         return stmtCtx.getFromNamespace(namespace, identifier);
92     }
93
94     @Override
95     public <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAll(
96             Class<N> namespace) {
97         return (Map<K, V>) stmtCtx.getAllFromNamespace(namespace);
98     }
99
100     @Override
101     public Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements() {
102         return substatements;
103     }
104
105     public StmtContext<A, D, ?> getStatementContext() {
106         return stmtCtx;
107     }
108
109     protected final <S extends EffectiveStatement<?, ?>> S firstEffective(
110             Class<S> type) {
111         S result = null;
112         try {
113             result = type.cast(Iterables.find(substatements,
114                     Predicates.instanceOf(type)));
115         } catch (NoSuchElementException e) {
116             result = null;
117         }
118         return result;
119     }
120
121     @SuppressWarnings("unchecked")
122     protected final <S extends EffectiveStatement<?, ?>> Collection<? extends S> allEffective(
123             Class<S> type) {
124         Collection<? extends S> result = null;
125
126         try {
127             result = Collection.class.cast(Collections2.filter(substatements,
128                     Predicates.instanceOf(type)));
129         } catch (NoSuchElementException e) {
130             result = Collections.emptyList();
131         }
132         return result;
133     }
134
135     protected final <S extends SchemaNode> S firstSchemaNode(Class<S> type) {
136         S result = null;
137         try {
138             result = type.cast(Iterables.find(substatements,
139                     Predicates.instanceOf(type)));
140         } catch (NoSuchElementException e) {
141             result = null;
142         }
143         return result;
144     }
145
146     @SuppressWarnings("unchecked")
147     protected final <S extends SchemaNode> Collection<? extends S> allSchemaNodes(
148             Class<S> type) {
149         Collection<? extends S> result = null;
150
151         try {
152             result = Collection.class.cast(Collections2.filter(substatements,
153                     Predicates.instanceOf(type)));
154         } catch (NoSuchElementException e) {
155             result = Collections.emptyList();
156         }
157         return result;
158     }
159
160 }