From 635af1cfca70d0be0192f997c155d80cbbc5ba5d Mon Sep 17 00:00:00 2001 From: Peter Kajsa Date: Thu, 5 May 2016 17:24:26 +0200 Subject: [PATCH] Bug 5200: Yang parser doesn't fill error-app-tag and error-message in constraints Length, Pattern, Range statements may contain error-app-tag and error-message substatements, but yang parser does not fill them correctly when corresponding constraint objects are created. Instead yang parser always constructs constant formatted message. Change-Id: I69edb1fa49bcd50098f247df851c839c2f871782 Signed-off-by: Peter Kajsa --- .../yang/model/util/BaseConstraints.java | 80 ++++++++++ .../yang/model/util/LengthConstraintImpl.java | 13 +- .../model/util/PatternConstraintImpl.java | 18 ++- .../yang/model/util/RangeConstraintImpl.java | 14 +- .../type/LengthRestrictedTypeBuilder.java | 4 +- .../util/type/RangeRestrictedTypeBuilder.java | 4 +- .../model/util/PatternConstraintImplTest.java | 2 +- .../parser/spi/meta/StmtContextUtils.java | 6 + .../yang/parser/stmt/rfc6020/TypeUtils.java | 14 +- .../DeclaredEffectiveStatementBase.java | 2 +- .../AbstractConstraintEffectiveStatement.java | 143 ++++++++++++++++++ .../type/LengthConstraintEffectiveImpl.java | 16 +- .../type/LengthEffectiveStatementImpl.java | 6 +- .../type/PatternConstraintEffectiveImpl.java | 17 ++- .../type/PatternEffectiveStatementImpl.java | 6 +- .../type/RangeConstraintEffectiveImpl.java | 16 +- .../type/RangeEffectiveStatementImpl.java | 6 +- .../yangtools/yang/stmt/test/Bug5200Test.java | 79 ++++++++++ .../src/test/resources/bugs/bug5200/foo.yang | 32 ++++ 19 files changed, 420 insertions(+), 58 deletions(-) create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/AbstractConstraintEffectiveStatement.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/Bug5200Test.java create mode 100644 yang/yang-parser-impl/src/test/resources/bugs/bug5200/foo.yang diff --git a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/BaseConstraints.java b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/BaseConstraints.java index 9b904c563e..4283ae5aeb 100644 --- a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/BaseConstraints.java +++ b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/BaseConstraints.java @@ -51,6 +51,33 @@ public final class BaseConstraints { return new LengthConstraintImpl(min, max, description, reference); } + /** + * Creates a {@link LengthConstraint}. + * + * Creates an instance of Length constraint based on supplied parameters + * with additional behaviour: + * + * + * + * @see LengthConstraint + * + * @param min length-restricting lower bound value. The value MUST NOT be negative. + * @param max length-restricting upper bound value. The value MUST NOT be negative. + * @param description Description associated with constraint. {@link Optional#absent()} if description is undefined. + * @param reference Reference associated with constraint. {@link Optional#absent()} if reference is undefined. + * @param errorAppTag error-app-tag associated with constraint. + * @param errorMessage error message associated with constraint. + * @return Instance of {@link LengthConstraint} + */ + public static LengthConstraint newLengthConstraint(final Number min, final Number max, + final Optional description, final Optional reference, final String errorAppTag, + final String errorMessage) { + return new LengthConstraintImpl(min, max, description, reference, errorAppTag, errorMessage); + } + /** * Creates a {@link RangeConstraint}. * @@ -77,6 +104,35 @@ public final class BaseConstraints { return new RangeConstraintImpl(min, max, description, reference); } + /** + * Creates a {@link RangeConstraint}. + * + * Creates an instance of Range constraint based on supplied parameters + * with additional behaviour: + * + *
    + *
  • {@link RangeConstraint#getErrorAppTag()} returns range-out-of-specified-bounds + *
  • {@link RangeConstraint#getErrorMessage()} returns The argument is out of bounds <min, max > + *
+ * + * + * @see RangeConstraint + * + * @param Type of constraint + * @param min value-restricting lower bound value. The value MUST NOT Be null. + * @param max value-restricting upper bound value. The value MUST NOT Be null. + * @param description Description associated with constraint. {@link Optional#absent()} if description is undefined. + * @param reference Reference associated with constraint. {@link Optional#absent()} if reference is undefined. + * @param errorAppTag error-app-tag associated with constraint. + * @param errorMessage error message associated with constraint. + * @return Instance of {@link RangeConstraint} + */ + public static RangeConstraint newRangeConstraint(final T min, final T max, + final Optional description, final Optional reference, final String errorAppTag, + final String errorMessage) { + return new RangeConstraintImpl(min, max, description, reference, errorAppTag, errorMessage); + } + /** * Creates a {@link PatternConstraint}. * @@ -98,4 +154,28 @@ public final class BaseConstraints { final Optional reference) { return new PatternConstraintImpl(pattern, description, reference); } + + /** + * Creates a {@link PatternConstraint}. + * + * Creates an instance of Pattern constraint based on supplied parameters + * with additional behaviour: + * + *
    + *
  • {@link PatternConstraint#getErrorAppTag()} returns invalid-regular-expression + *
+ * + * @see PatternConstraint + * + * @param pattern Regular expression, MUST NOT BE null. + * @param description Description associated with constraint. + * @param reference Reference associated with constraint. + * @param errorAppTag error-app-tag associated with constraint. + * @param errorMessage error message associated with constraint. + * @return Instance of {@link PatternConstraint} + */ + public static PatternConstraint newPatternConstraint(final String pattern, final Optional description, + final Optional reference, final String errorAppTag, final String errorMessage) { + return new PatternConstraintImpl(pattern, description, reference, errorAppTag, errorMessage); + } } diff --git a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/LengthConstraintImpl.java b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/LengthConstraintImpl.java index ca75b0c615..58f24dc190 100644 --- a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/LengthConstraintImpl.java +++ b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/LengthConstraintImpl.java @@ -38,14 +38,19 @@ final class LengthConstraintImpl implements LengthConstraint, Immutable { LengthConstraintImpl(final Number min, final Number max, final Optional description, final Optional reference) { - super(); + this(min, max, description, reference, "length-out-of-specified-bounds", "The argument is out of bounds <" + + min + ", " + max + ">"); + } + + LengthConstraintImpl(final Number min, final Number max, final Optional description, + final Optional reference, final String errorAppTag, final String errorMessage) { this.min = Preconditions.checkNotNull(min, "min must not be null."); this.max = Preconditions.checkNotNull(max, "max must not be null"); this.description = description.orNull(); this.reference = reference.orNull(); - - this.errorAppTag = "length-out-of-specified-bounds"; - this.errorMessage = "The argument is out of bounds <" + min + ", " + max + ">"; + this.errorAppTag = errorAppTag != null ? errorAppTag : "length-out-of-specified-bounds"; + this.errorMessage = errorMessage != null ? errorMessage : "The argument is out of bounds <" + min + ", " + max + + ">"; } @Override diff --git a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/PatternConstraintImpl.java b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/PatternConstraintImpl.java index eecc2a01f5..cd0ca2cf24 100644 --- a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/PatternConstraintImpl.java +++ b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/PatternConstraintImpl.java @@ -34,17 +34,19 @@ final class PatternConstraintImpl implements PatternConstraint, Immutable { private final String errorAppTag; private final String errorMessage; - public PatternConstraintImpl(final String regex, final Optional description, - final Optional reference) { - super(); + PatternConstraintImpl(final String regex, final Optional description, final Optional reference) { + this(regex, description, reference, "invalid-regular-expression", String.format( + "String %s is not valid regular expression.", regex)); + } + + PatternConstraintImpl(final String regex, final Optional description, final Optional reference, + final String errorAppTag, final String errorMessage) { this.regex = Preconditions.checkNotNull(regex, "regex must not be null."); this.description = description.orNull(); this.reference = reference.orNull(); - - // FIXME: Lookup better suitable error tag. - errorAppTag = "invalid-regular-expression"; - // TODO: add erro message - errorMessage = ""; + this.errorAppTag = errorAppTag != null ? errorAppTag : "invalid-regular-expression"; + this.errorMessage = errorMessage != null ? errorMessage : String.format( + "String %s is not valid regular expression.", regex); } @Override diff --git a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/RangeConstraintImpl.java b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/RangeConstraintImpl.java index f8db087052..132d52a1db 100644 --- a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/RangeConstraintImpl.java +++ b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/RangeConstraintImpl.java @@ -11,7 +11,6 @@ import com.google.common.base.Optional; import com.google.common.base.Preconditions; import java.util.Objects; import org.opendaylight.yangtools.concepts.Immutable; -import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint; import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint; /** @@ -38,14 +37,19 @@ final class RangeConstraintImpl implements RangeConstraint, Immutable { RangeConstraintImpl(final Number min, final Number max, final Optional description, final Optional reference) { - super(); + this(min, max, description, reference, "range-out-of-specified-bounds", "The argument is out of bounds <" + min + + ", " + max + ">"); + } + + RangeConstraintImpl(final Number min, final Number max, final Optional description, + final Optional reference, final String errorAppTag, final String errorMessage) { this.min = Preconditions.checkNotNull(min, "min must not be null."); this.max = Preconditions.checkNotNull(max, "max must not be null."); this.description = description.orNull(); this.reference = reference.orNull(); - - this.errorAppTag = "range-out-of-specified-bounds"; - this.errorMessage = "The argument is out of bounds <" + min + ", " + max + ">"; + this.errorAppTag = errorAppTag != null ? errorAppTag : "range-out-of-specified-bounds"; + this.errorMessage = errorMessage != null ? errorMessage : "The argument is out of bounds <" + min + ", " + max + + ">"; } @Override diff --git a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/type/LengthRestrictedTypeBuilder.java b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/type/LengthRestrictedTypeBuilder.java index fe217561b1..eb590a9128 100644 --- a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/type/LengthRestrictedTypeBuilder.java +++ b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/type/LengthRestrictedTypeBuilder.java @@ -63,7 +63,7 @@ public abstract class LengthRestrictedTypeBuilder> e ((UnresolvedNumber)min).resolveLength(baseLengthConstraints) : min; builder.add(BaseConstraints.newLengthConstraint(rMin, rMax, Optional.fromNullable(c.getDescription()), - Optional.fromNullable(c.getReference()))); + Optional.fromNullable(c.getReference()), c.getErrorAppTag(), c.getErrorMessage())); } else { builder.add(c); } @@ -101,7 +101,7 @@ public abstract class LengthRestrictedTypeBuilder> e c, clazz.getSimpleName()), e); } builder.add(BaseConstraints.newLengthConstraint(min, max, Optional.fromNullable(c.getDescription()), - Optional.fromNullable(c.getReference()))); + Optional.fromNullable(c.getReference()), c.getErrorAppTag(), c.getErrorMessage())); } else { builder.add(c); } diff --git a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/type/RangeRestrictedTypeBuilder.java b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/type/RangeRestrictedTypeBuilder.java index ebebbe3e42..e461d48abc 100644 --- a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/type/RangeRestrictedTypeBuilder.java +++ b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/type/RangeRestrictedTypeBuilder.java @@ -64,7 +64,7 @@ public abstract class RangeRestrictedTypeBuilder> ex ((UnresolvedNumber)min).resolveRange(baseRangeConstraints) : min; builder.add(BaseConstraints.newRangeConstraint(rMin, rMax, Optional.fromNullable(c.getDescription()), - Optional.fromNullable(c.getReference()))); + Optional.fromNullable(c.getReference()), c.getErrorAppTag(), c.getErrorMessage())); } else { builder.add(c); } @@ -103,7 +103,7 @@ public abstract class RangeRestrictedTypeBuilder> ex c, clazz.getSimpleName()), e); } builder.add(BaseConstraints.newRangeConstraint(min, max, Optional.fromNullable(c.getDescription()), - Optional.fromNullable(c.getReference()))); + Optional.fromNullable(c.getReference()), c.getErrorAppTag(), c.getErrorMessage())); } else { builder.add(c); } diff --git a/yang/yang-model-util/src/test/java/org/opendaylight/yangtools/yang/model/util/PatternConstraintImplTest.java b/yang/yang-model-util/src/test/java/org/opendaylight/yangtools/yang/model/util/PatternConstraintImplTest.java index 536d5a24de..305fea505c 100644 --- a/yang/yang-model-util/src/test/java/org/opendaylight/yangtools/yang/model/util/PatternConstraintImplTest.java +++ b/yang/yang-model-util/src/test/java/org/opendaylight/yangtools/yang/model/util/PatternConstraintImplTest.java @@ -35,7 +35,7 @@ public class PatternConstraintImplTest { assertNotNull("Object of PatternConstraintImpl shouldn't be null.", patternConstraint); assertEquals("Description should be 'test description'.", "test description", patternConstraint.getDescription()); assertEquals("Error app tag shouldn't be null.", "invalid-regular-expression", patternConstraint.getErrorAppTag()); - assertTrue("Error message should be empty.", patternConstraint.getErrorMessage().isEmpty()); + assertNotNull(patternConstraint.getErrorMessage()); assertEquals("Reference should be equals 'RFC 6020'.", "RFC 6020", patternConstraint.getReference()); assertEquals("Regular expression should be equls '\\D'.", "\\D", patternConstraint.getRegularExpression()); assertNotEquals("Hash codes shouldn't be equals.", patternConstraint.hashCode(), patternConstraint2.hashCode()); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContextUtils.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContextUtils.java index 05b7f67c33..6b5f8439df 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContextUtils.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContextUtils.java @@ -71,6 +71,12 @@ public final class StmtContextUtils { return producesDeclared(ctx, declaredType) ? (AT) ctx.getStatementArgument() : null; } + public static > AT firstSubstatementAttributeOf( + final StmtContext ctx, final Class
declaredType) { + AT firstAttribute = firstAttributeOf(ctx.effectiveSubstatements(), declaredType); + return firstAttribute != null ? firstAttribute : firstAttributeOf(ctx.declaredSubstatements(), declaredType); + } + @SuppressWarnings("unchecked") public static > StmtContext findFirstDeclaredSubstatement( final StmtContext stmtContext, final Class
declaredType) { diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/TypeUtils.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/TypeUtils.java index cd579073d6..11f460ae54 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/TypeUtils.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/TypeUtils.java @@ -157,13 +157,13 @@ public final class TypeUtils { } public static List parseLengthListFromString(final StmtContext ctx, - final String rangeArgument) { + final String lengthArgument) { Optional description = Optional.absent(); Optional reference = Optional.absent(); - List rangeConstraints = new ArrayList<>(); + List lengthConstraints = new ArrayList<>(); - for (final String singleRange : PIPE_SPLITTER.split(rangeArgument)) { + for (final String singleRange : PIPE_SPLITTER.split(lengthArgument)) { final Iterator boundaries = TWO_DOTS_SPLITTER.splitToList(singleRange).iterator(); final Number min = parseIntegerConstraintValue(ctx, boundaries.next()); @@ -183,15 +183,15 @@ public final class TypeUtils { } // some of intervals overlapping - if (rangeConstraints.size() > 1 && compareNumbers(min, Iterables.getLast(rangeConstraints).getMax()) != 1) { + if (lengthConstraints.size() > 1 && compareNumbers(min, Iterables.getLast(lengthConstraints).getMax()) != 1) { throw new InferenceException(ctx.getStatementSourceReference(), - "Some of the length ranges in %s are not disjoint", rangeArgument); + "Some of the length ranges in %s are not disjoint", lengthArgument); } - rangeConstraints.add(new LengthConstraintEffectiveImpl(min, max, description, reference)); + lengthConstraints.add(new LengthConstraintEffectiveImpl(min, max, description, reference)); } - return rangeConstraints; + return lengthConstraints; } public static boolean isYangTypeBodyStmtString(final String typeName) { diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/DeclaredEffectiveStatementBase.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/DeclaredEffectiveStatementBase.java index 2c96fba980..212a65e813 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/DeclaredEffectiveStatementBase.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/DeclaredEffectiveStatementBase.java @@ -62,7 +62,7 @@ public abstract class DeclaredEffectiveStatementBase> extends + DeclaredEffectiveStatementBase { + private final String description; + private final String reference; + private final String errorAppTag; + private final String errorMessage; + private final A constraints; + + public AbstractConstraintEffectiveStatement(final StmtContext ctx, ConstraintFactory constraintFactory) { + super(ctx); + String descriptionInit = null; + String referenceInit = null; + String errorAppTagInit = null; + String errorMessageInit = null; + + for (EffectiveStatement stmt : effectiveSubstatements()) { + if (stmt instanceof DescriptionEffectiveStatementImpl) { + descriptionInit = ((DescriptionEffectiveStatementImpl) stmt).argument(); + } + if (stmt instanceof ReferenceEffectiveStatementImpl) { + referenceInit = ((ReferenceEffectiveStatementImpl) stmt).argument(); + } + if (stmt instanceof ErrorAppTagEffectiveStatementImpl) { + errorAppTagInit = ((ErrorAppTagEffectiveStatementImpl) stmt).argument(); + } + if (stmt instanceof ErrorMessageEffectiveStatementImpl) { + errorMessageInit = ((ErrorMessageEffectiveStatementImpl) stmt).argument(); + } + } + + this.description = descriptionInit; + this.reference = referenceInit; + this.errorAppTag = errorAppTagInit; + this.errorMessage = errorMessageInit; + this.constraints = constraintFactory.createConstraints(this, super.argument()); + } + + @Override + public final A argument() { + return constraints; + } + + public final boolean isCustomizedStatement() { + return this.description != null || this.reference != null || this.errorAppTag != null + || this.errorMessage != null; + } + + public final String getDescription() { + return description; + } + + public final String getReference() { + return reference; + } + + public final String getErrorAppTag() { + return errorAppTag; + } + + public final String getErrorMessage() { + return errorMessage; + } +} + +abstract class ConstraintFactory { + abstract protected A createConstraints(AbstractConstraintEffectiveStatement stmt, A argument); +} + +abstract class ListConstraintFactory extends ConstraintFactory> { + @Override + protected List createConstraints(AbstractConstraintEffectiveStatement, ?> stmt, List argument) { + if (!stmt.isCustomizedStatement()) { + return ImmutableList.copyOf(argument); + } + + List customizedConstraints = new ArrayList<>(); + for (A constraint : argument) { + customizedConstraints.add(createCustomizedConstraint(constraint, stmt)); + } + return customizedConstraints; + } + + abstract protected A createCustomizedConstraint(A constraint, AbstractConstraintEffectiveStatement, ?> stmt); +} + +final class LengthConstraintFactory extends ListConstraintFactory { + @Override + protected LengthConstraint createCustomizedConstraint(LengthConstraint lengthConstraint, + AbstractConstraintEffectiveStatement, ?> stmt) { + return new LengthConstraintEffectiveImpl(lengthConstraint.getMin(), lengthConstraint.getMax(), + stmt.getDescription(), stmt.getReference(), stmt.getErrorAppTag(), stmt.getErrorMessage()); + } +} + +final class RangeConstraintFactory extends ListConstraintFactory { + @Override + protected RangeConstraint createCustomizedConstraint(RangeConstraint rangeConstraint, + AbstractConstraintEffectiveStatement, ?> stmt) { + return new RangeConstraintEffectiveImpl(rangeConstraint.getMin(), rangeConstraint.getMax(), + stmt.getDescription(), stmt.getReference(), stmt.getErrorAppTag(), stmt.getErrorMessage()); + } +} + +final class PatternConstraintFactory extends ConstraintFactory { + @Override + protected PatternConstraint createConstraints(AbstractConstraintEffectiveStatement stmt, PatternConstraint argument) { + if (!stmt.isCustomizedStatement()) { + return argument; + } else { + return createCustomizedConstraint(argument, stmt); + } + } + + private PatternConstraint createCustomizedConstraint(PatternConstraint patternConstraint, + AbstractConstraintEffectiveStatement stmt) { + return new PatternConstraintEffectiveImpl(patternConstraint.getRegularExpression(), stmt.getDescription(), + stmt.getReference(), stmt.getErrorAppTag(), stmt.getErrorMessage()); + } +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/LengthConstraintEffectiveImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/LengthConstraintEffectiveImpl.java index 32ca55e446..98e11ecf65 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/LengthConstraintEffectiveImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/LengthConstraintEffectiveImpl.java @@ -25,16 +25,20 @@ public class LengthConstraintEffectiveImpl implements LengthConstraint { public LengthConstraintEffectiveImpl(final Number min, final Number max, final Optional description, final Optional reference) { + this(min, max, description.orNull(), reference.orNull(), "length-out-of-specified-bounds", "The argument is out of bounds <" + + min + ", " + max + ">"); + } + public LengthConstraintEffectiveImpl(final Number min, final Number max, final String description, + final String reference, final String errorAppTag, final String errorMessage) { super(); - this.min = Preconditions.checkNotNull(min, "min must not be null."); this.max = Preconditions.checkNotNull(max, "max must not be null"); - this.description = description.orNull(); - this.reference = reference.orNull(); - - this.errorAppTag = "length-out-of-specified-bounds"; - this.errorMessage = "The argument is out of bounds <" + min + ", " + max + ">"; + this.description = description; + this.reference = reference; + this.errorAppTag = errorAppTag != null ? errorAppTag : "length-out-of-specified-bounds"; + this.errorMessage = errorMessage != null ? errorMessage : "The argument is out of bounds <" + min + ", " + max + + ">"; } @Override diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/LengthEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/LengthEffectiveStatementImpl.java index 84e7c993ac..19a71c04ae 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/LengthEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/LengthEffectiveStatementImpl.java @@ -11,10 +11,10 @@ import java.util.List; import org.opendaylight.yangtools.yang.model.api.stmt.LengthStatement; import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.DeclaredEffectiveStatementBase; -public class LengthEffectiveStatementImpl extends DeclaredEffectiveStatementBase, LengthStatement> { +public class LengthEffectiveStatementImpl extends + AbstractConstraintEffectiveStatement, LengthStatement> { public LengthEffectiveStatementImpl(final StmtContext, LengthStatement, ?> ctx) { - super(ctx); + super(ctx, new LengthConstraintFactory()); } } \ No newline at end of file diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/PatternConstraintEffectiveImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/PatternConstraintEffectiveImpl.java index 184ebc401b..d8799648f6 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/PatternConstraintEffectiveImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/PatternConstraintEffectiveImpl.java @@ -17,21 +17,24 @@ public class PatternConstraintEffectiveImpl implements PatternConstraint { private final String regEx; private final String description; private final String reference; - private final String errorAppTag; private final String errorMessage; public PatternConstraintEffectiveImpl(final String regex, final Optional description, final Optional reference) { + this(regex, description.orNull(), reference.orNull(), "invalid-regular-expression", String.format( + "String %s is not valid regular expression.", regex)); + } + public PatternConstraintEffectiveImpl(final String regex, final String description, final String reference, + final String errorAppTag, final String errorMessage) { super(); - this.regEx = Preconditions.checkNotNull(regex, "regex must not be null."); - this.description = description.orNull(); - this.reference = reference.orNull(); - - errorAppTag = "invalid-regular-expression"; - errorMessage = String.format("String %s is not valid regular expression.", regex); + this.description = description; + this.reference = reference; + this.errorAppTag = errorAppTag != null ? errorAppTag : "invalid-regular-expression"; + this.errorMessage = errorMessage != null ? errorMessage : String.format( + "String %s is not valid regular expression.", regex); } @Override diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/PatternEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/PatternEffectiveStatementImpl.java index fb59877b8b..eeb4d4c3ba 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/PatternEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/PatternEffectiveStatementImpl.java @@ -10,10 +10,10 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type; import org.opendaylight.yangtools.yang.model.api.stmt.PatternStatement; import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.DeclaredEffectiveStatementBase; -public class PatternEffectiveStatementImpl extends DeclaredEffectiveStatementBase { +public class PatternEffectiveStatementImpl extends + AbstractConstraintEffectiveStatement { public PatternEffectiveStatementImpl(final StmtContext ctx) { - super(ctx); + super(ctx, new PatternConstraintFactory()); } } \ No newline at end of file diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/RangeConstraintEffectiveImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/RangeConstraintEffectiveImpl.java index 4308ecb07b..6283689c55 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/RangeConstraintEffectiveImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/RangeConstraintEffectiveImpl.java @@ -26,16 +26,20 @@ public class RangeConstraintEffectiveImpl implements RangeConstraint { public RangeConstraintEffectiveImpl(final Number min, final Number max, final Optional description, final Optional reference) { + this(min, max, description.orNull(), reference.orNull(), "range-out-of-specified-bounds", + "The argument is out of bounds <" + min + ", " + max + ">"); + } + public RangeConstraintEffectiveImpl(final Number min, final Number max, final String description, + final String reference, final String errorAppTag, final String errorMessage) { super(); - this.min = Preconditions.checkNotNull(min, "min must not be null."); this.max = Preconditions.checkNotNull(max, "max must not be null."); - this.description = description.orNull(); - this.reference = reference.orNull(); - - this.errorAppTag = "range-out-of-specified-bounds"; - this.errorMessage = "The argument is out of bounds <" + min + ", " + max + ">"; + this.description = description; + this.reference = reference; + this.errorAppTag = errorAppTag != null ? errorAppTag : "range-out-of-specified-bounds"; + this.errorMessage = errorMessage != null ? errorMessage : "The argument is out of bounds <" + min + ", " + max + + ">"; } @Override diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/RangeEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/RangeEffectiveStatementImpl.java index 72f08e34a7..dec4c9ed22 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/RangeEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/RangeEffectiveStatementImpl.java @@ -11,10 +11,10 @@ import java.util.List; import org.opendaylight.yangtools.yang.model.api.stmt.RangeStatement; import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.DeclaredEffectiveStatementBase; -public class RangeEffectiveStatementImpl extends DeclaredEffectiveStatementBase, RangeStatement> { +public class RangeEffectiveStatementImpl extends + AbstractConstraintEffectiveStatement, RangeStatement> { public RangeEffectiveStatementImpl(final StmtContext, RangeStatement, ?> ctx) { - super(ctx); + super(ctx, new RangeConstraintFactory()); } } diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/Bug5200Test.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/Bug5200Test.java new file mode 100644 index 0000000000..409359ed6a --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/Bug5200Test.java @@ -0,0 +1,79 @@ +/* + * 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.stmt.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.FileNotFoundException; +import java.net.URISyntaxException; +import java.util.List; +import org.junit.Test; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint; +import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint; +import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint; +import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition; +import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; +import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; +import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; + +public class Bug5200Test { + private static final String NS = "foo"; + private static final String REV = "2016-05-05"; + + @Test + public void test() throws SourceException, FileNotFoundException, ReactorException, URISyntaxException { + SchemaContext context = StmtTestUtils.parseYangSources("/bugs/bug5200"); + assertNotNull(context); + + QName root = QName.create(NS, REV, "root"); + QName myLeaf = QName.create(NS, REV, "my-leaf"); + QName myLeaf2 = QName.create(NS, REV, "my-leaf-2"); + + SchemaNode myLeafNode = SchemaContextUtil.findDataSchemaNode(context, SchemaPath.create(true, root, myLeaf)); + SchemaNode myLeaf2Node = SchemaContextUtil.findDataSchemaNode(context, SchemaPath.create(true, root, myLeaf2)); + + assertTrue(myLeafNode instanceof LeafSchemaNode); + assertTrue(myLeaf2Node instanceof LeafSchemaNode); + + TypeDefinition myLeafType = ((LeafSchemaNode) myLeafNode).getType(); + TypeDefinition myLeaf2Type = ((LeafSchemaNode) myLeaf2Node).getType(); + + assertTrue(myLeafType instanceof StringTypeDefinition); + assertTrue(myLeaf2Type instanceof IntegerTypeDefinition); + + List lengthConstraints = ((StringTypeDefinition) myLeafType).getLengthConstraints(); + List patternConstraints = ((StringTypeDefinition) myLeafType).getPatternConstraints(); + + assertEquals(1, lengthConstraints.size()); + assertEquals(1, patternConstraints.size()); + + LengthConstraint lenghtConstraint = lengthConstraints.iterator().next(); + assertEquals("lenght constraint error-app-tag", lenghtConstraint.getErrorAppTag()); + assertEquals("lenght constraint error-app-message", lenghtConstraint.getErrorMessage()); + + PatternConstraint patternConstraint = patternConstraints.iterator().next(); + assertEquals("pattern constraint error-app-tag", patternConstraint.getErrorAppTag()); + assertEquals("pattern constraint error-app-message", patternConstraint.getErrorMessage()); + + List rangeConstraints = ((IntegerTypeDefinition) myLeaf2Type).getRangeConstraints(); + assertEquals(1, rangeConstraints.size()); + + RangeConstraint rangeConstraint = rangeConstraints.iterator().next(); + assertEquals("range constraint error-app-tag", rangeConstraint.getErrorAppTag()); + assertEquals("range constraint error-app-message", rangeConstraint.getErrorMessage()); + } +} diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug5200/foo.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug5200/foo.yang new file mode 100644 index 0000000000..d007127d8b --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/bugs/bug5200/foo.yang @@ -0,0 +1,32 @@ +module foo { + yang-version 1; + namespace "foo"; + prefix foo; + + revision 2016-05-05 { + description "Bug 5200 test."; + } + + container root { + leaf my-leaf { + type string { + length "1..255" { + error-app-tag "lenght constraint error-app-tag"; + error-message "lenght constraint error-app-message"; + } + pattern "[a-z]+" { + error-app-tag "pattern constraint error-app-tag"; + error-message "pattern constraint error-app-message"; + } + } + } + leaf my-leaf-2 { + type int32 { + range "1..100" { + error-app-tag "range constraint error-app-tag"; + error-message "range constraint error-app-message"; + } + } + } + } +} -- 2.36.6