/**
 *
 * Copyright (c) 2006-2018, 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.generator.translator.component;

import com.speedment.common.injector.annotation.InjectKey;
import com.speedment.runtime.config.trait.HasTypeMapper;
import com.speedment.runtime.typemapper.TypeMapper;

import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.Stream;

/**
 * Stores the currently installed {@link TypeMapper TypeMappers}.
 * 
 * @author  Emil Forslund
 * @since   2.2.0
 */
@InjectKey(TypeMapperComponent.class)
public interface TypeMapperComponent {
    
    /**
     * Installs the specified type mapper in this component.
     * 
     * @param databaseType        the type to install it for
     * @param typeMapperSupplier  the constructor for a mapper to install
     */
    void install(Class<?> databaseType, Supplier<TypeMapper<?, ?>> typeMapperSupplier);
    
    /**
     * Streams over all the type mappers installed in this component.
     * 
     * @param databaseType  the type to get mappers for
     * @return              all mappers
     */
    Stream<TypeMapper<?, ?>> mapFrom(Class<?> databaseType);
    
    /**
     * Streams over all the installed type mappers.
     * 
     * @return  stream of type mappers 
     */
    Stream<TypeMapper<?, ?>> stream();
    
    /**
     * Retrieve and return the type mapper with the specified absolute class
     * name. If it is not installed, return an empty optional.
     * 
     * @param absoluteClassName  the name as returned by {@code Class.getName()}
     * @return                   the type mapper or empty
     */
    Optional<TypeMapper<?, ?>> get(String absoluteClassName);
    
    /**
     * Returns the mapper class that will be used to generate a java
     * representation of the database types. If no type mapper is
     * specified, then an {@code IdentityTypeMapper} will be created
     * and returned.
     *
     * @param column  the column to retrieve the type mapper for
     * @return        the mapper class
     */
    TypeMapper<?, ?> get(HasTypeMapper column);
    
    /**
     * Locates the specified type mapper in the store and returns the database
     * type that it is been installed for. If the same {@code TypeMapper} has
     * been installed for multiple classes, the returned class is unspecified
     * but will be one of the installed types.
     * <p>
     * If the specified type mapper has not been installed in this component,
     * an empty optional is returned.
     * <p>
     * Warning! This is potentially a very expensive operation.
     * 
     * @param <DB_TYPE>    the database type
     * @param <JAVA_TYPE>  the java type
     * @param typeMapper   the type mapper to locate
     * @return             a database type for which the mapper is used
     */
    <DB_TYPE, JAVA_TYPE> Optional<Class<DB_TYPE>> findDatabaseTypeOf(TypeMapper<DB_TYPE, JAVA_TYPE> typeMapper);
}
@@ -738,16 +738,60 @@
 ectKey;%0A
+import com.speedment.runtime.config.Column;%0A
 import c
@@ -835,24 +835,24 @@
 TypeMapper;%0A
-
 import com.s
@@ -892,16 +892,47 @@
 apper;%0A%0A
+import java.lang.reflect.Type;%0A
 import j
@@ -1179,16 +1179,16 @@
 .class)%0A
-
 public i
@@ -1217,16 +1217,543 @@
 ponent %7B
+%0A%0A    /**%0A     * Returns the database type of the specified column.%0A     *%0A     * @param column  the column%0A     * @return        the database type%0A     */%0A    default Type typeOf(Column column) %7B%0A        return get(column).getJavaType(column);%0A    %7D%0A%0A    /**%0A     * Returns the database type of the specified column.%0A     *%0A     * @param column  the column%0A     * @return        the database type%0A     */%0A    default TypeMapper.Category categoryOf(Column column) %7B%0A        return get(column).getJavaTypeCategory(column);%0A    %7D
 %0A    %0A  

Make it easier to get the type of a column