All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tfw.value.ClassValueConstraint Maven / Gradle / Ivy

package tfw.value;

import java.util.HashMap;
import java.util.Map;
import tfw.check.Argument;
import tfw.immutable.ila.objectila.ObjectIla;

/**
 * The base class for a constraint where the value must be of a specifid type.
 * If a value is assignable to the class type of the
 * ClassValueConstraint then it is valid, otherwise it is
 * not valid.
 */
public class ClassValueConstraint extends ValueConstraint {
    /** A value constraint which allows any object. */
    public static final ClassValueConstraint OBJECT = new ClassValueConstraint(Object.class);

    /** A value constraint which allows an {@link ObjectIla} value. */
    public static final ClassValueConstraint OBJECTILA = new ClassValueConstraint(ObjectIla.class);

    /** A String value constraint which allows any string. */
    public static final ClassValueConstraint STRING = new ClassValueConstraint(String.class);

    /** A Boolean value constraint. */
    public static final ClassValueConstraint BOOLEAN = new ClassValueConstraint(Boolean.class);

    /** An Integer value constraint that allows any integer value. */
    public static final ClassValueConstraint INTEGER = new ClassValueConstraint(Integer.class);

    /** An Float value constraint that allows any float value. */
    public static final ClassValueConstraint FLOAT = new ClassValueConstraint(Float.class);

    /** An Double value constraint that allows any double value. */
    public static final ClassValueConstraint DOUBLE = new ClassValueConstraint(Double.class);

    /** A Long value constraint that allows any long value. */
    public static final ClassValueConstraint LONG = new ClassValueConstraint(Long.class);

    /** An Character value constraint that allows any character value. */
    public static final ClassValueConstraint CHARACTER = new ClassValueConstraint(Character.class);

    /** An Short value constraint that allows any short value. */
    public static final ClassValueConstraint SHORT = new ClassValueConstraint(Short.class);

    /** An Byte value constraint that allows any short value. */
    public static final ClassValueConstraint BYTE = new ClassValueConstraint(Byte.class);

    /** The string used to represent a value which complies with the constraint. */
    public static final String VALID = "Valid";

    private static final Map, ClassValueConstraint> constraints = getInitialConstraints();

    /** The class of the value. */
    protected final Class valueType;

    /**
     * Constructs a constraint
     * @param valueType the type for this constraint.
     */
    protected ClassValueConstraint(Class valueType) {
        Argument.assertNotNull(valueType, "valueType");
        this.valueType = valueType;
    }

    private static Map, ClassValueConstraint> getInitialConstraints() {
        HashMap, ClassValueConstraint> map = new HashMap, ClassValueConstraint>();

        map.put(BOOLEAN.valueType, BOOLEAN);
        map.put(OBJECT.valueType, OBJECT);
        map.put(STRING.valueType, STRING);

        return map;
    }

    /**
     * Returns an instance of a value constraint based on the specified class.
     * @param valueType the class for the value constraint.
     * @return an instance of a value constraint based on the specified class.
     */
    public static ClassValueConstraint getInstance(Class valueType) {
        ClassValueConstraint constraint = constraints.get(valueType);

        if (constraint == null) {
            constraint = new ClassValueConstraint(valueType);
            constraints.put(valueType, constraint);
        }

        return constraint;
    }

    /**
     * Returns true if the specified value complies with the
     * constraint, otherwise returns false.
     *
     * @param value the value to be checked.
     * @return true if the specified value complies with the
     * constraint, otherwise returns false.
     */
    public boolean isValid(Object value) {
        String valueCompliance = getValueCompliance(value);

        if (valueCompliance != VALID) {
            return false;
        }

        return true;
    }

    /**
     * Returns {@link #VALID} if the value complies with the constraint,
     * otherwise it returns a string indicating why the value does not comply.
     *
     * @param value The value to be evaluated.
     * @return {@link #VALID} if the value complies with the constraint,
     * otherwise it returns a string indicating why the value does not comply.
     */
    public String getValueCompliance(Object value) {
        if (valueType.isInstance(value)) {
            return VALID;
        }

        if (value == null) {
            return "value == null does not meet the constraints on this value";
        }

        StringBuffer sb = new StringBuffer();
        sb.append("The value, of type '");
        sb.append(value.getClass().getName());
        sb.append("', is not assignable to type '");
        sb.append(valueType.getName());
        sb.append("'.");

        return sb.toString();
    }

    /**
     * Returns true if every value which meets the specified constraint
     * also meets this constraint, otherwise returns false. Note that the
     * reverse is not necessarily true.
     *
     * @param constraint the constraint to be checked.
     *
     * @return true if every value which meets the specified constraint
     * also meets this constraint, otherwise returns false.
     */
    public boolean isCompatible(ValueConstraint constraint) {
        if (constraint instanceof ClassValueConstraint) {
            return valueType.equals(((ClassValueConstraint) constraint).valueType);
        }

        return false;
    }

    /**
     * Returns a string representation of this constraint.
     * @return a string representation of this constraint.
     */
    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append("ValueConstraint[");
        sb.append("type = ").append(valueType.getName());
        sb.append("]");

        return sb.toString();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy