import com.google.common.annotations.Beta;
import com.google.common.base.CharMatcher;
-import com.google.common.collect.Range;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import com.google.common.collect.RangeSet;
import java.util.Optional;
import java.util.regex.Pattern;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+ "\n - a hexadecimal number (prefix 0x)," + "%n - an octal number (prefix 0)."
+ "\nSigned values are allowed. Spaces between digits are NOT allowed.";
- private final List<Range<N>> rangeConstraints;
+ private final RangeSet<N> rangeConstraints;
- AbstractIntegerStringCodec(final Optional<T> typeDefinition, final List<RangeConstraint> constraints,
+ AbstractIntegerStringCodec(final Optional<T> typeDefinition, final Optional<RangeConstraint<?>> constraint,
final Class<N> outputClass) {
super(typeDefinition, outputClass);
- if (constraints.isEmpty()) {
- rangeConstraints = Collections.emptyList();
- } else {
- final List<Range<N>> builder = new ArrayList<>(constraints.size());
- for (final RangeConstraint yangConstraint : constraints) {
- builder.add(createRange(yangConstraint.getMin(), yangConstraint.getMax()));
- }
- rangeConstraints = builder;
- }
+ rangeConstraints = (RangeSet<N>) constraint.map(RangeConstraint::getAllowedRanges).orElse(null);
}
public static AbstractIntegerStringCodec<?, IntegerTypeDefinition> from(final IntegerTypeDefinition type) {
}
}
- private Range<N> createRange(final Number yangMin, final Number yangMax) {
- final N min = convertValue(yangMin);
- final N max = convertValue(yangMax);
- return Range.closed(min, max);
- }
-
@Override
public final N deserialize(final String stringRepresentation) {
final int base = provideBase(stringRepresentation);
*/
abstract N deserialize(String stringRepresentation, int radix);
- abstract N convertValue(Number value);
-
private void validate(final N value) {
- if (rangeConstraints.isEmpty()) {
- return;
- }
- for (final Range<N> constraint : rangeConstraints) {
- if (constraint.contains(value)) {
- return;
- }
+ if (rangeConstraints != null) {
+ checkArgument(rangeConstraints.contains(value), "Value '%s' is not in required ranges %s",
+ value, rangeConstraints);
}
- throw new IllegalArgumentException("Value '" + value + "' is not in required range " + rangeConstraints);
}
- protected static List<RangeConstraint> extractRange(final IntegerTypeDefinition type) {
- if (type == null) {
- return Collections.emptyList();
- }
- return type.getRangeConstraints();
+ protected static Optional<RangeConstraint<?>> extractRange(final IntegerTypeDefinition type) {
+ return type == null ? Optional.empty() : type.getRangeConstraint();
}
- protected static List<RangeConstraint> extractRange(final UnsignedIntegerTypeDefinition type) {
- if (type == null) {
- return Collections.emptyList();
- }
- return type.getRangeConstraints();
+ protected static Optional<RangeConstraint<?>> extractRange(final UnsignedIntegerTypeDefinition type) {
+ return type == null ? Optional.empty() : type.getRangeConstraint();
}
private static int provideBase(final String integer) {
public String serialize(final Short data) {
return Objects.toString(data, "");
}
-
- @Override
- Short convertValue(final Number value) {
- return value.shortValue();
- }
}
public String serialize(final Integer data) {
return Objects.toString(data, "");
}
-
- @Override
- Integer convertValue(final Number value) {
- return value.intValue();
- }
}
public String serialize(final Long data) {
return Objects.toString(data, "");
}
-
- @Override
- Long convertValue(final Number value) {
- return value.longValue();
- }
}
public String serialize(final Byte data) {
return Objects.toString(data, "");
}
-
- @Override
- Byte convertValue(final Number value) {
- return value.byteValue();
- }
}
public String serialize(final Integer data) {
return Objects.toString(data, "");
}
-
- @Override
- Integer convertValue(final Number value) {
- return value.intValue();
- }
}
public String serialize(final Long data) {
return Objects.toString(data, "");
}
-
- @Override
- Long convertValue(final Number value) {
- return value.longValue();
- }
}
public String serialize(final BigInteger data) {
return Objects.toString(data, "");
}
-
- @Override
- BigInteger convertValue(final Number value) {
- if (value instanceof BigInteger) {
- return (BigInteger) value;
- }
- return BigInteger.valueOf(value.longValue());
- }
}
Short deserialize(final String stringRepresentation, final int base) {
return Short.valueOf(stringRepresentation, base);
}
-
- @Override
- Short convertValue(final Number value) {
- return value.shortValue();
- }
}
*
* <dt>range
* <dd>{@link org.opendaylight.yangtools.yang.model.api.type.RangeConstraint}
- * <dd>{@link org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition#getRangeConstraints()}
- * <dd>{@link org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition#getRangeConstraints()}
+ * <dd>{@link org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition#getRangeConstraint()}
+ * <dd>{@link org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition#getRangeConstraint()}
*
* <dt>reference
* <dd>{@link org.opendaylight.yangtools.yang.model.api.SchemaNode#getReference()}
package org.opendaylight.yangtools.yang.model.api.stmt;
import java.util.List;
-
import javax.annotation.Nonnull;
-
import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
-import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
-
-public interface RangeStatement extends DeclaredStatement<List<RangeConstraint>>, DocumentedConstraintGroup {
+public interface RangeStatement extends DeclaredStatement<List<ValueRange>>, DocumentedConstraintGroup {
@Nonnull
- List<RangeConstraint> getRange();
+ @Override
+ List<ValueRange> argument();
}
import com.google.common.annotations.Beta;
import com.google.common.collect.Range;
-import java.util.List;
import org.opendaylight.yangtools.concepts.Immutable;
-import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
@Beta
public abstract class UnresolvedNumber extends Number implements Immutable {
private static final long serialVersionUID = 1L;
@Override
- public <T extends Number & Comparable<T>> T resolveLength(final Range<T> span) {
+ public <T extends Number & Comparable<T>> T resolveLength(final Range<? extends T> span) {
return resolve(span.upperEndpoint());
}
@Override
- public Number resolveRange(final List<RangeConstraint> constraints) {
- return resolve(constraints.get(constraints.size() - 1).getMax());
+ public <T extends Number & Comparable<T>> T resolveRange(final Range<? extends T> span) {
+ return resolve(span.upperEndpoint());
}
@Override
private static final long serialVersionUID = 1L;
@Override
- public <T extends Number & Comparable<T>> T resolveLength(final Range<T> span) {
+ public <T extends Number & Comparable<T>> T resolveLength(final Range<? extends T> span) {
return resolve(span.lowerEndpoint());
}
@Override
- public Number resolveRange(final List<RangeConstraint> constraints) {
- return resolve(constraints.get(0).getMin());
+ public <T extends Number & Comparable<T>> T resolveRange(final Range<? extends T> span) {
+ return resolve(span.lowerEndpoint());
}
@Override
return number;
}
- public abstract <T extends Number & Comparable<T>> T resolveLength(Range<T> span);
+ public abstract <T extends Number & Comparable<T>> T resolveLength(Range<? extends T> span);
- public abstract Number resolveRange(List<RangeConstraint> constraints);
+ public abstract <T extends Number & Comparable<T>> T resolveRange(Range<? extends T> span);
@Override
public abstract String toString();
*/
package org.opendaylight.yangtools.yang.model.api.type;
+import com.google.common.collect.RangeSet;
import org.opendaylight.yangtools.yang.model.api.ConstraintMetaDefinition;
/**
- * The Range Constraint interface is used to restrict integer and decimal
- * built-in types, or types derived from those.
- * <br>
- * A range consists of an explicit value consists of an explicit value, or a lower bound
- * returned by {@link #getMin()} and an upper bound returned by
- * {@link #getMax()}. <br>
- * <br>
- * Each explicit value and range boundary value given in
- * the range expression MUST match the type being restricted, or be one of the
- * special values "min" or "max". "min" and "max" mean the minimum and maximum
- * value accepted for the type being restricted, respectively
- * <br>
- * <br>
- * This interface was modeled according to definition in <a
- * href="https://tools.ietf.org/html/rfc6020#section-9.2.4">[RFC-6020] The
- * range Statement</a>.
+ * A single value range restriction, as expressed by a range statement, as specified by
+ * <a href="https://tools.ietf.org/html/rfc6020#section-9.2.4">[RFC-6020] The range Statement</a>.
*/
-public interface RangeConstraint extends ConstraintMetaDefinition {
-
- /**
- * Returns the length-restricting lower bound value.
- *
- * @return the length-restricting lower bound value.
- */
- Number getMin();
-
+public interface RangeConstraint<T extends Number & Comparable<T>> extends ConstraintMetaDefinition {
/**
- * Returns the length-restricting upper bound value.
+ * Return allowed length ranges. Returned RangeSet must not be empty.
*
- * @return the length-restricting upper bound value.
+ * @return Set of allowed lengths.
*/
- Number getMax();
+ RangeSet<? extends T> getAllowedRanges();
}
*/
package org.opendaylight.yangtools.yang.model.api.type;
-import java.util.List;
-import javax.annotation.Nonnull;
+import java.util.Optional;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
/**
*/
public interface RangeRestrictedTypeDefinition<T extends TypeDefinition<T>> extends TypeDefinition<T> {
/**
- * Returns range constraints for instance of this type. These are the effective constraints, e.g. they include
- * any range constraints imposed by base types.
+ * Returns range constraint of this type, if applicable. This is the effective constraint, e.g. it includes any
+ * range constraints implied by base type hierarchy.
*
- * @return list of range constraints which are specified as the argument of the <code>range</code> which is
- * a substatement of the <code>type</code> statement
+ * @return range constraint which are specified in the <code>range</code> substatement of the <code>type</code>
+ * statement.
*/
- @Nonnull List<RangeConstraint> getRangeConstraints();
+ Optional<RangeConstraint<?>> getRangeConstraint();
}
}
private void emitIntegerSpefication(final IntegerTypeDefinition typeDef) {
- emitRangeNodeOptional(typeDef.getRangeConstraints());
+ typeDef.getRangeConstraint().ifPresent(this::emitRangeNode);
}
private void emitUnsignedIntegerSpecification(final UnsignedIntegerTypeDefinition typeDef) {
- emitRangeNodeOptional(typeDef.getRangeConstraints());
-
+ typeDef.getRangeConstraint().ifPresent(this::emitRangeNode);
}
- private void emitRangeNodeOptional(final List<RangeConstraint> list) {
- // FIXME: BUG-2444: Wrong decomposition in API, should be
- // LenghtConstraint
- // which contains ranges.
- if (!list.isEmpty()) {
- super.writer.startRangeNode(toRangeString(list));
- final RangeConstraint first = list.iterator().next();
- first.getErrorMessage().ifPresent(this::emitErrorMessageNode);
- first.getErrorAppTag().ifPresent(this::emitErrorAppTagNode);
- emitDocumentedNode(first);
- super.writer.endNode();
- }
-
+ private void emitRangeNode(final RangeConstraint<?> constraint) {
+ super.writer.startRangeNode(toRangeString(constraint.getAllowedRanges()));
+ constraint.getErrorMessage().ifPresent(this::emitErrorMessageNode);
+ constraint.getErrorAppTag().ifPresent(this::emitErrorAppTagNode);
+ emitDocumentedNode(constraint);
+ super.writer.endNode();
}
private void emitDecimal64Specification(final DecimalTypeDefinition typeDefinition) {
emitFranctionDigitsNode(typeDefinition.getFractionDigits());
- emitRangeNodeOptional(typeDefinition.getRangeConstraints());
+ typeDefinition.getRangeConstraint().ifPresent(this::emitRangeNode);
}
private void emitFranctionDigitsNode(final Integer fractionDigits) {
return sb.toString();
}
- private static String toRangeString(final List<RangeConstraint> list) {
- final Iterator<RangeConstraint> it = list.iterator();
+ private static String toRangeString(final RangeSet<?> ranges) {
+ final Iterator<? extends Range<?>> it = ranges.asRanges().iterator();
if (!it.hasNext()) {
return "";
}
final StringBuilder sb = new StringBuilder();
boolean haveNext;
do {
- final RangeConstraint current = it.next();
+ final Range<?> current = it.next();
haveNext = it.hasNext();
- appendRange(sb, current.getMin(), current.getMax(), haveNext);
+ appendRange(sb, current.lowerEndpoint(), current.upperEndpoint(), haveNext);
} while (haveNext);
return sb.toString();
}
- private static void appendRange(final StringBuilder sb, final Number min, final Number max,
+ private static void appendRange(final StringBuilder sb, final Object min, final Object max,
final boolean haveNext) {
sb.append(min);
if (!min.equals(max)) {
import java.util.Optional;
import org.opendaylight.yangtools.yang.model.api.type.ModifierKind;
import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
-import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
/**
* Utility class which provides factory methods to construct Constraints.
* <p>
* Provides static factory methods which constructs instances of
* <ul>
- * <li>{@link RangeConstraint} - {@link #newRangeConstraint(Number, Number, Optional, Optional)}
* <li>{@link PatternConstraint} - {@link #newPatternConstraint(String, Optional, Optional)}
* </ul>
*/
throw new UnsupportedOperationException();
}
- /**
- * Creates a {@link RangeConstraint}.
- *
- * <p>
- * Creates an instance of Range constraint based on supplied parameters
- * with additional behaviour:
- * <ul>
- * <li>{@link RangeConstraint#getErrorAppTag()} returns <code>range-out-of-specified-bounds</code>
- * <li>{@link RangeConstraint#getErrorMessage()} returns <code>The argument is out of bounds
- * <<i>min</i>, <i>max</i> ></code>
- * </ul>
- *
- * @see RangeConstraint
- *
- * @param <T> 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#empty()} if description is undefined.
- * @param reference Reference associated with constraint. {@link Optional#empty()} if reference is undefined.
- * @return Instance of {@link RangeConstraint}
- */
- public static <T extends Number> RangeConstraint newRangeConstraint(final T min, final T max,
- final Optional<String> description, final Optional<String> reference) {
- return new RangeConstraintImpl(min, max, description, reference);
- }
-
- /**
- * Creates a {@link RangeConstraint}.
- *
- * <p>
- * Creates an instance of Range constraint based on supplied parameters
- * with additional behaviour:
- * <ul>
- * <li>{@link RangeConstraint#getErrorAppTag()} returns <code>range-out-of-specified-bounds</code>
- * <li>{@link RangeConstraint#getErrorMessage()} returns <code>The argument is out of bounds
- * <<i>min</i>, <i>max</i> ></code>
- * </ul>
- *
- * @see RangeConstraint
- *
- * @param <T> 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#empty()} if description is undefined.
- * @param reference Reference associated with constraint. {@link Optional#empty()} 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 <T extends Number> RangeConstraint newRangeConstraint(final T min, final T max,
- final Optional<String> description, final Optional<String> reference, final String errorAppTag,
- final String errorMessage) {
- return new RangeConstraintImpl(min, max, description, reference, errorAppTag, errorMessage);
- }
-
/**
* Creates a {@link PatternConstraint}.
*
+++ /dev/null
-/*
- * Copyright (c) 2014 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.model.util;
-
-import com.google.common.base.Preconditions;
-import java.util.Objects;
-import java.util.Optional;
-import org.opendaylight.yangtools.concepts.Immutable;
-import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
-
-/**
- * {@link Immutable} implementation of {@link RangeConstraint}.
- *
- * <p>
- * Range constraint based on supplied parameters with additional behavior:
- * <ul>
- * <li>{@link RangeConstraint#getErrorAppTag()} returns
- * <code>range-out-of-specified-bounds</code>
- * <li>{@link RangeConstraint#getErrorMessage()} returns <code>The argument is
- * out of bounds <<i>min</i>, <i>max</i> ></code>
- * </ul>
- */
-final class RangeConstraintImpl implements RangeConstraint, Immutable {
- private final Number min;
- private final Number max;
-
- private final String description;
- private final String reference;
-
- private final String errorAppTag;
- private final String errorMessage;
-
- RangeConstraintImpl(final Number min, final Number max, final Optional<String> description,
- final Optional<String> reference) {
- 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<String> description,
- final Optional<String> 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.orElse(null);
- this.reference = reference.orElse(null);
- this.errorAppTag = errorAppTag != null ? errorAppTag : "range-out-of-specified-bounds";
- this.errorMessage = errorMessage != null ? errorMessage : "The argument is out of bounds <" + min + ", " + max
- + ">";
- }
-
- @Override
- public Optional<String> getDescription() {
- return Optional.ofNullable(description);
- }
-
- @Override
- public Optional<String> getErrorAppTag() {
- return Optional.ofNullable(errorAppTag);
- }
-
- @Override
- public Optional<String> getErrorMessage() {
- return Optional.ofNullable(errorMessage);
- }
-
- @Override
- public Optional<String> getReference() {
- return Optional.ofNullable(reference);
- }
-
- @Override
- public Number getMin() {
- return min;
- }
-
- @Override
- public Number getMax() {
- return max;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + Objects.hashCode(description);
- result = prime * result + errorAppTag.hashCode();
- result = prime * result + errorMessage.hashCode();
- result = prime * result + max.hashCode();
- result = prime * result + min.hashCode();
- result = prime * result + Objects.hashCode(reference);
- return result;
- }
-
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!(obj instanceof RangeConstraintImpl)) {
- return false;
- }
- final RangeConstraintImpl other = (RangeConstraintImpl) obj;
- return Objects.equals(description, other.description) && Objects.equals(max, other.max)
- && Objects.equals(min, other.min) && Objects.equals(reference, other.reference);
- }
-
- @Override
- public String toString() {
- return "RangeConstraintImpl [min=" + min + ", max=" + max + ", description=" + description
- + ", reference=" + reference + ", errorAppTag=" + errorAppTag + ", errorMessage=" + errorMessage + "]";
- }
-}
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
-abstract class AbstractIntegerBaseType extends AbstractRangeRestrictedBaseType<IntegerTypeDefinition>
- implements IntegerTypeDefinition {
- AbstractIntegerBaseType(final QName qname, final Number minValue, final Number maxValue) {
+abstract class AbstractIntegerBaseType<C extends Number & Comparable<C>>
+ extends AbstractRangeRestrictedBaseType<IntegerTypeDefinition, C> implements IntegerTypeDefinition {
+ AbstractIntegerBaseType(final QName qname, final C minValue, final C maxValue) {
super(qname, minValue, maxValue);
}
*/
package org.opendaylight.yangtools.yang.model.util.type;
-import com.google.common.collect.ImmutableList;
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.collect.ImmutableRangeSet;
+import com.google.common.collect.Range;
import java.util.List;
import java.util.Optional;
import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.ConstraintMetaDefinition;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
import org.opendaylight.yangtools.yang.model.api.type.RangeRestrictedTypeDefinition;
-import org.opendaylight.yangtools.yang.model.util.BaseConstraints;
-abstract class AbstractRangeRestrictedBaseType<T extends RangeRestrictedTypeDefinition<T>> extends AbstractBaseType<T>
- implements RangeRestrictedTypeDefinition<T> {
- private final List<RangeConstraint> rangeConstraints;
+abstract class AbstractRangeRestrictedBaseType<T extends RangeRestrictedTypeDefinition<T>,
+ C extends Number & Comparable<C>> extends AbstractBaseType<T> implements RangeRestrictedTypeDefinition<T> {
+ private static final ConstraintMetaDefinition BUILTIN_CONSTRAINT = new ConstraintMetaDefinition() {
+
+ @Override
+ public Optional<String> getReference() {
+ return Optional.empty();
+ }
+
+ @Override
+ public Optional<String> getDescription() {
+ return Optional.empty();
+ }
+
+ @Override
+ public Optional<String> getErrorMessage() {
+ return Optional.empty();
+ }
+
+ @Override
+ public Optional<String> getErrorAppTag() {
+ return Optional.empty();
+ }
+ };
+
+ private final RangeConstraint<?> rangeConstraint;
- AbstractRangeRestrictedBaseType(final QName qname, final Number minValue, final Number maxValue) {
+ AbstractRangeRestrictedBaseType(final QName qname, final C minValue, final C maxValue) {
super(qname);
- this.rangeConstraints = ImmutableList.of(BaseConstraints.newRangeConstraint(
- minValue, maxValue, Optional.empty(), Optional.empty()));
+ this.rangeConstraint = new ResolvedRangeConstraint<>(BUILTIN_CONSTRAINT, ImmutableRangeSet.of(
+ Range.closed(minValue, maxValue)));
}
AbstractRangeRestrictedBaseType(final SchemaPath path, final List<UnknownSchemaNode> unknownSchemaNodes,
- final List<RangeConstraint> rangeConstraints) {
+ final RangeConstraint<?> rangeConstraint) {
super(path, unknownSchemaNodes);
- this.rangeConstraints = ImmutableList.copyOf(rangeConstraints);
+ this.rangeConstraint = requireNonNull(rangeConstraint);
}
@Override
@Nonnull
- public final List<RangeConstraint> getRangeConstraints() {
- return rangeConstraints;
+ public final Optional<RangeConstraint<?>> getRangeConstraint() {
+ return Optional.of(rangeConstraint);
}
}
package org.opendaylight.yangtools.yang.model.util.type;
import java.util.Collection;
-import java.util.List;
+import java.util.Optional;
import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.opendaylight.yangtools.yang.model.api.Status;
@Nonnull
@Override
- public final List<RangeConstraint> getRangeConstraints() {
- return baseType().getRangeConstraints();
+ public final Optional<RangeConstraint<?>> getRangeConstraint() {
+ return baseType().getRangeConstraint();
}
}
*/
package org.opendaylight.yangtools.yang.model.util.type;
-import com.google.common.collect.ImmutableList;
import java.util.Collection;
-import java.util.List;
+import java.util.Optional;
import javax.annotation.Nonnull;
+import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
abstract class AbstractRangeRestrictedType<T extends RangeRestrictedTypeDefinition<T>>
extends AbstractRestrictedType<T> implements RangeRestrictedTypeDefinition<T> {
- private final List<RangeConstraint> rangeConstraints;
+ private final @Nullable RangeConstraint<?> rangeConstraint;
AbstractRangeRestrictedType(final T baseType, final SchemaPath path,
- final Collection<UnknownSchemaNode> unknownSchemaNodes, final Collection<RangeConstraint> rangeConstraints) {
+ final Collection<UnknownSchemaNode> unknownSchemaNodes, final @Nullable RangeConstraint<?> rangeConstraint) {
super(baseType, path, unknownSchemaNodes);
- this.rangeConstraints = ImmutableList.copyOf(rangeConstraints);
+ this.rangeConstraint = rangeConstraint;
}
@Override
@Nonnull
- public final List<RangeConstraint> getRangeConstraints() {
- return rangeConstraints;
+ public final Optional<RangeConstraint<?>> getRangeConstraint() {
+ return Optional.ofNullable(rangeConstraint);
}
}
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
-abstract class AbstractUnsignedBaseType extends AbstractRangeRestrictedBaseType<UnsignedIntegerTypeDefinition>
+abstract class AbstractUnsignedBaseType<C extends Number & Comparable<C>>
+ extends AbstractRangeRestrictedBaseType<UnsignedIntegerTypeDefinition, C>
implements UnsignedIntegerTypeDefinition {
- AbstractUnsignedBaseType(final QName qname, final Number minValue, final Number maxValue) {
+ AbstractUnsignedBaseType(final QName qname, final C minValue, final C maxValue) {
super(qname, minValue, maxValue);
}
*/
package org.opendaylight.yangtools.yang.model.util.type;
+import static com.google.common.base.Verify.verifyNotNull;
+
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableList.Builder;
+import com.google.common.collect.ImmutableRangeSet;
+import com.google.common.collect.Range;
import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;
import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.ConstraintMetaDefinition;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
-import org.opendaylight.yangtools.yang.model.util.BaseConstraints;
-final class BaseDecimalType extends AbstractRangeRestrictedBaseType<DecimalTypeDefinition>
+final class BaseDecimalType extends AbstractRangeRestrictedBaseType<DecimalTypeDefinition, BigDecimal>
implements DecimalTypeDefinition {
- private static final List<List<RangeConstraint>> IMPLICIT_RANGE_STATEMENTS;
-
- static {
- final Builder<List<RangeConstraint>> b = ImmutableList.builder();
- b.add(createRangeConstraint("-922337203685477580.8", "922337203685477580.7"));
- b.add(createRangeConstraint("-92233720368547758.08", "92233720368547758.07"));
- b.add(createRangeConstraint("-9223372036854775.808", "9223372036854775.807"));
- b.add(createRangeConstraint("-922337203685477.5808", "922337203685477.5807"));
- b.add(createRangeConstraint("-92233720368547.75808", "92233720368547.75807"));
- b.add(createRangeConstraint("-9223372036854.775808", "9223372036854.775807"));
- b.add(createRangeConstraint("-922337203685.4775808", "922337203685.4775807"));
- b.add(createRangeConstraint("-92233720368.54775808", "92233720368.54775807"));
- b.add(createRangeConstraint("-9223372036.854775808", "9223372036.854775807"));
- b.add(createRangeConstraint("-922337203.6854775808", "922337203.6854775807"));
- b.add(createRangeConstraint("-92233720.36854775808", "92233720.36854775807"));
- b.add(createRangeConstraint("-9223372.036854775808", "9223372.036854775807"));
- b.add(createRangeConstraint("-922337.2036854775808", "922337.2036854775807"));
- b.add(createRangeConstraint("-92233.72036854775808", "92233.72036854775807"));
- b.add(createRangeConstraint("-9223.372036854775808", "9223.372036854775807"));
- b.add(createRangeConstraint("-922.3372036854775808", "922.3372036854775807"));
- b.add(createRangeConstraint("-92.23372036854775808", "92.23372036854775807"));
- b.add(createRangeConstraint("-9.223372036854775808", "9.223372036854775807"));
- IMPLICIT_RANGE_STATEMENTS = b.build();
- }
+ private static final ConstraintMetaDefinition BUILTIN_CONSTRAINT = new ConstraintMetaDefinition() {
+
+ @Override
+ public Optional<String> getReference() {
+ return Optional.of("https://tools.ietf.org/html/rfc6020#section-9.3.4");
+ }
+
+ @Override
+ public Optional<String> getDescription() {
+ return Optional.empty();
+ }
+
+ @Override
+ public Optional<String> getErrorMessage() {
+ return Optional.empty();
+ }
+
+ @Override
+ public Optional<String> getErrorAppTag() {
+ return Optional.empty();
+ }
+ };
+
+ private static final ImmutableList<RangeConstraint<BigDecimal>> IMPLICIT_RANGE_STATEMENTS = ImmutableList.of(
+ createRangeConstraint("-922337203685477580.8", "922337203685477580.7"),
+ createRangeConstraint("-92233720368547758.08", "92233720368547758.07"),
+ createRangeConstraint("-9223372036854775.808", "9223372036854775.807"),
+ createRangeConstraint("-922337203685477.5808", "922337203685477.5807"),
+ createRangeConstraint("-92233720368547.75808", "92233720368547.75807"),
+ createRangeConstraint("-9223372036854.775808", "9223372036854.775807"),
+ createRangeConstraint("-922337203685.4775808", "922337203685.4775807"),
+ createRangeConstraint("-92233720368.54775808", "92233720368.54775807"),
+ createRangeConstraint("-9223372036.854775808", "9223372036.854775807"),
+ createRangeConstraint("-922337203.6854775808", "922337203.6854775807"),
+ createRangeConstraint("-92233720.36854775808", "92233720.36854775807"),
+ createRangeConstraint("-9223372.036854775808", "9223372.036854775807"),
+ createRangeConstraint("-922337.2036854775808", "922337.2036854775807"),
+ createRangeConstraint("-92233.72036854775808", "92233.72036854775807"),
+ createRangeConstraint("-9223.372036854775808", "9223.372036854775807"),
+ createRangeConstraint("-922.3372036854775808", "922.3372036854775807"),
+ createRangeConstraint("-92.23372036854775808", "92.23372036854775807"),
+ createRangeConstraint("-9.223372036854775808", "9.223372036854775807"));
- private static List<RangeConstraint> createRangeConstraint(final String min, final String max) {
- return ImmutableList.of(BaseConstraints.newRangeConstraint(new BigDecimal(min), new BigDecimal(max),
- Optional.empty(), Optional.of("https://tools.ietf.org/html/rfc6020#section-9.3.4")));
+ private static RangeConstraint<BigDecimal> createRangeConstraint(final String min, final String max) {
+ return new ResolvedRangeConstraint<>(BUILTIN_CONSTRAINT, ImmutableRangeSet.of(
+ Range.closed(new BigDecimal(min), new BigDecimal(max))));
}
- static List<RangeConstraint> constraintsForDigits(final int fractionDigits) {
- return IMPLICIT_RANGE_STATEMENTS.get(fractionDigits - 1);
+ static RangeConstraint<BigDecimal> constraintsForDigits(final int fractionDigits) {
+ return verifyNotNull(IMPLICIT_RANGE_STATEMENTS.get(fractionDigits - 1));
}
private final Integer fractionDigits;
BaseDecimalType(final SchemaPath path, final List<UnknownSchemaNode> unknownSchemaNodes,
- final Integer fractionDigits, final List<RangeConstraint> rangeConstraints) {
- super(path, unknownSchemaNodes, rangeConstraints);
+ final Integer fractionDigits, final RangeConstraint<BigDecimal> rangeConstraint) {
+ super(path, unknownSchemaNodes, rangeConstraint);
this.fractionDigits = fractionDigits;
}
import org.opendaylight.yangtools.yang.model.util.BaseTypes;
-final class BaseInt16Type extends AbstractIntegerBaseType {
+final class BaseInt16Type extends AbstractIntegerBaseType<Short> {
static final BaseInt16Type INSTANCE = new BaseInt16Type();
private BaseInt16Type() {
import org.opendaylight.yangtools.yang.model.util.BaseTypes;
-final class BaseInt32Type extends AbstractIntegerBaseType {
+final class BaseInt32Type extends AbstractIntegerBaseType<Integer> {
static final BaseInt32Type INSTANCE = new BaseInt32Type();
private BaseInt32Type() {
import org.opendaylight.yangtools.yang.model.util.BaseTypes;
-final class BaseInt64Type extends AbstractIntegerBaseType {
+final class BaseInt64Type extends AbstractIntegerBaseType<Long> {
static final BaseInt64Type INSTANCE = new BaseInt64Type();
private BaseInt64Type() {
import org.opendaylight.yangtools.yang.model.util.BaseTypes;
-final class BaseInt8Type extends AbstractIntegerBaseType {
+final class BaseInt8Type extends AbstractIntegerBaseType<Byte> {
static final BaseInt8Type INSTANCE = new BaseInt8Type();
private BaseInt8Type() {
import org.opendaylight.yangtools.yang.model.util.BaseTypes;
-final class BaseUint16Type extends AbstractUnsignedBaseType {
+final class BaseUint16Type extends AbstractUnsignedBaseType<Integer> {
static final BaseUint16Type INSTANCE = new BaseUint16Type();
private BaseUint16Type() {
import org.opendaylight.yangtools.yang.model.util.BaseTypes;
-final class BaseUint32Type extends AbstractUnsignedBaseType {
+final class BaseUint32Type extends AbstractUnsignedBaseType<Long> {
static final BaseUint32Type INSTANCE = new BaseUint32Type();
private BaseUint32Type() {
import java.math.BigInteger;
import org.opendaylight.yangtools.yang.model.util.BaseTypes;
-final class BaseUint64Type extends AbstractUnsignedBaseType {
+final class BaseUint64Type extends AbstractUnsignedBaseType<BigInteger> {
static final BaseUint64Type INSTANCE = new BaseUint64Type();
private BaseUint64Type() {
import org.opendaylight.yangtools.yang.model.util.BaseTypes;
-final class BaseUint8Type extends AbstractUnsignedBaseType {
+final class BaseUint8Type extends AbstractUnsignedBaseType<Short> {
static final BaseUint8Type INSTANCE = new BaseUint8Type();
private BaseUint8Type() {
import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
import org.opendaylight.yangtools.yang.model.api.type.LengthRestrictedTypeDefinition;
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.RangeRestrictedTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
}
private static TypeDefinition<?> baseTypeIfNotConstrained(final DecimalTypeDefinition type) {
- final DecimalTypeDefinition base = type.getBaseType();
- return baseTypeIfNotConstrained(type, type.getRangeConstraints(), base, base.getRangeConstraints());
+ return baseTypeIfNotConstrained(type, type.getBaseType());
}
private static TypeDefinition<?> baseTypeIfNotConstrained(final InstanceIdentifierTypeDefinition type) {
}
private static TypeDefinition<?> baseTypeIfNotConstrained(final IntegerTypeDefinition type) {
- final IntegerTypeDefinition base = type.getBaseType();
- return baseTypeIfNotConstrained(type, type.getRangeConstraints(), base, base.getRangeConstraints());
+ return baseTypeIfNotConstrained(type, type.getBaseType());
}
private static TypeDefinition<?> baseTypeIfNotConstrained(final StringTypeDefinition type) {
}
private static TypeDefinition<?> baseTypeIfNotConstrained(final UnsignedIntegerTypeDefinition type) {
- final UnsignedIntegerTypeDefinition base = type.getBaseType();
- return baseTypeIfNotConstrained(type, type.getRangeConstraints(), base, base.getRangeConstraints());
+ return baseTypeIfNotConstrained(type, type.getBaseType());
}
- private static TypeDefinition<?> baseTypeIfNotConstrained(final TypeDefinition<?> type,
- final List<?> typeConstraints, final TypeDefinition<?> base, final List<?> baseConstraints) {
- return typeConstraints.isEmpty() || typeConstraints.equals(baseConstraints) ? base : type;
+ private static <T extends RangeRestrictedTypeDefinition<T>> T baseTypeIfNotConstrained(final T type,
+ final T base) {
+ final Optional<RangeConstraint<?>> optConstraint = type.getRangeConstraint();
+ if (!optConstraint.isPresent()) {
+ return base;
+ }
+ return optConstraint.equals(base.getRangeConstraint()) ? base : type;
}
private static <T extends LengthRestrictedTypeDefinition<T>> T baseTypeIfNotConstrained(final T type,
Preconditions.checkState(fractionDigits != null, "Fraction digits not defined");
return new BaseDecimalType(getPath(), getUnknownSchemaNodes(), fractionDigits,
- calculateRangeConstraints(BaseDecimalType.constraintsForDigits(fractionDigits)));
+ calculateRangeConstraint(BaseDecimalType.constraintsForDigits(fractionDigits)));
}
}
*/
package org.opendaylight.yangtools.yang.model.util.type;
+import static java.util.Objects.requireNonNull;
+
import com.google.common.annotations.Beta;
-import com.google.common.base.Preconditions;
-import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
+import com.google.common.collect.RangeSet;
@Beta
public class InvalidRangeConstraintException extends IllegalArgumentException {
private static final long serialVersionUID = 1L;
- private final RangeConstraint offendingRangeConstraint;
- protected InvalidRangeConstraintException(final RangeConstraint offendingConstraint, final String message) {
+ private final RangeSet<?> offendingRangeConstraint;
+
+ protected InvalidRangeConstraintException(final RangeSet<?> offendingConstraint, final String message) {
super(message);
- this.offendingRangeConstraint = Preconditions.checkNotNull(offendingConstraint);
+ this.offendingRangeConstraint = requireNonNull(offendingConstraint);
}
- public InvalidRangeConstraintException(final RangeConstraint offendingConstraint, final String format,
+ public InvalidRangeConstraintException(final RangeSet<?> offendingConstraint, final String format,
final Object... args) {
this(offendingConstraint, String.format(format, args));
}
- public RangeConstraint getOffendingConstraint() {
+ public RangeSet<?> getOffendingRanges() {
return offendingRangeConstraint;
}
}
*/
public final void setLengthConstraint(final @NonNull ConstraintMetaDefinition constraint,
final @NonNull List<ValueRange> ranges) throws InvalidLengthConstraintException {
- Preconditions.checkState(lengthConstraint == null, "Length alternatives already defined as %s",
- lengthConstraint);
+ Preconditions.checkState(lengthConstraint == null, "Length constraint already defined as %s", lengthConstraint);
final LengthConstraint baseLengths = findLenghts();
if (ranges.isEmpty()) {
lengthConstraint = baseLengths;
*/
package org.opendaylight.yangtools.yang.model.util.type;
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
+
import com.google.common.base.Preconditions;
import com.google.common.base.Verify;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableList.Builder;
-import java.util.Collection;
+import com.google.common.collect.ImmutableRangeSet;
+import com.google.common.collect.ImmutableRangeSet.Builder;
+import com.google.common.collect.Range;
+import com.google.common.collect.RangeSet;
+import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
import java.util.function.Function;
-import javax.annotation.Nonnull;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.model.api.ConstraintMetaDefinition;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.opendaylight.yangtools.yang.model.api.stmt.UnresolvedNumber;
+import org.opendaylight.yangtools.yang.model.api.stmt.ValueRange;
import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
import org.opendaylight.yangtools.yang.model.api.type.RangeRestrictedTypeDefinition;
-import org.opendaylight.yangtools.yang.model.util.BaseConstraints;
public abstract class RangeRestrictedTypeBuilder<T extends RangeRestrictedTypeDefinition<T>>
extends AbstractRestrictedTypeBuilder<T> {
- private List<RangeConstraint> rangeAlternatives;
+ private ConstraintMetaDefinition constraint;
+ private List<ValueRange> ranges;
RangeRestrictedTypeBuilder(final T baseType, final SchemaPath path) {
super(baseType, path);
}
- public final void setRangeAlternatives(@Nonnull final Collection<RangeConstraint> rangeAlternatives) {
- Preconditions.checkState(this.rangeAlternatives == null, "Range alternatives already defined as %s",
- this.rangeAlternatives);
- this.rangeAlternatives = ImmutableList.copyOf(rangeAlternatives);
+ public final void setRangeConstraint(final @NonNull ConstraintMetaDefinition constraint,
+ final @NonNull List<ValueRange> ranges) {
+ checkState(this.ranges == null, "Range constraint already defined as %s %s", this.ranges, this.constraint);
+
+ this.constraint = requireNonNull(constraint);
+ this.ranges = ImmutableList.copyOf(ranges);
touch();
}
- private static List<RangeConstraint> ensureResolvedRanges(final List<RangeConstraint> unresolved,
- final List<RangeConstraint> baseRangeConstraints) {
+ final <C extends Number & Comparable<C>> RangeConstraint<C> calculateRangeConstraint(
+ final RangeConstraint<C> baseRangeConstraint) {
+ if (ranges == null) {
+ return baseRangeConstraint;
+ }
+
+ // Run through alternatives and resolve them against the base type
+ final RangeSet<C> baseRangeSet = (RangeSet<C>) baseRangeConstraint.getAllowedRanges();
+ Verify.verify(!baseRangeSet.isEmpty(), "Base type %s does not define constraints", getBaseType());
+
+ final Range<? extends C> baseRange = baseRangeSet.span();
+ final List<ValueRange> resolvedRanges = ensureResolvedRanges(ranges, baseRange);
+
+ // Next up, ensure the of boundaries match base constraints
+ final RangeSet<C> typedRanges = ensureTypedRanges(resolvedRanges, baseRange.lowerEndpoint().getClass());
+
+ // Now verify if new ranges are strict subset of base ranges
+ if (!baseRangeSet.enclosesAll(typedRanges)) {
+ throw new InvalidRangeConstraintException(typedRanges,
+ "Range constraints %s is not a subset of parent constraints %s", typedRanges, baseRangeSet);
+ }
+
+ return new RangeConstraint<C>() {
+ @Override
+ public Optional<String> getErrorAppTag() {
+ return constraint.getErrorAppTag();
+ }
+
+ @Override
+ public Optional<String> getErrorMessage() {
+ return constraint.getErrorMessage();
+ }
+
+ @Override
+ public Optional<String> getDescription() {
+ return constraint.getDescription();
+ }
+
+ @Override
+ public Optional<String> getReference() {
+ return constraint.getReference();
+ }
+
+ @Override
+ public RangeSet<? extends C> getAllowedRanges() {
+ return typedRanges;
+ }
+ };
+ }
+
+ private static <C extends Number & Comparable<C>> List<ValueRange> ensureResolvedRanges(
+ final List<ValueRange> unresolved, final Range<? extends C> baseRange) {
// First check if we need to resolve anything at all
- for (RangeConstraint c : unresolved) {
- if (c.getMax() instanceof UnresolvedNumber || c.getMin() instanceof UnresolvedNumber) {
- return resolveRanges(unresolved, baseRangeConstraints);
+ for (ValueRange c : unresolved) {
+ if (c.lowerBound() instanceof UnresolvedNumber || c.upperBound() instanceof UnresolvedNumber) {
+ return resolveRanges(unresolved, baseRange);
}
}
return unresolved;
}
- private static List<RangeConstraint> resolveRanges(final List<RangeConstraint> unresolved,
- final List<RangeConstraint> baseRangeConstraints) {
- final Builder<RangeConstraint> builder = ImmutableList.builder();
-
- for (RangeConstraint c : unresolved) {
- final Number max = c.getMax();
- final Number min = c.getMin();
+ private static <T extends Number & Comparable<T>> List<ValueRange> resolveRanges(final List<ValueRange> unresolved,
+ final Range<? extends T> baseRange) {
+ final List<ValueRange> ret = new ArrayList<>(unresolved.size());
+ for (ValueRange range : unresolved) {
+ final Number min = range.lowerBound();
+ final Number max = range.upperBound();
if (max instanceof UnresolvedNumber || min instanceof UnresolvedNumber) {
- final Number rMax = max instanceof UnresolvedNumber
- ? ((UnresolvedNumber)max).resolveRange(baseRangeConstraints) : max;
final Number rMin = min instanceof UnresolvedNumber
- ? ((UnresolvedNumber)min).resolveRange(baseRangeConstraints) : min;
-
- builder.add(BaseConstraints.newRangeConstraint(rMin, rMax, c.getDescription(),
- c.getReference(), c.getErrorAppTag().orElse(null), c.getErrorMessage().orElse(null)));
+ ? ((UnresolvedNumber)min).resolveRange(baseRange) : min;
+ final Number rMax = max instanceof UnresolvedNumber
+ ? ((UnresolvedNumber)max).resolveRange(baseRange) : max;
+ ret.add(ValueRange.of((@NonNull Number)rMin, (@NonNull Number)rMax));
} else {
- builder.add(c);
+ ret.add(range);
}
-
}
- return builder.build();
+ return ret;
}
- private static List<RangeConstraint> ensureTypedRanges(final List<RangeConstraint> ranges,
+ private static <T extends Number & Comparable<T>> RangeSet<T> ensureTypedRanges(final List<ValueRange> ranges,
final Class<? extends Number> clazz) {
- for (RangeConstraint c : ranges) {
- if (!clazz.isInstance(c.getMin()) || !clazz.isInstance(c.getMax())) {
+ final Builder<T> builder = ImmutableRangeSet.builder();
+ for (ValueRange range : ranges) {
+ if (!clazz.isInstance(range.lowerBound()) || !clazz.isInstance(range.upperBound())) {
return typedRanges(ranges, clazz);
}
+
+ builder.add(Range.closed((T) range.lowerBound(), (T)range.upperBound()));
}
- return ranges;
+ return builder.build();
}
- private static List<RangeConstraint> typedRanges(final List<RangeConstraint> ranges,
+ private static <T extends Number & Comparable<T>> RangeSet<T> typedRanges(final List<ValueRange> ranges,
final Class<? extends Number> clazz) {
final Function<Number, ? extends Number> function = NumberUtil.converterTo(clazz);
Preconditions.checkArgument(function != null, "Unsupported range class %s", clazz);
- final Builder<RangeConstraint> builder = ImmutableList.builder();
+ final Builder<T> builder = ImmutableRangeSet.builder();
- for (RangeConstraint c : ranges) {
- if (!clazz.isInstance(c.getMin()) || !clazz.isInstance(c.getMax())) {
+ for (ValueRange range : ranges) {
+ if (!clazz.isInstance(range.lowerBound()) || !clazz.isInstance(range.upperBound())) {
final Number min;
final Number max;
try {
- min = function.apply(c.getMin());
- max = function.apply(c.getMax());
+ min = function.apply(range.lowerBound());
+ max = function.apply(range.upperBound());
} catch (NumberFormatException e) {
throw new IllegalArgumentException(String.format("Constraint %s does not fit into range of %s",
- c, clazz.getSimpleName()), e);
+ range, clazz.getSimpleName()), e);
}
- builder.add(BaseConstraints.newRangeConstraint(min, max, c.getDescription(), c.getReference(),
- c.getErrorAppTag().orElse(null), c.getErrorMessage().orElse(null)));
+
+ builder.add(Range.closed((T)min, (T)max));
} else {
- builder.add(c);
+ builder.add(Range.closed((T) range.lowerBound(), (T)range.upperBound()));
}
}
return builder.build();
}
-
- private static boolean rangeCovered(final List<RangeConstraint> where,
- final RangeConstraint what) {
- for (RangeConstraint c : where) {
- if (NumberUtil.isRangeCovered(what.getMin(), what.getMax(), c.getMin(), c.getMax())) {
- return true;
- }
- }
-
- return false;
- }
-
- final List<RangeConstraint> calculateRangeConstraints(final List<RangeConstraint> baseRangeConstraints) {
- if (rangeAlternatives == null || rangeAlternatives.isEmpty()) {
- return baseRangeConstraints;
- }
-
- // Run through alternatives and resolve them against the base type
- Verify.verify(!baseRangeConstraints.isEmpty(), "Base type %s does not define constraints", getBaseType());
- final List<RangeConstraint> resolvedRanges = ensureResolvedRanges(rangeAlternatives, baseRangeConstraints);
-
- // Next up, ensure the of boundaries match base constraints
- final Class<? extends Number> clazz = baseRangeConstraints.get(0).getMin().getClass();
- final List<RangeConstraint> typedRanges = ensureTypedRanges(resolvedRanges, clazz);
-
- // Now verify if new ranges are strict subset of base ranges
- for (RangeConstraint c : typedRanges) {
- if (!rangeCovered(baseRangeConstraints, c)) {
- throw new InvalidRangeConstraintException(c,
- "Range constraint %s is not a subset of parent constraints %s", c, baseRangeConstraints);
- }
- }
-
- return typedRanges;
- }
}
import static java.util.Objects.requireNonNull;
-import java.util.List;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
import org.opendaylight.yangtools.yang.model.api.type.RangeRestrictedTypeDefinition;
@Override
final T buildType() {
- return buildType(calculateRangeConstraints(getBaseType().getRangeConstraints()));
+ return buildType(calculateRangeConstraint(getBaseType().getRangeConstraint().get()));
}
- abstract T buildType(List<RangeConstraint> rangeConstraints);
+ abstract T buildType(RangeConstraint<?> rangeConstraints);
}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies, s.r.o. 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.model.util.type;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.collect.ImmutableRangeSet;
+import com.google.common.collect.RangeSet;
+import java.util.Optional;
+import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.yang.model.api.ConstraintMetaDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
+
+final class ResolvedRangeConstraint<T extends Number & Comparable<T>> implements RangeConstraint<T>, Immutable {
+ private final ConstraintMetaDefinition meta;
+ private final RangeSet<T> ranges;
+
+ ResolvedRangeConstraint(final ConstraintMetaDefinition meta, final RangeSet<T> ranges) {
+ this.meta = requireNonNull(meta);
+ this.ranges = ImmutableRangeSet.copyOf(ranges);
+ }
+
+ @Override
+ public Optional<String> getDescription() {
+ return meta.getDescription();
+ }
+
+ @Override
+ public Optional<String> getErrorAppTag() {
+ return meta.getErrorAppTag();
+ }
+
+ @Override
+ public Optional<String> getErrorMessage() {
+ return meta.getErrorMessage();
+ }
+
+ @Override
+ public Optional<String> getReference() {
+ return meta.getReference();
+ }
+
+ @Override
+ public RangeSet<? extends T> getAllowedRanges() {
+ return ranges;
+ }
+}
import java.util.Collection;
import javax.annotation.Nonnull;
+import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
final class RestrictedDecimalType extends AbstractRangeRestrictedType<DecimalTypeDefinition>
implements DecimalTypeDefinition {
RestrictedDecimalType(final DecimalTypeDefinition baseType, final SchemaPath path,
- final Collection<UnknownSchemaNode> unknownSchemaNodes, final Collection<RangeConstraint> rangeConstraints) {
- super(baseType, path, unknownSchemaNodes, rangeConstraints);
+ final Collection<UnknownSchemaNode> unknownSchemaNodes, final @Nullable RangeConstraint<?> rangeConstraint) {
+ super(baseType, path, unknownSchemaNodes, rangeConstraint);
}
@Nonnull
package org.opendaylight.yangtools.yang.model.util.type;
import java.util.Collection;
+import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
final class RestrictedIntegerType extends AbstractRangeRestrictedType<IntegerTypeDefinition>
implements IntegerTypeDefinition {
RestrictedIntegerType(final IntegerTypeDefinition baseType, final SchemaPath path,
- final Collection<UnknownSchemaNode> unknownSchemaNodes, final Collection<RangeConstraint> rangeConstraints) {
- super(baseType, path, unknownSchemaNodes, rangeConstraints);
+ final Collection<UnknownSchemaNode> unknownSchemaNodes, final @Nullable RangeConstraint<?> rangeConstraint) {
+ super(baseType, path, unknownSchemaNodes, rangeConstraint);
}
@Override
package org.opendaylight.yangtools.yang.model.util.type;
import com.google.common.annotations.Beta;
-import java.util.List;
import javax.annotation.Nonnull;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
final DecimalTypeDefinition baseType, final SchemaPath path) {
return new RangeRestrictedTypeBuilderWithBase<DecimalTypeDefinition>(baseType, path) {
@Override
- DecimalTypeDefinition buildType(final List<RangeConstraint> rangeConstraints) {
- return new RestrictedDecimalType(getBaseType(), getPath(), getUnknownSchemaNodes(), rangeConstraints);
+ DecimalTypeDefinition buildType(final RangeConstraint<?> rangeConstraint) {
+ return new RestrictedDecimalType(getBaseType(), getPath(), getUnknownSchemaNodes(), rangeConstraint);
}
};
}
final IntegerTypeDefinition baseType, final SchemaPath path) {
return new RangeRestrictedTypeBuilderWithBase<IntegerTypeDefinition>(baseType, path) {
@Override
- IntegerTypeDefinition buildType(final List<RangeConstraint> rangeConstraints) {
- return new RestrictedIntegerType(getBaseType(), getPath(), getUnknownSchemaNodes(), rangeConstraints);
+ IntegerTypeDefinition buildType(final RangeConstraint<?> rangeConstraint) {
+ return new RestrictedIntegerType(getBaseType(), getPath(), getUnknownSchemaNodes(), rangeConstraint);
}
};
}
final UnsignedIntegerTypeDefinition baseType, final SchemaPath path) {
return new RangeRestrictedTypeBuilderWithBase<UnsignedIntegerTypeDefinition>(baseType, path) {
@Override
- UnsignedIntegerTypeDefinition buildType(final List<RangeConstraint> rangeConstraints) {
- return new RestrictedUnsignedType(getBaseType(), getPath(), getUnknownSchemaNodes(), rangeConstraints);
+ UnsignedIntegerTypeDefinition buildType(final RangeConstraint<?> rangeConstraint) {
+ return new RestrictedUnsignedType(getBaseType(), getPath(), getUnknownSchemaNodes(), rangeConstraint);
}
};
}
package org.opendaylight.yangtools.yang.model.util.type;
import java.util.Collection;
+import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
implements UnsignedIntegerTypeDefinition {
RestrictedUnsignedType(final UnsignedIntegerTypeDefinition baseType, final SchemaPath path,
- final Collection<UnknownSchemaNode> unknownSchemaNodes, final Collection<RangeConstraint> rangeConstraints) {
- super(baseType, path, unknownSchemaNodes, rangeConstraints);
+ final Collection<UnknownSchemaNode> unknownSchemaNodes, final @Nullable RangeConstraint<?> rangeConstraint) {
+ super(baseType, path, unknownSchemaNodes, rangeConstraint);
}
@Override
static int hashCode(final DecimalTypeDefinition type) {
return Objects.hash(type.getPath(), type.getUnknownSchemaNodes(), type.getBaseType(),
type.getUnits().orElse(null), type.getDefaultValue().orElse(null), type.getFractionDigits(),
- type.getRangeConstraints());
+ type.getRangeConstraint().orElse(null));
}
static int hashCode(final EmptyTypeDefinition type) {
static int hashCode(final IntegerTypeDefinition type) {
return Objects.hash(type.getPath(), type.getUnknownSchemaNodes(), type.getBaseType(),
- type.getUnits().orElse(null), type.getDefaultValue().orElse(null), type.getRangeConstraints());
+ type.getUnits().orElse(null), type.getDefaultValue().orElse(null), type.getRangeConstraint().orElse(null));
}
static int hashCode(final LeafrefTypeDefinition type) {
static int hashCode(final UnsignedIntegerTypeDefinition type) {
return Objects.hash(type.getPath(), type.getUnknownSchemaNodes(), type.getBaseType(), type.getUnits(),
- type.getDefaultValue(), type.getRangeConstraints());
+ type.getDefaultValue(), type.getRangeConstraint());
}
static boolean equals(final BinaryTypeDefinition type, final Object obj) {
final DecimalTypeDefinition other = castIfEquals(DecimalTypeDefinition.class, type, obj);
return other != null && type.getFractionDigits().equals(other.getFractionDigits())
- && type.getRangeConstraints().equals(other.getRangeConstraints());
+ && type.getRangeConstraint().equals(other.getRangeConstraint());
}
static boolean equals(final EmptyTypeDefinition type, final Object obj) {
}
final IntegerTypeDefinition other = castIfEquals(IntegerTypeDefinition.class, type, obj);
- return other != null && type.getRangeConstraints().equals(other.getRangeConstraints());
+ return other != null && type.getRangeConstraint().equals(other.getRangeConstraint());
}
static boolean equals(final LeafrefTypeDefinition type, final Object obj) {
}
final UnsignedIntegerTypeDefinition other = castIfEquals(UnsignedIntegerTypeDefinition.class, type, obj);
- return other != null && type.getRangeConstraints().equals(other.getRangeConstraints());
+ return other != null && type.getRangeConstraint().equals(other.getRangeConstraint());
}
static String toString(final BinaryTypeDefinition type) {
static String toString(final DecimalTypeDefinition type) {
return toStringHelper(type).add("fractionDigits", type.getFractionDigits())
- .add("range", type.getRangeConstraints()).toString();
+ .add("range", type.getRangeConstraint().orElse(null)).toString();
}
static String toString(final EmptyTypeDefinition type) {
}
static String toString(final IntegerTypeDefinition type) {
- return toStringHelper(type).add("range", type.getRangeConstraints()).toString();
+ return toStringHelper(type).add("range", type.getRangeConstraint().orElse(null)).toString();
}
static String toString(final LeafrefTypeDefinition type) {
}
static String toString(final UnsignedIntegerTypeDefinition type) {
- return toStringHelper(type).add("range", type.getRangeConstraints()).toString();
+ return toStringHelper(type).add("range", type.getRangeConstraint().orElse(null)).toString();
}
}
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import com.google.common.collect.ImmutableList;
-import java.util.ArrayList;
+import com.google.common.collect.ImmutableRangeSet;
+import com.google.common.collect.Range;
+import com.google.common.collect.RangeSet;
import java.util.List;
import java.util.Optional;
import org.junit.Test;
import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
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.api.type.UnsignedIntegerTypeDefinition;
import org.opendaylight.yangtools.yang.model.util.BaseConstraints;
final IntegerTypeDefinition integerTypeDefinition8 = BaseTypes.int8Type();
final RangeRestrictedTypeBuilder<?> rangeRestrictedTypeBuilder = RestrictedTypes
.newIntegerBuilder(integerTypeDefinition8, SCHEMA_PATH);
- final RangeConstraint rangeConstraint = BaseConstraints.newRangeConstraint(min, max, ABSENT, ABSENT);
- final ArrayList<RangeConstraint> rangeArrayList = new ArrayList<>(1);
- rangeArrayList.add(rangeConstraint);
- rangeRestrictedTypeBuilder.setRangeAlternatives(rangeArrayList);
+ rangeRestrictedTypeBuilder.setRangeConstraint(mock(ConstraintMetaDefinition.class), lengthArrayList);
final TypeDefinition<?> typeDefinition1 = rangeRestrictedTypeBuilder.buildType();
assertNotNull(typeDefinition1);
}
public void exceptionTest() {
final UnresolvedNumber min = UnresolvedNumber.min();
final UnresolvedNumber max = UnresolvedNumber.max();
- final RangeConstraint rangeConstraint = BaseConstraints.newRangeConstraint(min, max, Optional.empty(),
- Optional.empty());
-
final EnumPair enumPair = EnumPairBuilder.create("enum1", 1).setDescription("description")
.setReference("reference").setUnknownSchemaNodes(mock(UnknownSchemaNode.class)).build();
+ final RangeSet<Integer> rangeset = ImmutableRangeSet.of(Range.closed(1, 2));
final InvalidRangeConstraintException invalidRangeConstraintException = new InvalidRangeConstraintException(
- rangeConstraint, "error msg", "other important messages");
- assertEquals(invalidRangeConstraintException.getOffendingConstraint(), rangeConstraint);
+ rangeset, "error msg", "other important messages");
+ assertSame(rangeset, invalidRangeConstraintException.getOffendingRanges());
final InvalidBitDefinitionException invalidBitDefinitionException = new InvalidBitDefinitionException(
BIT_A, "error msg", "other important messages");
import java.math.BigDecimal;
import java.util.List;
-import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.DescriptionStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.ErrorMessageStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.RangeStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceStatement;
-import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
+import org.opendaylight.yangtools.yang.model.api.stmt.ValueRange;
import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement;
import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator;
import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.RangeEffectiveStatementImpl;
-public class RangeStatementImpl extends AbstractDeclaredStatement<List<RangeConstraint>> implements RangeStatement {
+public class RangeStatementImpl extends AbstractDeclaredStatement<List<ValueRange>> implements RangeStatement {
private static final SubstatementValidator SUBSTATEMENT_VALIDATOR = SubstatementValidator.builder(YangStmtMapping
.RANGE)
.addOptional(YangStmtMapping.DESCRIPTION)
public static final BigDecimal YANG_MIN_NUM = BigDecimal.valueOf(-Double.MAX_VALUE);
public static final BigDecimal YANG_MAX_NUM = BigDecimal.valueOf(Double.MAX_VALUE);
- protected RangeStatementImpl(final StmtContext<List<RangeConstraint>, RangeStatement, ?> context) {
+ protected RangeStatementImpl(final StmtContext<List<ValueRange>, RangeStatement, ?> context) {
super(context);
}
- public static class Definition extends AbstractStatementSupport<List<RangeConstraint>, RangeStatement,
- EffectiveStatement<List<RangeConstraint>, RangeStatement>> {
+ public static class Definition extends AbstractStatementSupport<List<ValueRange>, RangeStatement,
+ EffectiveStatement<List<ValueRange>, RangeStatement>> {
public Definition() {
super(YangStmtMapping.RANGE);
}
@Override
- public List<RangeConstraint> parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
+ public List<ValueRange> parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
return TypeUtils.parseRangeListFromString(ctx, value);
}
@Override
- public RangeStatement createDeclared(final StmtContext<List<RangeConstraint>, RangeStatement, ?> ctx) {
+ public RangeStatement createDeclared(final StmtContext<List<ValueRange>, RangeStatement, ?> ctx) {
return new RangeStatementImpl(ctx);
}
@Override
- public EffectiveStatement<List<RangeConstraint>, RangeStatement> createEffective(
- final StmtContext<List<RangeConstraint>, RangeStatement, EffectiveStatement<List<RangeConstraint>,
+ public EffectiveStatement<List<ValueRange>, RangeStatement> createEffective(
+ final StmtContext<List<ValueRange>, RangeStatement, EffectiveStatement<List<ValueRange>,
RangeStatement>> ctx) {
return new RangeEffectiveStatementImpl(ctx);
}
public ReferenceStatement getReference() {
return firstDeclared(ReferenceStatement.class);
}
-
- @Nonnull
- @Override
- public List<RangeConstraint> getRange() {
- return argument();
- }
}
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
import java.util.Set;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.YangVersion;
import org.opendaylight.yangtools.yang.model.api.stmt.ValueRange;
import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
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.source.SourceException;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.RangeConstraintEffectiveImpl;
/**
* Utility class for manipulating YANG base and extended types implementation.
}
}
- public static List<RangeConstraint> parseRangeListFromString(final StmtContext<?, ?, ?> ctx,
- final String rangeArgument) {
-
- final Optional<String> description = Optional.empty();
- final Optional<String> reference = Optional.empty();
-
- final List<RangeConstraint> rangeConstraints = new ArrayList<>();
+ public static List<ValueRange> parseRangeListFromString(final StmtContext<?, ?, ?> ctx,
+ final String rangeArgument) {
+ final List<ValueRange> ranges = new ArrayList<>();
for (final String singleRange : PIPE_SPLITTER.split(rangeArgument)) {
- final Iterator<String> boundaries = TWO_DOTS_SPLITTER.splitToList(singleRange).iterator();
+ final Iterator<String> boundaries = TWO_DOTS_SPLITTER.split(singleRange).iterator();
final Number min = parseDecimalConstraintValue(ctx, boundaries.next());
final Number max;
max = parseDecimalConstraintValue(ctx, boundaries.next());
// if min larger than max then error
- InferenceException.throwIf(compareNumbers(min, max) == 1, ctx.getStatementSourceReference(),
+ SourceException.throwIf(compareNumbers(min, max) == 1, ctx.getStatementSourceReference(),
"Range constraint %s has descending order of boundaries; should be ascending", singleRange);
-
SourceException.throwIf(boundaries.hasNext(), ctx.getStatementSourceReference(),
"Wrong number of boundaries in range constraint %s", singleRange);
} else {
}
// some of intervals overlapping
- if (rangeConstraints.size() > 1 && compareNumbers(min, Iterables.getLast(rangeConstraints).getMax()) != 1) {
- throw new InferenceException(ctx.getStatementSourceReference(),
- "Some of the ranges in %s are not disjoint", rangeArgument);
- }
-
- rangeConstraints.add(new RangeConstraintEffectiveImpl(min, max, description, reference));
+ InferenceException.throwIf(ranges.size() > 1
+ && compareNumbers(min, Iterables.getLast(ranges).upperBound()) != 1,
+ ctx.getStatementSourceReference(), "Some of the value ranges in %s are not disjoint",
+ rangeArgument);
+ ranges.add(ValueRange.of(min, max));
}
- return rangeConstraints;
+ return ranges;
}
public static List<ValueRange> parseLengthListFromString(final StmtContext<?, ?, ?> ctx,
// if min larger than max then error
SourceException.throwIf(compareNumbers(min, max) == 1, ctx.getStatementSourceReference(),
- "Length constraint %s has descending order of boundaries; should be ascending.",
- singleRange);
+ "Length constraint %s has descending order of boundaries; should be ascending.", singleRange);
SourceException.throwIf(boundaries.hasNext(), ctx.getStatementSourceReference(),
"Wrong number of boundaries in length constraint %s.", singleRange);
} else {
&& compareNumbers(min, Iterables.getLast(ranges).upperBound()) != 1,
ctx.getStatementSourceReference(), "Some of the length ranges in %s are not disjoint",
lengthArgument);
-
ranges.add(ValueRange.of(min, max));
}
package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type;
import com.google.common.collect.ImmutableList;
-import java.util.ArrayList;
import java.util.List;
import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
@Override
final List<T> createConstraints(final List<T> argument) {
- if (!isCustomizedStatement()) {
- return ImmutableList.copyOf(argument);
- }
-
- final List<T> customizedConstraints = new ArrayList<>(argument.size());
- for (final T constraint : argument) {
- customizedConstraints.add(createCustomizedConstraint(constraint));
- }
- return ImmutableList.copyOf(customizedConstraints);
+ return ImmutableList.copyOf(argument);
}
-
- abstract T createCustomizedConstraint(T constraint);
}
builder.setFractionDigits(((FractionDigitsEffectiveStatementImpl) stmt).argument());
}
if (stmt instanceof RangeEffectiveStatementImpl) {
- builder.setRangeAlternatives(((RangeEffectiveStatementImpl)stmt).argument());
+ final RangeEffectiveStatementImpl range = (RangeEffectiveStatementImpl) stmt;
+ builder.setRangeConstraint(range, range.argument());
}
if (stmt instanceof UnknownEffectiveStatementImpl) {
builder.addUnknownSchemaNode((UnknownEffectiveStatementImpl)stmt);
for (EffectiveStatement<?, ?> stmt : effectiveSubstatements()) {
if (stmt instanceof RangeEffectiveStatementImpl) {
- builder.setRangeAlternatives(((RangeEffectiveStatementImpl)stmt).argument());
+ final RangeEffectiveStatementImpl range = (RangeEffectiveStatementImpl) stmt;
+ builder.setRangeConstraint(range, range.argument());
}
if (stmt instanceof UnknownEffectiveStatementImpl) {
builder.addUnknownSchemaNode((UnknownEffectiveStatementImpl)stmt);
import org.opendaylight.yangtools.yang.model.api.stmt.TypeEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement;
import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
import org.opendaylight.yangtools.yang.model.util.type.InvalidRangeConstraintException;
import org.opendaylight.yangtools.yang.model.util.type.RangeRestrictedTypeBuilder;
import org.opendaylight.yangtools.yang.model.util.type.RestrictedTypes;
for (EffectiveStatement<?, ?> stmt : effectiveSubstatements()) {
if (stmt instanceof RangeEffectiveStatementImpl) {
- builder.setRangeAlternatives(((RangeEffectiveStatementImpl)stmt).argument());
+ final RangeEffectiveStatementImpl range = (RangeEffectiveStatementImpl) stmt;
+ builder.setRangeConstraint(range, range.argument());
}
if (stmt instanceof UnknownEffectiveStatementImpl) {
builder.addUnknownSchemaNode((UnknownEffectiveStatementImpl)stmt);
try {
typeDefinition = builder.build();
} catch (InvalidRangeConstraintException e) {
- final RangeConstraint c = e.getOffendingConstraint();
- throw new SourceException(ctx.getStatementSourceReference(), e, "Invalid range constraint: <%s, %s>",
- c.getMin(), c.getMax());
+ throw new SourceException(ctx.getStatementSourceReference(), e, "Invalid range constraint: %s",
+ e.getOffendingRanges());
}
}
public class LengthEffectiveStatementImpl extends
AbstractListConstraintEffectiveStatement<ValueRange, LengthStatement> {
-
public LengthEffectiveStatementImpl(final StmtContext<List<ValueRange>, LengthStatement, ?> ctx) {
super(ctx);
}
-
- @Override
- final ValueRange createCustomizedConstraint(final ValueRange lengthConstraint) {
- return lengthConstraint;
- }
}
\ No newline at end of file
+++ /dev/null
-/**
- * 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.type;
-
-import static java.util.Objects.requireNonNull;
-
-import java.util.Objects;
-import java.util.Optional;
-import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
-
-public class RangeConstraintEffectiveImpl implements RangeConstraint {
-
- public static final String DEFAULT_REFERENCE = "https://tools.ietf.org/html/rfc6020#section-9.2.4";
- private final Number min;
- private final Number max;
-
- private final String description;
- private final String reference;
-
- private final String errorAppTag;
- private final String errorMessage;
-
- public RangeConstraintEffectiveImpl(final Number min, final Number max, final Optional<String> description,
- final Optional<String> reference) {
- this(min, max, description.orElse(null), reference.orElse(null), "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) {
- this.min = requireNonNull(min, "min must not be null");
- this.max = requireNonNull(max, "max must not be null");
- 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
- public Optional<String> getDescription() {
- return Optional.ofNullable(description);
- }
-
- @Override
- public Optional<String> getErrorAppTag() {
- return Optional.ofNullable(errorAppTag);
- }
-
- @Override
- public Optional<String> getErrorMessage() {
- return Optional.ofNullable(errorMessage);
- }
-
- @Override
- public Optional<String> getReference() {
- return Optional.ofNullable(reference);
- }
-
- @Override
- public Number getMin() {
- return min;
- }
-
- @Override
- public Number getMax() {
- return max;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + Objects.hashCode(description);
- result = prime * result + errorAppTag.hashCode();
- result = prime * result + errorMessage.hashCode();
- result = prime * result + max.hashCode();
- result = prime * result + min.hashCode();
- result = prime * result + Objects.hashCode(reference);
- return result;
- }
-
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- final RangeConstraintEffectiveImpl other = (RangeConstraintEffectiveImpl) obj;
- if (!Objects.equals(description, other.description)) {
- return false;
- }
- if (!Objects.equals(max, other.max)) {
- return false;
- }
- if (!Objects.equals(min, other.min)) {
- return false;
- }
- if (!Objects.equals(reference, other.reference)) {
- return false;
- }
- return true;
- }
-
- @Override
- public String toString() {
- return RangeConstraintEffectiveImpl.class.getSimpleName() + " [min=" + min + ", max=" + max + ", description="
- + description + ", reference=" + reference + ", errorAppTag=" + errorAppTag + ", errorMessage="
- + errorMessage + "]";
- }
-}
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.model.api.stmt.ValueRange;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
-public class RangeEffectiveStatementImpl extends
- AbstractListConstraintEffectiveStatement<RangeConstraint, RangeStatement> {
- public RangeEffectiveStatementImpl(final StmtContext<List<RangeConstraint>, RangeStatement, ?> ctx) {
+public class RangeEffectiveStatementImpl extends AbstractListConstraintEffectiveStatement<ValueRange, RangeStatement> {
+ public RangeEffectiveStatementImpl(final StmtContext<List<ValueRange>, RangeStatement, ?> ctx) {
super(ctx);
}
-
- @Override
- final RangeConstraint createCustomizedConstraint(final RangeConstraint rangeConstraint) {
- return new RangeConstraintEffectiveImpl(rangeConstraint.getMin(), rangeConstraint.getMax(),
- getDescription().orElse(null), getReference().orElse(null), getErrorAppTag().orElse(null),
- getErrorMessage().orElse(null));
- }
}
for (EffectiveStatement<?, ?> stmt : effectiveSubstatements()) {
if (stmt instanceof RangeEffectiveStatementImpl) {
- builder.setRangeAlternatives(((RangeEffectiveStatementImpl)stmt).argument());
+ final RangeEffectiveStatementImpl rangeStmt = (RangeEffectiveStatementImpl)stmt;
+ builder.setRangeConstraint(rangeStmt, rangeStmt.argument());
}
if (stmt instanceof UnknownEffectiveStatementImpl) {
builder.addUnknownSchemaNode((UnknownEffectiveStatementImpl)stmt);
assertFalse(decimal64Eff.getReference().isPresent());
assertEquals(Status.CURRENT, decimal64Eff.getStatus());
- assertEquals(3, decimal64Eff.getRangeConstraints().size());
+ assertEquals(3, decimal64Eff.getRangeConstraint().get().getAllowedRanges().asRanges().size());
assertNotNull(decimal64Eff.toString());
assertNotNull(decimal64Eff.hashCode());
assertTrue(decimal64Eff.getFractionDigits().equals(2));
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import com.google.common.collect.Range;
import java.math.BigDecimal;
-import java.util.List;
import java.util.Set;
import org.junit.Test;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils;
public class TypedefConstraintsTest {
assertNotNull(myDecimal);
assertTrue(myDecimal instanceof DecimalTypeDefinition);
- final List<RangeConstraint> rangeConstraints = ((DecimalTypeDefinition) myDecimal)
- .getRangeConstraints();
+ final Set<? extends Range<?>> rangeConstraints = ((DecimalTypeDefinition) myDecimal).getRangeConstraint()
+ .get().getAllowedRanges().asRanges();
assertNotNull(rangeConstraints);
assertEquals(1, rangeConstraints.size());
assertTrue(type instanceof DecimalTypeDefinition);
final DecimalTypeDefinition decType = (DecimalTypeDefinition) type;
- final List<RangeConstraint> decRangeConstraints = decType.getRangeConstraints();
+ final Set<? extends Range<?>> decRangeConstraints = decType.getRangeConstraint().get().getAllowedRanges()
+ .asRanges();
assertEquals(1, decRangeConstraints.size());
- final RangeConstraint range = decRangeConstraints.iterator().next();
- assertEquals(new BigDecimal(1.5), range.getMin());
- assertEquals(new BigDecimal(5.5), range.getMax());
+ final Range<?> range = decRangeConstraints.iterator().next();
+ assertEquals(new BigDecimal(1.5), range.lowerEndpoint());
+ assertEquals(new BigDecimal(5.5), range.upperEndpoint());
assertTrue(decType.getQName().getModule().equals(leafDecimal.getQName().getModule()));
assertTrue(decType.getQName().getLocalName().equals(TypeUtils.DECIMAL64));
TestUtils.loadModuleResources(getClass(), "/negative-scenario/testfile6.yang");
fail("ReactorException should be thrown");
} catch (final ReactorException e) {
- assertTrue(e.getCause().getMessage().contains("Invalid range constraint: <5, 20>"));
+ assertTrue(e.getCause().getMessage().startsWith("Invalid range constraint: [[5..20]]"));
}
}
assertEquals(Optional.of("mile"), leafType.getUnits());
assertEquals(Optional.of("11"), leafType.getDefaultValue());
- final List<RangeConstraint> ranges = leafType.getRangeConstraints();
+ final RangeSet<? extends Number> rangeset = leafType.getRangeConstraint().get().getAllowedRanges();
+ final Set<? extends Range<? extends Number>> ranges = rangeset.asRanges();
assertEquals(1, ranges.size());
- final RangeConstraint range = ranges.get(0);
- assertEquals(12, range.getMin().intValue());
- assertEquals(20, range.getMax().intValue());
-
- final IntegerTypeDefinition baseType = leafType.getBaseType();
- assertEquals(QName.create(BAR, "int32-ext2"), baseType.getQName());
- assertEquals(Optional.of("mile"), baseType.getUnits());
- assertEquals(Optional.of("11"), baseType.getDefaultValue());
-
- final List<RangeConstraint> baseTypeRanges = baseType.getRangeConstraints();
- assertEquals(2, baseTypeRanges.size());
- final RangeConstraint baseTypeRange1 = baseTypeRanges.get(0);
- assertEquals(3, baseTypeRange1.getMin().intValue());
- assertEquals(9, baseTypeRange1.getMax().intValue());
- final RangeConstraint baseTypeRange2 = baseTypeRanges.get(1);
- assertEquals(11, baseTypeRange2.getMin().intValue());
- assertEquals(20, baseTypeRange2.getMax().intValue());
-
- final IntegerTypeDefinition base = baseType.getBaseType();
- final QName baseQName = base.getQName();
+
+ final Range<? extends Number> range = ranges.iterator().next();
+ assertEquals(12, range.lowerEndpoint().intValue());
+ assertEquals(20, range.upperEndpoint().intValue());
+
+ final IntegerTypeDefinition firstBaseType = leafType.getBaseType();
+ assertEquals(QName.create(BAR, "int32-ext2"), firstBaseType.getQName());
+ assertEquals(Optional.of("mile"), firstBaseType.getUnits());
+ assertEquals(Optional.of("11"), firstBaseType.getDefaultValue());
+
+ final RangeSet<? extends Number> firstRangeset = firstBaseType.getRangeConstraint().get().getAllowedRanges();
+ final Set<? extends Range<? extends Number>> baseRanges = firstRangeset.asRanges();
+ assertEquals(2, baseRanges.size());
+
+ final Iterator<? extends Range<? extends Number>> it = baseRanges.iterator();
+ final Range<? extends Number> baseTypeRange1 = it.next();
+ assertEquals(3, baseTypeRange1.lowerEndpoint().intValue());
+ assertEquals(9, baseTypeRange1.upperEndpoint().intValue());
+ final Range<? extends Number> baseTypeRange2 = it.next();
+ assertEquals(11, baseTypeRange2.lowerEndpoint().intValue());
+ assertEquals(20, baseTypeRange2.upperEndpoint().intValue());
+
+ final IntegerTypeDefinition secondBaseType = firstBaseType.getBaseType();
+ final QName baseQName = secondBaseType.getQName();
assertEquals("int32-ext1", baseQName.getLocalName());
assertEquals(BAR, baseQName.getModule());
- assertEquals(Optional.empty(), base.getUnits());
- assertEquals(Optional.empty(), base.getDefaultValue());
+ assertEquals(Optional.empty(), secondBaseType.getUnits());
+ assertEquals(Optional.empty(), secondBaseType.getDefaultValue());
- final List<RangeConstraint> baseRanges = base.getRangeConstraints();
- assertEquals(1, baseRanges.size());
- final RangeConstraint baseRange = baseRanges.get(0);
- assertEquals(2, baseRange.getMin().intValue());
- assertEquals(20, baseRange.getMax().intValue());
+ final Set<? extends Range<? extends Number>> secondRanges = secondBaseType.getRangeConstraint().get()
+ .getAllowedRanges().asRanges();
+ assertEquals(1, secondRanges.size());
+ final Range<? extends Number> secondRange = secondRanges.iterator().next();
+ assertEquals(2, secondRange.lowerEndpoint().intValue());
+ assertEquals(20, secondRange.upperEndpoint().intValue());
- assertEquals(BaseTypes.int32Type(), base.getBaseType());
+ assertEquals(BaseTypes.int32Type(), secondBaseType.getBaseType());
}
@Test
assertEquals(Optional.empty(), type.getUnits());
assertEquals(Optional.empty(), type.getDefaultValue());
assertEquals(6, type.getFractionDigits().intValue());
- assertEquals(1, type.getRangeConstraints().size());
+ assertEquals(1, type.getRangeConstraint().get().getAllowedRanges().asRanges().size());
final DecimalTypeDefinition typeBase = type.getBaseType();
assertEquals(QName.create(BAR, "decimal64"), typeBase.getQName());
assertEquals(Optional.empty(), typeBase.getUnits());
assertEquals(Optional.empty(), typeBase.getDefaultValue());
assertEquals(6, typeBase.getFractionDigits().intValue());
- assertEquals(1, typeBase.getRangeConstraints().size());
+ assertEquals(1, typeBase.getRangeConstraint().get().getAllowedRanges().asRanges().size());
assertNull(typeBase.getBaseType());
}
assertEquals(Optional.empty(), type.getUnits());
assertEquals(Optional.empty(), type.getDefaultValue());
assertEquals(6, type.getFractionDigits().intValue());
- assertEquals(1, type.getRangeConstraints().size());
+ assertEquals(1, type.getRangeConstraint().get().getAllowedRanges().asRanges().size());
final DecimalTypeDefinition baseTypeDecimal = type.getBaseType();
assertEquals(6, baseTypeDecimal.getFractionDigits().intValue());
assertEquals(Optional.empty(), unionType1.getUnits());
assertEquals(Optional.empty(), unionType1.getDefaultValue());
- final List<RangeConstraint> ranges = unionType1.getRangeConstraints();
- assertEquals(1, ranges.size());
- final RangeConstraint range = ranges.get(0);
- assertEquals(1, range.getMin().intValue());
- assertEquals(100, range.getMax().intValue());
+ final RangeConstraint<?> ranges = unionType1.getRangeConstraint().get();
+ assertEquals(1, ranges.getAllowedRanges().asRanges().size());
+ final Range<?> range = ranges.getAllowedRanges().span();
+ assertEquals((short)1, range.lowerEndpoint());
+ assertEquals((short)100, range.upperEndpoint());
assertEquals(BaseTypes.int16Type(), unionType1.getBaseType());
assertEquals(BaseTypes.int32Type(), unionTypes.get(1));
assertEquals(QName.create(BAR, "int16"), int16Ext.getQName());
assertEquals(Optional.empty(), int16Ext.getUnits());
assertEquals(Optional.empty(), int16Ext.getDefaultValue());
- final List<RangeConstraint> ranges = int16Ext.getRangeConstraints();
+ final Set<? extends Range<? extends Number>> ranges = int16Ext.getRangeConstraint().get().getAllowedRanges()
+ .asRanges();
assertEquals(1, ranges.size());
- final RangeConstraint range = ranges.get(0);
- assertEquals(1, range.getMin().intValue());
- assertEquals(100, range.getMax().intValue());
+ final Range<? extends Number> range = ranges.iterator().next();
+ assertEquals(1, range.lowerEndpoint().intValue());
+ assertEquals(100, range.upperEndpoint().intValue());
assertEquals(BaseTypes.int16Type(), int16Ext.getBaseType());
}
import static org.opendaylight.yangtools.yang.stmt.StmtTestUtils.sourceForResource;
import com.google.common.collect.Iterables;
+import com.google.common.collect.Range;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
import org.opendaylight.yangtools.yang.model.api.UsesNode;
-import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
final UnsignedIntegerTypeDefinition dscpExt = (UnsignedIntegerTypeDefinition) TestUtils.findTypedef(
module.getTypeDefinitions(), "dscp-ext");
- final List<RangeConstraint> ranges = dscpExt.getRangeConstraints();
+ final Set<? extends Range<?>> ranges = dscpExt.getRangeConstraint().get().getAllowedRanges().asRanges();
assertEquals(1, ranges.size());
- final RangeConstraint range = ranges.get(0);
- assertEquals(0, range.getMin().intValue());
- assertEquals(63, range.getMax().intValue());
+ final Range<?> range = ranges.iterator().next();
+ assertEquals((short)0, range.lowerEndpoint());
+ assertEquals((short)63, range.upperEndpoint());
}
@Test
assertEquals(Optional.of("pattern constraint error-app-tag"), patternConstraint.getErrorAppTag());
assertEquals(Optional.of("pattern constraint error-app-message"), patternConstraint.getErrorMessage());
- List<RangeConstraint> rangeConstraints = ((IntegerTypeDefinition) myLeaf2Type).getRangeConstraints();
- assertEquals(1, rangeConstraints.size());
+ RangeConstraint<?> rangeConstraint = ((IntegerTypeDefinition) myLeaf2Type).getRangeConstraint().get();
+ assertEquals(1, rangeConstraint.getAllowedRanges().asRanges().size());
- RangeConstraint rangeConstraint = rangeConstraints.iterator().next();
assertEquals(Optional.of("range constraint error-app-tag"), rangeConstraint.getErrorAppTag());
assertEquals(Optional.of("range constraint error-app-message"), rangeConstraint.getErrorMessage());
}