net.revelc.code.blazon.Type.java Source code

Java tutorial

Introduction

Here is the source code for net.revelc.code.blazon.Type.java

Source

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.revelc.code.blazon;

import com.google.common.base.Optional;

/**
 * It provides a mechanism to validate a configuration property, either before or after conversion
 * (or both). A successful conversion will go through {@link #checkPreconditions(Optional)}, then
 * {@link #convert(String)}, then {@link #checkPostconditions(Object)}. See {@link #parse(String)}.
 * Subclasses may choose to throw a specific {@link RuntimeException} like
 * {@link IllegalArgumentException} or {@link NumberFormatException}, in case of error, or they may
 * wish to log the error and return {@link Optional#absent()} in any of the methods to signal that a
 * default should be used.
 *
 * @param <T> the target Java type which this class represents
 */
public abstract class Type<T> {

    /**
     * Optional. Validate and normalize the raw string input. Override this method to enforce any
     * preconditions for conversion, such as to require that it be present. One could also apply any
     * locale-based, or case-conversion, or other normalization here. When the preconditions are not
     * satisfied, this method may throw an appropriate {@link RuntimeException} or return
     * {@link Optional#absent()} to signal that a default value should be used.
     *
     * @param raw an {@link Optional} which is either absent or contains the raw string to be checked
     * @return a non-null instance of {@link Optional}, either containing a normalized form of the raw
     *         input after validation, or absent, to signal that a default should be used in its place
     */
    protected Optional<String> checkPreconditions(final Optional<String> raw) {
        return raw;
    }

    /**
     * Convert the value to the appropriate type. If the raw string cannot be converted to the
     * expected type, this method may throw an appropriate {@link RuntimeException} or return
     * {@link Optional#absent()} to signal that a default value should be used.
     *
     * @param normalized the non-null normalized value to be converted
     * @return a non-null instance of {@link Optional}, either containing the converted value, or
     *         absent, to signal that a default should be used in its place
     */
    protected abstract Optional<T> convert(final String normalized);

    /**
     * Optional. Apply any constraints on the converted value. If the postconditions are not
     * satisfied, this method may throw an appropriate {@link RuntimeException} or return
     * {@link Optional#absent()} to signal that a default value should be used.
     *
     * @param converted the non-null converted value to be checked
     * @return a non-null instance of {@link Optional}, either containing the converted value which
     *         was passed in, or absent, to signal that a default should be used in its place
     */
    protected Optional<T> checkPostconditions(final T converted) {
        return Optional.of(converted);
    }

    /**
     * Parses the raw value by first applying {@link #checkPreconditions(Optional)}, then
     * {@link #convert(String)}, then {@link #checkPostconditions(Object)}.
     *
     * @param raw the raw value to be converted
     * @return the value, after validation, conversion, and applying any post-conversion constraints
     */
    public final T parse(final String raw) {
        final Optional<String> normalized = checkPreconditions(Optional.fromNullable(raw));
        if (!normalized.isPresent()) {
            return null;
        }
        final Optional<T> converted = convert(normalized.get());
        if (!converted.isPresent()) {
            return null;
        }
        final Optional<T> verified = checkPostconditions(converted.get());
        return verified.orNull();
    }

    /**
     * Provides a description of this type, which can be useful for documentation or generated error
     * messages.
     *
     * @return a description of this instance
     */
    public abstract String description();

}