001package org.andromda.core.common; 002 003import java.lang.reflect.Constructor; 004import java.lang.reflect.Method; 005import java.util.HashMap; 006import java.util.Map; 007import org.apache.log4j.Logger; 008 009/** 010 * A class used for converting simple types to other types (i.e. 011 * java.lang.String to java.lang.Integer, etc). 012 * 013 * @author Chad Brandon 014 * @author Bob Fields 015 */ 016public class Converter 017{ 018 /** 019 * The prefix of the 'valueOf' method available on wrapper classes. 020 */ 021 private static final String VALUE_OF_METHOD_NAME = "valueOf"; 022 023 /** 024 * The logger instance. 025 */ 026 private static final Logger LOGGER = Logger.getLogger(Converter.class); 027 028 /** 029 * Attempts to convert the <code>object</code> to the <code>expectedType</code>. 030 * 031 * @param object the object to convert. 032 * @param expectedType the type to which it should be converted. 033 * @return the converted object 034 */ 035 public static Object convert( 036 Object object, 037 Class expectedType) 038 { 039 Method method = null; 040 try 041 { 042 if (expectedType == String.class) 043 { 044 object = object.toString(); 045 } 046 else if (expectedType == Class.class) 047 { 048 object = ClassUtils.loadClass(object.toString()); 049 } 050 else 051 { 052 final Class originalType = expectedType; 053 if (expectedType.isPrimitive()) 054 { 055 expectedType = (Class)primitiveWrappers.get(expectedType); 056 } 057 try 058 { 059 method = expectedType.getDeclaredMethod( 060 VALUE_OF_METHOD_NAME, 061 new Class[] {object.getClass()}); 062 object = method.invoke( 063 expectedType, 064 object); 065 } 066 catch (final NoSuchMethodException exception) 067 { 068 // - ignore 069 } 070 071 // - if we couldn't find the method try with the constructor 072 if (method == null) 073 { 074 Constructor constructor; 075 try 076 { 077 constructor = expectedType.getConstructor(new Class[] {originalType}); 078 object = constructor.newInstance(object); 079 } 080 catch (final NoSuchMethodException exception) 081 { 082 throw new IntrospectorException("Could not convert '" + object + "' to type '" + 083 expectedType.getName() + '\''); 084 } 085 } 086 } 087 } 088 catch (Throwable throwable) 089 { 090 if (throwable.getCause()!=null) 091 { 092 throwable = throwable.getCause(); 093 } 094 // At least output the location where the error happened, not the entire stack trace. 095 StackTraceElement[] trace = throwable.getStackTrace(); 096 String location = " AT " + trace[0].getClassName() + '.' + trace[0].getMethodName() + ':' + trace[0].getLineNumber(); 097 if (throwable.getMessage()!=null) 098 { 099 location += ' ' + throwable.getMessage(); 100 } 101 LOGGER.error("Converter " + throwable + " invoking " + object + " METHOD " + method + " WITH " + expectedType.getName() + location); 102 throw new IntrospectorException(throwable); 103 } 104 return object; 105 } 106 107 /** 108 * Stores each primitive and its associated wrapper class. 109 */ 110 private static final Map primitiveWrappers = new HashMap(); 111 112 /** 113 * Initialize the primitiveWrappers. 114 */ 115 static 116 { 117 primitiveWrappers.put( 118 boolean.class, 119 Boolean.class); 120 primitiveWrappers.put( 121 int.class, 122 Integer.class); 123 primitiveWrappers.put( 124 long.class, 125 Long.class); 126 primitiveWrappers.put( 127 short.class, 128 Short.class); 129 primitiveWrappers.put( 130 byte.class, 131 Byte.class); 132 primitiveWrappers.put( 133 float.class, 134 Float.class); 135 primitiveWrappers.put( 136 double.class, 137 Double.class); 138 primitiveWrappers.put( 139 char.class, 140 Character.class); 141 } 142}