/* * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt; import static java.util.Objects.requireNonNull; import com.google.common.annotations.Beta; import com.google.common.collect.Collections2; import com.google.common.collect.ImmutableList; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.function.Predicate; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.opendaylight.yangtools.yang.model.api.YangStmtMapping; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase; public abstract class EffectiveStatementBase> implements EffectiveStatement { private final List> substatements; /** * Constructor. * * @param ctx * context of statement. */ protected EffectiveStatementBase(final StmtContext ctx) { final Collection> effectiveSubstatements = ctx.effectiveSubstatements(); final Collection> substatementsInit = new ArrayList<>(); final Collection> supportedDeclaredSubStmts = Collections2.filter( ctx.declaredSubstatements(), StmtContext::isSupportedByFeatures); for (final StmtContext declaredSubstatement : supportedDeclaredSubStmts) { if (YangStmtMapping.USES == declaredSubstatement.getPublicDefinition()) { substatementsInit.add(declaredSubstatement); substatementsInit.addAll(declaredSubstatement.getEffectOfStatement()); ((StatementContextBase) ctx).removeStatementsFromEffectiveSubstatements(declaredSubstatement .getEffectOfStatement()); } else { substatementsInit.add(declaredSubstatement); } } substatementsInit.addAll(effectiveSubstatements); this.substatements = ImmutableList.copyOf(initSubstatements(substatementsInit)); } /** * Create a set of substatements. This method is split out so it can be overridden in * ExtensionEffectiveStatementImpl to leak a not-fully-initialized instance. * * @param substatementsInit proposed substatements * @return Filtered substatements */ protected Collection> initSubstatements( final Collection> substatementsInit) { return Collections2.transform(Collections2.filter(substatementsInit, StmtContext::isSupportedToBuildEffective), StmtContext::buildEffective); } @Override public final > V get(@Nonnull final Class namespace, @Nonnull final K identifier) { return findAll(namespace).get(requireNonNull(identifier)); } @Override public final > Map getAll(@Nonnull final Class namespace) { return getNamespaceContents(requireNonNull(namespace)).orElse(null); } /** * Return the statement-specific contents of specified namespace, if available. * * @param namespace Requested namespace * @return Namespace contents, if available. */ @Beta protected > Optional> getNamespaceContents( final @NonNull Class namespace) { return Optional.empty(); } @Nonnull @Override public final Collection> effectiveSubstatements() { return substatements; } /** * Find first substatement of specified type. * * @param type Requested type * @return First matching substatement, or null if no match is found. * * @deprecated Use {@link #findFirstEffectiveSubstatement(Class)} instead. */ @Deprecated public final > S firstEffective(final Class type) { return findFirstEffectiveSubstatement(type).orElse(null); } protected final S firstSchemaNode(final Class type) { return substatements.stream().filter(type::isInstance).findFirst().map(type::cast).orElse(null); } @SuppressWarnings("unchecked") public final Collection allSubstatementsOfType(final Class type) { return Collection.class.cast(Collections2.filter(substatements, type::isInstance)); } @Nullable protected final T firstSubstatementOfType(final Class type) { return substatements.stream().filter(type::isInstance).findFirst().map(type::cast).orElse(null); } protected final R firstSubstatementOfType(final Class type, final Class returnType) { return substatements.stream() .filter(((Predicate)type::isInstance).and(returnType::isInstance)) .findFirst().map(returnType::cast).orElse(null); } protected final EffectiveStatement firstEffectiveSubstatementOfType(final Class type) { return substatements.stream().filter(type::isInstance).findFirst().orElse(null); } }