00001 /* 00002 * Licensed to the Apache Software Foundation (ASF) under one 00003 * or more contributor license agreements. See the NOTICE file 00004 * distributed with this work for additional information 00005 * regarding copyright ownership. The ASF licenses this file 00006 * to you under the Apache License, Version 2.0 (the 00007 * "License"); you may not use this file except in compliance 00008 * with the License. You may obtain a copy of the License at 00009 * 00010 * http://www.apache.org/licenses/LICENSE-2.0 00011 * 00012 * Unless required by applicable law or agreed to in writing, 00013 * software distributed under the License is distributed on an 00014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 00015 * KIND, either express or implied. See the License for the 00016 * specific language governing permissions and limitations 00017 * under the License. 00018 */ 00019 package org.apache.xmlrpc.common; 00020 00021 import java.io.Serializable; 00022 import java.math.BigDecimal; 00023 import java.math.BigInteger; 00024 import java.util.ArrayList; 00025 import java.util.Calendar; 00026 import java.util.Collection; 00027 import java.util.Date; 00028 import java.util.Hashtable; 00029 import java.util.List; 00030 import java.util.Map; 00031 import java.util.Properties; 00032 import java.util.Vector; 00033 00034 import org.w3c.dom.Document; 00035 00036 00039 public class TypeConverterFactoryImpl implements TypeConverterFactory { 00040 private static class IdentityTypeConverter implements TypeConverter { 00041 private final Class clazz; 00042 IdentityTypeConverter(Class pClass) { 00043 clazz = pClass; 00044 } 00045 public boolean isConvertable(Object pObject) { 00046 return pObject == null || clazz.isAssignableFrom(pObject.getClass()); 00047 } 00048 public Object convert(Object pObject) { 00049 return pObject; 00050 } 00051 public Object backConvert(Object pObject) { 00052 return pObject; 00053 } 00054 } 00055 00056 private static abstract class ListTypeConverter implements TypeConverter { 00057 private final Class clazz; 00058 ListTypeConverter(Class pClass) { 00059 clazz = pClass; 00060 } 00061 protected abstract List newList(int pSize); 00062 00063 public boolean isConvertable(Object pObject) { 00064 return pObject == null || pObject instanceof Object[] || pObject instanceof Collection; 00065 } 00066 00067 public Object convert(Object pObject) { 00068 if (pObject == null) { 00069 return null; 00070 } 00071 if (clazz.isAssignableFrom(pObject.getClass())) { 00072 return pObject; 00073 } 00074 if (pObject instanceof Object[]) { 00075 Object[] objects = (Object[]) pObject; 00076 List result = newList(objects.length); 00077 for (int i = 0; i < objects.length; i++) { 00078 result.add(objects[i]); 00079 } 00080 return result; 00081 } 00082 Collection collection = (Collection) pObject; 00083 List result = newList(collection.size()); 00084 result.addAll(collection); 00085 return result; 00086 } 00087 00088 public Object backConvert(Object pObject) { 00089 return ((List) pObject).toArray(); 00090 } 00091 } 00092 00093 private static class PrimitiveTypeConverter implements TypeConverter { 00094 private final Class clazz; 00095 PrimitiveTypeConverter(Class pClass) { 00096 clazz = pClass; 00097 } 00098 public boolean isConvertable(Object pObject) { 00099 return pObject != null && pObject.getClass().isAssignableFrom(clazz); 00100 } 00101 public Object convert(Object pObject) { 00102 return pObject; 00103 } 00104 public Object backConvert(Object pObject) { 00105 return pObject; 00106 } 00107 } 00108 00109 private static final TypeConverter voidTypeConverter = new IdentityTypeConverter(void.class); 00110 private static final TypeConverter mapTypeConverter = new IdentityTypeConverter(Map.class); 00111 private static final TypeConverter objectArrayTypeConverter = new IdentityTypeConverter(Object[].class); 00112 private static final TypeConverter byteArrayTypeConverter = new IdentityTypeConverter(byte[].class); 00113 private static final TypeConverter stringTypeConverter = new IdentityTypeConverter(String.class); 00114 private static final TypeConverter booleanTypeConverter = new IdentityTypeConverter(Boolean.class); 00115 private static final TypeConverter characterTypeConverter = new IdentityTypeConverter(Character.class); 00116 private static final TypeConverter byteTypeConverter = new IdentityTypeConverter(Byte.class); 00117 private static final TypeConverter shortTypeConverter = new IdentityTypeConverter(Short.class); 00118 private static final TypeConverter integerTypeConverter = new IdentityTypeConverter(Integer.class); 00119 private static final TypeConverter longTypeConverter = new IdentityTypeConverter(Long.class); 00120 private static final TypeConverter bigDecimalTypeConverter = new IdentityTypeConverter(BigDecimal.class); 00121 private static final TypeConverter bigIntegerTypeConverter = new IdentityTypeConverter(BigInteger.class); 00122 private static final TypeConverter floatTypeConverter = new IdentityTypeConverter(Float.class); 00123 private static final TypeConverter doubleTypeConverter = new IdentityTypeConverter(Double.class); 00124 private static final TypeConverter dateTypeConverter = new IdentityTypeConverter(Date.class); 00125 private static final TypeConverter calendarTypeConverter = new IdentityTypeConverter(Calendar.class); 00126 private static final TypeConverter domTypeConverter = new IdentityTypeConverter(Document.class); 00127 private static final TypeConverter primitiveBooleanTypeConverter = new PrimitiveTypeConverter(Boolean.class); 00128 private static final TypeConverter primitiveCharTypeConverter = new PrimitiveTypeConverter(Character.class); 00129 private static final TypeConverter primitiveByteTypeConverter = new PrimitiveTypeConverter(Byte.class); 00130 private static final TypeConverter primitiveShortTypeConverter = new PrimitiveTypeConverter(Short.class); 00131 private static final TypeConverter primitiveIntTypeConverter = new PrimitiveTypeConverter(Integer.class); 00132 private static final TypeConverter primitiveLongTypeConverter = new PrimitiveTypeConverter(Long.class); 00133 private static final TypeConverter primitiveFloatTypeConverter = new PrimitiveTypeConverter(Float.class); 00134 private static final TypeConverter primitiveDoubleTypeConverter = new PrimitiveTypeConverter(Double.class); 00135 00136 private static final TypeConverter propertiesTypeConverter = new TypeConverter() { 00137 public boolean isConvertable(Object pObject) { 00138 return pObject == null || pObject instanceof Map; 00139 } 00140 00141 public Object convert(Object pObject) { 00142 if (pObject == null) { 00143 return null; 00144 } 00145 Properties props = new Properties(); 00146 props.putAll((Map) pObject); 00147 return props; 00148 } 00149 00150 public Object backConvert(Object pObject) { 00151 return pObject; 00152 } 00153 }; 00154 00155 private static final TypeConverter hashTableTypeConverter = new TypeConverter() { 00156 public boolean isConvertable(Object pObject) { 00157 return pObject == null || pObject instanceof Map; 00158 } 00159 00160 public Object convert(Object pObject) { 00161 if (pObject == null) { 00162 return null; 00163 } 00164 return new Hashtable((Map) pObject); 00165 } 00166 00167 public Object backConvert(Object pObject) { 00168 return pObject; 00169 } 00170 }; 00171 00172 private static final TypeConverter listTypeConverter = new ListTypeConverter(List.class) { 00173 protected List newList(int pSize) { 00174 return new ArrayList(pSize); 00175 } 00176 }; 00177 00178 private static final TypeConverter vectorTypeConverter = new ListTypeConverter(Vector.class) { 00179 protected List newList(int pSize) { 00180 return new Vector(pSize); 00181 } 00182 }; 00183 00184 private static class CastCheckingTypeConverter implements TypeConverter { 00185 private final Class clazz; 00186 CastCheckingTypeConverter(Class pClass) { 00187 clazz = pClass; 00188 } 00189 public boolean isConvertable(Object pObject) { 00190 return pObject == null || clazz.isAssignableFrom(pObject.getClass()); 00191 } 00192 public Object convert(Object pObject) { 00193 return pObject; 00194 } 00195 public Object backConvert(Object pObject) { 00196 return pObject; 00197 } 00198 } 00199 00202 public TypeConverter getTypeConverter(Class pClass) { 00203 if (void.class.equals(pClass)) { 00204 return voidTypeConverter; 00205 } 00206 if (pClass.isAssignableFrom(boolean.class)) { 00207 return primitiveBooleanTypeConverter; 00208 } 00209 if (pClass.isAssignableFrom(char.class)) { 00210 return primitiveCharTypeConverter; 00211 } 00212 if (pClass.isAssignableFrom(byte.class)) { 00213 return primitiveByteTypeConverter; 00214 } 00215 if (pClass.isAssignableFrom(short.class)) { 00216 return primitiveShortTypeConverter; 00217 } 00218 if (pClass.isAssignableFrom(int.class)) { 00219 return primitiveIntTypeConverter; 00220 } 00221 if (pClass.isAssignableFrom(long.class)) { 00222 return primitiveLongTypeConverter; 00223 } 00224 if (pClass.isAssignableFrom(float.class)) { 00225 return primitiveFloatTypeConverter; 00226 } 00227 if (pClass.isAssignableFrom(double.class)) { 00228 return primitiveDoubleTypeConverter; 00229 } 00230 if (pClass.isAssignableFrom(String.class)) { 00231 return stringTypeConverter; 00232 } 00233 if (pClass.isAssignableFrom(Boolean.class)) { 00234 return booleanTypeConverter; 00235 } 00236 if (pClass.isAssignableFrom(Character.class)) { 00237 return characterTypeConverter; 00238 } 00239 if (pClass.isAssignableFrom(Byte.class)) { 00240 return byteTypeConverter; 00241 } 00242 if (pClass.isAssignableFrom(Short.class)) { 00243 return shortTypeConverter; 00244 } 00245 if (pClass.isAssignableFrom(Integer.class)) { 00246 return integerTypeConverter; 00247 } 00248 if (pClass.isAssignableFrom(Long.class)) { 00249 return longTypeConverter; 00250 } 00251 if (pClass.isAssignableFrom(BigDecimal.class)) { 00252 return bigDecimalTypeConverter; 00253 } 00254 if (pClass.isAssignableFrom(BigInteger.class)) { 00255 return bigIntegerTypeConverter; 00256 } 00257 if (pClass.isAssignableFrom(Float.class)) { 00258 return floatTypeConverter; 00259 } 00260 if (pClass.isAssignableFrom(Double.class)) { 00261 return doubleTypeConverter; 00262 } 00263 if (pClass.isAssignableFrom(Date.class)) { 00264 return dateTypeConverter; 00265 } 00266 if (pClass.isAssignableFrom(Calendar.class)) { 00267 return calendarTypeConverter; 00268 } 00269 if (pClass.isAssignableFrom(Object[].class)) { 00270 return objectArrayTypeConverter; 00271 } 00272 if (pClass.isAssignableFrom(List.class)) { 00273 return listTypeConverter; 00274 } 00275 if (pClass.isAssignableFrom(Vector.class)) { 00276 return vectorTypeConverter; 00277 } 00278 if (pClass.isAssignableFrom(Map.class)) { 00279 return mapTypeConverter; 00280 } 00281 if (pClass.isAssignableFrom(Hashtable.class)) { 00282 return hashTableTypeConverter; 00283 } 00284 if (pClass.isAssignableFrom(Properties.class)) { 00285 return propertiesTypeConverter; 00286 } 00287 if (pClass.isAssignableFrom(byte[].class)) { 00288 return byteArrayTypeConverter; 00289 } 00290 if (pClass.isAssignableFrom(Document.class)) { 00291 return domTypeConverter; 00292 } 00293 if (Serializable.class.isAssignableFrom(pClass)) { 00294 return new CastCheckingTypeConverter(pClass); 00295 } 00296 throw new IllegalStateException("Invalid parameter or result type: " + pClass.getName()); 00297 } 00298 }