/* * 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.stmt.rfc6020.effective; import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Collections2; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping; import org.opendaylight.yangtools.yang.model.api.SchemaNode; 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.spi.meta.StmtContextUtils; import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase; public abstract class EffectiveStatementBase> implements EffectiveStatement { private static final Predicate> IS_SUPPORTED_TO_BUILD_EFFECTIVE = new Predicate>() { @Override public boolean apply(final StmtContext input) { return input.isSupportedToBuildEffective(); } }; private static final Predicate> IS_UNKNOWN_STATEMENT_CONTEXT = new Predicate>() { @Override public boolean apply(final StmtContext input) { return StmtContextUtils.isUnknownStatement(input); } }; private static final Predicate> ARE_FEATURES_SUPPORTED = new Predicate>() { @Override public boolean apply(StmtContext input) { return StmtContextUtils.areFeaturesSupported(input); } }; private final List> substatements; private final List> unknownSubstatementsToBuild; protected EffectiveStatementBase(final StmtContext ctx) { this(ctx, true); } /** * Constructor. * * @param ctx * context of statement. * @param buildUnknownSubstatements * if it is false, the unknown substatements are omitted from * build of effective substatements till the call of either * effectiveSubstatements or getOmittedUnknownSubstatements * method. The main purpose of this is to allow the build of * recursive extension definitions. */ protected EffectiveStatementBase(final StmtContext ctx, boolean buildUnknownSubstatements) { final Collection> effectiveSubstatements = ctx.effectiveSubstatements(); final Collection> substatementsInit = new ArrayList<>(); for (StatementContextBase declaredSubstatement : ctx.declaredSubstatements()) { if (declaredSubstatement.getPublicDefinition().equals(Rfc6020Mapping.USES)) { substatementsInit.add(declaredSubstatement); substatementsInit.addAll(declaredSubstatement.getEffectOfStatement()); ((StatementContextBase) ctx).removeStatementsFromEffectiveSubstatements(declaredSubstatement .getEffectOfStatement()); } else { substatementsInit.add(declaredSubstatement); } } substatementsInit.addAll(effectiveSubstatements); Collection> substatementsToBuild = Collections2.filter(substatementsInit, IS_SUPPORTED_TO_BUILD_EFFECTIVE); if (!buildUnknownSubstatements) { this.unknownSubstatementsToBuild = ImmutableList.copyOf(Collections2.filter(substatementsToBuild, IS_UNKNOWN_STATEMENT_CONTEXT)); substatementsToBuild = Collections2.filter(substatementsToBuild, Predicates.not(IS_UNKNOWN_STATEMENT_CONTEXT)); } else { this.unknownSubstatementsToBuild = ImmutableList.of(); } substatementsToBuild = Collections2.filter(substatementsToBuild, ARE_FEATURES_SUPPORTED); Function>, EffectiveStatement> buildEffective = StmtContextUtils.buildEffective(); this.substatements = ImmutableList.copyOf(Collections2.transform(substatementsToBuild, buildEffective)); } Collection> getOmittedUnknownSubstatements() { Function>, EffectiveStatement> buildEffective = StmtContextUtils.buildEffective(); return Collections2.transform(unknownSubstatementsToBuild, buildEffective); } @Override public final > V get(final Class namespace, final K identifier) { throw new UnsupportedOperationException("Not implemented yet."); } @Override public final > Map getAll(final Class namespace) { throw new UnsupportedOperationException("Not implemented yet."); } @Override public final Collection> effectiveSubstatements() { if (unknownSubstatementsToBuild.isEmpty()) { return substatements; } else { return ImmutableList.copyOf(Iterables.concat(substatements, getOmittedUnknownSubstatements())); } } protected final > S firstEffective(final Class type) { Optional> possible = Iterables.tryFind(substatements, Predicates.instanceOf(type)); return possible.isPresent() ? type.cast(possible.get()) : null; } protected final S firstSchemaNode(final Class type) { Optional> possible = Iterables.tryFind(substatements, Predicates.instanceOf(type)); return possible.isPresent() ? type.cast(possible.get()) : null; } @SuppressWarnings("unchecked") protected final Collection allSubstatementsOfType(final Class type) { return Collection.class.cast(Collections2.filter(substatements, Predicates.instanceOf(type))); } protected final T firstSubstatementOfType(final Class type) { Optional> possible = Iterables.tryFind(substatements, Predicates.instanceOf(type)); return possible.isPresent() ? type.cast(possible.get()) : null; } protected final R firstSubstatementOfType(final Class type, final Class returnType) { Optional> possible = Iterables.tryFind(substatements, Predicates.and(Predicates.instanceOf(type), Predicates.instanceOf(returnType))); return possible.isPresent() ? returnType.cast(possible.get()) : null; } protected final EffectiveStatement firstEffectiveSubstatementOfType(final Class type) { return Iterables.tryFind(substatements, Predicates.instanceOf(type)).orNull(); } }