/* * Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code 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 * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ package org.visage.runtime; import java.util.HashMap; import java.util.Map; import org.visage.runtime.sequence.*; /** * TypeInfo * * @author Brian Goetz */ public class TypeInfo<T> { public final T defaultValue; public final Types type; public final ArraySequence<T> emptySequence; public enum Types { INT, FLOAT, OBJECT, DOUBLE, BOOLEAN, LONG, SHORT, BYTE, CHAR, OTHER } private static final Object[] emptyArray = new Object[0]; protected TypeInfo(T defaultValue, Types type) { this.defaultValue = defaultValue; this.type = type; ArraySequence<?> empty; switch (type) { case BOOLEAN: empty = new BooleanArraySequence(0, (TypeInfo<Boolean>) this); break; case CHAR:empty = new CharArraySequence(0, (TypeInfo<Character>) this); break; case BYTE: empty = new ByteArraySequence(0, (TypeInfo<Byte>) this); break; case SHORT: empty = new ShortArraySequence(0, (TypeInfo<Short>) this); break; case INT: empty = new IntArraySequence(0, (TypeInfo<Integer>) this); break; case LONG: empty = new LongArraySequence(0, (TypeInfo<Long>) this); break; case FLOAT: empty = new FloatArraySequence(0, (TypeInfo<Float>) this); break; case DOUBLE: empty = new DoubleArraySequence(0, (TypeInfo<Double>) this); break; default: empty = new ObjectArraySequence<T>(this, (T[]) emptyArray, true); } empty.setMaxShared(); this.emptySequence = (ArraySequence<T>) empty; } public boolean isNumeric() { return false; } public static final TypeInfo<Object> Object = new TypeInfo<Object>(null, Types.OBJECT); public static final TypeInfo<Boolean> Boolean = new TypeInfo<Boolean>(false, Types.BOOLEAN); public static final TypeInfo<Character> Character = new TypeInfo<Character>('\0', Types.CHAR); public static final TypeInfo<String> String = new TypeInfo<String>("", Types.OTHER); public static final NumericTypeInfo<Byte> Byte = new NumericTypeInfo<Byte>((byte)0, Types.BYTE); public static final NumericTypeInfo<Short> Short = new NumericTypeInfo<Short>((short)0, Types.SHORT); public static final NumericTypeInfo<Integer> Integer = new NumericTypeInfo<Integer>(0, Types.INT); public static final NumericTypeInfo<Long> Long = new NumericTypeInfo<Long>(0L, Types.LONG); public static final NumericTypeInfo<Float> Float = new NumericTypeInfo<Float>(0.0f, Types.FLOAT); public static final NumericTypeInfo<Double> Double = new NumericTypeInfo<Double>(0.0, Types.DOUBLE); private static final Map<Class<?>, TypeInfo<?>> map = new HashMap<Class<?>, TypeInfo<?>>(); static { // map.put(Number.class, Number); map.put(Byte.class, Byte); map.put(Short.class, Short); map.put(Integer.class, Integer); map.put(Long.class, Long); map.put(Float.class, Float); map.put(Double.class, Double); map.put(Boolean.class, Boolean); map.put(Character.class, Character); map.put(String.class, String); } @SuppressWarnings("unchecked") public static<T> TypeInfo<T> getTypeInfo() { return (TypeInfo)Object; } @SuppressWarnings("unchecked") public static<T> TypeInfo<T> getTypeInfo(Class<T> clazz) { TypeInfo<T> ti = (TypeInfo<T>) map.get(clazz); if (ti == null) ti = TypeInfo.getTypeInfo(); return ti; } public static<T> TypeInfo<T> makeTypeInfo(T defaultValue) { return new TypeInfo<T>(defaultValue, Types.OTHER); } public static<T> TypeInfo<T> makeAndRegisterTypeInfo(Class clazz, T defaultValue) { TypeInfo<T> ti = new TypeInfo<T>(defaultValue, Types.OTHER); map.put(clazz, ti); return ti; } public static<T> TypeInfo<T> makeAndRegisterTypeInfo(T defaultValue) { return makeAndRegisterTypeInfo(defaultValue.getClass(), defaultValue); } }