001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.object;
006:
007: import com.tc.util.Assert;
008: import com.tc.util.ClassUtils;
009:
010: import java.math.BigDecimal;
011: import java.math.BigInteger;
012: import java.util.Collections;
013: import java.util.Currency;
014: import java.util.HashMap;
015: import java.util.Map;
016:
017: /**
018: * Responsible for handling literal values
019: */
020: public class LiteralValues {
021:
022: public final static String ENUM_CLASS_DOTS = "java.lang.Enum";
023:
024: /*********************************************************************************************************************
025: * NOTE:: READ THIS IF YOU ARE ADDING NEW TYPES TO THIS FILE. XXX:: If you are adding more types, please see
026: * PhysicalStateClassLoader and DNAEncoding. You need to be adding New code in both those classes or else some things
027: * will be broken.
028: ********************************************************************************************************************/
029: public final static int INTEGER = 0;
030: public final static int LONG = 1;
031: public final static int CHARACTER = 2;
032: public final static int FLOAT = 3;
033: public final static int DOUBLE = 4;
034: public final static int BYTE = 5;
035: public final static int STRING = 6;
036: public final static int BOOLEAN = 7;
037: public final static int SHORT = 8;
038: public final static int ARRAY = 9;
039: public final static int OBJECT = 10;
040: public final static int OBJECT_ID = 11;
041: public final static int STRING_BYTES = 12;
042: public final static int JAVA_LANG_CLASS = 13;
043: public final static int JAVA_LANG_CLASS_HOLDER = 14;
044: public final static int STACK_TRACE_ELEMENT = 15;
045: public final static int BIG_INTEGER = 16;
046: public final static int BIG_DECIMAL = 17;
047: public final static int JAVA_LANG_CLASSLOADER = 18;
048: public final static int JAVA_LANG_CLASSLOADER_HOLDER = 19;
049: public final static int ENUM = 20;
050: public final static int ENUM_HOLDER = 21;
051: public final static int CURRENCY = 22;
052:
053: private final Map values;
054:
055: public LiteralValues() {
056: super ();
057:
058: Map tmp = new HashMap();
059:
060: addMapping(tmp, Integer.class.getName(), INTEGER);
061: addMapping(tmp, int.class.getName(), INTEGER);
062: addMapping(tmp, Long.class.getName(), LONG);
063: addMapping(tmp, long.class.getName(), LONG);
064: addMapping(tmp, Character.class.getName(), CHARACTER);
065: addMapping(tmp, char.class.getName(), CHARACTER);
066: addMapping(tmp, Float.class.getName(), FLOAT);
067: addMapping(tmp, float.class.getName(), FLOAT);
068: addMapping(tmp, Double.class.getName(), DOUBLE);
069: addMapping(tmp, double.class.getName(), DOUBLE);
070: addMapping(tmp, Byte.class.getName(), BYTE);
071: addMapping(tmp, byte.class.getName(), BYTE);
072: addMapping(tmp, String.class.getName(), STRING);
073:
074: addMapping(tmp, "com.tc.object.dna.impl.UTF8ByteDataHolder",
075: STRING_BYTES);
076:
077: addMapping(tmp, Short.class.getName(), SHORT);
078: addMapping(tmp, short.class.getName(), SHORT);
079: addMapping(tmp, Boolean.class.getName(), BOOLEAN);
080: addMapping(tmp, boolean.class.getName(), BOOLEAN);
081:
082: addMapping(tmp, BigInteger.class.getName(), BIG_INTEGER);
083: addMapping(tmp, BigDecimal.class.getName(), BIG_DECIMAL);
084:
085: addMapping(tmp, java.lang.Class.class.getName(),
086: JAVA_LANG_CLASS);
087:
088: addMapping(tmp, "com.tc.object.dna.impl.ClassInstance",
089: JAVA_LANG_CLASS_HOLDER);
090:
091: addMapping(tmp, ObjectID.class.getName(), OBJECT_ID);
092: addMapping(tmp, StackTraceElement.class.getName(),
093: STACK_TRACE_ELEMENT);
094:
095: addMapping(tmp, "com.tc.object.dna.impl.ClassLoaderInstance",
096: JAVA_LANG_CLASSLOADER_HOLDER);
097:
098: addMapping(tmp, ENUM_CLASS_DOTS, ENUM);
099:
100: addMapping(tmp, "com.tc.object.dna.impl.EnumInstance",
101: ENUM_HOLDER);
102:
103: addMapping(tmp, Currency.class.getName(), CURRENCY);
104:
105: values = Collections.unmodifiableMap(tmp);
106: }
107:
108: /**
109: * Determine LiteralValue code for an instance object
110: * @param pojo Object instance, should never be null
111: * @return Literal value code for the pojo's class
112: */
113: public int valueFor(Object pojo) {
114: if (pojo instanceof ClassLoader) {
115: return JAVA_LANG_CLASSLOADER;
116: }
117:
118: Class clazz = pojo.getClass();
119: int i = valueForClassName(clazz.getName());
120: if (i == OBJECT && ClassUtils.isEnum(pojo.getClass())) {
121: return ENUM;
122: }
123: return i;
124: }
125:
126: /**
127: * Determine whether a class is a literal
128: * @param className Class name
129: * @return True if literal value class
130: */
131: public boolean isLiteral(String className) {
132: int i = valueForClassName(className);
133: return i != OBJECT && i != ARRAY;
134: }
135:
136: /**
137: * Determine whether the instance is a literal
138: * @param obj Instance object, may be null
139: * @return True if literal value instance, false if null or not literal value instance
140: */
141: public boolean isLiteralInstance(Object obj) {
142: if (obj == null) {
143: return false;
144: }
145: int i = valueFor(obj);
146: return i != OBJECT && i != ARRAY;
147: }
148:
149: private static void addMapping(Map map, String className, int i) {
150: Object prev = map.put(className, new Integer(i));
151: Assert.assertNull(className, prev);
152: }
153:
154: /**
155: * Get literal value code for class name
156: * @param className Class name, may be null
157: * @return Literal value marker or {@link #OBJECT} if className is null
158: */
159: public int valueForClassName(String className) {
160: if ((className != null) && className.startsWith("[")) {
161: return ARRAY;
162: }
163: Integer i = (Integer) values.get(className);
164: if (i == null)
165: return OBJECT;
166: return i.intValue();
167: }
168: }
|