1 /* 2 * Copyright 2004 Clinton Begin 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.ibatis.sqlmap.engine.type; 17 18 import com.ibatis.sqlmap.client.SqlMapException; 19 20 import java.math.BigDecimal; 21 import java.util; 22 23 /** 24 * Not much of a suprise, this is a factory class for TypeHandler objects. 25 */ 26 public class TypeHandlerFactory { 27 28 private final Map typeHandlerMap = new HashMap(); 29 private final TypeHandler unknownTypeHandler = new UnknownTypeHandler(this); 30 private final HashMap typeAliases = new HashMap(); 31 32 33 /* Constructor */ 34 35 /** 36 * Default constructor 37 */ 38 public TypeHandlerFactory() { 39 TypeHandler handler; 40 41 handler = new BooleanTypeHandler(); 42 register(Boolean.class, handler); 43 register(boolean.class, handler); 44 45 handler = new ByteTypeHandler(); 46 register(Byte.class, handler); 47 register(byte.class, handler); 48 49 handler = new ShortTypeHandler(); 50 register(Short.class, handler); 51 register(short.class, handler); 52 53 handler = new IntegerTypeHandler(); 54 register(Integer.class, handler); 55 register(int.class, handler); 56 57 handler = new LongTypeHandler(); 58 register(Long.class, handler); 59 register(long.class, handler); 60 61 handler = new FloatTypeHandler(); 62 register(Float.class, handler); 63 register(float.class, handler); 64 65 handler = new DoubleTypeHandler(); 66 register(Double.class, handler); 67 register(double.class, handler); 68 69 register(String.class, new StringTypeHandler()); 70 register(String.class, "CLOB", new CustomTypeHandler(new ClobTypeHandlerCallback())); 71 register(String.class, "LONGVARCHAR", new CustomTypeHandler(new ClobTypeHandlerCallback())); 72 73 register(BigDecimal.class, new BigDecimalTypeHandler()); 74 75 register(byte[].class, new ByteArrayTypeHandler()); 76 register(byte[].class, "BLOB", new CustomTypeHandler(new BlobTypeHandlerCallback())); 77 register(byte[].class, "LONGVARBINARY", new CustomTypeHandler(new BlobTypeHandlerCallback())); 78 79 register(Object.class, new ObjectTypeHandler()); 80 register(Object.class, "OBJECT", new ObjectTypeHandler()); 81 82 register(Date.class, new DateTypeHandler()); 83 register(Date.class, "DATE", new DateOnlyTypeHandler()); 84 register(Date.class, "TIME", new TimeOnlyTypeHandler()); 85 86 87 register(java.sql.Date.class, new SqlDateTypeHandler()); 88 register(java.sql.Time.class, new SqlTimeTypeHandler()); 89 register(java.sql.Timestamp.class, new SqlTimestampTypeHandler()); 90 91 putTypeAlias("string", String.class.getName()); 92 putTypeAlias("byte", Byte.class.getName()); 93 putTypeAlias("long", Long.class.getName()); 94 putTypeAlias("short", Short.class.getName()); 95 putTypeAlias("int", Integer.class.getName()); 96 putTypeAlias("integer", Integer.class.getName()); 97 putTypeAlias("double", Double.class.getName()); 98 putTypeAlias("float", Float.class.getName()); 99 putTypeAlias("boolean", Boolean.class.getName()); 100 putTypeAlias("date", Date.class.getName()); 101 putTypeAlias("decimal", BigDecimal.class.getName()); 102 putTypeAlias("object", Object.class.getName()); 103 putTypeAlias("map", Map.class.getName()); 104 putTypeAlias("hashmap", HashMap.class.getName()); 105 putTypeAlias("list", List.class.getName()); 106 putTypeAlias("arraylist", ArrayList.class.getName()); 107 putTypeAlias("collection", Collection.class.getName()); 108 putTypeAlias("iterator", Iterator.class.getName()); 109 110 } 111 112 /* Public Methods */ 113 114 /** 115 * Get a TypeHandler for a class 116 * 117 * @param type - the class you want a TypeHandler for 118 * 119 * @return - the handler 120 */ 121 public TypeHandler getTypeHandler(Class type) { 122 return getTypeHandler(type, null); 123 } 124 125 /** 126 * Get a TypeHandler for a class and a JDBC type 127 * 128 * @param type - the class 129 * @param jdbcType - the jdbc type 130 * 131 * @return - the handler 132 */ 133 public TypeHandler getTypeHandler(Class type, String jdbcType) { 134 Map jdbcHandlerMap = (Map) typeHandlerMap.get(type); 135 TypeHandler handler = null; 136 if (jdbcHandlerMap != null) { 137 handler = (TypeHandler) jdbcHandlerMap.get(jdbcType); 138 if (handler == null) { 139 handler = (TypeHandler) jdbcHandlerMap.get(null); 140 } 141 } 142 return handler; 143 } 144 145 /** 146 * When in doubt, get the "unknown" type handler 147 * 148 * @return - if I told you, it would not be unknown, would it? 149 */ 150 public TypeHandler getUnkownTypeHandler() { 151 return unknownTypeHandler; 152 } 153 154 155 /** 156 * Tells you if a particular class has a TypeHandler 157 * 158 * @param type - the class 159 * 160 * @return - true if there is a TypeHandler 161 */ 162 public boolean hasTypeHandler(Class type) { 163 return getTypeHandler(type) != null; 164 } 165 166 /** 167 * Register (add) a type handler for a class 168 * 169 * @param type - the class 170 * @param handler - the handler instance 171 */ 172 public void register(Class type, TypeHandler handler) { 173 register(type, null, handler); 174 } 175 176 /** 177 * Register (add) a type handler for a class and JDBC type 178 * 179 * @param type - the class 180 * @param jdbcType - the JDBC type 181 * @param handler - the handler instance 182 */ 183 public void register(Class type, String jdbcType, TypeHandler handler) { 184 Map map = (Map) typeHandlerMap.get(type); 185 if (map == null) { 186 map = new HashMap(); 187 typeHandlerMap.put(type, map); 188 } 189 map.put(jdbcType, handler); 190 } 191 192 /** 193 * Lookup an aliased class and return it's REAL name 194 * 195 * @param string - the alias 196 * 197 * @return - the REAL name 198 */ 199 public String resolveAlias(String string) { 200 String newString = null; 201 if (typeAliases.containsKey(string)) { 202 newString = (String) typeAliases.get(string); 203 } 204 if (newString != null) { 205 string = newString; 206 } 207 return string; 208 } 209 210 /** 211 * Add an alias 212 * @param alias - the alias 213 * @param value - the real class name 214 */ 215 public void putTypeAlias(String alias, String value) { 216 if (typeAliases.containsKey(alias) && !typeAliases.get(alias).equals(value)) { 217 throw new SqlMapException("Error in XmlSqlMapClientBuilder. Alias name conflict occurred. The alias '" + alias + "' is already mapped to the value '" + typeAliases.get(alias) + "'."); 218 } 219 typeAliases.put(alias, value); 220 } 221 222 }