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