/**
 *
 * Copyright (c) 2006-2017, Speedment, Inc. All Rights Reserved.
 *
 * 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 com.speedment.runtime.typemapper;


import com.speedment.runtime.config.Column;
import com.speedment.runtime.typemapper.internal.IdentityTypeMapper;
import com.speedment.runtime.typemapper.primitive.PrimitiveTypeMapper;

import java.lang.reflect.Type;
import java.util.Comparator;

import static java.util.Comparator.comparing;

/**
 * A type mapper contains logic for converting between the database and the java
 * type for a field. Implementations of this class should be installed in the
 * {@code TypeMapperComponent}.
 *
 * @param <DB_TYPE>   the type as it is represented in the JDBC driver
 * @param <JAVA_TYPE> the type as it should be represented in generated code
 *
 * @author  Emil Forslund
 * @since   2.2.0
 */

public interface TypeMapper<DB_TYPE, JAVA_TYPE> {

    /**
     * The standard comparator to use for instances of the {@link TypeMapper}
     * interface. This comparator will use the name of the database type as
     * comparison index and if two mappers share the same database type, it will
     * use the label in alphabetical order.
     */
    Comparator<TypeMapper<?, ?>> COMPARATOR = comparing(TypeMapper::getLabel);

    /**
     * Returns the label for this mapper that should appear to the end user.
     *
     * @return  the label
     */
    String getLabel();

    /**
     * Returns a type describing the resulting java type when this mapper is
     * applied to a database result.
     * 
     * @param column    the column that is being mapped
     * @return          the resulting java type
     */
    Type getJavaType(Column column);
    
    /**
     * Converts a value from the database domain to the java domain.
     *
     * @param column      the column that is being mapped
     * @param entityType  the entity type that the mapping is for
     * @param value       the value to convert
     * @return            the converted value
     */
    JAVA_TYPE toJavaType(Column column, Class<?> entityType, DB_TYPE value);

    /**
     * Converts a value from the java domain to the database domain.
     *
     * @param value  the value to convert
     * @return       the converted value
     */
    DB_TYPE toDatabaseType(JAVA_TYPE value);

    /**
     * Returns an identity type mapper.
     *
     * @param <T>  the type of the identity type mapper
     * @return     an identity type mapper
     */
    static <T> TypeMapper<T, T> identity() {
        return new IdentityTypeMapper<>();
    }
    
    /**
     * Returns an primitive type mapper.
     *
     * @param <T>  the wrapper type of the primitive type mapper
     * @return     an primitive type mapper
     */
    static <T> TypeMapper<T, T> primitive() {
        return new PrimitiveTypeMapper<>();
    }
}
@@ -1358,17 +1358,16 @@
 2.0%0A */%0A
-%0A
 public i
@@ -1409,16 +1409,362 @@
 YPE%3E %7B%0A%0A
+    /**%0A     * Which category the %7B@link #getJavaType(Column)%7D result belong to.%0A     *%0A     * @author Emil Forslund%0A     * @since  3.0.10%0A     */%0A    enum Category %7B%0A        BYTE,%0A        SHORT,%0A        INT,%0A        LONG,%0A        DOUBLE,%0A        FLOAT,%0A        BOOLEAN,%0A        CHAR,%0A        REFERENCE,%0A        COMPARABLE,%0A        STRING%0A    %7D%0A%0A
     /**%0A
@@ -2518,24 +2518,24 @@
 ype%0A     */%0A
-
     Type get
@@ -2558,16 +2558,1226 @@
 column);
+%0A%0A    /**%0A     * Returns the %7B@link Category%7D of the type returned by%0A     * %7B@link #getJavaType(Column)%7D.%0A     *%0A     * @param column  the column%0A     * @return        the category%0A     */%0A    default Category getJavaTypeCategory(Column column) %7B%0A        final Type type       = getJavaType(column);%0A        final String typeName = getJavaType(column).getTypeName();%0A%0A        switch (typeName) %7B%0A            case %22byte%22    : return Category.BYTE;%0A            case %22short%22   : return Category.SHORT;%0A            case %22int%22     : return Category.INT;%0A            case %22long%22    : return Category.LONG;%0A            case %22double%22  : return Category.DOUBLE;%0A            case %22float%22   : return Category.FLOAT;%0A            case %22boolean%22 : return Category.BOOLEAN;%0A            case %22char%22    : return Category.CHAR;%0A            case %22java.lang.String%22 : return Category.STRING;%0A            default : %7B%0A                if (type instanceof Class%3C?%3E) %7B%0A                    return Comparable.class.isAssignableFrom((Class%3C?%3E) type)%0A                        ? Category.COMPARABLE : Category.REFERENCE;%0A                %7D else %7B%0A                    return Category.REFERENCE;%0A                %7D%0A            %7D%0A        %7D%0A    %7D
 %0A    %0A  

Fix #451 Add enum and method for determining category of TypeMapper