Skip to content

Commit

Permalink
+ValueType, MetaInfo improvement
Browse files Browse the repository at this point in the history
  • Loading branch information
hohwille committed Jan 2, 2024
1 parent 3793f13 commit b801fbf
Show file tree
Hide file tree
Showing 6 changed files with 410 additions and 90 deletions.
119 changes: 119 additions & 0 deletions core/src/main/java/io/github/mmm/base/lang/ValueType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/* Copyright (c) The m-m-m Team, Licensed under the Apache License, Version 2.0
* http://www.apache.org/licenses/LICENSE-2.0 */
package io.github.mmm.base.lang;

import java.util.Objects;

import io.github.mmm.base.number.NumberType;

/**
* Interface for generic support of a {@link #getType() value type}. It does not represent a value itself but only its
* type with ability to {@link #format(Object) format} and {@link #parse(String) parse} values of the represented type.
*
* @param <V> the {@link #getType() type type}.
* @since 1.0.0
* @see io.github.mmm.base.number.NumberType
* @see io.github.mmm.base.temporal.TemporalType
*/
public abstract class ValueType<V> {

/** {@link ValueType} for {@link String}. */
public static final ValueType<String> STRING = new ValueType<>(String.class, null) {
@Override
public String parse(String value) {

return value;
}
};

/** {@link ValueType} for {@link String}. */
public static final ValueType<Boolean> BOOLEAN = new ValueType<>(Boolean.class, boolean.class) {
@Override
public Boolean parse(String value) {

if (value == null) {
return null;
}
if ("true".equals(value)) {
return Boolean.TRUE;
} else if ("false".equals(value)) {
return Boolean.FALSE;
}
throw new IllegalArgumentException(value);
}
};

/** @see #getType() */
protected final Class<V> type;

/** @see #getType() */
protected final Class<V> primitiveType;

/**
* The constructor.
*
* @param type the {@link #getType() value type}.
*/
public ValueType(Class<V> type) {

this(type, null);
}

/**
* The constructor.
*
* @param type the {@link #getType() value type}.
* @param primitiveType the {@link #getPrimitiveType() primitive type}.
*/
public ValueType(Class<V> type, Class<V> primitiveType) {

super();
Objects.requireNonNull(type);
this.type = type;
this.primitiveType = primitiveType;
}

/**
* @return the {@link Class} reflecting the {@link Number} represented by this {@link NumberType}.
*/
public Class<V> getType() {

return this.type;
}

/**
* @return the primitive type corresponding to the {@link #getType() value type} or {@code null} if not available.
*/
public Class<V> getPrimitiveType() {

return this.primitiveType;
}

/**
* @param value the value as {@link String}.
* @return the parsed value as its {@link #getType() value type}.
*/
public abstract V parse(String value);

/**
* @param value the value to format.
* @return the {@link Object#toString() string representation} of the given {@code value}.
*/
public String format(V value) {

if (value == null) {
return null;
}
return value.toString();
}

@Override
public String toString() {

String name = this.type.getName();
if (name.startsWith("java.")) {
return this.type.getSimpleName();
}
return name;
}
}
80 changes: 38 additions & 42 deletions core/src/main/java/io/github/mmm/base/number/NumberType.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,23 @@
import java.math.BigDecimal;
import java.math.BigInteger;

import io.github.mmm.base.lang.ValueType;

/**
* A {@link NumberType} represents a specific {@link Number} {@link Class}. It allows to check attributes like
* {@link #isDecimal()} or {@link #getExactness()}. <br>
* Further it acts as factory to create according numbers {@link #valueOf(String) from string} or
* {@link #valueOf(Number) from number}. <br>
* Further it acts as factory to create according numbers {@link #parse(String) from string} or {@link #valueOf(Number)
* from number}. <br>
* This is a class and NOT an {@link Enum} to be extensible.
*
* @param <N> type of the {@link #getType() represented number-class}.
*
* @since 1.0.0
*/
public abstract class NumberType<N extends Number> {
public abstract class NumberType<N extends Number> extends ValueType<N> {

/** The {@link NumberType} for {@link Byte}. */
public static final NumberType<Byte> BYTE = new NumberType<>(Byte.class, 1, Byte.valueOf(Byte.MIN_VALUE),
public static final NumberType<Byte> BYTE = new NumberType<>(Byte.class, byte.class, 1, Byte.valueOf(Byte.MIN_VALUE),
Byte.valueOf(Byte.MAX_VALUE)) {

@Override
Expand All @@ -35,16 +37,16 @@ protected Byte convert(Number number, boolean exact) {
}

@Override
public Byte valueOf(String number, int radix) {
public Byte parse(String number, int radix) {

return Byte.valueOf(number, radix);
}

};

/** The {@link NumberType} for {@link Short}. */
public static final NumberType<Short> SHORT = new NumberType<>(Short.class, 2, Short.valueOf(Short.MIN_VALUE),
Short.valueOf(Short.MAX_VALUE)) {
public static final NumberType<Short> SHORT = new NumberType<>(Short.class, short.class, 2,
Short.valueOf(Short.MIN_VALUE), Short.valueOf(Short.MAX_VALUE)) {

@Override
protected Short convert(Number number, boolean exact) {
Expand All @@ -59,15 +61,15 @@ protected Short convert(Number number, boolean exact) {
}

@Override
public Short valueOf(String number, int radix) {
public Short parse(String number, int radix) {

return Short.valueOf(number, radix);
}

};

/** The {@link NumberType} for {@link Integer}. */
public static final NumberType<Integer> INTEGER = new NumberType<>(Integer.class, 3,
public static final NumberType<Integer> INTEGER = new NumberType<>(Integer.class, int.class, 3,
Integer.valueOf(Integer.MIN_VALUE), Integer.valueOf(Integer.MAX_VALUE)) {

@Override
Expand All @@ -83,15 +85,15 @@ protected Integer convert(Number number, boolean exact) {
}

@Override
public Integer valueOf(String number, int radix) {
public Integer parse(String number, int radix) {

return Integer.valueOf(number, radix);
}

};

/** The {@link NumberType} for {@link Long}. */
public static final NumberType<Long> LONG = new NumberType<>(Long.class, 4, Long.valueOf(Long.MIN_VALUE),
public static final NumberType<Long> LONG = new NumberType<>(Long.class, long.class, 4, Long.valueOf(Long.MIN_VALUE),
Long.valueOf(Long.MAX_VALUE)) {

@Override
Expand All @@ -107,7 +109,7 @@ protected Long convert(Number number, boolean exact) {
}

@Override
public Long valueOf(String number, int radix) {
public Long parse(String number, int radix) {

return Long.valueOf(number, radix);
}
Expand All @@ -123,9 +125,9 @@ public String format(Long number, int radix) {
};

/** The {@link NumberType} for {@link Float}. */
public static final NumberType<Float> FLOAT = new NumberType<>(Float.class, 5, Float.valueOf(-Float.MAX_VALUE),
Float.valueOf(Float.MAX_VALUE), Float.valueOf(Float.NaN), Float.valueOf(Float.POSITIVE_INFINITY),
Float.valueOf(Float.NEGATIVE_INFINITY)) {
public static final NumberType<Float> FLOAT = new NumberType<>(Float.class, float.class, 5,
Float.valueOf(-Float.MAX_VALUE), Float.valueOf(Float.MAX_VALUE), Float.valueOf(Float.NaN),
Float.valueOf(Float.POSITIVE_INFINITY), Float.valueOf(Float.NEGATIVE_INFINITY)) {

@Override
protected Float convert(Number number, boolean exact) {
Expand All @@ -140,7 +142,7 @@ protected Float convert(Number number, boolean exact) {
}

@Override
public Float valueOf(String number, int radix) {
public Float parse(String number, int radix) {

if (radix == 16) {
number = "0x" + number;
Expand All @@ -167,9 +169,9 @@ public String format(Float number, int radix) {
};

/** The {@link NumberType} for {@link Double}. */
public static final NumberType<Double> DOUBLE = new NumberType<>(Double.class, 6, Double.valueOf(-Double.MAX_VALUE),
Double.valueOf(Double.MAX_VALUE), Double.valueOf(Double.NaN), Double.valueOf(Double.POSITIVE_INFINITY),
Double.valueOf(Double.NEGATIVE_INFINITY)) {
public static final NumberType<Double> DOUBLE = new NumberType<>(Double.class, double.class, 6,
Double.valueOf(-Double.MAX_VALUE), Double.valueOf(Double.MAX_VALUE), Double.valueOf(Double.NaN),
Double.valueOf(Double.POSITIVE_INFINITY), Double.valueOf(Double.NEGATIVE_INFINITY)) {

@Override
protected Double convert(Number number, boolean exact) {
Expand Down Expand Up @@ -201,7 +203,7 @@ protected Double convert(Number number, boolean exact) {
}

@Override
public Double valueOf(String number, int radix) {
public Double parse(String number, int radix) {

if (radix == 16) {
number = "0x" + number;
Expand All @@ -228,7 +230,7 @@ public String format(Double number, int radix) {
};

/** The {@link NumberType} for {@link BigInteger}. */
public static final NumberType<BigInteger> BIG_INTEGER = new NumberType<>(BigInteger.class, 7, null, null) {
public static final NumberType<BigInteger> BIG_INTEGER = new NumberType<>(BigInteger.class, null, 7, null, null) {

@Override
protected BigInteger convert(Number number, boolean exact) {
Expand All @@ -244,7 +246,7 @@ protected BigInteger convert(Number number, boolean exact) {
}

@Override
public BigInteger valueOf(String number, int radix) {
public BigInteger parse(String number, int radix) {

return new BigInteger(number, radix);
}
Expand Down Expand Up @@ -280,7 +282,7 @@ public String format(BigInteger number, int radix) {
};

/** The {@link NumberType} for {@link BigDecimal}. */
public static final NumberType<BigDecimal> BIG_DECIMAL = new NumberType<>(BigDecimal.class, 8, null, null) {
public static final NumberType<BigDecimal> BIG_DECIMAL = new NumberType<>(BigDecimal.class, null, 8, null, null) {

@Override
protected BigDecimal convert(Number number, boolean exact) {
Expand All @@ -289,7 +291,7 @@ protected BigDecimal convert(Number number, boolean exact) {
}

@Override
public BigDecimal valueOf(String number, int radix) {
public BigDecimal parse(String number, int radix) {

if (radix != 10) {
throw illegalRadixException(radix);
Expand Down Expand Up @@ -332,8 +334,6 @@ public String format(BigDecimal number, int radix) {
private static final NumberType<?>[] TYPES = { null, BYTE, SHORT, INTEGER, LONG, FLOAT, DOUBLE, BIG_INTEGER,
BIG_DECIMAL };

private final Class<N> type;

final int exactness;

private final N min;
Expand All @@ -354,30 +354,32 @@ public String format(BigDecimal number, int radix) {
* The constructor.
*
* @param type the {@link #getType() type}.
* @param primitiveType the {@link #getPrimitiveType() primitive type}.
* @param exactness the {@link #getExactness() exactness}.
* @param min the {@link #getMin() minimum value}.
* @param max the {@link #getMax() maximum value}.
*/
protected NumberType(Class<N> type, int exactness, N min, N max) {
protected NumberType(Class<N> type, Class<N> primitiveType, int exactness, N min, N max) {

this(type, exactness, min, max, null, null, null);
this(type, primitiveType, exactness, min, max, null, null, null);
}

/**
* The constructor.
*
* @param type the {@link #getType() type}.
* @param primitiveType the {@link #getPrimitiveType() primitive type}.
* @param exactness the {@link #getExactness() exactness}.
* @param min the {@link #getMin() minimum value}.
* @param max the {@link #getMax() maximum value}.
* @param nan the {@link #getNaN() not-a-number value}.
* @param positiveInfinity the {@link #getPositiveInfinity() positive infinity value}.
* @param negativeInfinity the {@link #getNegativeInfinity() negative infinity value}.
*/
protected NumberType(Class<N> type, int exactness, N min, N max, N nan, N positiveInfinity, N negativeInfinity) {
protected NumberType(Class<N> type, Class<N> primitiveType, int exactness, N min, N max, N nan, N positiveInfinity,
N negativeInfinity) {

super();
this.type = type;
super(type, primitiveType);
this.exactness = exactness;
this.min = min;
this.max = max;
Expand All @@ -388,14 +390,6 @@ protected NumberType(Class<N> type, int exactness, N min, N max, N nan, N positi
this.negativeInfinity = negativeInfinity;
}

/**
* @return the {@link Class} reflecting the {@link Number} represented by this {@link NumberType}.
*/
public Class<N> getType() {

return this.type;
}

/**
* @param number is the number to convert.
* @param exact {@code true} if {@code null} shall be returned in case the conversion looses precision, {@code false}
Expand Down Expand Up @@ -492,9 +486,10 @@ public N valueOf(Number number, boolean exact) {
* @return the parsed number of the according {@link #getType() type}.
* @throws NumberFormatException if the given {@link String} has an invalid format for this {@link #getType() type}.
*/
public N valueOf(String number) throws NumberFormatException {
@Override
public N parse(String number) throws NumberFormatException {

return valueOf(number, 10);
return parse(number, 10);
}

/**
Expand All @@ -505,7 +500,7 @@ public N valueOf(String number) throws NumberFormatException {
* @throws IllegalArgumentException if the given {@code radix} is not supported. The radix {@code 10} is always
* supported, and {@code 16} is supported for types other than {@link #BIG_DECIMAL}.
*/
public abstract N valueOf(String number, int radix) throws NumberFormatException;
public abstract N parse(String number, int radix) throws NumberFormatException;

/**
* @param number the {@link Number} to format a {@link String}.
Expand All @@ -523,6 +518,7 @@ public String format(N number, int radix) throws IllegalArgumentException {
if (number == null) {
return null;
}
// overridden for Long, BigInteger and decimal types
return Integer.toString(number.intValue(), radix);
}

Expand Down
Loading

0 comments on commit b801fbf

Please sign in to comment.