X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-parser-rfc7950%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Frfc7950%2Fstmt%2FEffectiveStatementMixins.java;h=5e0331da7da8b0880b6688892d1e2324a8f0a558;hb=712c3ae6a666023f8febb1c7eb7c72ede2e31022;hp=b87da7e799ae67bccb3f28e124ae3160bbb26dc3;hpb=bbdfd546e8f79773f2162717f607551bb79fcbda;p=yangtools.git diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/EffectiveStatementMixins.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/EffectiveStatementMixins.java index b87da7e799..5e0331da7d 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/EffectiveStatementMixins.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/EffectiveStatementMixins.java @@ -8,13 +8,13 @@ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt; import com.google.common.annotations.Beta; +import com.google.common.base.MoreObjects; +import com.google.common.base.Strings; import com.google.common.collect.Collections2; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import java.util.Collection; -import java.util.List; import java.util.Optional; -import java.util.Set; +import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.NonNullByDefault; import org.opendaylight.yangtools.concepts.Mutable; import org.opendaylight.yangtools.yang.common.QName; @@ -23,17 +23,22 @@ import org.opendaylight.yangtools.yang.model.api.ActionNodeContainer; import org.opendaylight.yangtools.yang.model.api.AddedByUsesAware; import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; import org.opendaylight.yangtools.yang.model.api.AugmentationTarget; +import org.opendaylight.yangtools.yang.model.api.ConstraintMetaDefinition; +import org.opendaylight.yangtools.yang.model.api.ContainerLike; import org.opendaylight.yangtools.yang.model.api.CopyableNode; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DerivableSchemaNode; import org.opendaylight.yangtools.yang.model.api.DocumentedNode; import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.InputSchemaNode; import org.opendaylight.yangtools.yang.model.api.MandatoryAware; import org.opendaylight.yangtools.yang.model.api.MustConstraintAware; import org.opendaylight.yangtools.yang.model.api.MustDefinition; import org.opendaylight.yangtools.yang.model.api.NotificationDefinition; import org.opendaylight.yangtools.yang.model.api.NotificationNodeContainer; -import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath; +import org.opendaylight.yangtools.yang.model.api.OperationDefinition; +import org.opendaylight.yangtools.yang.model.api.OutputSchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.opendaylight.yangtools.yang.model.api.Status; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; @@ -43,11 +48,15 @@ import org.opendaylight.yangtools.yang.model.api.WhenConditionAware; 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.stmt.DescriptionEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.ErrorAppTagEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.ErrorMessageEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.InputEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.OutputEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.WhenEffectiveStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.CopyHistory; -import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; +import org.opendaylight.yangtools.yang.xpath.api.YangXPathExpression.QualifiedBound; /** * Mix-in interfaces providing services required by SchemaNode et al. These interfaces provide implementations, or @@ -58,19 +67,9 @@ public final class EffectiveStatementMixins { // Marker interface requiring all mixins to be derived from EffectiveStatement. private interface Mixin> extends EffectiveStatement { @SuppressWarnings("unchecked") - default Collection filterEffectiveStatements(final Class type) { + default @NonNull Collection filterEffectiveStatements(final Class type) { // Yeah, this is not nice, but saves one transformation - return (Collection) Collections2.filter(effectiveSubstatements(), type::isInstance); - } - - // FIXME: YANGTOOLS-1068: eliminate this once we can return collections - default List filterEffectiveStatementsList(final Class type) { - return ImmutableList.copyOf(filterEffectiveStatements(type)); - } - - // FIXME: YANGTOOLS-1068: eliminate this once we can return collections - default Set filterEffectiveStatementsSet(final Class type) { - return ImmutableSet.copyOf(filterEffectiveStatements(type)); + return (Collection) Collections2.filter(effectiveSubstatements(), type::isInstance); } } @@ -83,8 +82,8 @@ public final class EffectiveStatementMixins { public interface AugmentationTargetMixin> extends Mixin, AugmentationTarget { @Override - default Set getAvailableAugmentations() { - return filterEffectiveStatementsSet(AugmentationSchemaNode.class); + default Collection getAvailableAugmentations() { + return filterEffectiveStatements(AugmentationSchemaNode.class); } } @@ -111,8 +110,8 @@ public final class EffectiveStatementMixins { public interface ActionNodeContainerMixin> extends Mixin, ActionNodeContainer { @Override - default Set getActions() { - return filterEffectiveStatementsSet(ActionDefinition.class); + default Collection getActions() { + return filterEffectiveStatements(ActionDefinition.class); } } @@ -125,8 +124,8 @@ public final class EffectiveStatementMixins { public interface NotificationNodeContainerMixin> extends Mixin, NotificationNodeContainer { @Override - default Set getNotifications() { - return filterEffectiveStatementsSet(NotificationDefinition.class); + default Collection getNotifications() { + return filterEffectiveStatements(NotificationDefinition.class); } } @@ -138,7 +137,7 @@ public final class EffectiveStatementMixins { */ public interface MustConstraintMixin> extends Mixin, MustConstraintAware { @Override - default Collection getMustConstraints() { + default Collection getMustConstraints() { return filterEffectiveStatements(MustDefinition.class); } } @@ -164,26 +163,23 @@ public final class EffectiveStatementMixins { */ public interface DataNodeContainerMixin> extends DataNodeContainer, Mixin { @Override - default Set> getTypeDefinitions() { - // TODO: the cast here is needed to work around Java 11 javac type inference issue - return (Set) effectiveSubstatements().stream().filter(TypedefEffectiveStatement.class::isInstance) - .map(stmt -> ((TypedefEffectiveStatement) stmt).getTypeDefinition()) - .collect(ImmutableSet.toImmutableSet()); + default Collection> getTypeDefinitions() { + return filterTypeDefinitions(this); } @Override - default Collection getChildNodes() { + default Collection getChildNodes() { return filterEffectiveStatements(DataSchemaNode.class); } @Override - default Set getGroupings() { - return filterEffectiveStatementsSet(GroupingDefinition.class); + default Collection getGroupings() { + return filterEffectiveStatements(GroupingDefinition.class); } @Override - default Set getUses() { - return filterEffectiveStatementsSet(UsesNode.class); + default Collection getUses() { + return filterEffectiveStatements(UsesNode.class); } } @@ -244,8 +240,27 @@ public final class EffectiveStatementMixins { } @Override - default List getUnknownSchemaNodes() { - return filterEffectiveStatementsList(UnknownSchemaNode.class); + default Collection getUnknownSchemaNodes() { + return filterEffectiveStatements(UnknownSchemaNode.class); + } + } + + /** + * Bridge between {@link EffectiveStatementWithFlags} and {@link ConstraintMetaDefinition}. + * + * @param Argument type ({@link Void} if statement does not have argument.) + * @param Class representing declared version of this statement. + */ + public interface ConstraintMetaDefinitionMixin> extends DocumentedNodeMixin, + ConstraintMetaDefinition { + @Override + default Optional getErrorAppTag() { + return findFirstEffectiveSubstatementArgument(ErrorAppTagEffectiveStatement.class); + } + + @Override + default Optional getErrorMessage() { + return findFirstEffectiveSubstatementArgument(ErrorMessageEffectiveStatement.class); } } @@ -289,6 +304,21 @@ public final class EffectiveStatementMixins { } } + /** + * Bridge between {@link EffectiveStatementWithFlags} and {@link UnknownSchemaNode}. + * + * @param Argument type ({@link Void} if statement does not have argument.) + * @param Class representing declared version of this statement. + */ + public interface UnknownSchemaNodeMixin> + extends SchemaNodeMixin, CopyableMixin, UnknownSchemaNode { + + @Override + default String getNodeParameter() { + return Strings.nullToEmpty(getDeclared().rawArgument()); + } + } + /** * Bridge between {@link EffectiveStatementWithFlags} and {@code ordered-by} statement. * @@ -310,11 +340,102 @@ public final class EffectiveStatementMixins { */ public interface WhenConditionMixin> extends Mixin, WhenConditionAware { @Override - default Optional getWhenCondition() { + default Optional getWhenCondition() { return findFirstEffectiveSubstatementArgument(WhenEffectiveStatement.class); } } + /** + * Helper bridge for operation containers ({@code input} and {@code output}). + * + * @param Class representing declared version of this statement. + */ + public interface OperationContainerMixin> + extends ContainerLike, DocumentedNodeMixin.WithStatus, DataNodeContainerMixin, + MustConstraintMixin, WhenConditionMixin, AugmentationTargetMixin, + SchemaNodeMixin, CopyableMixin { + @Override + default @NonNull QName argument() { + return getQName(); + } + + @Override + default Optional findAction(final QName qname) { + return Optional.empty(); + } + + @Override + default Optional findNotification(final QName qname) { + return Optional.empty(); + } + + @Override + default Collection getActions() { + return ImmutableSet.of(); + } + + @Override + default Collection getNotifications() { + return ImmutableSet.of(); + } + + @Override + default boolean isConfiguration() { + return false; + } + + default String defaultToString() { + return MoreObjects.toStringHelper(this).add("path", getPath()).toString(); + } + } + + /** + * Helper bridge for {@code anydata} and {@code anyxml} opaque data. + * + * @param Class representing declared version of this statement. + */ + public interface OpaqueDataSchemaNodeMixin> + extends DerivableSchemaNode, DataSchemaNodeMixin, DocumentedNodeMixin.WithStatus, + MandatoryMixin, MustConstraintMixin, WhenConditionMixin { + @Override + default @NonNull QName argument() { + return getQName(); + } + } + + /** + * Helper bridge for {@code rpc} and {@code action} operations. + * + * @param Class representing declared version of this statement. + */ + public interface OperationDefinitionMixin> + extends SchemaNodeMixin, OperationDefinition { + @Override + default @NonNull QName argument() { + return getQName(); + } + + @Override + default Collection> getTypeDefinitions() { + return filterTypeDefinitions(this); + } + + @Override + default Collection getGroupings() { + return filterEffectiveStatements(GroupingDefinition.class); + } + + @Override + default InputSchemaNode getInput() { + return findAsContainer(this, InputEffectiveStatement.class, InputSchemaNode.class); + } + + @Override + default OutputSchemaNode getOutput() { + return findAsContainer(this, OutputEffectiveStatement.class, OutputSchemaNode.class); + } + } + /** * Support interface for various mixins. Implementations are required to store 32bits worth of flags, which are * globally assigned to sub-interfaces -- thus providing storage for many low-cardinality properties. @@ -360,20 +481,8 @@ public final class EffectiveStatementMixins { } public FlagsBuilder setHistory(final CopyHistory history) { - int bits; - if (history.contains(CopyType.ADDED_BY_USES_AUGMENTATION)) { - bits = AUGMENTING | ADDED_BY_USES; - } else { - bits = 0; - if (history.contains(CopyType.ADDED_BY_AUGMENTATION)) { - bits |= AUGMENTING; - } - if (history.contains(CopyType.ADDED_BY_USES)) { - bits |= ADDED_BY_USES; - } - } - - flags = flags & ~MASK_HISTORY | bits; + flags = flags & ~MASK_HISTORY + | (history.isAugmenting() ? AUGMENTING : 0) | (history.isAddedByUses() ? ADDED_BY_USES : 0); return this; } @@ -405,7 +514,7 @@ public final class EffectiveStatementMixins { bits = STATUS_DEPRECATED; break; case OBSOLETE: - bits = STATUS_DEPRECATED; + bits = STATUS_OBSOLETE; break; default: throw new IllegalStateException("Unhandled status " + status); @@ -429,4 +538,17 @@ public final class EffectiveStatementMixins { } } } + + private EffectiveStatementMixins() { + } + + static T findAsContainer(final EffectiveStatement stmt, + final Class> type, Class target) { + return target.cast(stmt.findFirstEffectiveSubstatement(type).get()); + } + + static Collection> filterTypeDefinitions(final Mixin stmt) { + return Collections2.transform(stmt.filterEffectiveStatements(TypedefEffectiveStatement.class), + TypedefEffectiveStatement::getTypeDefinition); + } }