org.lunarray.model.descriptor.converter.def.AbstractDefaultConverterTool.java Source code

Java tutorial

Introduction

Here is the source code for org.lunarray.model.descriptor.converter.def.AbstractDefaultConverterTool.java

Source

/* 
 * Model Tools.
 * Copyright (C) 2013 Pal Hargitai (pal@lunarray.org)
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.lunarray.model.descriptor.converter.def;

import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.lang.Validate;
import org.lunarray.common.generics.GenericsUtil;
import org.lunarray.model.descriptor.converter.Converter;
import org.lunarray.model.descriptor.converter.ConverterTool;
import org.lunarray.model.descriptor.converter.def.converters.AtomicBooleanConverter;
import org.lunarray.model.descriptor.converter.def.converters.AtomicIntegerConverter;
import org.lunarray.model.descriptor.converter.def.converters.AtomicLongConverter;
import org.lunarray.model.descriptor.converter.def.converters.BigDecimalConverter;
import org.lunarray.model.descriptor.converter.def.converters.BigIntegerConverter;
import org.lunarray.model.descriptor.converter.def.converters.BooleanConverter;
import org.lunarray.model.descriptor.converter.def.converters.ByteConverter;
import org.lunarray.model.descriptor.converter.def.converters.CalendarConverter;
import org.lunarray.model.descriptor.converter.def.converters.CharacterConverter;
import org.lunarray.model.descriptor.converter.def.converters.ClazzConverter;
import org.lunarray.model.descriptor.converter.def.converters.CompositeNameConverter;
import org.lunarray.model.descriptor.converter.def.converters.CurrencyConverter;
import org.lunarray.model.descriptor.converter.def.converters.DOMConverter;
import org.lunarray.model.descriptor.converter.def.converters.DateConverter;
import org.lunarray.model.descriptor.converter.def.converters.DoubleConverter;
import org.lunarray.model.descriptor.converter.def.converters.FloatConverter;
import org.lunarray.model.descriptor.converter.def.converters.IdempotentConverter;
import org.lunarray.model.descriptor.converter.def.converters.InetAddressConverter;
import org.lunarray.model.descriptor.converter.def.converters.InetSocketAddressConverter;
import org.lunarray.model.descriptor.converter.def.converters.IntegerConverter;
import org.lunarray.model.descriptor.converter.def.converters.LdapNameConverter;
import org.lunarray.model.descriptor.converter.def.converters.LinkRefConverter;
import org.lunarray.model.descriptor.converter.def.converters.LongConverter;
import org.lunarray.model.descriptor.converter.def.converters.NetworkInterfaceConverter;
import org.lunarray.model.descriptor.converter.def.converters.ShortConverter;
import org.lunarray.model.descriptor.converter.def.converters.SqlDateConverter;
import org.lunarray.model.descriptor.converter.def.converters.SqlTimeConverter;
import org.lunarray.model.descriptor.converter.def.converters.SqlTimestampConverter;
import org.lunarray.model.descriptor.converter.def.converters.URIConverter;
import org.lunarray.model.descriptor.converter.def.converters.URLConverter;
import org.lunarray.model.descriptor.converter.def.converters.UUIDConverter;
import org.lunarray.model.descriptor.converter.def.converters.XMLDurationConverter;
import org.lunarray.model.descriptor.converter.def.converters.XMLGregorianCalendarConverter;
import org.lunarray.model.descriptor.converter.exceptions.ConverterException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Abstract converter tool with some default converters.
 * 
 * @author Pal Hargitai (pal@lunarray.org)
 */
public abstract class AbstractDefaultConverterTool implements ConverterTool {

    /** Validation message. */
    private static final String CONVERTER_NULL = "Converter may not be null.";
    /** The logger. */
    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractDefaultConverterTool.class);
    /** The map of converters. */
    private final transient Map<Class<?>, Converter<?>> converters;

    /**
     * Default constructor.
     */
    public AbstractDefaultConverterTool() {
        this.converters = new HashMap<Class<?>, Converter<?>>();
        this.populateDefaultConverters();
    }

    /**
     * Adds a converter.
     * 
     * @param type
     *            The converter type. May not be null.
     * @param converter
     *            The converter. May not be null.
     * @param <T>
     *            The convertable type.
     */
    public final <T> void addConverter(final Class<T> type, final Converter<T> converter) {
        Validate.notNull(type, "Converter type may not be null.");
        Validate.notNull(converter, AbstractDefaultConverterTool.CONVERTER_NULL);
        this.converters.put(type, converter);
    }

    /**
     * Adds a converter.
     * 
     * @param converter
     *            The converter.
     */
    public final void addConverter(final Converter<?> converter) {
        Validate.notNull(converter, AbstractDefaultConverterTool.CONVERTER_NULL);
        final Type converterType = GenericsUtil.getEntityGenericType(converter.getClass(), 0, Converter.class);
        this.converters.put(GenericsUtil.guessClazz(converterType), converter);
    }

    /** {@inheritDoc} */
    @Override
    public final <T> T convertToInstance(final Class<T> type, final String stringValue) throws ConverterException {
        AbstractDefaultConverterTool.LOGGER.debug("Converting to instance type {} with value: {}", type,
                stringValue);
        return this.resolve(type).convertToInstance(stringValue);
    }

    /** {@inheritDoc} */
    @Override
    public final <T> T convertToInstance(final Class<T> type, final String stringValue, final Locale locale)
            throws ConverterException {
        AbstractDefaultConverterTool.LOGGER.debug("Converting to instance type {} with locale {} and value: {}",
                type, locale, stringValue);
        return this.resolve(type).convertToInstance(stringValue, locale);
    }

    /** {@inheritDoc} */
    @Override
    public final <T> T convertToInstance(final Class<T> type, final String stringValue, final Locale locale,
            final String format) throws ConverterException {
        AbstractDefaultConverterTool.LOGGER.debug(
                "Converting to instance type {} with locale {}, format '{}' and value: {}", type, locale, format,
                stringValue);
        return this.resolve(type).convertToInstance(stringValue, locale, format);
    }

    /** {@inheritDoc} */
    @Override
    public final <T> T convertToInstance(final Class<T> type, final String stringValue, final String format)
            throws ConverterException {
        AbstractDefaultConverterTool.LOGGER.debug("Converting to instance type {} with format '{}' and value: {}",
                type, format, stringValue);
        return this.resolve(type).convertToInstance(stringValue, format);
    }

    /** {@inheritDoc} */
    @Override
    public final <T> String convertToString(final Class<T> type, final T instance) throws ConverterException {
        AbstractDefaultConverterTool.LOGGER.debug("Converting to string with value type {} with value: {}", type,
                instance);
        return this.resolve(type).convertToString(instance);
    }

    /** {@inheritDoc} */
    @Override
    public final <T> String convertToString(final Class<T> type, final T instance, final Locale locale)
            throws ConverterException {
        AbstractDefaultConverterTool.LOGGER.debug(
                "Converting to string with value type {} with locale {} and value: {}", type, locale, instance);
        return this.resolve(type).convertToString(instance, locale);
    }

    /** {@inheritDoc} */
    @Override
    public final <T> String convertToString(final Class<T> type, final T instance, final Locale locale,
            final String format) throws ConverterException {
        AbstractDefaultConverterTool.LOGGER.debug(
                "Converting to string with value type {} with locale {}, format '{}' and value: {}", type, locale,
                format, instance);
        return this.resolve(type).convertToString(instance, locale, format);
    }

    /** {@inheritDoc} */
    @Override
    public final <T> String convertToString(final Class<T> type, final T instance, final String format)
            throws ConverterException {
        AbstractDefaultConverterTool.LOGGER.debug(
                "Converting to string with value type {} with format '{}' and value: {}", type, format, instance);
        return this.resolve(type).convertToString(instance, format);
    }

    /**
     * Add all default converters.
     */
    private void populateDefaultConverters() {
        this.populateSimpleConverters();
        // Concurrent.
        this.addConverter(new AtomicBooleanConverter());
        this.addConverter(new AtomicIntegerConverter());
        this.addConverter(new AtomicLongConverter());
        // Class.
        this.addConverter(new ClazzConverter());
        // Naming.
        this.addConverter(new CompositeNameConverter());
        this.addConverter(new LdapNameConverter());
        this.addConverter(new LinkRefConverter());
        // Currency.
        this.addConverter(new CurrencyConverter());
        // XML DOM
        this.addConverter(new DOMConverter());
        // XML JAXB types.
        this.addConverter(new XMLDurationConverter());
        this.addConverter(new XMLGregorianCalendarConverter());
        // Network.
        this.addConverter(new InetAddressConverter());
        this.addConverter(new InetSocketAddressConverter());
        this.addConverter(new NetworkInterfaceConverter());
        // Resource types.
        this.addConverter(new URIConverter());
        this.addConverter(new URLConverter());
        this.addConverter(new UUIDConverter());
    }

    /**
     * Populates the simple converters.
     */
    private void populateSimpleConverters() {
        // Primitives.
        this.converters.put(Integer.TYPE, new IntegerConverter());
        this.converters.put(Double.TYPE, new DoubleConverter());
        this.converters.put(Float.TYPE, new FloatConverter());
        this.converters.put(Long.TYPE, new LongConverter());
        this.converters.put(Byte.TYPE, new ByteConverter());
        this.converters.put(Short.TYPE, new ShortConverter());
        this.converters.put(Character.TYPE, new CharacterConverter());
        this.converters.put(Boolean.TYPE, new BooleanConverter());
        // Date types.
        this.addConverter(new CalendarConverter());
        this.addConverter(new DateConverter());
        // SQL Date types.
        this.addConverter(new SqlDateConverter());
        this.addConverter(new SqlTimeConverter());
        this.addConverter(new SqlTimestampConverter());
        // String.
        this.addConverter(new IdempotentConverter());
        // Numbers.
        this.addConverter(new IntegerConverter());
        this.addConverter(new DoubleConverter());
        this.addConverter(new FloatConverter());
        this.addConverter(new LongConverter());
        this.addConverter(new ByteConverter());
        this.addConverter(new ShortConverter());
        // Character.
        this.addConverter(new CharacterConverter());
        // Math types.
        this.addConverter(new BigDecimalConverter());
        this.addConverter(new BigIntegerConverter());
        // Boolean.
        this.addConverter(new BooleanConverter());
    }

    /**
     * Resolves a converter.
     * 
     * @param <T>
     *            The converter type.
     * @param type
     *            The converter type. May not be null.
     * @return The converter of the given type, or null.
     * @throws ConverterException
     *             Thrown if no compatible converter could be found.
     */
    @SuppressWarnings("unchecked")
    // We filled it this way.
    protected final <T> Converter<T> resolve(final Class<T> type) throws ConverterException {
        Validate.notNull(type, "Type may not be null.");
        if (this.converters.containsKey(type)) {
            final Converter<T> result = (Converter<T>) this.converters.get(type);
            AbstractDefaultConverterTool.LOGGER.debug("Resolved converter {} for type {}", result, type);
            return result;
        } else {
            throw new ConverterException(String.format("Could not find converter for '%s'.", type));
        }
    }
}