YANGTOOLS-706: reorganize statement definitions
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / rfc7950 / stmt / 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.rfc7950.stmt;
9
10 import com.google.common.collect.Collections2;
11 import com.google.common.collect.ImmutableList;
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.function.Predicate;
17 import javax.annotation.Nonnull;
18 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
19 import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
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.StmtContext;
24 import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase;
25
26 public abstract class EffectiveStatementBase<A, D extends DeclaredStatement<A>> implements EffectiveStatement<A, D> {
27     private final List<? extends EffectiveStatement<?, ?>> substatements;
28
29     /**
30      * Constructor.
31      *
32      * @param ctx
33      *            context of statement.
34      */
35     protected EffectiveStatementBase(final StmtContext<A, D, ?> ctx) {
36         final Collection<? extends StmtContext<?, ?, ?>> effectiveSubstatements = ctx.effectiveSubstatements();
37         final Collection<StmtContext<?, ?, ?>> substatementsInit = new ArrayList<>();
38
39         final Collection<? extends StmtContext<?, ?, ?>> supportedDeclaredSubStmts = Collections2.filter(
40                 ctx.declaredSubstatements(), StmtContext::isSupportedByFeatures);
41         for (final StmtContext<?, ?, ?> declaredSubstatement : supportedDeclaredSubStmts) {
42             if (YangStmtMapping.USES == declaredSubstatement.getPublicDefinition()) {
43                 substatementsInit.add(declaredSubstatement);
44                 substatementsInit.addAll(declaredSubstatement.getEffectOfStatement());
45                 ((StatementContextBase<?, ?, ?>) ctx).removeStatementsFromEffectiveSubstatements(declaredSubstatement
46                         .getEffectOfStatement());
47             } else {
48                 substatementsInit.add(declaredSubstatement);
49             }
50         }
51         substatementsInit.addAll(effectiveSubstatements);
52
53         this.substatements = ImmutableList.copyOf(initSubstatements(substatementsInit));
54     }
55
56     /**
57      * Create a set of substatements. This method is split out so it can be overridden in
58      * {@link org.opendaylight.yangtools.yang.parser.rfc7950.stmt.extension.ExtensionEffectiveStatementImpl} to leak
59      * a not-fully-initialized instance.
60      *
61      * @param substatementsInit proposed substatements
62      * @return Filtered substatements
63      */
64     protected Collection<? extends EffectiveStatement<?, ?>> initSubstatements(
65             final Collection<? extends StmtContext<?, ?, ?>> substatementsInit) {
66         return Collections2.transform(Collections2.filter(substatementsInit,
67             StmtContext::isSupportedToBuildEffective), StmtContext::buildEffective);
68     }
69
70     @Override
71     public final <K, V, N extends IdentifierNamespace<K, V>> V get(@Nonnull final Class<N> namespace,
72             @Nonnull final K identifier) {
73         throw new UnsupportedOperationException("Not implemented yet.");
74     }
75
76     @Override
77     public final <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAll(@Nonnull final Class<N> namespace) {
78         throw new UnsupportedOperationException("Not implemented yet.");
79     }
80
81     @Nonnull
82     @Override
83     public final Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements() {
84         return substatements;
85     }
86
87     public final <S extends EffectiveStatement<?, ?>> S firstEffective(final Class<S> type) {
88         return substatements.stream().filter(type::isInstance).findFirst().map(type::cast).orElse(null);
89     }
90
91     protected final <S extends SchemaNode> S firstSchemaNode(final Class<S> type) {
92         return substatements.stream().filter(type::isInstance).findFirst().map(type::cast).orElse(null);
93     }
94
95     @SuppressWarnings("unchecked")
96     public final <T> Collection<T> allSubstatementsOfType(final Class<T> type) {
97         return Collection.class.cast(Collections2.filter(substatements, type::isInstance));
98     }
99
100     protected final <T> T firstSubstatementOfType(final Class<T> type) {
101         return substatements.stream().filter(type::isInstance).findFirst().map(type::cast).orElse(null);
102     }
103
104     protected final <R> R firstSubstatementOfType(final Class<?> type, final Class<R> returnType) {
105         return substatements.stream()
106                 .filter(((Predicate<Object>)type::isInstance).and(returnType::isInstance))
107                 .findFirst().map(returnType::cast).orElse(null);
108     }
109
110     protected final EffectiveStatement<?, ?> firstEffectiveSubstatementOfType(final Class<?> type) {
111         return substatements.stream().filter(type::isInstance).findFirst().orElse(null);
112     }
113 }