Open Source Repository

Home /sojo/sojo-1.0.0 | Repository Home



net/sf/sojo/core/reflect/ReflectionHelper.java
/*
 * Copyright 2002-2005 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */  
package net.sf.sojo.core.reflect;

import java.lang.reflect.Constructor;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URL;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Collection;
import java.util.GregorianCalendar;
import java.util.Hashtable;
import java.util.Map;

import net.sf.sojo.util.StackTraceElementWrapper;
import net.sf.sojo.util.ThrowableWrapper;
import net.sf.sojo.util.Util;

/**
 * Helper class for use reflection for internal cases.
 
 @author linke
 *
 */
public final class ReflectionHelper {

  private final static Map isSimpleType = new Hashtable();
  
  static {
    isSimpleType.put(String.class, String.class);
    isSimpleType.put(Boolean.class, Boolean.class);
    isSimpleType.put(boolean.class, boolean.class);
    isSimpleType.put(Byte.class, Byte.class);
    isSimpleType.put(byte.class, byte.class);
    isSimpleType.put(Short.class, Short.class);
    isSimpleType.put(short.class, short.class);
    isSimpleType.put(Integer.class, Integer.class);
    isSimpleType.put(int.class, int.class);
    isSimpleType.put(Long.class, Long.class);
    isSimpleType.put(long.class, long.class);
    isSimpleType.put(Float.class, Float.class);
    isSimpleType.put(float.class, float.class);
    isSimpleType.put(Double.class, Double.class);
    isSimpleType.put(double.class, double.class);
    isSimpleType.put(Character.class, Character.class);
    isSimpleType.put(char.class, char.class);
    isSimpleType.put(BigDecimal.class, BigDecimal.class);
    isSimpleType.put(StringBuffer.class, StringBuffer.class);
    isSimpleType.put(BigInteger.class, BigInteger.class);
    isSimpleType.put(Class.class, Class.class);
    isSimpleType.put(java.sql.Date.class, java.sql.Date.class);
    isSimpleType.put(java.util.Date.class, java.util.Date.class);
    isSimpleType.put(Time.class, Time.class);
    isSimpleType.put(Timestamp.class, Timestamp.class);
    isSimpleType.put(Calendar.class, Calendar.class);
    isSimpleType.put(GregorianCalendar.class, GregorianCalendar.class);
    isSimpleType.put(URL.class, URL.class);
    isSimpleType.put(Object.class, Object.class);
  }
  
  protected ReflectionHelper() {}

  public static boolean isSimpleType(Object pvObject) {
    if (pvObject == null) { return false}
    return isSimpleType(pvObject.getClass());
  }

  public static boolean isSimpleType(Class pvClass) {
    if (pvClass == null) { return false}
    return isSimpleType.containsKey(pvClass);
  }
  
  public static void addSimpleType(Class pvSimpleType) {
    if (pvSimpleType != null) {
      isSimpleType.put(pvSimpleType, pvSimpleType);
    }
  }

  public static void removeSimpleType(Class pvSimpleType) {
    if (pvSimpleType != null) {
      isSimpleType.remove(pvSimpleType);
    }
  }

  
  public static boolean isMapType(Class pvType) {
    boolean lvReturn = false;
    if (pvType != null) {
      lvReturn = (Map.class.isAssignableFrom(pvType));
    }
    return lvReturn;
  }
  
  public static boolean isMapType(Object pvObject) {
    boolean lvReturn = false;
    if (pvObject == null) { 
      lvReturn = false;
    }
    else if (pvObject instanceof Map) {
      lvReturn = true;
    }

    return lvReturn;
  }
  
  public static boolean isIterateableType(Object pvObject) {
    boolean lvReturn = false;
    if (pvObject == null) { 
      lvReturn = false;
    }
    else if (pvObject instanceof Collection) {
      lvReturn = true;
    }
    else if (pvObject.getClass().isArray()) {
      lvReturn = true;
    }

    return lvReturn;
  }

  public static boolean isIterateableType(Class pvType) {
    boolean lvReturn = false;
    if (pvType == null) {
      lvReturn = false;
    }
    else if (Collection.class.isAssignableFrom(pvType)) {
      lvReturn = true;
    else if (pvType.isArray()) {
      lvReturn = true;
    }
    return lvReturn;
  }

  public static boolean isComplexMapType(Class pvType) {
    boolean lvReturn = true;
    if (pvType == null) { 
      lvReturn = false;
    }
    else if (isSimpleType(pvType)) {
      lvReturn = false;
    }
    else if (isIterateableType(pvType)) { 
      lvReturn = false;
    }
    else if (isMapType(pvType)) { 
      lvReturn = false;
    }

    return lvReturn;
  }
  
  public static boolean isComplexMapType(Object pvObject) {
    boolean lvReturn = isMapType(pvObject);
    if (lvReturn == true) {
      Map lvMap = (MappvObject;
      lvReturn = lvMap.containsKey(Util.getKeyWordClass());
    }
    return lvReturn;
  }

  public static boolean isComplexType(Object pvObject) {
    boolean lvReturn = true;
    if (pvObject == null) { 
      lvReturn = false;
    }
    else if (isSimpleType(pvObject)) {
      lvReturn = false;
    }
    else if (isIterateableType(pvObject)) { 
      lvReturn = false;
    }
    else if (isMapType(pvObject)) { 
      lvReturn = false;
    }
    
    return lvReturn;
  }

  public static boolean isComplexType(Class pvType) {
    boolean lvReturn = true;
    if (pvType == null) { 
      lvReturn = false;
    }
    else if (isSimpleType(pvType)) {
      lvReturn = false;
    }
    else if (isIterateableType(pvType)) {
      lvReturn = false;
    }
    else if (isMapType(pvType)) {
      lvReturn = false;
    }

    return lvReturn;
  }
  
  
  public static Object createNewSimpleObject(final Class pvSimpleClass, final Object pvSimpleParamObjectthrows InstantiationException {
    try {
        if (pvSimpleClass == null) { return null}
        String lvSimpleParamObjectString = "0";
        if (pvSimpleParamObject != null && pvSimpleParamObject.toString().length() 0) { 
          lvSimpleParamObjectString = pvSimpleParamObject.toString()
        }
        
        if (pvSimpleClass.equals(String.class)) { return lvSimpleParamObjectString; }
        else if (pvSimpleClass.equals(int.class)) { return Integer.valueOf(lvSimpleParamObjectString)}
        else if (pvSimpleClass.equals(Integer.class)) { return Integer.valueOf(lvSimpleParamObjectString)}
          else if (pvSimpleClass.equals(short.class)) { return Short.valueOf(lvSimpleParamObjectString)}
          else if (pvSimpleClass.equals(Short.class)) { return Short.valueOf(lvSimpleParamObjectString)}
          else if (pvSimpleClass.equals(byte.class))  { return Byte.valueOf(lvSimpleParamObjectString)}
          else if (pvSimpleClass.equals(Byte.class))  { return Byte.valueOf(lvSimpleParamObjectString)}
          else if (pvSimpleClass.equals(long.class))  { return Long.valueOf(lvSimpleParamObjectString)}
          else if (pvSimpleClass.equals(Long.class))  { return Long.valueOf(lvSimpleParamObjectString)}
  
          
          else if (pvSimpleClass.equals(double.class)) { return Double.valueOf(lvSimpleParamObjectString)}
          else if (pvSimpleClass.equals(Double.class)) { return Double.valueOf(lvSimpleParamObjectString)}
          else if (pvSimpleClass.equals(float.class)) { return Float.valueOf(lvSimpleParamObjectString)}
          else if (pvSimpleClass.equals(Float.class)) { return Float.valueOf(lvSimpleParamObjectString)}
  
          else if (pvSimpleClass.equals(char.class)) { return new Character(lvSimpleParamObjectString.charAt(0))}
          else if (pvSimpleClass.equals(Character.class)) { return new Character(lvSimpleParamObjectString.charAt(0))}
          
          else if (pvSimpleClass.equals(boolean.class)) { return Boolean.valueOf(lvSimpleParamObjectString)}
          else if (pvSimpleClass.equals(Boolean.class)) { return Boolean.valueOf(lvSimpleParamObjectString)}
        
          else if (pvSimpleClass.equals(BigDecimal.class)) { return new BigDecimal(lvSimpleParamObjectString)}
          else if (pvSimpleClass.equals(BigInteger.class)) { return new BigInteger(lvSimpleParamObjectString)}
        
          else if (pvSimpleClass.equals(StringBuffer.class)) { return new StringBuffer(lvSimpleParamObjectString)}
        
          else if (pvSimpleClass.equals(URL.class)) {
            try {
              return new URL(lvSimpleParamObjectString);
            catch (Exception e) {
              throw new InstantiationException("Can't create a new instance from type URL for String: " 
                  + lvSimpleParamObjectString + " (" + e + ")");
            }
          }
        
          else if (pvSimpleClass.equals(Class.class)) { 
            try {
              if (lvSimpleParamObjectString.startsWith("class ")) {
                lvSimpleParamObjectString = lvSimpleParamObjectString.substring("class ".length());
              }
          Class lvClass = ReflectionHelper.forName(lvSimpleParamObjectString);
          return lvClass;
        catch (Exception e) {
          throw new InstantiationException("Can't create a new instance from type class for String: " 
              + lvSimpleParamObjectString + " (" + e + ")");
        }
          }
        
          else if (pvSimpleClass.equals(java.sql.Date.class)) { 
            java.util.Date lvDate = Util.string2Date(lvSimpleParamObjectString)
            return new java.sql.Date(lvDate.getTime());
          }
          else if (pvSimpleClass.equals(java.util.Date.class)) { 
            return Util.string2Date(lvSimpleParamObjectString)
          }
          else if (pvSimpleClass.equals(Time.class)) { 
            return new Time(new Long(lvSimpleParamObjectString).longValue())}
          else if (pvSimpleClass.equals(Timestamp.class)) { 
            long lvTime = Util.string2Date(lvSimpleParamObjectString).getTime();
            return new Timestamp(lvTime);
          }
    catch (NumberFormatException e) {
      throw new InstantiationException("Can't create a new instance from type: " + pvSimpleClass.getName() 
                            " with constructor-argument: " + pvSimpleParamObject);
    }
      
      return pvSimpleParamObject;
  }
  

  
  public static Constructor findConstructorByParameterTypes(Class pvClass, Class pvParameterTypes[]) {
    Constructor[] lvConstructors = pvClass.getConstructors();
    for (int i = 0; i < lvConstructors.length; i++) {
      Class[] lvParamTypes = lvConstructors[i].getParameterTypes();
      if (pvParameterTypes.length == lvParamTypes.length) {
        boolean lvFind = true;
        for (int j = 0; j < lvParamTypes.length; j++) {
          if (lvParamTypes[j].equals(pvParameterTypes[j])) ) {
            lvFind = false;
          }
        }
        if (lvFind) {
          return lvConstructors[i];
        }
      }
    }
    
    return null;
  }
  

  public static Object createNewIteratableInstance(Class pvNewInstanceClass, int pvSize) {
    Object lvRetObj = null;
    try {
      Constructor lvConstructor = ReflectionHelper.findConstructorByParameterTypes(pvNewInstanceClass, new Class [] { int.class });
      if (lvConstructor != null) {
        lvRetObj = lvConstructor.newInstance(new Object[] { Integer.valueOf(Integer.toString(pvSize)) });
        
      else {
        lvRetObj = pvNewInstanceClass.newInstance();
      }
    catch (Exception e) {
      throw new IllegalArgumentException("Can't create a new instance of class : " + pvNewInstanceClass);
    }   
    return lvRetObj;
  }

  public static Object createBeanFromMap(final Map pvMap, final Class pvToTypethrows InstantiationException, IllegalAccessException {
    Object lvClass = null;
    if (pvMap != null) {
      lvClass = pvMap.get(Util.getKeyWordClass());
    }
    Class lvBeanType = pvToType;
    if (lvClass instanceof String) {
      try {
        lvBeanType = ReflectionHelper.forName(lvClass.toString());
      catch (ClassNotFoundException e) {
        throw new InstantiationException("Can't create a class for String: " + lvClass);
      }
    else if (lvClass instanceof Class) {
      lvBeanType = (ClasslvClass;
    }
    
    if (lvBeanType == null) {
      throw new NullPointerException("No type (class) was set for create a Bean. Map is: " 
          + pvMap + " an type is: " + pvToType);
    }
    
    Object lvBeanObject = null;
    try {
      lvBeanObject = lvBeanType.newInstance();
    catch (InstantiationException e) {
      throw new InstantiationException("Can't create a Bean from class: " + lvBeanType);
    catch (IllegalAccessException e) {
      throw new IllegalAccessException("Can't create a Bean from class: " + lvBeanType);
    }

    return lvBeanObject;
  }

  public static Class mapFromSimpeToWrapper(Class pvSimpleType ) {
    Class lvReturnClass = pvSimpleType;
    if (byte.class.equals(pvSimpleType)) {
      lvReturnClass = Byte.class;
    else if (short.class.equals(pvSimpleType)) {
      lvReturnClass = Short.class;
    else if (int.class.equals(pvSimpleType)) {
      lvReturnClass = Integer.class;
    else if (long.class.equals(pvSimpleType)) {
      lvReturnClass = Long.class;
    else if (float.class.equals(pvSimpleType)) {
      lvReturnClass = Float.class;
    else if (double.class.equals(pvSimpleType)) {
      lvReturnClass = Double.class;
    else if (char.class.equals(pvSimpleType)) {
      lvReturnClass = Character.class;
    else if (boolean.class.equals(pvSimpleType)) {
      lvReturnClass = Boolean.class;
    }      
    
    return lvReturnClass;
  }
  
  
  public static Throwable createThrowable(ThrowableWrapper pvThrowableWrapper) {
    return createThrowable(pvThrowableWrapper, null);
  }
  
  public static Throwable createThrowable(ThrowableWrapper pvThrowableWrapper, Class pvToClass) {
    Throwable lvThrowable = null;
    
    try {
      Class lvClass = pvToClass;
      if (lvClass == null) {
        lvClass = ReflectionHelper.forName(pvThrowableWrapper.getExceptionClassName());
      else if ! Throwable.class.isAssignableFrom(lvClass)) {
        throw new InstantiationException("The Class: " + lvClass.getName() " is not from type Throwable!");
      }
      
      Constructor lvConstructor = findConstructorByParameterTypes(lvClass, new Class [] { String.class, Throwable.class});
      if (lvConstructor != null) {
        ThrowableWrapper lvCauseWrapper = pvThrowableWrapper.getCauseWrapper();
        if (lvCauseWrapper != null) {
          Throwable lvCause = createThrowable(lvCauseWrapper, null);
          lvThrowable = (ThrowablelvConstructor.newInstance(new Object [] { pvThrowableWrapper.getMessage(), lvCause });
        else {
          lvThrowable = (ThrowablelvConstructor.newInstance(new Object [] { pvThrowableWrapper.getMessage()null});
        }        
      }
      else {
        lvConstructor = findConstructorByParameterTypes(lvClass, new Class [] { String.class});
        if (lvConstructor != null) {  
          lvThrowable = (ThrowablelvConstructor.newInstance(new Object [] { pvThrowableWrapper.getMessage() });
        else {
          lvConstructor = lvClass.getConstructor(null);
          if (lvConstructor != null) {  
            lvThrowable = (ThrowablelvConstructor.newInstance(null);
          
        }
      }
      

    catch (Exception e) {
      if (instanceof InstantiationException) {
        lvThrowable = e;
      else {
        lvThrowable = new InstantiationException(e.toString());
      }
    }
    
    StackTraceElementWrapper lvElementWrapper[] = pvThrowableWrapper.getStackTraceElementWrapperList();
    StackTraceElement lvElement[] new StackTraceElement[lvElementWrapper.length];
    for (int i = 0; i < lvElementWrapper.length; i++) {
      StackTraceElement lvSTE = lvElementWrapper[i].tryToCreateStackTraceElement();
      lvElement[i= lvSTE;
    }
    lvThrowable.setStackTrace(lvElement);

    
    
    return lvThrowable;
  }
  
  public static Class forName(String namethrows ClassNotFoundException {
    Class clazz = Class.forName(name, true, Thread.currentThread().getContextClassLoader());
    return clazz;
  }
}