From f27abd088b1cf645824e2b332c58541519822cb3 Mon Sep 17 00:00:00 2001 From: Tony Tkacik Date: Tue, 7 Apr 2015 16:46:38 +0200 Subject: [PATCH] Bug 2362: Added range validation as last part of deserialization. Change-Id: I801aa22f868a13c098686aa077c46a378af8dfe4 Signed-off-by: Tony Tkacik --- .../codec/AbstractIntegerStringCodec.java | 104 +++++++++++++++--- .../data/impl/codec/Int16StringCodec.java | 22 ++-- .../data/impl/codec/Int32StringCodec.java | 20 ++-- .../data/impl/codec/Int64StringCodec.java | 20 ++-- .../yang/data/impl/codec/Int8StringCodec.java | 20 ++-- .../data/impl/codec/Uint16StringCodec.java | 25 +++-- .../data/impl/codec/Uint32StringCodec.java | 21 ++-- .../data/impl/codec/Uint64StringCodec.java | 23 ++-- .../data/impl/codec/Uint8StringCodec.java | 23 ++-- 9 files changed, 195 insertions(+), 83 deletions(-) diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/AbstractIntegerStringCodec.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/AbstractIntegerStringCodec.java index d8e7df867c..79118c3676 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/AbstractIntegerStringCodec.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/AbstractIntegerStringCodec.java @@ -9,9 +9,16 @@ package org.opendaylight.yangtools.yang.data.impl.codec; import com.google.common.base.CharMatcher; import com.google.common.base.Optional; +import com.google.common.collect.Range; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint; +import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition; abstract class AbstractIntegerStringCodec, T extends TypeDefinition> extends TypeDefinitionAwareCodec{ @@ -28,6 +35,86 @@ abstract class AbstractIntegerStringCodec, T ex + "\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> rangeConstraints; + + protected AbstractIntegerStringCodec(final Optional typeDefinition, final List constraints , final Class outputClass) { + super(typeDefinition, outputClass); + if(constraints.isEmpty()) { + rangeConstraints = Collections.emptyList(); + } else { + final ArrayList> builder = new ArrayList<>(constraints.size()); + for(final RangeConstraint yangConstraint : constraints) { + builder.add(createRange(yangConstraint.getMin(),yangConstraint.getMax())); + } + rangeConstraints = builder; + } + + } + + private Range 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); + final N deserialized; + if (base == 16) { + deserialized = deserialize(normalizeHexadecimal(stringRepresentation),base); + } else { + deserialized = deserialize(stringRepresentation,base); + } + validate(deserialized); + return deserialized; + } + + + private final void validate(final N value) { + if (rangeConstraints.isEmpty()) { + return; + } + for (final Range constraint : rangeConstraints) { + if (constraint.contains(value)) { + return; + } + } + // FIXME: Provide better error report. + throw new IllegalArgumentException("Value is not in required range."); + } + + /** + * Deserializes value from supplied string representation + * is supplied radix. + * + * See {@link Integer#parseInt(String, int)} for in-depth + * description about string and radix relationship. + * + * @param stringRepresentation String representation + * @param radix numeric base. + * @return Deserialized value. + */ + protected abstract N deserialize(String stringRepresentation, int radix); + + protected abstract N convertValue(Number value); + + + protected static List extractRange(final IntegerTypeDefinition type) { + if(type == null) { + return Collections.emptyList(); + } + return type.getRangeConstraints(); + } + + protected static List extractRange(final UnsignedIntegerTypeDefinition type) { + if(type == null) { + return Collections.emptyList(); + } + return type.getRangeConstraints(); + } + private static final int provideBase(final String integer) { if (integer == null) { throw new IllegalArgumentException("String representing integer number cannot be NULL"); @@ -62,21 +149,4 @@ abstract class AbstractIntegerStringCodec, T ex return X_MATCHER.removeFrom(hexInt); } - - protected AbstractIntegerStringCodec(final Optional typeDefinition, final Class outputClass) { - super(typeDefinition, outputClass); - - } - - @Override - public final N deserialize(final String stringRepresentation) { - final int base = provideBase(stringRepresentation); - if (base == 16) { - return deserialize(normalizeHexadecimal(stringRepresentation),base); - } - return deserialize(stringRepresentation,base); - } - - protected abstract N deserialize(String stringRepresentation, int base); - } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/Int16StringCodec.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/Int16StringCodec.java index f686cc3816..5a0e90794a 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/Int16StringCodec.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/Int16StringCodec.java @@ -1,9 +1,9 @@ /* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * 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 + * 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.data.impl.codec; @@ -11,13 +11,14 @@ import com.google.common.base.Optional; import org.opendaylight.yangtools.yang.data.api.codec.Int16Codec; import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition; -class Int16StringCodec extends AbstractIntegerStringCodec implements - Int16Codec { +class Int16StringCodec extends AbstractIntegerStringCodec implements Int16Codec { protected Int16StringCodec(final Optional typeDef) { - super(typeDef, Short.class); + super(typeDef, extractRange(typeDef.orNull()), Short.class); } + + @Override public final Short deserialize(final String stringRepresentation, final int base) { return Short.valueOf(stringRepresentation, base); @@ -27,4 +28,9 @@ class Int16StringCodec extends AbstractIntegerStringCodec implements - Int32Codec { +class Int32StringCodec extends AbstractIntegerStringCodec implements Int32Codec { protected Int32StringCodec(final Optional typeDef) { - super(typeDef, Integer.class); + super(typeDef, extractRange(typeDef.orNull()), Integer.class); } @Override @@ -27,4 +26,9 @@ class Int32StringCodec extends AbstractIntegerStringCodec implements - Int64Codec { +class Int64StringCodec extends AbstractIntegerStringCodec implements Int64Codec { protected Int64StringCodec(final Optional typeDef) { - super(typeDef, Long.class); + super(typeDef, extractRange(typeDef.orNull()), Long.class); } @Override @@ -27,4 +26,9 @@ class Int64StringCodec extends AbstractIntegerStringCodec implements - Int8Codec { +class Int8StringCodec extends AbstractIntegerStringCodec implements Int8Codec { protected Int8StringCodec(final Optional typeDef) { - super(typeDef, Byte.class); + super(typeDef, extractRange(typeDef.orNull()), Byte.class); } @Override @@ -27,4 +26,9 @@ class Int8StringCodec extends AbstractIntegerStringCodec - implements Uint16Codec { +class Uint16StringCodec extends AbstractIntegerStringCodec implements + Uint16Codec { protected Uint16StringCodec(final Optional typeDef) { - super(typeDef, Integer.class); + super(typeDef, extractRange(typeDef.orNull()), Integer.class); } @Override - public Integer deserialize(final String stringRepresentation, final int base) { + public final Integer deserialize(final String stringRepresentation, final int base) { return Integer.valueOf(stringRepresentation, base); } @Override - public String serialize(final Integer data) { + public final String serialize(final Integer data) { return data == null ? "" : data.toString(); } -} \ No newline at end of file + + @Override + protected Integer convertValue(final Number value) { + return value.intValue(); + } +} diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/Uint32StringCodec.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/Uint32StringCodec.java index f16d25e668..ba305db528 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/Uint32StringCodec.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/Uint32StringCodec.java @@ -1,9 +1,9 @@ /* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * 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 + * 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.data.impl.codec; @@ -11,11 +11,11 @@ import com.google.common.base.Optional; import org.opendaylight.yangtools.yang.data.api.codec.Uint32Codec; import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition; -class Uint32StringCodec extends AbstractIntegerStringCodec - implements Uint32Codec { +class Uint32StringCodec extends AbstractIntegerStringCodec implements + Uint32Codec { protected Uint32StringCodec(final Optional typeDef) { - super(typeDef, Long.class); + super(typeDef, extractRange(typeDef.orNull()), Long.class); } @Override @@ -27,4 +27,9 @@ class Uint32StringCodec extends AbstractIntegerStringCodec implements Uint64Codec { +class Uint64StringCodec extends AbstractIntegerStringCodec implements + Uint64Codec { protected Uint64StringCodec(final Optional typeDef) { - super(typeDef, BigInteger.class); + super(typeDef, extractRange(typeDef.orNull()), BigInteger.class); } @Override @@ -27,4 +28,12 @@ class Uint64StringCodec extends AbstractIntegerStringCodec - implements Uint8Codec { +class Uint8StringCodec extends AbstractIntegerStringCodec implements + Uint8Codec { protected Uint8StringCodec(final Optional typeDef) { - super(typeDef, Short.class); + super(typeDef, extractRange(typeDef.orNull()), Short.class); } @Override @@ -24,7 +24,12 @@ class Uint8StringCodec extends AbstractIntegerStringCodec