/* * Copyright (C) 2014 Civilian Framework. * * Licensed under the Civilian License (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.civilian-framework.org/license.txt * * 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 org.civilian.type; import java.math.BigDecimal; import java.math.BigInteger; import java.time.LocalDate; import java.util.HashMap; import java.util.Iterator; import org.civilian.Application; import org.civilian.application.AppConfig; import org.civilian.util.Date; /** * TypeLibrary is a collection of Type implementations. It also provides constants * for the predefined types. * Each {@link Application} has a TypeLibrary which is especially used when parameter * values are parsed or formatted in a locale dependent way. * If you need additional Type implementations not covered by the standard library, * you should implement them for yourself and add them to the applications type library * during application setup (see {@link AppConfig#setTypeLibrary(TypeLib)} */ public class TypeLib implements Iterable<Type<?>> { public static final Type<BigDecimal> BIGDECIMAL = SimpleType.BIGDECIMAL; public static final Type<BigInteger> BIGINTEGER = SimpleType.BIGINTEGER; public static final Type<Boolean> BOOLEAN = SimpleType.BOOLEAN; public static final Type<Byte> BYTE = SimpleType.BYTE; public static final Type<Character> CHARACTER = SimpleType.CHARACTER; public static final DateType<java.util.Calendar> DATE_CALENDAR = DateCalendarType.INSTANCE; public static final DateType<Date> DATE_CIVILIAN = DateCivilianType.INSTANCE; public static final DateType<LocalDate> DATE_LOCAL = DateLocalType.INSTANCE; public static final DateType<java.util.Date> DATE_JAVA_UTIL = DateJavaUtilType.INSTANCE; public static final DateType<java.sql.Date> DATE_JAVA_SQL = DateJavaSqlType.INSTANCE; public static final Type<Double> DOUBLE = SimpleType.DOUBLE; public static final Type<Float> FLOAT = SimpleType.FLOAT; public static final Type<Integer> INTEGER = SimpleType.INTEGER; public static final Type<Long> LONG = SimpleType.LONG; public static final Type<Short> SHORT = SimpleType.SHORT; public static final Type<String> STRING = SimpleType.STRING; /** * Creates a new type library which contains all type implementations from the lib subpackge. */ public TypeLib() { this(true); } /** * Creates a new TypeLibrary. * @param addDefaults if true, then all type implementations from the lib subpackage * are added, else the type library is initially empty. */ public TypeLib(boolean addDefaults) { if (addDefaults) { put(BIGDECIMAL); put(BIGINTEGER); put(BOOLEAN); put(BYTE); put(CHARACTER); put(DATE_CALENDAR); put(DATE_CIVILIAN); put(DATE_JAVA_UTIL); put(DATE_JAVA_SQL); put(DOUBLE); put(FLOAT); put(INTEGER); put(LONG); put(SHORT); put(STRING); } } /** * Returns the number of type contained in the library. */ public int size() { return map_.size(); } /** * Adds a type to the library. */ public <T> void put(Type<T> type) { map_.put(type.getJavaType(), type); } /** * Returns a Type for a Java class. */ @SuppressWarnings("unchecked") public <T> Type<T> get(Class<T> c) { if (c == null) return null; else return (Type<T>)map_.get(c.isPrimitive() ? getObjectClassForPrimitiveType(c) : c); } /** * Returns a Type for a Java class. * @throws IllegalArgumentException if no type is registered for the class. */ public <T> Type<T> getSafe(Class<T> clas) { Type<T> type = get(clas); if (type == null) throw new IllegalArgumentException("no type for '" + clas + "' defined"); return type; } /** * Removes a Type from the library. */ @SuppressWarnings("unchecked") public <T> Type<T> remove(Class<T> c) { return (Type<T>)map_.remove(c.isPrimitive() ? getObjectClassForPrimitiveType(c) : c); } /** * Removes a Type from the library. */ public <T> Type<T> remove(Type<T> type) { return remove(type.getJavaType()); } /** * Returns an iterator for the types. */ @Override public Iterator<Type<?>> iterator() { return map_.values().iterator(); } /** * Returns the associated class of a class of primitive type. * @param c a class for a primitive type (e.g. int.class) */ public static Class<?> getObjectClassForPrimitiveType(Class<?> c) { Object value = getPrimitiveDefaultValue(c); return value != null ? value.getClass() : null; } /** * Returns a default value for a primitive java type */ @SuppressWarnings("unchecked") public static <T> T getPrimitiveDefaultValue(Class<T> c) { return (T)PRIMITIVE_MAP.get(c); } private HashMap<Class<?>, Type<?>> map_ = new HashMap<>(); private static final HashMap<Class<?>, Object> PRIMITIVE_MAP = new HashMap<>(); static { PRIMITIVE_MAP.put(boolean.class, Boolean.FALSE); PRIMITIVE_MAP.put(byte.class, Byte.valueOf((byte)0)); PRIMITIVE_MAP.put(short.class, Short.valueOf((short)0)); PRIMITIVE_MAP.put(char.class, Character.valueOf((char)0)); PRIMITIVE_MAP.put(int.class, Integer.valueOf(0)); PRIMITIVE_MAP.put(long.class, Long.valueOf(0L)); PRIMITIVE_MAP.put(float.class, Float.valueOf(0.0f)); PRIMITIVE_MAP.put(double.class, Double.valueOf(0.0d)); } }