From 35691e4c2baa44e60dd8a882319e9b63b3b1b43e Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Fri, 21 Oct 2016 15:45:43 +0200 Subject: [PATCH] BUG-6522: create a specialized CopyHistory object Copy histories have a limited number of operations, hence mutating implementation can express the set of required operations more efficiently. Also adds some tests to make sure the class works correctly. Change-Id: I0b2fd9fffa8a4bc754a9eff3808648f8f5726243 Signed-off-by: Robert Varga --- .../yang/parser/spi/meta/CopyHistory.java | 110 ++++++++++++++++++ .../yang/parser/spi/meta/CopyType.java | 31 +++++ .../yang/parser/spi/meta/StmtContext.java | 15 +-- .../stmt/reactor/RootStatementContext.java | 18 +-- .../stmt/reactor/StatementContextBase.java | 29 +---- .../stmt/reactor/SubstatementContext.java | 14 +-- .../parser/stmt/rfc6020/AugmentUtils.java | 18 +-- .../parser/stmt/rfc6020/GroupingUtils.java | 6 +- .../yang/parser/stmt/rfc6020/Utils.java | 4 +- .../AbstractEffectiveDataSchemaNode.java | 12 +- ...tractEffectiveSimpleDataNodeContainer.java | 11 +- .../GroupingEffectiveStatementImpl.java | 10 +- .../UnknownEffectiveStatementBase.java | 11 +- .../effective/UsesEffectiveStatementImpl.java | 9 +- .../yang/parser/spi/meta/CopyHistoryTest.java | 71 +++++++++++ 15 files changed, 274 insertions(+), 95 deletions(-) create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/CopyHistory.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/CopyType.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/spi/meta/CopyHistoryTest.java diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/CopyHistory.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/CopyHistory.java new file mode 100644 index 0000000000..eb1e26765b --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/CopyHistory.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2016 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.spi.meta; + +import com.google.common.annotations.Beta; +import com.google.common.base.Verify; +import org.opendaylight.yangtools.concepts.Immutable; + +@Beta +public final class CopyHistory implements Immutable { + private static final CopyType[] VALUES = CopyType.values(); + + private static final CopyHistory[][] CACHE = new CopyHistory[VALUES.length][]; + static { + /* + * Cache size is dependent on number of items in CopyType, it costs N * 2^N objects. + * For 4 types that boils down to 4 * 16 = 64 objects. + * For 5 types that boils down to 5 * 32 = 160 objects. + * For 6 types that boils down to 6 * 64 = 384 objects. + * + * If we ever hit 6 types, the caching strategy needs to be revisited. + */ + Verify.verify(VALUES.length < 6); + } + + private static final CopyHistory ORIGINAL = cacheObject(CopyType.ORIGINAL, CopyType.ORIGINAL.bit()); + + private final short operations; + private final short lastOperation; + + private CopyHistory(final int operations, final CopyType lastOperation) { + this.operations = (short) operations; + this.lastOperation = (short) lastOperation.ordinal(); + } + + public static CopyHistory original() { + return ORIGINAL; + } + + private static CopyHistory[] cacheArray(final CopyType lastOperation) { + final int ordinal = lastOperation.ordinal(); + CopyHistory[] ret = CACHE[ordinal]; + if (ret == null) { + synchronized (CACHE) { + ret = CACHE[ordinal]; + if (ret == null) { + ret = new CopyHistory[1 << VALUES.length]; + CACHE[ordinal] = ret; + } + } + } + + return ret; + } + + private static CopyHistory cacheObject(final CopyType lastOperation, final int operations) { + final CopyHistory[] array = cacheArray(lastOperation); + CopyHistory ret = array[operations]; + if (ret == null) { + synchronized (array) { + ret = array[operations]; + if (ret == null) { + ret = new CopyHistory(operations, lastOperation); + array[operations] = ret; + } + } + } + + return ret; + } + + public boolean contains(final CopyType type) { + return (operations & type.bit()) != 0; + } + + public CopyType getLastOperation() { + return VALUES[lastOperation]; + } + + public CopyHistory append(final CopyType typeOfCopy, final CopyHistory toAppend) { + final int newOperations = operations | toAppend.operations | typeOfCopy.bit(); + if (newOperations == operations && typeOfCopy.ordinal() == lastOperation) { + return this; + } + + return cacheObject(typeOfCopy, newOperations); + } + + @Override + public int hashCode() { + return Integer.hashCode(operations | (lastOperation << Short.SIZE)); + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof CopyHistory)) { + return false; + } + final CopyHistory other = (CopyHistory) obj; + return operations == other.operations && lastOperation == other.lastOperation; + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/CopyType.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/CopyType.java new file mode 100644 index 0000000000..1686cb1e8c --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/CopyType.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2016 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.spi.meta; + +import com.google.common.annotations.Beta; +import com.google.common.base.Verify; + +@Beta +public enum CopyType { + ORIGINAL, + ADDED_BY_USES, + ADDED_BY_AUGMENTATION, + ADDED_BY_USES_AUGMENTATION; + + private final int bit; + + CopyType() { + // CopyHistory relies on the fact that the result fits into a short + Verify.verify(ordinal() < Short.SIZE); + bit = 1 << ordinal(); + } + + int bit() { + return bit; + } +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java index fd44a86e0d..b49363f991 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java @@ -9,7 +9,6 @@ package org.opendaylight.yangtools.yang.parser.spi.meta; import com.google.common.base.Optional; import java.util.Collection; -import java.util.List; import java.util.Map; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -88,18 +87,14 @@ public interface StmtContext, E extends Effect void addAsEffectOfStatement(StatementContextBase ctx); StatementContextBase createCopy( - StatementContextBase newParent, TypeOfCopy typeOfCopy) + StatementContextBase newParent, CopyType typeOfCopy) throws SourceException; StatementContextBase createCopy(QNameModule newQNameModule, - StatementContextBase newParent, TypeOfCopy typeOfCopy) + StatementContextBase newParent, CopyType typeOfCopy) throws SourceException; - enum TypeOfCopy { - ORIGINAL, ADDED_BY_USES, ADDED_BY_AUGMENTATION, ADDED_BY_USES_AUGMENTATION - } - - List getCopyHistory(); + CopyHistory getCopyHistory(); enum SupportedByFeatures { UNDEFINED, SUPPORTED, NOT_SUPPORTED @@ -107,9 +102,7 @@ public interface StmtContext, E extends Effect SupportedByFeatures getSupportedByFeatures(); - void addAllToCopyHistory(List typeOfCopyList); - - void addToCopyHistory(TypeOfCopy typeOfCopy); + void appendCopyHistory(CopyType typeOfCopy, CopyHistory toAppend); StatementContextBase getOriginalCtx(); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java index 54f93ebe8a..36e406233a 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java @@ -22,6 +22,7 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.Regist import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; +import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.IncludedModuleContext; /** @@ -41,7 +42,7 @@ public class RootStatementContext, E extends E } RootStatementContext(final RootStatementContext original, final QNameModule newQNameModule, - final TypeOfCopy typeOfCopy) { + final CopyType typeOfCopy) { super(original); sourceContext = original.sourceContext; @@ -61,7 +62,7 @@ public class RootStatementContext, E extends E * @throws org.opendaylight.yangtools.yang.parser.spi.source.SourceException */ private void copyDeclaredStmts(final RootStatementContext original, final QNameModule newQNameModule, - final TypeOfCopy typeOfCopy) { + final CopyType typeOfCopy) { final Collection> originalDeclaredSubstatements = original.declaredSubstatements(); for (final StatementContextBase stmtContext : originalDeclaredSubstatements) { if (!StmtContextUtils.areFeaturesSupported(stmtContext)) { @@ -79,7 +80,7 @@ public class RootStatementContext, E extends E * @throws org.opendaylight.yangtools.yang.parser.spi.source.SourceException */ private void copyEffectiveStmts(final RootStatementContext original, final QNameModule newQNameModule, - final TypeOfCopy typeOfCopy) { + final CopyType typeOfCopy) { final Collection> originalEffectiveSubstatements = original.effectiveSubstatements(); for (final StmtContext stmtContext : originalEffectiveSubstatements) { this.addEffectiveSubstatement(stmtContext.createCopy(newQNameModule, this, typeOfCopy)); @@ -132,28 +133,27 @@ public class RootStatementContext, E extends E } /** - * @return copy of this considering {@link TypeOfCopy} (augment, uses) + * @return copy of this considering {@link CopyType} (augment, uses) * * @throws org.opendaylight.yangtools.yang.parser.spi.source.SourceException instance of SourceException */ @Override public StatementContextBase createCopy(final StatementContextBase newParent, - final TypeOfCopy typeOfCopy) { + final CopyType typeOfCopy) { return createCopy(null, newParent, typeOfCopy); } /** - * @return copy of this considering {@link TypeOfCopy} (augment, uses) + * @return copy of this considering {@link CopyType} (augment, uses) * * @throws org.opendaylight.yangtools.yang.parser.spi.source.SourceException instance of SourceException */ @Override public StatementContextBase createCopy(final QNameModule newQNameModule, - final StatementContextBase newParent, final TypeOfCopy typeOfCopy) { + final StatementContextBase newParent, final CopyType typeOfCopy) { final RootStatementContext copy = new RootStatementContext<>(this, newQNameModule, typeOfCopy); - copy.addAllToCopyHistory(this.getCopyHistory()); - copy.addToCopyHistory(typeOfCopy); + copy.appendCopyHistory(typeOfCopy, this.getCopyHistory()); if (this.getOriginalCtx() != null) { copy.setOriginalCtx(this.getOriginalCtx()); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java index 8d92f34f9b..bb45a4a78c 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java @@ -9,7 +9,6 @@ package org.opendaylight.yangtools.yang.parser.stmt.reactor; import com.google.common.base.Preconditions; import com.google.common.base.Throwables; -import com.google.common.collect.ImmutableList; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; import java.util.ArrayList; @@ -19,7 +18,6 @@ import java.util.EnumMap; import java.util.EventListener; import java.util.Iterator; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; import javax.annotation.Nonnull; import org.opendaylight.yangtools.concepts.Identifiable; @@ -29,6 +27,8 @@ import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; import org.opendaylight.yangtools.yang.model.api.meta.StatementSource; +import org.opendaylight.yangtools.yang.parser.spi.meta.CopyHistory; +import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour; @@ -71,8 +71,6 @@ public abstract class StatementContextBase, E boolean isFinished(); } - private final static List ORIGINAL_COPY = ImmutableList.of(TypeOfCopy.ORIGINAL); - private final StatementDefinitionContext definition; private final StatementIdentifier identifier; private final StatementSourceReference statementDeclSource; @@ -90,7 +88,7 @@ public abstract class StatementContextBase, E private final Collection> effectOfStatement = new ArrayList<>(1); private SupportedByFeatures supportedByFeatures = SupportedByFeatures.UNDEFINED; - private List copyHistory = ORIGINAL_COPY; + private CopyHistory copyHistory = CopyHistory.original(); private boolean isSupportedToBuildEffective = true; private ModelProcessingPhase completedPhase = null; private StatementContextBase originalCtx; @@ -144,28 +142,13 @@ public abstract class StatementContextBase, E } @Override - public List getCopyHistory() { + public CopyHistory getCopyHistory() { return copyHistory; } - private void growCopyHistory(final int growBy) { - if (copyHistory == ORIGINAL_COPY) { - final List newCopyHistory = new ArrayList<>(growBy + 1); - newCopyHistory.add(TypeOfCopy.ORIGINAL); - copyHistory = newCopyHistory; - } - } - - @Override - public void addToCopyHistory(final TypeOfCopy typeOfCopy) { - growCopyHistory(1); - this.copyHistory.add(typeOfCopy); - } - @Override - public void addAllToCopyHistory(final List typeOfCopyList) { - growCopyHistory(typeOfCopyList.size()); - this.copyHistory.addAll(typeOfCopyList); + public void appendCopyHistory(final CopyType typeOfCopy, final CopyHistory toAppend) { + copyHistory = copyHistory.append(typeOfCopy, toAppend); } @Override diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SubstatementContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SubstatementContext.java index 5536dfe7c5..6d369e6b6f 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SubstatementContext.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SubstatementContext.java @@ -23,6 +23,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.KeyStatement; import org.opendaylight.yangtools.yang.model.api.stmt.RefineStatement; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.NamespaceStorageNode; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.Registry; @@ -50,7 +51,7 @@ final class SubstatementContext, E extends Eff @SuppressWarnings("unchecked") SubstatementContext(final SubstatementContext original, final QNameModule newQNameModule, - final StatementContextBase newParent, final TypeOfCopy typeOfCopy) { + final StatementContextBase newParent, final CopyType typeOfCopy) { super(original); this.parent = newParent; @@ -71,7 +72,7 @@ final class SubstatementContext, E extends Eff } private void copyDeclaredStmts(final SubstatementContext original, final QNameModule newQNameModule, - final TypeOfCopy typeOfCopy) { + final CopyType typeOfCopy) { final Collection> originalDeclaredSubstatements = original .declaredSubstatements(); for (final StatementContextBase stmtContext : originalDeclaredSubstatements) { @@ -88,7 +89,7 @@ final class SubstatementContext, E extends Eff } private void copyEffectiveStmts(final SubstatementContext original, final QNameModule newQNameModule, - final TypeOfCopy typeOfCopy) { + final CopyType typeOfCopy) { final Collection> originalEffectiveSubstatements = original .effectiveSubstatements(); for (final StatementContextBase stmtContext : originalEffectiveSubstatements) { @@ -128,17 +129,16 @@ final class SubstatementContext, E extends Eff @Override public StatementContextBase createCopy(final StatementContextBase newParent, - final TypeOfCopy typeOfCopy) { + final CopyType typeOfCopy) { return createCopy(null, newParent, typeOfCopy); } @Override public StatementContextBase createCopy(final QNameModule newQNameModule, - final StatementContextBase newParent, final TypeOfCopy typeOfCopy) { + final StatementContextBase newParent, final CopyType typeOfCopy) { final SubstatementContext copy = new SubstatementContext<>(this, newQNameModule, newParent, typeOfCopy); - copy.addAllToCopyHistory(this.getCopyHistory()); - copy.addToCopyHistory(typeOfCopy); + copy.appendCopyHistory(typeOfCopy, this.getCopyHistory()); if (this.getOriginalCtx() != null) { copy.setOriginalCtx(this.getOriginalCtx()); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentUtils.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentUtils.java index 2ae751d4aa..09e78b4b42 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentUtils.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentUtils.java @@ -22,8 +22,8 @@ import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement; import org.opendaylight.yangtools.yang.model.api.stmt.WhenStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; +import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace; import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace.ValidationBundleType; import org.opendaylight.yangtools.yang.parser.stmt.reactor.RootStatementContext; @@ -44,9 +44,9 @@ public final class AugmentUtils { private static void copyDeclaredStmts(final StatementContextBase sourceCtx, final StatementContextBase targetCtx) { - final TypeOfCopy typeOfCopy = sourceCtx.getParentContext().getPublicDefinition() - .getDeclaredRepresentationClass().equals(UsesStatement.class) ? TypeOfCopy.ADDED_BY_USES_AUGMENTATION - : TypeOfCopy.ADDED_BY_AUGMENTATION; + final CopyType typeOfCopy = sourceCtx.getParentContext().getPublicDefinition() + .getDeclaredRepresentationClass().equals(UsesStatement.class) ? CopyType.ADDED_BY_USES_AUGMENTATION + : CopyType.ADDED_BY_AUGMENTATION; for (final StatementContextBase originalStmtCtx : sourceCtx.declaredSubstatements()) { if (!StmtContextUtils.areFeaturesSupported(originalStmtCtx)) { @@ -65,9 +65,9 @@ public final class AugmentUtils { private static void copyEffectiveStmts(final StatementContextBase sourceCtx, final StatementContextBase targetCtx) { - final TypeOfCopy typeOfCopy = sourceCtx.getParentContext().getPublicDefinition() - .getDeclaredRepresentationClass().equals(UsesStatement.class) ? TypeOfCopy.ADDED_BY_USES_AUGMENTATION - : TypeOfCopy.ADDED_BY_AUGMENTATION; + final CopyType typeOfCopy = sourceCtx.getParentContext().getPublicDefinition() + .getDeclaredRepresentationClass().equals(UsesStatement.class) ? CopyType.ADDED_BY_USES_AUGMENTATION + : CopyType.ADDED_BY_AUGMENTATION; for (final StatementContextBase originalStmtCtx : sourceCtx.effectiveSubstatements()) { if (needToCopyByAugment(originalStmtCtx)) { @@ -82,13 +82,13 @@ public final class AugmentUtils { } private static void validateNodeCanBeCopiedByAugment(final StatementContextBase sourceCtx, - final StatementContextBase targetCtx, final TypeOfCopy typeOfCopy) { + final StatementContextBase targetCtx, final CopyType typeOfCopy) { if (sourceCtx.getPublicDefinition().getDeclaredRepresentationClass().equals(WhenStatement.class)) { return; } - if (typeOfCopy == TypeOfCopy.ADDED_BY_AUGMENTATION && reguiredCheckOfMandatoryNodes(sourceCtx, targetCtx)) { + if (typeOfCopy == CopyType.ADDED_BY_AUGMENTATION && reguiredCheckOfMandatoryNodes(sourceCtx, targetCtx)) { final List> sourceSubStatements = new Builder>() .addAll(sourceCtx.declaredSubstatements()).addAll(sourceCtx.effectiveSubstatements()).build(); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/GroupingUtils.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/GroupingUtils.java index b16054ee05..5c7954526e 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/GroupingUtils.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/GroupingUtils.java @@ -19,9 +19,9 @@ import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; import org.opendaylight.yangtools.yang.model.api.stmt.RefineStatement; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName; import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; @@ -68,7 +68,7 @@ public final class GroupingUtils { } if (needToCopyByUses(originalStmtCtx)) { final StatementContextBase copy = originalStmtCtx.createCopy(newQNameModule, targetCtx, - TypeOfCopy.ADDED_BY_USES); + CopyType.ADDED_BY_USES); targetCtx.addEffectiveSubstatement(copy); usesNode.addAsEffectOfStatement(copy); } else if (isReusedByUsesOnTop(originalStmtCtx)) { @@ -85,7 +85,7 @@ public final class GroupingUtils { for (final StatementContextBase originalStmtCtx : sourceGrpStmtCtx.effectiveSubstatements()) { if (needToCopyByUses(originalStmtCtx)) { final StatementContextBase copy = originalStmtCtx.createCopy(newQNameModule, targetCtx, - TypeOfCopy.ADDED_BY_USES); + CopyType.ADDED_BY_USES); targetCtx.addEffectiveSubstatement(copy); usesNode.addAsEffectOfStatement(copy); } else if (isReusedByUsesOnTop(originalStmtCtx)) { diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/Utils.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/Utils.java index 05de618fa2..ac6ad4afcb 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/Utils.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/Utils.java @@ -18,7 +18,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap.Builder; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -57,6 +56,7 @@ import org.opendaylight.yangtools.yang.model.util.RevisionAwareXPathImpl; import org.opendaylight.yangtools.yang.parser.spi.meta.QNameCacheNamespace; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; +import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; import org.opendaylight.yangtools.yang.parser.spi.source.BelongsToPrefixToModuleName; import org.opendaylight.yangtools.yang.parser.spi.source.ImpPrefixToModuleIdentifier; import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName; @@ -515,7 +515,7 @@ public final class Utils { qNameModule = getRootModuleQName(ctx); } if (qNameModule == null - && Iterables.getLast(ctx.getCopyHistory()) == StmtContext.TypeOfCopy.ADDED_BY_AUGMENTATION) { + && ctx.getCopyHistory().getLastOperation() == CopyType.ADDED_BY_AUGMENTATION) { ctx = ctx.getOriginalCtx(); qNameModule = getModuleQNameByPrefix(ctx, prefix); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveDataSchemaNode.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveDataSchemaNode.java index b8863bda72..c82beb5a1e 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveDataSchemaNode.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveDataSchemaNode.java @@ -7,13 +7,13 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; -import java.util.List; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.CopyHistory; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; +import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; abstract class AbstractEffectiveDataSchemaNode> extends AbstractEffectiveSchemaNode implements DataSchemaNode { @@ -30,12 +30,12 @@ abstract class AbstractEffectiveDataSchemaNode copyTypesFromOriginal = ctx.getCopyHistory(); - if (copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES_AUGMENTATION)) { + final CopyHistory originalHistory = ctx.getCopyHistory(); + if (originalHistory.contains(CopyType.ADDED_BY_USES_AUGMENTATION)) { this.addedByUses = this.augmenting = true; } else { - this.augmenting = copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_AUGMENTATION); - this.addedByUses = copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES); + this.augmenting = originalHistory.contains(CopyType.ADDED_BY_AUGMENTATION); + this.addedByUses = originalHistory.contains(CopyType.ADDED_BY_USES); } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveSimpleDataNodeContainer.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveSimpleDataNodeContainer.java index e343df4011..c6cde2adb8 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveSimpleDataNodeContainer.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveSimpleDataNodeContainer.java @@ -23,8 +23,9 @@ import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.CopyHistory; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; +import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; abstract class AbstractEffectiveSimpleDataNodeContainer> extends AbstractEffectiveDocumentedDataNodeContainer implements DataNodeContainer, AugmentationTarget, @@ -64,12 +65,12 @@ abstract class AbstractEffectiveSimpleDataNodeContainer copyTypesFromOriginal = ctx.getCopyHistory(); - if (copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES_AUGMENTATION)) { + final CopyHistory copyTypesFromOriginal = ctx.getCopyHistory(); + if (copyTypesFromOriginal.contains(CopyType.ADDED_BY_USES_AUGMENTATION)) { this.addedByUses = this.augmenting = true; } else { - this.augmenting = copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_AUGMENTATION); - this.addedByUses = copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES); + this.augmenting = copyTypesFromOriginal.contains(CopyType.ADDED_BY_AUGMENTATION); + this.addedByUses = copyTypesFromOriginal.contains(CopyType.ADDED_BY_USES); } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/GroupingEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/GroupingEffectiveStatementImpl.java index 8a83eb9d19..d526f002e3 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/GroupingEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/GroupingEffectiveStatementImpl.java @@ -19,7 +19,7 @@ import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.GroupingStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; +import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; public class GroupingEffectiveStatementImpl extends AbstractEffectiveDocumentedDataNodeContainer implements GroupingDefinition { @@ -35,13 +35,7 @@ public class GroupingEffectiveStatementImpl extends qname = ctx.getStatementArgument(); path = ctx.getSchemaPath().get(); - // initCopyType - List copyTypesFromOriginal = ctx.getCopyHistory(); - if (copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES)) { - addedByUses = true; - } else { - addedByUses = false; - } + addedByUses = ctx.getCopyHistory().contains(CopyType.ADDED_BY_USES); final Builder b = ImmutableList.builder(); for (EffectiveStatement effectiveStatement : effectiveSubstatements()) { diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UnknownEffectiveStatementBase.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UnknownEffectiveStatementBase.java index 1fbf48fc3d..1a281b55cf 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UnknownEffectiveStatementBase.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UnknownEffectiveStatementBase.java @@ -18,8 +18,9 @@ import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ExtensionStatement; import org.opendaylight.yangtools.yang.model.api.stmt.UnknownStatement; import org.opendaylight.yangtools.yang.parser.spi.ExtensionNamespace; +import org.opendaylight.yangtools.yang.parser.spi.meta.CopyHistory; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; +import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; public abstract class UnknownEffectiveStatementBase extends AbstractEffectiveDocumentedNode> implements UnknownSchemaNode { @@ -47,12 +48,12 @@ public abstract class UnknownEffectiveStatementBase extends AbstractEffective } // initCopyType - List copyTypesFromOriginal = ctx.getCopyHistory(); - if (copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES_AUGMENTATION)) { + final CopyHistory copyTypesFromOriginal = ctx.getCopyHistory(); + if (copyTypesFromOriginal.contains(CopyType.ADDED_BY_USES_AUGMENTATION)) { this.addedByUses = this.addedByAugmentation = true; } else { - this.addedByAugmentation = copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_AUGMENTATION); - this.addedByUses = copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES); + this.addedByAugmentation = copyTypesFromOriginal.contains(CopyType.ADDED_BY_AUGMENTATION); + this.addedByUses = copyTypesFromOriginal.contains(CopyType.ADDED_BY_USES); } nodeParameter = (ctx.rawStatementArgument() == null) ? "" : ctx.rawStatementArgument(); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UsesEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UsesEffectiveStatementImpl.java index a861f354dd..cb212de724 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UsesEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UsesEffectiveStatementImpl.java @@ -32,7 +32,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement; import org.opendaylight.yangtools.yang.parser.spi.GroupingNamespace; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; +import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; public final class UsesEffectiveStatementImpl extends AbstractEffectiveDocumentedNode implements UsesNode { private final SchemaPath groupingPath; @@ -52,12 +52,7 @@ public final class UsesEffectiveStatementImpl extends AbstractEffectiveDocumente this.groupingPath = grpCtx.getSchemaPath().get(); // initCopyType - final List copyTypesFromOriginal = ctx.getCopyHistory(); - if (copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES)) { - addedByUses = true; - } else { - addedByUses = false; - } + addedByUses = ctx.getCopyHistory().contains(CopyType.ADDED_BY_USES); // initSubstatementCollections final Collection> effectiveSubstatements = effectiveSubstatements(); diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/spi/meta/CopyHistoryTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/spi/meta/CopyHistoryTest.java new file mode 100644 index 0000000000..6a5c112c2a --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/spi/meta/CopyHistoryTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2016 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.spi.meta; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class CopyHistoryTest { + + @Test + public void testSingleton() { + final CopyHistory original = CopyHistory.original(); + + assertEquals(CopyType.ORIGINAL, original.getLastOperation()); + assertTrue(original.contains(CopyType.ORIGINAL)); + assertFalse(original.contains(CopyType.ADDED_BY_USES)); + assertFalse(original.contains(CopyType.ADDED_BY_AUGMENTATION)); + assertFalse(original.contains(CopyType.ADDED_BY_USES_AUGMENTATION)); + + assertSame(original, CopyHistory.original()); + } + + @Test + public void testAppend() { + final CopyHistory original = CopyHistory.original(); + assertSame(original, original.append(CopyType.ORIGINAL, original)); + + final CopyHistory originalUA = original.append(CopyType.ADDED_BY_USES_AUGMENTATION, original); + assertEquals(CopyType.ADDED_BY_USES_AUGMENTATION, originalUA.getLastOperation()); + assertTrue(originalUA.contains(CopyType.ORIGINAL)); + assertFalse(originalUA.contains(CopyType.ADDED_BY_USES)); + assertFalse(originalUA.contains(CopyType.ADDED_BY_AUGMENTATION)); + assertTrue(originalUA.contains(CopyType.ADDED_BY_USES_AUGMENTATION)); + + assertSame(originalUA, original.append(CopyType.ADDED_BY_USES_AUGMENTATION, original)); + assertSame(originalUA, originalUA.append(CopyType.ADDED_BY_USES_AUGMENTATION, original)); + + final CopyHistory originalU = original.append(CopyType.ADDED_BY_USES, original); + assertEquals(CopyType.ADDED_BY_USES, originalU.getLastOperation()); + assertTrue(originalU.contains(CopyType.ORIGINAL)); + assertTrue(originalU.contains(CopyType.ADDED_BY_USES)); + assertFalse(originalU.contains(CopyType.ADDED_BY_AUGMENTATION)); + assertFalse(originalU.contains(CopyType.ADDED_BY_USES_AUGMENTATION)); + + final CopyHistory uaU = originalUA.append(CopyType.ADDED_BY_USES, original); + assertEquals(CopyType.ADDED_BY_USES, uaU.getLastOperation()); + assertTrue(uaU.contains(CopyType.ORIGINAL)); + assertTrue(uaU.contains(CopyType.ADDED_BY_USES)); + assertFalse(uaU.contains(CopyType.ADDED_BY_AUGMENTATION)); + assertTrue(uaU.contains(CopyType.ADDED_BY_USES_AUGMENTATION)); + + assertSame(uaU, originalUA.append(CopyType.ADDED_BY_USES, original)); + + final CopyHistory res = originalUA.append(CopyType.ADDED_BY_AUGMENTATION, originalU); + assertEquals(CopyType.ADDED_BY_AUGMENTATION, res.getLastOperation()); + assertTrue(res.contains(CopyType.ORIGINAL)); + assertTrue(res.contains(CopyType.ADDED_BY_USES)); + assertTrue(res.contains(CopyType.ADDED_BY_AUGMENTATION)); + assertTrue(res.contains(CopyType.ADDED_BY_USES_AUGMENTATION)); + } + +} -- 2.36.6