001: /*
002: * Copyright 2004 Clinton Begin
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package com.ibatis.sqlmap.engine.type;
017:
018: import com.ibatis.sqlmap.client.SqlMapException;
019:
020: import java.math.BigDecimal;
021: import java.util.*;
022:
023: /**
024: * Not much of a suprise, this is a factory class for TypeHandler objects.
025: */
026: public class TypeHandlerFactory {
027:
028: private final Map typeHandlerMap = new HashMap();
029: private final TypeHandler unknownTypeHandler = new UnknownTypeHandler(
030: this );
031: private final HashMap typeAliases = new HashMap();
032:
033: /* Constructor */
034:
035: /**
036: * Default constructor
037: */
038: public TypeHandlerFactory() {
039: TypeHandler handler;
040:
041: handler = new BooleanTypeHandler();
042: register(Boolean.class, handler);
043: register(boolean.class, handler);
044:
045: handler = new ByteTypeHandler();
046: register(Byte.class, handler);
047: register(byte.class, handler);
048:
049: handler = new ShortTypeHandler();
050: register(Short.class, handler);
051: register(short.class, handler);
052:
053: handler = new IntegerTypeHandler();
054: register(Integer.class, handler);
055: register(int.class, handler);
056:
057: handler = new LongTypeHandler();
058: register(Long.class, handler);
059: register(long.class, handler);
060:
061: handler = new FloatTypeHandler();
062: register(Float.class, handler);
063: register(float.class, handler);
064:
065: handler = new DoubleTypeHandler();
066: register(Double.class, handler);
067: register(double.class, handler);
068:
069: register(String.class, new StringTypeHandler());
070: register(String.class, "CLOB", new CustomTypeHandler(
071: new ClobTypeHandlerCallback()));
072: register(String.class, "LONGVARCHAR", new CustomTypeHandler(
073: new ClobTypeHandlerCallback()));
074:
075: register(BigDecimal.class, new BigDecimalTypeHandler());
076:
077: register(byte[].class, new ByteArrayTypeHandler());
078: register(byte[].class, "BLOB", new CustomTypeHandler(
079: new BlobTypeHandlerCallback()));
080: register(byte[].class, "LONGVARBINARY", new CustomTypeHandler(
081: new BlobTypeHandlerCallback()));
082:
083: register(Object.class, new ObjectTypeHandler());
084: register(Object.class, "OBJECT", new ObjectTypeHandler());
085:
086: register(Date.class, new DateTypeHandler());
087: register(Date.class, "DATE", new DateOnlyTypeHandler());
088: register(Date.class, "TIME", new TimeOnlyTypeHandler());
089:
090: register(java.sql.Date.class, new SqlDateTypeHandler());
091: register(java.sql.Time.class, new SqlTimeTypeHandler());
092: register(java.sql.Timestamp.class,
093: new SqlTimestampTypeHandler());
094:
095: putTypeAlias("string", String.class.getName());
096: putTypeAlias("byte", Byte.class.getName());
097: putTypeAlias("long", Long.class.getName());
098: putTypeAlias("short", Short.class.getName());
099: putTypeAlias("int", Integer.class.getName());
100: putTypeAlias("integer", Integer.class.getName());
101: putTypeAlias("double", Double.class.getName());
102: putTypeAlias("float", Float.class.getName());
103: putTypeAlias("boolean", Boolean.class.getName());
104: putTypeAlias("date", Date.class.getName());
105: putTypeAlias("decimal", BigDecimal.class.getName());
106: putTypeAlias("object", Object.class.getName());
107: putTypeAlias("map", Map.class.getName());
108: putTypeAlias("hashmap", HashMap.class.getName());
109: putTypeAlias("list", List.class.getName());
110: putTypeAlias("arraylist", ArrayList.class.getName());
111: putTypeAlias("collection", Collection.class.getName());
112: putTypeAlias("iterator", Iterator.class.getName());
113: putTypeAlias("cursor", java.sql.ResultSet.class.getName());
114:
115: }
116:
117: /* Public Methods */
118:
119: /**
120: * Get a TypeHandler for a class
121: *
122: * @param type - the class you want a TypeHandler for
123: *
124: * @return - the handler
125: */
126: public TypeHandler getTypeHandler(Class type) {
127: return getTypeHandler(type, null);
128: }
129:
130: /**
131: * Get a TypeHandler for a class and a JDBC type
132: *
133: * @param type - the class
134: * @param jdbcType - the jdbc type
135: *
136: * @return - the handler
137: */
138: public TypeHandler getTypeHandler(Class type, String jdbcType) {
139: Map jdbcHandlerMap = (Map) typeHandlerMap.get(type);
140: TypeHandler handler = null;
141: if (jdbcHandlerMap != null) {
142: handler = (TypeHandler) jdbcHandlerMap.get(jdbcType);
143: if (handler == null) {
144: handler = (TypeHandler) jdbcHandlerMap.get(null);
145: }
146: }
147: return handler;
148: }
149:
150: /**
151: * When in doubt, get the "unknown" type handler
152: *
153: * @return - if I told you, it would not be unknown, would it?
154: */
155: public TypeHandler getUnkownTypeHandler() {
156: return unknownTypeHandler;
157: }
158:
159: /**
160: * Tells you if a particular class has a TypeHandler
161: *
162: * @param type - the class
163: *
164: * @return - true if there is a TypeHandler
165: */
166: public boolean hasTypeHandler(Class type) {
167: return getTypeHandler(type) != null;
168: }
169:
170: /**
171: * Register (add) a type handler for a class
172: *
173: * @param type - the class
174: * @param handler - the handler instance
175: */
176: public void register(Class type, TypeHandler handler) {
177: register(type, null, handler);
178: }
179:
180: /**
181: * Register (add) a type handler for a class and JDBC type
182: *
183: * @param type - the class
184: * @param jdbcType - the JDBC type
185: * @param handler - the handler instance
186: */
187: public void register(Class type, String jdbcType,
188: TypeHandler handler) {
189: Map map = (Map) typeHandlerMap.get(type);
190: if (map == null) {
191: map = new HashMap();
192: typeHandlerMap.put(type, map);
193: }
194: map.put(jdbcType, handler);
195: }
196:
197: /**
198: * Lookup an aliased class and return it's REAL name
199: *
200: * @param string - the alias
201: *
202: * @return - the REAL name
203: */
204: public String resolveAlias(String string) {
205: String key = null;
206: if (string != null)
207: key = string.toLowerCase();
208: String value = null;
209: if (typeAliases.containsKey(key)) {
210: value = (String) typeAliases.get(key);
211: } else {
212: value = string;
213: }
214:
215: return value;
216: }
217:
218: /**
219: * Adds a type alias that is case insensitive. All of the following String, string, StRiNg will equate to the same alias.
220: * @param alias - the alias
221: * @param value - the real class name
222: */
223: public void putTypeAlias(String alias, String value) {
224: String key = null;
225: if (alias != null)
226: key = alias.toLowerCase();
227: if (typeAliases.containsKey(key)
228: && !typeAliases.get(key).equals(value)) {
229: throw new SqlMapException(
230: "Error in XmlSqlMapClientBuilder. Alias name conflict occurred. The alias '"
231: + key
232: + "' is already mapped to the value '"
233: + typeAliases.get(alias) + "'.");
234: }
235: typeAliases.put(key, value);
236: }
237:
238: }
|