/*
* Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 David Berkman
*
* This file is part of the SmallMind Code Project.
*
* The SmallMind Code Project is free software, you can redistribute
* it and/or modify it under either, at your discretion...
*
* 1) The terms of GNU Affero General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* ...or...
*
* 2) The terms of the Apache License, Version 2.0.
*
* The SmallMind Code Project 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
* General Public License or Apache License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* and the Apache License along with the SmallMind Code Project. If not, see
* <http://www.gnu.org/licenses/> or <http://www.apache.org/licenses/LICENSE-2.0>.
*
* Additional permission under the GNU Affero GPL version 3 section 7
* ------------------------------------------------------------------
* If you modify this Program, or any covered work, by linking or
* combining it with other code, such other code is not for that reason
* alone subject to any of the requirements of the GNU Affero GPL
* version 3.
*/
package org.smallmind.nutsnbolts.reflection.type.converter;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
public class DefaultStringConverterFactory implements StringConverterFactory {
private static final StringConverter[] NO_SUPPLEMENTAL_CONVERTERS = new StringConverter[0];
private static final StringConverterFactory INSTANCE = new DefaultStringConverterFactory();
private final ConcurrentHashMap<Class, StringConverter<?>> converterMap = new ConcurrentHashMap<Class, StringConverter<?>>();
public static StringConverterFactory getInstance () {
return INSTANCE;
}
public DefaultStringConverterFactory () {
this(NO_SUPPLEMENTAL_CONVERTERS);
}
public DefaultStringConverterFactory (StringConverter<?>... supplementalStringConverters) {
converterMap.put(Long.class, new LongStringConverter());
converterMap.put(Character.class, new CharacterStringConverter());
converterMap.put(Integer.class, new IntegerStringConverter());
converterMap.put(Byte.class, new ByteStringConverter());
converterMap.put(Short.class, new ShortStringConverter());
converterMap.put(Float.class, new FloatStringConverter());
converterMap.put(Double.class, new DoubleStringConverter());
converterMap.put(Boolean.class, new BooleanStringConverter());
converterMap.put(String.class, new StringStringConverter());
if (supplementalStringConverters != null) {
for (StringConverter<?> supplementalStringConverter : supplementalStringConverters) {
converterMap.put(supplementalStringConverter.getType(), supplementalStringConverter);
}
}
if (!converterMap.containsKey(Date.class)) {
converterMap.put(Date.class, new DateStringConverter());
}
}
public StringConverter getStringConverter (Class parameterClass)
throws StringConversionException {
StringConverter<?> stringConverter;
Class convergedClass;
if ((stringConverter = converterMap.get(convergedClass = getConvergedClass(parameterClass))) == null) {
if (convergedClass.isEnum()) {
converterMap.put(convergedClass, stringConverter = new EnumStringConverter((Class<? extends Enum<?>>)convergedClass));
}
else {
throw new StringConversionException("No known converter for type(%s)", convergedClass.getName());
}
}
return stringConverter;
}
private static Class getConvergedClass (Class parameterClass)
throws StringConversionException {
if (parameterClass.isPrimitive()) {
if (parameterClass.equals(long.class)) {
return Long.class;
}
if (parameterClass.equals(char.class)) {
return Character.class;
}
if (parameterClass.equals(int.class)) {
return Integer.class;
}
if (parameterClass.equals(byte.class)) {
return Byte.class;
}
if (parameterClass.equals(short.class)) {
return Short.class;
}
if (parameterClass.equals(float.class)) {
return Float.class;
}
if (parameterClass.equals(double.class)) {
return Double.class;
}
if (parameterClass.equals(boolean.class)) {
return Boolean.class;
}
}
return parameterClass;
}
}