package org.opendaylight.yangtools.yang.data.impl.codec;
import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Objects.requireNonNull;
import com.google.common.annotations.Beta;
-import com.google.common.collect.ImmutableRangeSet;
-import com.google.common.collect.Range;
-import com.google.common.collect.RangeSet;
-import com.google.common.collect.TreeRangeSet;
import com.google.common.io.BaseEncoding;
import java.util.Optional;
import javax.xml.bind.DatatypeConverter;
public abstract class BinaryStringCodec extends TypeDefinitionAwareCodec<byte[], BinaryTypeDefinition>
implements BinaryCodec<String> {
private static final class Restricted extends BinaryStringCodec {
- private final RangeSet<Integer> ranges;
+ private final LengthConstraint lengthConstraint;
- Restricted(final BinaryTypeDefinition typeDef) {
+ Restricted(final BinaryTypeDefinition typeDef, final LengthConstraint lengthConstraint) {
super(typeDef);
-
- final RangeSet<Integer> r = TreeRangeSet.create();
- for (LengthConstraint c : typeDef.getLengthConstraints()) {
- r.add(Range.closed(c.getMin().intValue(), c.getMax().intValue()));
- }
-
- ranges = ImmutableRangeSet.copyOf(r);
+ this.lengthConstraint = requireNonNull(lengthConstraint);
}
@Override
void validate(final byte[] value) {
- checkArgument(ranges.contains(value.length), "Value length %s does not match constraints %s", value.length,
- ranges);
+ // FIXME: throw an exception capturing the constraint violation
+ checkArgument(lengthConstraint.getAllowedRanges().contains(value.length),
+ "Value length %s does not match constraint %s", value.length, lengthConstraint);
}
}
}
public static BinaryStringCodec from(final BinaryTypeDefinition type) {
- return type.getLengthConstraints().isEmpty() ? new Unrestricted(type) : new Restricted(type);
+ final java.util.Optional<LengthConstraint> optConstraint = type.getLengthConstraint();
+ return optConstraint.isPresent() ? new Restricted(type, optConstraint.get()) : new Unrestricted(type);
}
@Override
import static java.util.Objects.requireNonNull;
import com.google.common.annotations.Beta;
-import com.google.common.collect.ImmutableRangeSet;
-import com.google.common.collect.Range;
-import com.google.common.collect.RangeSet;
-import com.google.common.collect.TreeRangeSet;
-import java.util.Collection;
import java.util.Optional;
import org.opendaylight.yangtools.yang.data.api.codec.StringCodec;
import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
public class StringStringCodec extends TypeDefinitionAwareCodec<String, StringTypeDefinition>
implements StringCodec<String> {
- private final RangeSet<Integer> lengths;
+ private final LengthConstraint lengthConstraint;
StringStringCodec(final StringTypeDefinition typeDef) {
super(Optional.of(typeDef), String.class);
-
- final Collection<LengthConstraint> constraints = typeDef.getLengthConstraints();
- if (!constraints.isEmpty()) {
- final RangeSet<Integer> tmp = TreeRangeSet.create();
- for (LengthConstraint c : constraints) {
- tmp.add(Range.closed(c.getMin().intValue(), c.getMax().intValue()));
- }
-
- lengths = ImmutableRangeSet.copyOf(tmp);
- } else {
- lengths = null;
- }
+ lengthConstraint = typeDef.getLengthConstraint().orElse(null);
}
public static StringStringCodec from(final StringTypeDefinition normalizedType) {
}
void validate(final String str) {
- if (lengths != null) {
- checkArgument(lengths.contains(str.length()), "String '%s' does not match allowed lengths %s", lengths);
+ if (lengthConstraint != null) {
+ checkArgument(lengthConstraint.getAllowedRanges().contains(str.length()),
+ "String '%s' does not match allowed length constraint %s", lengthConstraint);
}
}
}
*
* <dt>length
* <dd>{@link org.opendaylight.yangtools.yang.model.api.type.LengthConstraint}
- * <dd>{@link org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition#getLengthConstraints()}
+ * <dd>{@link org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition#getLengthConstraint()}
*
* <dt>list
* <dd>{@link org.opendaylight.yangtools.yang.model.api.ListSchemaNode}
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.LengthConstraint;
-public interface LengthStatement extends DeclaredStatement<List<LengthConstraint>>, DocumentedConstraintGroup {
+public interface LengthStatement extends DeclaredStatement<List<ValueRange>>, DocumentedConstraintGroup {
@Nonnull
@Override
- List<LengthConstraint> argument();
+ List<ValueRange> argument();
}
* 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;
+package org.opendaylight.yangtools.yang.model.api.stmt;
import static com.google.common.base.Preconditions.checkArgument;
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.LengthConstraint;
import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
@Beta
private static final long serialVersionUID = 1L;
@Override
- public Number resolveLength(final List<LengthConstraint> constraints) {
- return resolve(constraints.get(constraints.size() - 1).getMax());
+ public <T extends Number & Comparable<T>> T resolveLength(final Range<T> span) {
+ return resolve(span.upperEndpoint());
}
@Override
private static final long serialVersionUID = 1L;
@Override
- public Number resolveLength(final List<LengthConstraint> constraints) {
- return resolve(constraints.get(0).getMin());
+ public <T extends Number & Comparable<T>> T resolveLength(final Range<T> span) {
+ return resolve(span.lowerEndpoint());
}
@Override
throw new UnsupportedOperationException();
}
- private static Number resolve(final Number number) {
+ private static <T extends Number> T resolve(final T number) {
checkArgument(!(number instanceof UnresolvedNumber));
return number;
}
- public abstract Number resolveLength(List<LengthConstraint> constraints);
+ public abstract <T extends Number & Comparable<T>> T resolveLength(Range<T> span);
public abstract Number resolveRange(List<RangeConstraint> constraints);
--- /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.api.stmt;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.annotations.Beta;
+import java.util.Objects;
+import org.eclipse.jdt.annotation.NonNull;
+
+/**
+ * YANG specification of a numeric value range. This object is used for {@link LengthStatement} and
+ * {@link RangeStatement}.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public abstract class ValueRange {
+ private static final class Singleton extends ValueRange {
+ private final @NonNull Number value;
+
+ Singleton(final @NonNull Number value) {
+ this.value = requireNonNull(value);
+ }
+
+ @Override
+ public @NonNull Number lowerBound() {
+ return value;
+ }
+
+ @Override
+ public @NonNull Number upperBound() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return value.toString();
+ }
+ }
+
+ private static final class Range extends ValueRange {
+ private final @NonNull Number lower;
+ private final @NonNull Number upper;
+
+ Range(final Number lower, final Number upper) {
+ this.lower = requireNonNull(lower);
+ this.upper = requireNonNull(upper);
+ }
+
+ @Override
+ public @NonNull Number lowerBound() {
+ return lower;
+ }
+
+ @Override
+ public @NonNull Number upperBound() {
+ return upper;
+ }
+
+ @Override
+ public String toString() {
+ return lower + ".." + upper;
+ }
+ }
+
+ public static ValueRange of(final @NonNull Number value) {
+ return new Singleton(value);
+ }
+
+ public static ValueRange of(final @NonNull Number lower, final @NonNull Number upper) {
+ return lower.equals(upper) ? of(lower) : new Range(lower, upper);
+ }
+
+ public abstract @NonNull Number lowerBound();
+
+ public abstract @NonNull Number upperBound();
+
+ @Override
+ public final int hashCode() {
+ return Objects.hash(lowerBound(), upperBound());
+ }
+
+ @Override
+ public final boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof ValueRange)) {
+ return false;
+ }
+ final ValueRange other = (ValueRange) obj;
+ return lowerBound().equals(other.lowerBound()) && upperBound().equals(other.upperBound());
+ }
+}
*/
package org.opendaylight.yangtools.yang.model.api.type;
+import com.google.common.collect.RangeSet;
import org.opendaylight.yangtools.yang.model.api.ConstraintMetaDefinition;
/**
- * The Lenght Constraint value consists of an explicit value, or a lower bound
- * returned by {@link #getMin()} and an upper bound returned by
- * {@link #getMax()}. <br>
- * <br>
- * Length-restricting values MUST NOT be negative. A length value is a
- * non-negative integer, or one of the special values <code>min</code> or
- * <code>max</code>. The defined <code>min</code> and <code>max</code> mean the
- * minimum and maximum length accepted for the type being restricted,
- * respectively. <br>
- * An implementation is not required to support a length value larger than
- * {@link Long#MAX_VALUE} <br>
- * <br>
- * The interface extends definitions from {@link ConstraintMetaDefinition} <br>
- * <br>
- * This interface was modeled according to definition in <a
- * href="https://tools.ietf.org/html/rfc6020#section-9.4.4">[RFC-6020] The
- * length Statement</a>.
- *
- * @see ConstraintMetaDefinition
+ * A single value length restriction, as expressed by a length statement, as specified by
+ * <a href="https://tools.ietf.org/html/rfc6020#section-9.4.4">[RFC-6020] The length Statement</a>.
*/
public interface LengthConstraint extends ConstraintMetaDefinition {
-
- /**
- * Returns the length-restricting lower bound value. <br>
- * The value MUST NOT be negative.
- *
- * @return the length-restricting lower bound value.
- */
- Number getMin();
-
/**
- * Returns the length-restricting upper bound value. <br>
- * The value MUST NOT be negative.
+ * Return allowed length ranges. Returned RangeSet must not be empty.
*
- * @return length-restricting upper bound value.
+ * @return Set of allowed lengths.
*/
- Number getMax();
+ RangeSet<Integer> getAllowedRanges();
}
*/
package org.opendaylight.yangtools.yang.model.api.type;
-import java.util.List;
+import java.util.Optional;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
/**
*/
public interface LengthRestrictedTypeDefinition<T extends TypeDefinition<T>> extends TypeDefinition<T> {
/**
- * Returns length constraints. These are the effective constraints, e.g. they include any length constraints
- * implied by base types.
+ * Returns length constraint of this type, if applicable. This is the effective constraint, e.g. it includes any
+ * length constraints implied by base type hierarchy.
*
- * @return list of length constraint which are specified in the <code>length</code> substatement
- * of the <code>type</code> statement.
+ * @return length constraint which are specified in the <code>length</code> substatement of the <code>type</code>
+ * statement.
*/
- List<LengthConstraint> getLengthConstraints();
+ Optional<LengthConstraint> getLengthConstraint();
}
import com.google.common.base.Predicates;
import com.google.common.base.Strings;
import com.google.common.collect.Collections2;
+import com.google.common.collect.Range;
+import com.google.common.collect.RangeSet;
import com.google.common.primitives.UnsignedInteger;
import java.net.URI;
import java.util.Collection;
} else if (typeDef instanceof UnionTypeDefinition) {
emitUnionSpecification((UnionTypeDefinition) typeDef);
} else if (typeDef instanceof BinaryTypeDefinition) {
- emitLength(((BinaryTypeDefinition) typeDef).getLengthConstraints());
+ ((BinaryTypeDefinition) typeDef).getLengthConstraint().ifPresent(this::emitLength);
} else if (typeDef instanceof BooleanTypeDefinition || typeDef instanceof EmptyTypeDefinition) {
// NOOP
} else {
}
private void emitStringRestrictions(final StringTypeDefinition typeDef) {
-
- // FIXME: BUG-2444: Wrong decomposition in API, should be
- // LenghtConstraint
- // which contains ranges.
- emitLength(typeDef.getLengthConstraints());
+ typeDef.getLengthConstraint().ifPresent(this::emitLength);
for (final PatternConstraint pattern : typeDef.getPatternConstraints()) {
emitPatternNode(pattern);
}
-
}
- private void emitLength(final List<LengthConstraint> list) {
- if (!list.isEmpty()) {
- super.writer.startLengthNode(toLengthString(list));
- // FIXME: BUG-2444: Workaround for incorrect decomposition in
- // API
- final LengthConstraint first = list.iterator().next();
- emitErrorMessageNode(first.getErrorMessage());
- emitErrorAppTagNode(first.getErrorAppTag());
- emitDescriptionNode(first.getDescription());
- emitReferenceNode(first.getReference());
- super.writer.endNode();
- }
+ private void emitLength(final LengthConstraint constraint) {
+ super.writer.startLengthNode(toLengthString(constraint.getAllowedRanges()));
+ emitErrorMessageNode(constraint.getErrorMessage());
+ emitErrorAppTagNode(constraint.getErrorAppTag());
+ emitDescriptionNode(constraint.getDescription());
+ emitReferenceNode(constraint.getReference());
+ super.writer.endNode();
}
- private static String toLengthString(final List<LengthConstraint> list) {
- final Iterator<LengthConstraint> it = list.iterator();
+ private static String toLengthString(final RangeSet<Integer> ranges) {
+ final Iterator<Range<Integer>> it = ranges.asRanges().iterator();
if (!it.hasNext()) {
return "";
}
final StringBuilder sb = new StringBuilder();
boolean haveNext;
do {
- final LengthConstraint current = it.next();
+ final Range<Integer> 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();
<leaf name="bin-leaf-2">
<type name="binary" />
</leaf>
-</module>
\ No newline at end of file
+</module>
package org.opendaylight.yangtools.yang.model.util;
import java.util.Optional;
-import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
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;
* <p>
* Provides static factory methods which constructs instances of
* <ul>
- * <li>{@link LengthConstraint} - {@link #newLengthConstraint(Number, Number, Optional, Optional)}
* <li>{@link RangeConstraint} - {@link #newRangeConstraint(Number, Number, Optional, Optional)}
* <li>{@link PatternConstraint} - {@link #newPatternConstraint(String, Optional, Optional)}
* </ul>
throw new UnsupportedOperationException();
}
- /**
- * Creates a {@link LengthConstraint}.
- *
- * <p>
- * Creates an instance of Length constraint based on supplied parameters
- * with additional behaviour:
- * <ul>
- * <li>{@link LengthConstraint#getErrorAppTag()} returns <code>length-out-of-specified-bounds</code>
- * <li>{@link LengthConstraint#getErrorMessage()} returns <code>The argument is out of bounds
- * <<i>min</i>, <i>max</i> ></code>
- * </ul>
- *
- * @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#empty()} if description is undefined.
- * @param reference Reference associated with constraint. {@link Optional#empty()} if reference is undefined.
- * @return Instance of {@link LengthConstraint}
- */
- public static LengthConstraint newLengthConstraint(final Number min, final Number max,
- final Optional<String> description, final Optional<String> reference) {
- return new LengthConstraintImpl(min, max, description, reference);
- }
-
- /**
- * Creates a {@link LengthConstraint}.
- *
- * <p>
- * Creates an instance of Length constraint based on supplied parameters
- * with additional behaviour:
- * <ul>
- * <li>{@link LengthConstraint#getErrorAppTag()} returns <code>length-out-of-specified-bounds</code>
- * <li>{@link LengthConstraint#getErrorMessage()} returns <code>The argument is out of bounds
- * <<i>min</i>, <i>max</i> ></code>
- * </ul>
- *
- * @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#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 LengthConstraint}
- */
- public static LengthConstraint newLengthConstraint(final Number min, final Number max,
- final Optional<String> description, final Optional<String> reference, final String errorAppTag,
- final String errorMessage) {
- return new LengthConstraintImpl(min, max, description, reference, errorAppTag, errorMessage);
- }
-
/**
* Creates a {@link RangeConstraint}.
*
+++ /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.LengthConstraint;
-
-/**
- * {@link Immutable} implementation of {@link LengthConstraint}.
- * Length constraint based on supplied parameters with additional behaviour:
- *
- * <ul>
- * <li>{@link LengthConstraint#getErrorAppTag()} returns
- * <code>length-out-of-specified-bounds</code>
- * <li>{@link LengthConstraint#getErrorMessage()} returns <code>The argument is
- * out of bounds <<i>min</i>, <i>max</i> ></code>
- * </ul>
- */
-final class LengthConstraintImpl implements LengthConstraint, 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;
-
- LengthConstraintImpl(final Number min, final Number max, final Optional<String> description,
- final Optional<String> reference) {
- 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<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 : "length-out-of-specified-bounds";
- this.errorMessage = errorMessage != null ? errorMessage : "The argument is out of bounds <" + min + ", " + max
- + ">";
- }
-
- @Override
- public String getDescription() {
- return description;
- }
-
- @Override
- public String getErrorAppTag() {
- return errorAppTag;
- }
-
- @Override
- public String getErrorMessage() {
- return errorMessage;
- }
-
- @Override
- public String getReference() {
- return 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 LengthConstraintImpl other = (LengthConstraintImpl) obj;
- if (!Objects.equals(description, other.description)) {
- return false;
- }
- if (!Objects.equals(errorAppTag, other.errorAppTag)) {
- return false;
- }
- if (!Objects.equals(errorMessage, other.errorMessage)) {
- return false;
- }
- if (max != other.max) {
- return false;
- }
- if (min != other.min) {
- return false;
- }
- if (!Objects.equals(reference, other.reference)) {
- return false;
- }
- return true;
- }
-
- @Override
- public String toString() {
- return "LengthConstraintImpl [min=" + min
- + ", max=" + max
- + ", description=" + description
- + ", errorAppTag=" + errorAppTag
- + ", reference=" + reference
- + ", errorMessage=" + errorMessage
- + "]";
- }
-}
*/
package org.opendaylight.yangtools.yang.model.util.type;
-import com.google.common.collect.ImmutableList;
-import java.util.List;
+import java.util.Optional;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
import org.opendaylight.yangtools.yang.model.api.type.LengthRestrictedTypeDefinition;
}
@Override
- public final List<LengthConstraint> getLengthConstraints() {
- return ImmutableList.of();
+ public final Optional<LengthConstraint> getLengthConstraint() {
+ return Optional.empty();
}
}
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<LengthConstraint> getLengthConstraints() {
- return baseType().getLengthConstraints();
+ public final Optional<LengthConstraint> getLengthConstraint() {
+ return baseType().getLengthConstraint();
}
}
*/
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 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.LengthConstraint;
abstract class AbstractLengthRestrictedType<T extends LengthRestrictedTypeDefinition<T>>
extends AbstractRestrictedType<T> implements LengthRestrictedTypeDefinition<T> {
- private final List<LengthConstraint> lengthConstraints;
+ private final @Nullable LengthConstraint lengthConstraint;
AbstractLengthRestrictedType(final T baseType, final SchemaPath path,
- final Collection<UnknownSchemaNode> unknownSchemaNodes, final Collection<LengthConstraint> lengthConstraints) {
+ final Collection<UnknownSchemaNode> unknownSchemaNodes, final @Nullable LengthConstraint lengthConstraint) {
super(baseType, path, unknownSchemaNodes);
- this.lengthConstraints = ImmutableList.copyOf(lengthConstraints);
+ this.lengthConstraint = lengthConstraint;
}
@Override
- public final List<LengthConstraint> getLengthConstraints() {
- return lengthConstraints;
+ public final Optional<LengthConstraint> getLengthConstraint() {
+ return Optional.ofNullable(lengthConstraint);
}
}
import com.google.common.base.Preconditions;
import java.util.List;
+import java.util.Optional;
import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
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.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.StringTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
}
}
- private static TypeDefinition<?> baseTypeIfNotConstrained(final BinaryTypeDefinition type) {
- final BinaryTypeDefinition base = type.getBaseType();
- return baseTypeIfNotConstrained(type, type.getLengthConstraints(), base, base.getLengthConstraints());
+ private static BinaryTypeDefinition baseTypeIfNotConstrained(final BinaryTypeDefinition type) {
+ return baseTypeIfNotConstrained(type, type.getBaseType());
}
private static TypeDefinition<?> baseTypeIfNotConstrained(final DecimalTypeDefinition type) {
private static TypeDefinition<?> baseTypeIfNotConstrained(final StringTypeDefinition type) {
final StringTypeDefinition base = type.getBaseType();
final List<PatternConstraint> patterns = type.getPatternConstraints();
- final List<LengthConstraint> lengths = type.getLengthConstraints();
+ final Optional<LengthConstraint> optLengths = type.getLengthConstraint();
if ((patterns.isEmpty() || patterns.equals(base.getPatternConstraints()))
- && (lengths.isEmpty() || lengths.equals(base.getLengthConstraints()))) {
+ && (!optLengths.isPresent() || optLengths.equals(base.getLengthConstraint()))) {
return base;
}
private static TypeDefinition<?> baseTypeIfNotConstrained(final TypeDefinition<?> type,
final List<?> typeConstraints, final TypeDefinition<?> base, final List<?> baseConstraints) {
- if (typeConstraints.isEmpty() || typeConstraints.equals(baseConstraints)) {
+ return typeConstraints.isEmpty() || typeConstraints.equals(baseConstraints) ? base : type;
+ }
+
+ private static <T extends LengthRestrictedTypeDefinition<T>> T baseTypeIfNotConstrained(final T type,
+ final T base) {
+ final Optional<LengthConstraint> optConstraint = type.getLengthConstraint();
+ if (!optConstraint.isPresent()) {
return base;
}
- return type;
+ return optConstraint.equals(base.getLengthConstraint()) ? base : type;
}
}
package org.opendaylight.yangtools.yang.model.util.type;
import com.google.common.annotations.Beta;
-import com.google.common.base.Preconditions;
-import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
+import org.eclipse.jdt.annotation.NonNull;
@Beta
-public class InvalidLengthConstraintException extends IllegalArgumentException {
+public final class InvalidLengthConstraintException extends Exception {
private static final long serialVersionUID = 1L;
- private final LengthConstraint offendingConstraint;
- protected InvalidLengthConstraintException(final LengthConstraint offendingConstraint, final String message) {
- super(message);
- this.offendingConstraint = Preconditions.checkNotNull(offendingConstraint);
- }
-
- public InvalidLengthConstraintException(final LengthConstraint offendingRange, final String format,
- final Object... args) {
- this(offendingRange, String.format(format, args));
- }
-
- public LengthConstraint getOffendingConstraint() {
- return offendingConstraint;
+ public InvalidLengthConstraintException(final @NonNull String format, final Object... args) {
+ super(String.format(format, args));
}
}
*/
package org.opendaylight.yangtools.yang.model.util.type;
-import com.google.common.collect.ImmutableList;
-import java.util.List;
-import java.util.Optional;
+import com.google.common.collect.ImmutableRangeSet;
+import com.google.common.collect.Range;
+import com.google.common.collect.RangeSet;
import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
-import org.opendaylight.yangtools.yang.model.util.BaseConstraints;
final class JavaLengthConstraints {
private JavaLengthConstraints() {
throw new UnsupportedOperationException();
}
- static final List<LengthConstraint> INTEGER_SIZE_CONSTRAINTS = ImmutableList.of(
- BaseConstraints.newLengthConstraint(0, Integer.MAX_VALUE, Optional.empty(), Optional.empty()));
+ private static final RangeSet<Integer> INTEGER_ALLOWED_RANGES =
+ ImmutableRangeSet.of(Range.closed(0, Integer.MAX_VALUE));
+
+ static final LengthConstraint INTEGER_SIZE_CONSTRAINTS = new LengthConstraint() {
+ @Override
+ public String getReference() {
+ return null;
+ }
+
+ @Override
+ public String getErrorMessage() {
+ return null;
+ }
+
+ @Override
+ public String getErrorAppTag() {
+ return null;
+ }
+
+ @Override
+ public String getDescription() {
+ return null;
+ }
+
+ @Override
+ public RangeSet<Integer> getAllowedRanges() {
+ return INTEGER_ALLOWED_RANGES;
+ }
+ };
}
*/
package org.opendaylight.yangtools.yang.model.util.type;
+import static java.util.Objects.requireNonNull;
+
import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableList.Builder;
-import java.util.Collection;
+import com.google.common.base.Verify;
+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.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.LengthConstraint;
import org.opendaylight.yangtools.yang.model.api.type.LengthRestrictedTypeDefinition;
-import org.opendaylight.yangtools.yang.model.util.BaseConstraints;
-import org.opendaylight.yangtools.yang.model.util.UnresolvedNumber;
public abstract class LengthRestrictedTypeBuilder<T extends LengthRestrictedTypeDefinition<T>>
extends AbstractRestrictedTypeBuilder<T> {
- private List<LengthConstraint> lengthAlternatives;
+ private LengthConstraint lengthConstraint;
LengthRestrictedTypeBuilder(final T baseType, final SchemaPath path) {
- super(Preconditions.checkNotNull(baseType), path);
+ super(requireNonNull(baseType), path);
}
- public final void setLengthAlternatives(@Nonnull final Collection<LengthConstraint> lengthAlternatives) {
- Preconditions.checkState(this.lengthAlternatives == null, "Range alternatives already defined as %s",
- lengthAlternatives);
- this.lengthAlternatives = ImmutableList.copyOf(lengthAlternatives);
- touch();
- }
-
- private static List<LengthConstraint> ensureResolvedLengths(final List<LengthConstraint> unresolved,
- final List<LengthConstraint> baseRangeConstraints) {
- // First check if we need to resolve anything at all
- for (LengthConstraint c : unresolved) {
- if (c.getMax() instanceof UnresolvedNumber || c.getMin() instanceof UnresolvedNumber) {
- return resolveLengths(unresolved, baseRangeConstraints);
- }
+ /**
+ * Set a new length constraint.
+ *
+ * @param constraint Constraint metadata
+ * @param ranges Allowed ranges
+ * @throws IllegalStateException if the constraint has already been set
+ * @throws InvalidLengthConstraintException if one of the proposed ranges does not overlap with supertype
+ * @throws NullPointerException if any of the arguments is null
+ */
+ 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);
+ final LengthConstraint baseLengths = findLenghts();
+ if (ranges.isEmpty()) {
+ lengthConstraint = baseLengths;
+ return;
}
- // No need, just return the same list
- return unresolved;
- }
-
- private static List<LengthConstraint> resolveLengths(final List<LengthConstraint> unresolved,
- final List<LengthConstraint> baseLengthConstraints) {
- final Builder<LengthConstraint> builder = ImmutableList.builder();
-
- for (LengthConstraint c : unresolved) {
- final Number max = c.getMax();
- final Number min = c.getMin();
-
- if (max instanceof UnresolvedNumber || min instanceof UnresolvedNumber) {
- final Number rMax = max instanceof UnresolvedNumber
- ? ((UnresolvedNumber)max).resolveLength(baseLengthConstraints) : max;
- final Number rMin = min instanceof UnresolvedNumber
- ? ((UnresolvedNumber)min).resolveLength(baseLengthConstraints) : min;
-
- builder.add(BaseConstraints.newLengthConstraint(rMin, rMax, Optional.ofNullable(c.getDescription()),
- Optional.ofNullable(c.getReference()), c.getErrorAppTag(), c.getErrorMessage()));
- } else {
- builder.add(c);
- }
- }
-
- return builder.build();
- }
+ // Run through alternatives and resolve them against the base type
+ requireNonNull(constraint);
+ final Builder<Integer> builder = ImmutableRangeSet.builder();
+ final Range<Integer> span = baseLengths.getAllowedRanges().span();
- private static List<LengthConstraint> ensureTypedLengths(final List<LengthConstraint> lengths,
- final Class<? extends Number> clazz) {
- for (LengthConstraint c : lengths) {
- if (!clazz.isInstance(c.getMin()) || !clazz.isInstance(c.getMax())) {
- return typedLengths(lengths, clazz);
- }
+ for (ValueRange c : ranges) {
+ builder.add(Range.closed(resolveLength(c.lowerBound(), span), resolveLength(c.upperBound(), span)));
}
- return lengths;
- }
- private static List<LengthConstraint> typedLengths(final List<LengthConstraint> lengths,
- final Class<? extends Number> clazz) {
- final Function<Number, Number> function = NumberUtil.converterTo(clazz);
- Preconditions.checkArgument(function != null, "Unsupported range class %s", clazz);
-
- final Builder<LengthConstraint> builder = ImmutableList.builder();
-
- for (LengthConstraint c : lengths) {
- if (!clazz.isInstance(c.getMin()) || !clazz.isInstance(c.getMax())) {
- final Number min;
- final Number max;
-
- try {
- min = function.apply(c.getMin());
- max = function.apply(c.getMax());
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException(String.format("Constraint %s does not fit into range of %s",
- c, clazz.getSimpleName()), e);
- }
- builder.add(BaseConstraints.newLengthConstraint(min, max, Optional.ofNullable(c.getDescription()),
- Optional.ofNullable(c.getReference()), c.getErrorAppTag(), c.getErrorMessage()));
- } else {
- builder.add(c);
+ // Now verify if new ranges are strict subset of base ranges
+ final RangeSet<Integer> allowed = builder.build();
+ final RangeSet<Integer> baseRanges = baseLengths.getAllowedRanges();
+ for (Range<Integer> range : allowed.asRanges()) {
+ if (!baseRanges.encloses(range)) {
+ throw new InvalidLengthConstraintException("Range %s is not a subset of parent constraint %s", range,
+ baseRanges);
}
}
- return builder.build();
+ lengthConstraint = new ResolvedLengthConstraint(constraint, allowed);
+ touch();
}
- private static boolean lengthCovered(final List<LengthConstraint> where,
- final LengthConstraint what) {
- for (LengthConstraint c : where) {
- if (NumberUtil.isRangeCovered(what.getMin(), what.getMax(), c.getMin(), c.getMax())) {
- return true;
- }
- }
-
- return false;
- }
+ abstract T buildType(LengthConstraint lengthConstraint);
@Override
final T buildType() {
- final List<LengthConstraint> baseLengths = findLenghts();
-
- if (lengthAlternatives == null || lengthAlternatives.isEmpty()) {
- return buildType(baseLengths);
- }
-
- // Run through alternatives and resolve them against the base type
- final List<LengthConstraint> resolvedLengths = ensureResolvedLengths(lengthAlternatives, baseLengths);
+ return buildType(lengthConstraint != null ? lengthConstraint : findLenghts());
+ }
- // Next up, ensure the of boundaries match base constraints
- final Class<? extends Number> clazz = baseLengths.get(0).getMin().getClass();
- final List<LengthConstraint> typedLengths = ensureTypedLengths(resolvedLengths, clazz);
+ abstract LengthConstraint typeLengthConstraints();
- // Now verify if new ranges are strict subset of base ranges
- for (LengthConstraint c : typedLengths) {
- if (!lengthCovered(baseLengths, c)) {
- throw new InvalidLengthConstraintException(c,
- "Length constraint %s is not a subset of parent constraints %s", c, baseLengths);
- }
+ private static Integer resolveLength(final Number unresolved, final Range<Integer> span) {
+ if (unresolved instanceof Integer) {
+ return (Integer) unresolved;
+ }
+ if (unresolved instanceof UnresolvedNumber) {
+ return ((UnresolvedNumber)unresolved).resolveLength(span);
}
- return buildType(typedLengths);
+ return Verify.verifyNotNull(NumberUtil.converterTo(Integer.class)).apply(unresolved);
}
- abstract T buildType(List<LengthConstraint> lengthConstraints);
-
- abstract List<LengthConstraint> typeLengthConstraints();
-
- private List<LengthConstraint> findLenghts() {
- List<LengthConstraint> ret = ImmutableList.of();
+ private LengthConstraint findLenghts() {
+ Optional<LengthConstraint> ret = Optional.empty();
T wlk = getBaseType();
- while (wlk != null && ret.isEmpty()) {
- ret = wlk.getLengthConstraints();
+ while (wlk != null && !ret.isPresent()) {
+ ret = wlk.getLengthConstraint();
wlk = wlk.getBaseType();
}
- return ret.isEmpty() ? typeLengthConstraints() : ret;
+ return ret.orElse(typeLengthConstraints());
}
}
throw new UnsupportedOperationException();
}
- static Function<Number, Number> converterTo(final Class<? extends Number> clazz) {
- return CONVERTERS.get(clazz);
+ @SuppressWarnings("unchecked")
+ static <T extends Number> Function<Number, T> converterTo(final Class<T> clazz) {
+ return (Function<Number, T>) CONVERTERS.get(clazz);
}
static boolean isRangeCovered(final Number min, final Number max, final Number superMin, final Number superMax) {
import java.util.function.Function;
import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.stmt.UnresolvedNumber;
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;
-import org.opendaylight.yangtools.yang.model.util.UnresolvedNumber;
public abstract class RangeRestrictedTypeBuilder<T extends RangeRestrictedTypeDefinition<T>>
extends AbstractRestrictedTypeBuilder<T> {
private static List<RangeConstraint> typedRanges(final List<RangeConstraint> ranges,
final Class<? extends Number> clazz) {
- final Function<Number, Number> function = NumberUtil.converterTo(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();
--- /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 org.opendaylight.yangtools.yang.model.api.ConstraintMetaDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
+
+final class ResolvedLengthConstraint implements LengthConstraint {
+ private final ConstraintMetaDefinition meta;
+ private final RangeSet<Integer> ranges;
+
+ ResolvedLengthConstraint(final ConstraintMetaDefinition meta, final RangeSet<Integer> ranges) {
+ this.meta = requireNonNull(meta);
+ this.ranges = ImmutableRangeSet.copyOf(ranges);
+ }
+
+ @Override
+ public String getDescription() {
+ return meta.getDescription();
+ }
+
+ @Override
+ public String getErrorAppTag() {
+ return meta.getErrorAppTag();
+ }
+
+ @Override
+ public String getErrorMessage() {
+ return meta.getErrorMessage();
+ }
+
+ @Override
+ public String getReference() {
+ return meta.getReference();
+ }
+
+ @Override
+ public RangeSet<Integer> getAllowedRanges() {
+ return ranges;
+ }
+}
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.BinaryTypeDefinition;
implements BinaryTypeDefinition {
RestrictedBinaryType(final BinaryTypeDefinition baseType, final SchemaPath path,
final Collection<UnknownSchemaNode> unknownSchemaNodes,
- final Collection<LengthConstraint> lengthConstraints) {
- super(baseType, path, unknownSchemaNodes, lengthConstraints);
+ final @Nullable LengthConstraint lengthConstraint) {
+ super(baseType, path, unknownSchemaNodes, lengthConstraint);
}
@Override
import com.google.common.collect.ImmutableList;
import java.util.Collection;
import java.util.List;
+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.LengthConstraint;
private final List<PatternConstraint> patternConstraints;
RestrictedStringType(final StringTypeDefinition baseType, final SchemaPath path,
- final Collection<UnknownSchemaNode> unknownSchemaNodes, final Collection<LengthConstraint> lengthConstraints,
+ final Collection<UnknownSchemaNode> unknownSchemaNodes,
+ final @Nullable LengthConstraint lengthConstraints,
final List<PatternConstraint> patternConstraints) {
super(baseType, path, unknownSchemaNodes, lengthConstraints);
this.patternConstraints = ImmutableList.copyOf(patternConstraints);
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;
import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
@Nonnull final BinaryTypeDefinition baseType, @Nonnull final SchemaPath path) {
return new LengthRestrictedTypeBuilder<BinaryTypeDefinition>(baseType, path) {
@Override
- BinaryTypeDefinition buildType(final List<LengthConstraint> lengthConstraints) {
- return new RestrictedBinaryType(getBaseType(), getPath(), getUnknownSchemaNodes(), lengthConstraints);
+ BinaryTypeDefinition buildType(final @Nullable LengthConstraint lengthConstraint) {
+ return new RestrictedBinaryType(getBaseType(), getPath(), getUnknownSchemaNodes(), lengthConstraint);
}
@Override
- List<LengthConstraint> typeLengthConstraints() {
+ LengthConstraint typeLengthConstraints() {
/**
* Length constraint imposed on YANG binary type by our implementation. byte[].length is an integer,
* capping our ability to support arbitrary binary data.
import com.google.common.base.Preconditions;
import java.util.ArrayList;
import java.util.List;
+import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
}
@Override
- List<LengthConstraint> typeLengthConstraints() {
+ LengthConstraint typeLengthConstraints() {
/**
* Length constraint imposed on YANG string type by our implementation. {@link String#length()} is an integer,
* capping our ability to support strings up to 18446744073709551615 as defined in
}
@Override
- StringTypeDefinition buildType(final List<LengthConstraint> lengthConstraints) {
+ StringTypeDefinition buildType(final @Nullable LengthConstraint lengthConstraints) {
return new RestrictedStringType(getBaseType(), getPath(), getUnknownSchemaNodes(),
lengthConstraints, patternConstraints);
}
static int hashCode(final BinaryTypeDefinition type) {
return Objects.hash(type.getPath(), type.getUnknownSchemaNodes(), type.getBaseType(), type.getUnits(),
- type.getDefaultValue(), type.getLengthConstraints());
+ type.getDefaultValue(), type.getLengthConstraint());
}
static int hashCode(final BitsTypeDefinition type) {
static int hashCode(final StringTypeDefinition type) {
return Objects.hash(type.getPath(), type.getUnknownSchemaNodes(), type.getBaseType(), type.getUnits(),
- type.getDefaultValue(), type.getLengthConstraints(), type.getPatternConstraints());
+ type.getDefaultValue(), type.getLengthConstraint(), type.getPatternConstraints());
}
static int hashCode(final UnionTypeDefinition type) {
}
final BinaryTypeDefinition other = castIfEquals(BinaryTypeDefinition.class, type, obj);
- return other != null && type.getLengthConstraints().equals(other.getLengthConstraints());
+ return other != null && type.getLengthConstraint().equals(other.getLengthConstraint());
}
static boolean equals(final BitsTypeDefinition type, final Object obj) {
}
final StringTypeDefinition other = castIfEquals(StringTypeDefinition.class, type, obj);
- return other != null && type.getLengthConstraints().equals(other.getLengthConstraints())
+ return other != null && type.getLengthConstraint().equals(other.getLengthConstraint())
&& type.getPatternConstraints().equals(other.getPatternConstraints());
}
}
static String toString(final BinaryTypeDefinition type) {
- return toStringHelper(type).add("length", type.getLengthConstraints()).toString();
+ return toStringHelper(type).add("length", type.getLengthConstraint().orElse(null)).toString();
}
static String toString(final BitsTypeDefinition type) {
}
static String toString(final StringTypeDefinition type) {
- return toStringHelper(type).add("length", type.getLengthConstraints())
+ return toStringHelper(type).add("length", type.getLengthConstraint().orElse(null))
.add("patterns", type.getPatternConstraints()).toString();
}
+++ /dev/null
-/*
- * Copyright (c) 2013 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 static org.junit.Assert.assertEquals;
-
-import java.util.Optional;
-import org.junit.Test;
-import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
-import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
-
-public class BaseConstraintsTest {
-
- @Test
- public void canCreateConstraints() {
- final Number min = 5;
- final Number max = 99;
- final String description = "Any description";
- final String reference = "any_ref";
-
- LengthConstraint lengthCons = BaseConstraints.newLengthConstraint(min, max, Optional.of(description),
- Optional.of(reference));
-
- assertEquals("LengthConstraints Get min", min, lengthCons.getMin());
- assertEquals("LengthConstraints Get max", max, lengthCons.getMax());
- assertEquals("LengthConstraints Get description", description, lengthCons.getDescription());
- assertEquals("LengthConstraints Get reference", reference, lengthCons.getReference());
-
- final String reg_exp = "x|z";
- final Optional<String> desc = Optional.of(description);
- final Optional<String> ref = Optional.of(reference);
- PatternConstraint patternCons = BaseConstraints.newPatternConstraint(reg_exp, desc, ref);
-
- assertEquals("PatternConstraints Get regex", reg_exp, patternCons.getRegularExpression());
- assertEquals("PatternConstraints Get description", description, patternCons.getDescription());
- assertEquals("PatternConstraints Get reference", reference, patternCons.getReference());
- }
-}
final BinaryTypeDefinition binType = binaryType();
final BinaryTypeDefinition binType1 = binaryType();
- assertEquals(0, binType.getLengthConstraints().size());
+ assertFalse(binType.getLengthConstraint().isPresent());
assertNull(binType.getDefaultValue());
assertEquals("CURRENT", Status.CURRENT, binType.getStatus());
assertEquals("Base type is null", null, binType.getBaseType());
+++ /dev/null
-/*
- * 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.model.util;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Optional;
-import org.junit.Test;
-import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
-
-public class LengthConstraintImplTest {
-
- @Test
- public void testLengthConstraint() {
- LengthConstraint lengthConstraint = new LengthConstraintImpl(3, 5, Optional.of("test description"),
- Optional.of("test reference"));
- LengthConstraint lengthConstraint2 = new LengthConstraintImpl(3, 5, Optional.of("test description"),
- Optional.of("test reference"));
- assertTrue(lengthConstraint.equals(lengthConstraint2));
-
- assertFalse(lengthConstraint.equals(null));
- assertFalse(lengthConstraint.equals(new Object()));
-
- lengthConstraint2 = new LengthConstraintImpl(3, 5, Optional.of("another test description"),
- Optional.of("test reference"));
- assertFalse(lengthConstraint.equals(lengthConstraint2));
-
- lengthConstraint2 = new LengthConstraintImpl(3, 5, Optional.of("test description"),
- Optional.of("another test reference"));
- assertFalse(lengthConstraint.equals(lengthConstraint2));
-
- lengthConstraint = new LengthConstraintImpl(3, 5, Optional.of("test description"),
- Optional.of("test reference"), "error app-tag", "error message");
- lengthConstraint2 = new LengthConstraintImpl(2, 5, Optional.of("test description"),
- Optional.of("test reference"), "error app-tag", "error message");
- assertFalse(lengthConstraint.equals(lengthConstraint2));
-
- lengthConstraint2 = new LengthConstraintImpl(3, 6, Optional.of("test description"),
- Optional.of("test reference"), "error app-tag", "error message");
- assertFalse(lengthConstraint.equals(lengthConstraint2));
-
- lengthConstraint2 = new LengthConstraintImpl(3, 5, Optional.of("test description"),
- Optional.of("test reference"), "another error app-tag", "error message");
- assertFalse(lengthConstraint.equals(lengthConstraint2));
-
- lengthConstraint2 = new LengthConstraintImpl(3, 5, Optional.of("test description"),
- Optional.of("test reference"), "error app-tag", "another error message");
- assertFalse(lengthConstraint.equals(lengthConstraint2));
- }
-}
@Test
public void testConverterToShort() {
- final short shortNum = 20;
- final Function<Number, Number> numberFunction = NumberUtil.converterTo(Short.class);
+ final Short shortNum = 20;
+ final Function<Number, Short> numberFunction = NumberUtil.converterTo(Short.class);
assertEquals(shortNum, numberFunction.apply(shortNum));
final byte byteNum = 20;
@Test
public void testConverterToInteger() {
- final int intNum = 20;
+ final Integer intNum = 20;
final byte byteNum = 20;
- final Function<Number, Number> numberFunction = NumberUtil.converterTo(Integer.class);
+ final Function<Number, Integer> numberFunction = NumberUtil.converterTo(Integer.class);
assertEquals(intNum, numberFunction.apply(byteNum));
}
@Test
public void testConverterToLong() {
- final long longNum = 20L;
- final Function<Number, Number> numberFunction = NumberUtil.converterTo(Long.class);
+ final Long longNum = 20L;
+ final Function<Number, Long> numberFunction = NumberUtil.converterTo(Long.class);
assertEquals(longNum, numberFunction.apply(longNum));
final byte byteNum = 20;
@Test
public void testConverterToBigDecimal() {
BigDecimal bigDecNum = new BigDecimal(20.0);
- final Function<Number, Number> numberFunction = NumberUtil.converterTo(BigDecimal.class);
+ final Function<Number, BigDecimal> numberFunction = NumberUtil.converterTo(BigDecimal.class);
assertEquals(bigDecNum, numberFunction.apply(bigDecNum));
int intNum = 20;
@Test public void testConverterToBigInteger() {
final BigInteger bigIntNum = new BigInteger("20");
- final Function<Number, Number> numberFunction = NumberUtil.converterTo(BigInteger.class);
+ final Function<Number, BigInteger> numberFunction = NumberUtil.converterTo(BigInteger.class);
assertEquals(bigIntNum, numberFunction.apply(bigIntNum));
final int intNum = 20;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
+import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
+import java.util.List;
import java.util.Optional;
import org.junit.Test;
import org.opendaylight.yangtools.concepts.Builder;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.ConstraintMetaDefinition;
import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.opendaylight.yangtools.yang.model.api.Status;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+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.BinaryTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit;
import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
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.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.api.type.UnsignedIntegerTypeDefinition;
import org.opendaylight.yangtools.yang.model.util.BaseConstraints;
import org.opendaylight.yangtools.yang.model.util.RevisionAwareXPathImpl;
-import org.opendaylight.yangtools.yang.model.util.UnresolvedNumber;
public class TypeTest {
private static final QName Q_NAME = QName.create("test.namespace", "2016-01-01", "test-name");
final BaseBinaryType baseBinaryType1 = BaseBinaryType.INSTANCE;
final BaseBinaryType baseBinaryType2 = (BaseBinaryType)BaseTypes.binaryType();
hashCodeEqualsToStringTest(baseBinaryType1, baseBinaryType2);
- assertEquals(baseBinaryType1.getLengthConstraints(), baseBinaryType2.getLengthConstraints());
+ assertEquals(baseBinaryType1.getLengthConstraint(), baseBinaryType2.getLengthConstraint());
final DerivedBinaryType derivedBinaryType1 = (DerivedBinaryType)DerivedTypes.derivedTypeBuilder(baseBinaryType1,
SCHEMA_PATH).build();
final BaseStringType baseStringType1 = BaseStringType.INSTANCE;
final BaseStringType baseStringType2 = (BaseStringType)BaseTypes.stringType();
hashCodeEqualsToStringTest(baseStringType1, baseStringType2);
- assertEquals(baseStringType1.getLengthConstraints(), baseStringType2.getLengthConstraints());
+ assertEquals(baseStringType1.getLengthConstraint(), baseStringType2.getLengthConstraint());
assertEquals(baseStringType1.getPatternConstraints(), baseStringType2.getPatternConstraints());
final DerivedStringType derivedStringType1 = (DerivedStringType)
}
@Test
- public void constraintTypeBuilderTest() {
+ public void constraintTypeBuilderTest() throws InvalidLengthConstraintException {
final BaseBinaryType baseBinaryType = (BaseBinaryType)BaseTypes.binaryType();
final LengthRestrictedTypeBuilder<?> lengthRestrictedTypeBuilder = RestrictedTypes
.newBinaryBuilder(baseBinaryType, SCHEMA_PATH);
final Long min = Long.valueOf(0);
final UnresolvedNumber max = UnresolvedNumber.max();
- final LengthConstraint lengthConstraint = BaseConstraints.newLengthConstraint(min, max, ABSENT, ABSENT);
- final ArrayList<LengthConstraint> lengthArrayList = new ArrayList<>(1);
- assertEquals(lengthConstraint.getErrorAppTag(), "length-out-of-specified-bounds");
- assertEquals(lengthConstraint.getErrorMessage(), "The argument is out of bounds <0, max>");
- lengthArrayList.add(lengthConstraint);
- lengthRestrictedTypeBuilder.setLengthAlternatives(lengthArrayList);
+ final List<ValueRange> lengthArrayList = ImmutableList.of(ValueRange.of(min, max));
+ lengthRestrictedTypeBuilder.setLengthConstraint(mock(ConstraintMetaDefinition.class), lengthArrayList);
final TypeDefinition<?> typeDefinition = lengthRestrictedTypeBuilder.buildType();
assertNotNull(typeDefinition);
public void exceptionTest() {
final UnresolvedNumber min = UnresolvedNumber.min();
final UnresolvedNumber max = UnresolvedNumber.max();
- final LengthConstraint lengthConstraint = BaseConstraints.newLengthConstraint(min, max, ABSENT, ABSENT);
- final RangeConstraint rangeConstraint = BaseConstraints.newRangeConstraint(min, max, ABSENT, ABSENT);
+ 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 InvalidLengthConstraintException invalidLengthConstraintException = new InvalidLengthConstraintException(
- lengthConstraint, "error msg", "other important messages");
- assertEquals(invalidLengthConstraintException.getOffendingConstraint(), lengthConstraint);
-
final InvalidRangeConstraintException invalidRangeConstraintException = new InvalidRangeConstraintException(
rangeConstraint, "error msg", "other important messages");
assertEquals(invalidRangeConstraintException.getOffendingConstraint(), rangeConstraint);
import org.opendaylight.yangtools.yang.model.api.stmt.ErrorMessageStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.LengthStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceStatement;
-import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
+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.LengthEffectiveStatementImpl;
-public class LengthStatementImpl extends AbstractDeclaredStatement<List<LengthConstraint>> implements LengthStatement {
+public class LengthStatementImpl extends AbstractDeclaredStatement<List<ValueRange>>
+ implements LengthStatement {
private static final SubstatementValidator SUBSTATEMENT_VALIDATOR = SubstatementValidator.builder(YangStmtMapping
.LENGTH)
.addOptional(YangStmtMapping.DESCRIPTION)
.addOptional(YangStmtMapping.REFERENCE)
.build();
- protected LengthStatementImpl(final StmtContext<List<LengthConstraint>, LengthStatement, ?> context) {
+ protected LengthStatementImpl(final StmtContext<List<ValueRange>, LengthStatement, ?> context) {
super(context);
}
- public static class Definition extends AbstractStatementSupport<List<LengthConstraint>, LengthStatement,
- EffectiveStatement<List<LengthConstraint>, LengthStatement>> {
+ public static class Definition extends AbstractStatementSupport<List<ValueRange>, LengthStatement,
+ EffectiveStatement<List<ValueRange>, LengthStatement>> {
public Definition() {
super(YangStmtMapping.LENGTH);
}
@Override
- public List<LengthConstraint> parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
+ public List<ValueRange> parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
return TypeUtils.parseLengthListFromString(ctx, value);
}
@Override
- public LengthStatement createDeclared(final StmtContext<List<LengthConstraint>, LengthStatement, ?> ctx) {
+ public LengthStatement createDeclared(final StmtContext<List<ValueRange>, LengthStatement, ?> ctx) {
return new LengthStatementImpl(ctx);
}
@Override
- public EffectiveStatement<List<LengthConstraint>, LengthStatement> createEffective(
- final StmtContext<List<LengthConstraint>, LengthStatement, EffectiveStatement<List<LengthConstraint>,
+ public EffectiveStatement<List<ValueRange>, LengthStatement> createEffective(
+ final StmtContext<List<ValueRange>, LengthStatement, EffectiveStatement<List<ValueRange>,
LengthStatement>> ctx) {
return new LengthEffectiveStatementImpl(ctx);
}
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.TypeEffectiveStatement;
+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.BitsTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
-import org.opendaylight.yangtools.yang.model.util.UnresolvedNumber;
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.LengthConstraintEffectiveImpl;
import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.RangeConstraintEffectiveImpl;
/**
try {
return new BigInteger(value);
} catch (final NumberFormatException e) {
- throw new SourceException(String.format("Value %s is not a valid integer", value),
- ctx.getStatementSourceReference(), e);
+ throw new SourceException(ctx.getStatementSourceReference(), e, "Value %s is not a valid integer", value);
}
}
return rangeConstraints;
}
- public static List<LengthConstraint> parseLengthListFromString(final StmtContext<?, ?, ?> ctx,
+ public static List<ValueRange> parseLengthListFromString(final StmtContext<?, ?, ?> ctx,
final String lengthArgument) {
- final Optional<String> description = Optional.empty();
- final Optional<String> reference = Optional.empty();
-
- final List<LengthConstraint> lengthConstraints = new ArrayList<>();
+ final List<ValueRange> ranges = new ArrayList<>();
for (final String singleRange : PIPE_SPLITTER.split(lengthArgument)) {
- final Iterator<String> boundaries = TWO_DOTS_SPLITTER.splitToList(singleRange).iterator();
+ final Iterator<String> boundaries = TWO_DOTS_SPLITTER.split(singleRange).iterator();
final Number min = parseIntegerConstraintValue(ctx, boundaries.next());
final Number max;
}
// some of intervals overlapping
- InferenceException.throwIf(lengthConstraints.size() > 1
- && compareNumbers(min, Iterables.getLast(lengthConstraints).getMax()) != 1,
+ InferenceException.throwIf(ranges.size() > 1
+ && compareNumbers(min, Iterables.getLast(ranges).upperBound()) != 1,
ctx.getStatementSourceReference(), "Some of the length ranges in %s are not disjoint",
lengthArgument);
- lengthConstraints.add(new LengthConstraintEffectiveImpl(min, max, description, reference));
+ ranges.add(ValueRange.of(min, max));
}
- return lengthConstraints;
+ return ranges;
}
public static boolean isYangTypeBodyStmtString(final String typeName) {
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.BinaryTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
import org.opendaylight.yangtools.yang.model.util.type.InvalidLengthConstraintException;
import org.opendaylight.yangtools.yang.model.util.type.LengthRestrictedTypeBuilder;
import org.opendaylight.yangtools.yang.model.util.type.RestrictedTypes;
for (EffectiveStatement<?, ?> stmt : effectiveSubstatements()) {
if (stmt instanceof LengthEffectiveStatementImpl) {
- builder.setLengthAlternatives(((LengthEffectiveStatementImpl)stmt).argument());
+ final LengthEffectiveStatementImpl length = (LengthEffectiveStatementImpl)stmt;
+
+ try {
+ builder.setLengthConstraint(length, length.argument());
+ } catch (IllegalStateException e) {
+ throw new SourceException(ctx.getStatementSourceReference(), e,
+ "Multiple length constraints encountered");
+ } catch (InvalidLengthConstraintException e) {
+ throw new SourceException(ctx.getStatementSourceReference(), e, "Invalid length constraint %s",
+ length.argument());
+ }
}
+
if (stmt instanceof UnknownEffectiveStatementImpl) {
builder.addUnknownSchemaNode((UnknownEffectiveStatementImpl)stmt);
}
}
- try {
- typeDefinition = builder.build();
- } catch (InvalidLengthConstraintException e) {
- final LengthConstraint c = e.getOffendingConstraint();
- throw new SourceException(ctx.getStatementSourceReference(), e, "Invalid length constraint: <%s, %s>",
- c.getMin(), c.getMax());
- }
+ typeDefinition = builder.build();
}
@Nonnull
+++ /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.LengthConstraint;
-
-public class LengthConstraintEffectiveImpl implements LengthConstraint {
-
- 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 LengthConstraintEffectiveImpl(final Number min, final Number max, final Optional<String> description,
- final Optional<String> reference) {
- this(min, max, description.orElse(null), reference.orElse(null), "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) {
- 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 : "length-out-of-specified-bounds";
- this.errorMessage = errorMessage != null ? errorMessage : "The argument is out of bounds <" + min + ", " + max
- + ">";
- }
-
- @Override
- public Number getMin() {
- return min;
- }
-
- @Override
- public Number getMax() {
- return max;
- }
-
- @Override
- public String getDescription() {
- return description;
- }
-
- @Override
- public String getErrorAppTag() {
- return errorAppTag;
- }
-
- @Override
- public String getErrorMessage() {
- return errorMessage;
- }
-
- @Override
- public String getReference() {
- return reference;
- }
-
- @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 LengthConstraintEffectiveImpl other = (LengthConstraintEffectiveImpl) obj;
- if (!Objects.equals(description, other.description)) {
- return false;
- }
- if (!Objects.equals(errorAppTag, other.errorAppTag)) {
- return false;
- }
- if (!Objects.equals(errorMessage, other.errorMessage)) {
- 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 LengthConstraintEffectiveImpl.class.getSimpleName()
- + " [min=" + min
- + ", max=" + max
- + ", description=" + description
- + ", errorAppTag=" + errorAppTag
- + ", reference=" + reference
- + ", errorMessage=" + errorMessage
- + "]";
- }
-}
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.model.api.stmt.ValueRange;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
public class LengthEffectiveStatementImpl extends
- AbstractListConstraintEffectiveStatement<LengthConstraint, LengthStatement> {
+ AbstractListConstraintEffectiveStatement<ValueRange, LengthStatement> {
- public LengthEffectiveStatementImpl(final StmtContext<List<LengthConstraint>, LengthStatement, ?> ctx) {
+ public LengthEffectiveStatementImpl(final StmtContext<List<ValueRange>, LengthStatement, ?> ctx) {
super(ctx);
}
@Override
- final LengthConstraint createCustomizedConstraint(final LengthConstraint lengthConstraint) {
- return new LengthConstraintEffectiveImpl(lengthConstraint.getMin(), lengthConstraint.getMax(),
- getDescription(), getReference(), getErrorAppTag(), getErrorMessage());
+ final ValueRange createCustomizedConstraint(final ValueRange lengthConstraint) {
+ return lengthConstraint;
}
}
\ No newline at end of file
import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
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.LengthConstraint;
import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
import org.opendaylight.yangtools.yang.model.util.type.InvalidLengthConstraintException;
for (EffectiveStatement<?, ?> stmt : effectiveSubstatements()) {
if (stmt instanceof LengthEffectiveStatementImpl) {
- builder.setLengthAlternatives(((LengthEffectiveStatementImpl)stmt).argument());
+ final LengthEffectiveStatementImpl length = (LengthEffectiveStatementImpl)stmt;
+
+ try {
+ builder.setLengthConstraint(length, length.argument());
+ } catch (IllegalStateException e) {
+ throw new SourceException(ctx.getStatementSourceReference(), e,
+ "Multiple length constraints encountered");
+ } catch (InvalidLengthConstraintException e) {
+ throw new SourceException(ctx.getStatementSourceReference(), e, "Invalid length constraint %s",
+ length.argument());
+ }
}
if (stmt instanceof PatternEffectiveStatementImpl) {
final PatternConstraint pattern = ((PatternEffectiveStatementImpl)stmt).argument();
}
}
- try {
- typeDefinition = builder.build();
- } catch (InvalidLengthConstraintException e) {
- final LengthConstraint c = e.getOffendingConstraint();
- throw new SourceException(ctx.getStatementSourceReference(), e, "Invalid length constraint: <%s, %s>",
- c.getMin(), c.getMax());
- }
+ typeDefinition = builder.build();
}
@Nonnull
package org.opendaylight.yangtools.yang.stmt;
+import com.google.common.collect.Range;
import java.io.File;
import java.util.List;
import org.junit.Assert;
Assert.assertEquals(unknownSchemaNode.getNodeParameter(), "unknown");
Assert.assertEquals(unknownSchemaNode.getNodeType().getModule().getNamespace().toString(), "urn:simple.extension.typedefs");
- final List<LengthConstraint> lengthConstraints = ((StringTypeDefinition) type).getLengthConstraints();
+ final LengthConstraint lengthConstraint = ((StringTypeDefinition) type).getLengthConstraint().get();
final List<PatternConstraint> patternConstraints = ((StringTypeDefinition) type).getPatternConstraints();
- Assert.assertNotNull(lengthConstraints);
+ Assert.assertNotNull(lengthConstraint);
Assert.assertNotNull(patternConstraints);
- Assert.assertFalse(lengthConstraints.size() == 0);
- Assert.assertFalse(patternConstraints.size() == 0);
+ Assert.assertFalse(lengthConstraint.getAllowedRanges().isEmpty());
+ Assert.assertFalse(patternConstraints.isEmpty());
- final LengthConstraint lengthConstraint = lengthConstraints.get(0);
- Assert.assertEquals(lengthConstraint.getMin(), Integer.valueOf(2));
- Assert.assertEquals(lengthConstraint.getMax(), Integer.valueOf(10));
+ final Range<Integer> span = lengthConstraint.getAllowedRanges().span();
+ Assert.assertEquals(Integer.valueOf(2), span.lowerEndpoint());
+ Assert.assertEquals(Integer.valueOf(10), span.upperEndpoint());
final PatternConstraint patternConstraint = patternConstraints.get(0);
Assert.assertEquals(patternConstraint.getRegularExpression(), "^[0-9a-fA-F]$");
Assert.assertEquals(unknownSchemaNode.getNodeParameter(), "unknown");
Assert.assertEquals(unknownSchemaNode.getNodeType().getModule().getNamespace().toString(), "urn:simple.extension.typedefs");
- final List<LengthConstraint> lengthConstraints = ((StringTypeDefinition) type).getLengthConstraints();
+ final LengthConstraint lengthConstraints = ((StringTypeDefinition) type).getLengthConstraint().get();
final List<PatternConstraint> patternConstraints = ((StringTypeDefinition) type).getPatternConstraints();
Assert.assertNotNull(lengthConstraints);
Assert.assertNotNull(patternConstraints);
- Assert.assertFalse(lengthConstraints.size() == 0);
- Assert.assertFalse(patternConstraints.size() == 0);
+ Assert.assertEquals(1, lengthConstraints.getAllowedRanges().asRanges().size());
+ Assert.assertFalse(patternConstraints.isEmpty());
- final LengthConstraint lengthConstraint = lengthConstraints.get(0);
- Assert.assertEquals(lengthConstraint.getMin(), Integer.valueOf(2));
- Assert.assertEquals(lengthConstraint.getMax(), Integer.valueOf(10));
+ final Range<Integer> lengthConstraint = lengthConstraints.getAllowedRanges().span();
+ Assert.assertEquals(Integer.valueOf(2), lengthConstraint.lowerEndpoint());
+ Assert.assertEquals(Integer.valueOf(10), lengthConstraint.upperEndpoint());
final PatternConstraint patternConstraint = patternConstraints.get(0);
Assert.assertEquals(patternConstraint.getRegularExpression(), "^[0-9a-fA-F]$");
Assert.assertEquals(unknownSchemaNode.getNodeParameter(), "unknown");
Assert.assertEquals(unknownSchemaNode.getNodeType().getModule().getNamespace().toString(), "urn:simple.extension.typedefs");
- final List<LengthConstraint> lengthConstraints = ((StringTypeDefinition) type).getLengthConstraints();
+ final LengthConstraint lengthConstraints =
+ ((StringTypeDefinition) type).getLengthConstraint().get();
final List<PatternConstraint> patternConstraints = ((StringTypeDefinition) type).getPatternConstraints();
Assert.assertNotNull(lengthConstraints);
Assert.assertNotNull(patternConstraints);
- Assert.assertFalse(lengthConstraints.size() == 0);
+ Assert.assertEquals(1, lengthConstraints.getAllowedRanges().asRanges().size());
Assert.assertFalse(patternConstraints.size() == 0);
- final LengthConstraint lengthConstraint = lengthConstraints.get(0);
- Assert.assertEquals(lengthConstraint.getMin(), Integer.valueOf(2));
- Assert.assertEquals(lengthConstraint.getMax(), Integer.valueOf(10));
+ final Range<Integer> lengthConstraint = lengthConstraints.getAllowedRanges().span();
+ Assert.assertEquals(Integer.valueOf(2), lengthConstraint.lowerEndpoint());
+ Assert.assertEquals(Integer.valueOf(10), lengthConstraint.upperEndpoint());
final PatternConstraint patternConstraint = patternConstraints.get(0);
Assert.assertEquals(patternConstraint.getRegularExpression(), "^[0-9a-fA-F]$");
import static org.junit.Assert.assertTrue;
import static org.opendaylight.yangtools.yang.stmt.StmtTestUtils.sourceForResource;
+import com.google.common.collect.Range;
import java.util.List;
-import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Test;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
private static final StatementStreamSource IMPORTED_MODULE = sourceForResource("/type-tests/types.yang");
private static SchemaContext effectiveSchemaContext;
- private static LeafSchemaNode currentLeaf;
private static Module types;
- @Before
- public void setup() throws ReactorException {
+ private LeafSchemaNode currentLeaf;
+
+ @BeforeClass
+ public static void setup() throws ReactorException {
final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
reactor.addSource(IMPORTED_MODULE);
effectiveSchemaContext = reactor.buildEffective();
currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(), "leaf-binary"));
assertNotNull(currentLeaf.getType());
- final BinaryTypeDefinition binaryEff = (BinaryTypeDefinition) ((TypeEffectiveStatement<?>) ((LeafEffectiveStatementImpl) currentLeaf)
+ final BinaryTypeDefinition binaryEff = (BinaryTypeDefinition)
+ ((TypeEffectiveStatement<?>) ((LeafEffectiveStatementImpl) currentLeaf)
.effectiveSubstatements().iterator().next()).getTypeDefinition();
assertNull(binaryEff.getBaseType());
assertNull(binaryEff.getUnits());
assertNull(binaryEff.getDefaultValue());
assertEquals("binary", binaryEff.getQName().getLocalName());
- assertEquals(0, binaryEff.getLengthConstraints().size());
+ assertFalse(binaryEff.getLengthConstraint().isPresent());
assertEquals("CURRENT", binaryEff.getStatus().toString());
assertEquals("binary", binaryEff.getPath().getPathFromRoot().iterator().next().getLocalName());
assertNotNull(binaryEff.getUnknownSchemaNodes());
public void testLengthConstraint() {
currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(),
"leaf-length-pattern"));
- assertNotNull(currentLeaf.getType());
- final LengthConstraint lengthConstraint = ((StringTypeDefinition) currentLeaf.getType())
- .getLengthConstraints().get(0);
- final LengthConstraint lengthConstraintThird = ((StringTypeDefinition) currentLeaf.getType())
- .getLengthConstraints().get(0);
- currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(),
- "leaf-length-pattern-second"));
- assertNotNull(currentLeaf.getType());
- final LengthConstraint lengthConstraintSecond = ((StringTypeDefinition) currentLeaf.getType())
- .getLengthConstraints().get(0);
- assertEquals(1, lengthConstraint.getMin().intValue());
- assertEquals(255, lengthConstraint.getMax().intValue());
+ final StringTypeDefinition leafType = (StringTypeDefinition) currentLeaf.getType();
+ assertNotNull(leafType);
+ final LengthConstraint lengthConstraint = leafType.getLengthConstraint().get();
+
+ final Range<Integer> span = lengthConstraint.getAllowedRanges().span();
+ assertEquals(1, span.lowerEndpoint().intValue());
+ assertEquals(255, span.upperEndpoint().intValue());
assertNull(lengthConstraint.getReference());
assertNull(lengthConstraint.getDescription());
- assertEquals("The argument is out of bounds <1, 255>", lengthConstraint.getErrorMessage());
- assertEquals("length-out-of-specified-bounds", lengthConstraint.getErrorAppTag());
+ assertNull(lengthConstraint.getErrorMessage());
+ assertNull(lengthConstraint.getErrorAppTag());
assertNotNull(lengthConstraint.toString());
assertNotNull(lengthConstraint.hashCode());
assertFalse(lengthConstraint.equals(null));
assertFalse(lengthConstraint.equals("test"));
+
+ currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(),
+ "leaf-length-pattern-second"));
+ assertNotNull(currentLeaf.getType());
+ final LengthConstraint lengthConstraintSecond = ((StringTypeDefinition) currentLeaf.getType())
+ .getLengthConstraint().get();
assertFalse(lengthConstraint.equals(lengthConstraintSecond));
- assertTrue(lengthConstraint.equals(lengthConstraintThird));
}
@Test
assertFalse(stringEff.equals("test"));
assertTrue(stringEff.equals(stringEff));
assertEquals("string", stringEff.getPath().getLastComponent().getLocalName());
- assertEquals(0, stringEff.getLengthConstraints().size());
+ assertFalse(stringEff.getLengthConstraint().isPresent());
assertNotNull(stringEff.getPatternConstraints());
}
}
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.List;
import java.util.Set;
+ "([a-zA-Z0-9_]([a-zA-Z0-9\\-_]){0,61})?[a-zA-Z0-9]\\.?)" + "|\\.$";
assertEquals(expectedPattern, patterns.get(0).getRegularExpression());
- List<LengthConstraint> lengths = type.getLengthConstraints();
- assertEquals(1, lengths.size());
- LengthConstraint length = type.getLengthConstraints().get(0);
- assertEquals(Integer.valueOf(1), length.getMin());
- assertEquals(Integer.valueOf(253), length.getMax());
+ LengthConstraint lengths = type.getLengthConstraint().get();
+ assertEquals(1, lengths.getAllowedRanges().asRanges().size());
+ Range<Integer> length = lengths.getAllowedRanges().span();
+ assertEquals(Integer.valueOf(1), length.lowerEndpoint());
+ assertEquals(Integer.valueOf(253), length.upperEndpoint());
}
@Test
TestUtils.loadModuleResources(getClass(), "/negative-scenario/testfile5.yang");
fail("ReactorException should be thrown");
} catch (final ReactorException e) {
- assertTrue(e.getCause().getMessage().contains("Invalid length constraint: <4, 10>"));
+ final String message = e.getCause().getMessage();
+
+ assertTrue(message.contains("Invalid length constraint [4..10]"));
}
}
import static org.junit.Assert.assertTrue;
import static org.opendaylight.yangtools.yang.stmt.StmtTestUtils.sourceForResource;
+import com.google.common.collect.Range;
+import com.google.common.collect.RangeSet;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
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.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;
assertEquals(1, patterns.size());
PatternConstraint pattern = patterns.iterator().next();
assertEquals("^[e-z]*$", pattern.getRegularExpression());
- assertEquals(1, type.getLengthConstraints().size());
+ assertEquals(1, type.getLengthConstraint().get().getAllowedRanges().asRanges().size());
final StringTypeDefinition baseType1 = type.getBaseType();
final QName baseType1QName = baseType1.getQName();
assertEquals(1, patterns.size());
pattern = patterns.iterator().next();
assertEquals("^[b-u]*$", pattern.getRegularExpression());
- assertEquals(1, baseType1.getLengthConstraints().size());
+ assertEquals(1, baseType1.getLengthConstraint().get().getAllowedRanges().asRanges().size());
final StringTypeDefinition baseType2 = baseType1.getBaseType();
final QName baseType2QName = baseType2.getQName();
assertNull(baseType2.getUnits());
assertNull(baseType2.getDefaultValue());
assertTrue(baseType2.getPatternConstraints().isEmpty());
- final List<LengthConstraint> baseType2Lengths = baseType2.getLengthConstraints();
- assertEquals(1, baseType2Lengths.size());
- LengthConstraint length = baseType2Lengths.get(0);
- assertEquals(6, length.getMin().intValue());
- assertEquals(10, length.getMax().intValue());
+ final RangeSet<Integer> baseType2Lengths = baseType2.getLengthConstraint().get().getAllowedRanges();
+ assertEquals(1, baseType2Lengths.asRanges().size());
+ Range<Integer> length = baseType2Lengths.span();
+ assertEquals(6, length.lowerEndpoint().intValue());
+ assertEquals(10, length.upperEndpoint().intValue());
final StringTypeDefinition baseType3 = baseType2.getBaseType();
assertEquals(QName.create(BAR, "string-ext1"), baseType3.getQName());
assertEquals(1, patterns.size());
pattern = patterns.iterator().next();
assertEquals("^[a-k]*$", pattern.getRegularExpression());
- final List<LengthConstraint> baseType3Lengths = baseType3.getLengthConstraints();
- assertEquals(1, baseType3Lengths.size());
- length = baseType3Lengths.get(0);
- assertEquals(5, length.getMin().intValue());
- assertEquals(11, length.getMax().intValue());
+ final RangeSet<Integer> baseType3Lengths = baseType3.getLengthConstraint().get().getAllowedRanges();
+ assertEquals(1, baseType3Lengths.asRanges().size());
+ length = baseType3Lengths.span();
+ assertEquals(5, length.lowerEndpoint().intValue());
+ assertEquals(11, length.upperEndpoint().intValue());
assertEquals(BaseTypes.stringType(), baseType3.getBaseType());
}
assertEquals(1, patterns.size());
final PatternConstraint pattern = patterns.iterator().next();
assertEquals("^[e-z]*$", pattern.getRegularExpression());
- assertEquals(1, type.getLengthConstraints().size());
+ assertEquals(1, type.getLengthConstraint().get().getAllowedRanges().asRanges().size());
final LeafSchemaNode multiplePatternDirectStringDefLeaf = (LeafSchemaNode) foo
.getDataChildByName(QName.create(foo.getQNameModule(), "multiple-pattern-direct-string-def-leaf"));
@Test
public void testTypedefLengthsResolving() {
- final LeafSchemaNode lengthLeaf = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "length-leaf"));
+ final LeafSchemaNode lengthLeaf = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(),
+ "length-leaf"));
final StringTypeDefinition type = (StringTypeDefinition) lengthLeaf.getType();
assertEquals(QName.create(FOO, "string-ext2"), type.getQName());
assertNull(type.getUnits());
assertNull(type.getDefaultValue());
assertTrue(type.getPatternConstraints().isEmpty());
- final List<LengthConstraint> typeLengths = type.getLengthConstraints();
- assertEquals(1, typeLengths.size());
- LengthConstraint length = typeLengths.get(0);
- assertEquals(7, length.getMin().intValue());
- assertEquals(10, length.getMax().intValue());
+ final RangeSet<Integer> typeLengths = type.getLengthConstraint().get().getAllowedRanges();
+ assertEquals(1, typeLengths.asRanges().size());
+ Range<Integer> length = typeLengths.span();
+ assertEquals(7, length.lowerEndpoint().intValue());
+ assertEquals(10, length.upperEndpoint().intValue());
final StringTypeDefinition baseType1 = type.getBaseType();
assertEquals(QName.create(BAR, "string-ext2"), baseType1.getQName());
assertNull(baseType1.getUnits());
assertNull(baseType1.getDefaultValue());
assertTrue(baseType1.getPatternConstraints().isEmpty());
- final List<LengthConstraint> baseType2Lengths = baseType1.getLengthConstraints();
- assertEquals(1, baseType2Lengths.size());
- length = baseType2Lengths.get(0);
- assertEquals(6, length.getMin().intValue());
- assertEquals(10, length.getMax().intValue());
+ final RangeSet<Integer> baseType2Lengths = baseType1.getLengthConstraint().get().getAllowedRanges();
+ assertEquals(1, baseType2Lengths.asRanges().size());
+ length = baseType2Lengths.span();
+ assertEquals(6, length.lowerEndpoint().intValue());
+ assertEquals(10, length.upperEndpoint().intValue());
final StringTypeDefinition baseType2 = baseType1.getBaseType();
assertEquals(QName.create(BAR, "string-ext1"), baseType2.getQName());
assertEquals(1, patterns.size());
final PatternConstraint pattern = patterns.iterator().next();
assertEquals("^[a-k]*$", pattern.getRegularExpression());
- final List<LengthConstraint> baseType3Lengths = baseType2.getLengthConstraints();
- assertEquals(1, baseType3Lengths.size());
- length = baseType3Lengths.get(0);
- assertEquals(5, length.getMin().intValue());
- assertEquals(11, length.getMax().intValue());
+ final RangeSet<Integer> baseType3Lengths = baseType2.getLengthConstraint().get().getAllowedRanges();
+ assertEquals(1, baseType3Lengths.asRanges().size());
+ length = baseType3Lengths.span();
+ assertEquals(5, length.lowerEndpoint().intValue());
+ assertEquals(11, length.upperEndpoint().intValue());
assertEquals(BaseTypes.stringType(), baseType2.getBaseType());
}
assertTrue(myLeafType instanceof StringTypeDefinition);
assertTrue(myLeaf2Type instanceof IntegerTypeDefinition);
- List<LengthConstraint> lengthConstraints = ((StringTypeDefinition) myLeafType).getLengthConstraints();
- List<PatternConstraint> patternConstraints = ((StringTypeDefinition) myLeafType).getPatternConstraints();
+ final LengthConstraint lengthConstraint =
+ ((StringTypeDefinition) myLeafType).getLengthConstraint().get();
+ final List<PatternConstraint> patternConstraints = ((StringTypeDefinition) myLeafType).getPatternConstraints();
- assertEquals(1, lengthConstraints.size());
+ assertEquals(1, lengthConstraint.getAllowedRanges().asRanges().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());
+ assertEquals("lenght constraint error-app-tag", lengthConstraint.getErrorAppTag());
+ assertEquals("lenght constraint error-app-message", lengthConstraint.getErrorMessage());
PatternConstraint patternConstraint = patternConstraints.iterator().next();
assertEquals("pattern constraint error-app-tag", patternConstraint.getErrorAppTag());