2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt;
10 import com.google.common.collect.Collections2;
11 import com.google.common.collect.ImmutableList;
12 import java.util.Collection;
13 import java.util.function.Predicate;
14 import org.eclipse.jdt.annotation.NonNull;
15 import org.eclipse.jdt.annotation.Nullable;
16 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
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.parser.spi.meta.StmtContext;
22 * Stateful version of {@link AbstractEffectiveStatement}, which holds substatements in an {@link ImmutableList}.
24 * @param <A> Argument type ({@link Void} if statement does not have argument.)
25 * @param <D> Class representing declared version of this statement.
27 * @deprecated This class has a number of design problems. Please use either {@link AbstractDeclaredEffectiveStatement}
28 * or {@link AbstractUndeclaredEffectiveStatement} instead.
30 // TODO: This class is problematic in that it interacts with its subclasses via methods which are guaranteed to allows
31 // atrocities like RecursiveObjectLeaker tricks. That should be avoided and pushed to caller in a way where
32 // this class is a pure holder taking {@code ImmutableList<? extends EffectiveStatement<?, ?>>} in the
35 // From memory efficiency perspective, it is very common to have effective statements without any substatements,
36 // in which case 'substatements' field is redundant.
37 @Deprecated(forRemoval = true)
38 // FIXME: 6.0.0: fold this into AbstractEffectiveDocumentedNodeWithStatus
39 public abstract class EffectiveStatementBase<A, D extends DeclaredStatement<A>>
40 extends AbstractEffectiveStatement<A, D> {
41 private final @NonNull ImmutableList<? extends EffectiveStatement<?, ?>> substatements;
46 * @param ctx context of statement.
48 protected EffectiveStatementBase(final StmtContext<A, D, ?> ctx) {
49 this.substatements = ImmutableList.copyOf(initSubstatements(BaseStatementSupport.declaredSubstatements(ctx)));
53 * Create a set of substatements. This method is split out so it can be overridden in
54 * ExtensionEffectiveStatementImpl to leak a not-fully-initialized instance.
56 * @param substatementsInit proposed substatements
57 * @return Filtered substatements
59 // FIXME: 6.0.0: this facility is only overridden by ExtensionEffectiveStatementImpl
60 protected Collection<? extends EffectiveStatement<?, ?>> initSubstatements(
61 final Collection<? extends StmtContext<?, ?, ?>> substatementsInit) {
62 return Collections2.transform(Collections2.filter(substatementsInit,
63 StmtContext::isSupportedToBuildEffective), StmtContext::buildEffective);
67 public final Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements() {
71 @SuppressWarnings("unchecked")
72 public final <T> Collection<T> allSubstatementsOfType(final Class<T> type) {
73 return Collection.class.cast(Collections2.filter(effectiveSubstatements(), type::isInstance));
76 protected final <T> @Nullable T firstSubstatementOfType(final Class<T> type) {
77 return effectiveSubstatements().stream().filter(type::isInstance).findFirst().map(type::cast).orElse(null);
80 protected final <R> R firstSubstatementOfType(final Class<?> type, final Class<R> returnType) {
81 return effectiveSubstatements().stream()
82 .filter(((Predicate<Object>)type::isInstance).and(returnType::isInstance))
83 .findFirst().map(returnType::cast).orElse(null);
86 protected final EffectiveStatement<?, ?> firstEffectiveSubstatementOfType(final Class<?> type) {
87 return effectiveSubstatements().stream().filter(type::isInstance).findFirst().orElse(null);
90 // FIXME: rename to 'getFirstEffectiveStatement()'
91 protected final <S extends SchemaNode> S firstSchemaNode(final Class<S> type) {
92 return findFirstEffectiveSubstatement(type).orElse(null);