Package org.eclipse.e4.xwt.internal.utils

Source Code of org.eclipse.e4.xwt.internal.utils.ObjectUtil

/*******************************************************************************
* Copyright (c) 2006, 2008 Soyatec (http://www.soyatec.com) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     Soyatec - initial API and implementation
*******************************************************************************/
package org.eclipse.e4.xwt.internal.utils;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.databinding.conversion.IConverter;
import org.eclipse.e4.xwt.XWT;

/**
* Object Tools.
*
* @author yyang (yves.yang@soyatec.com)
* @version 1.0
*/
public class ObjectUtil {

  public static final Class<?>[] EMPTY = new Class[0];

  private ObjectUtil() {
  }
 
  public static Class<?> normalizedType(Class<?> type) {
    if (type == int.class) {
      return Integer.class;
    }
    if (type == double.class) {
      return Double.class;
    }
    if (type == float.class) {
      return Float.class;
    }
    if (type == boolean.class) {
      return Boolean.class;
    }
    return type;
  }

  public static boolean isAssignableFrom(Class<?> source, Class<?> target) {
    if (normalizedType(source) == normalizedType(target)) {
      return true;
    }
    return source.isAssignableFrom(target);
  }
 
  /**
   * Find the compatible class. This includes superclasses, interfaces and so on.
   *
   * @param clazz
   *            the specified class.
   * @return Returns the class array includes its superclasses, interfaces and itself.
   */
  public static final Class<?>[] findCompatibleClasses(Class<?> clazz) {
    Set<Class<?>> classes = new LinkedHashSet<Class<?>>();

    // Add itself to list.
    classes.add(clazz);

    // Add primitive compatible type
    if (clazz == Boolean.class) {
      classes.add(boolean.class);
    } else if (clazz == Byte.class) {
      classes.add(byte.class);
    } else if (clazz == Short.class) {
      classes.add(short.class);
    } else if (clazz == Integer.class) {
      classes.add(int.class);
    } else if (clazz == Long.class) {
      classes.add(long.class);
    } else if (clazz == Float.class) {
      classes.add(float.class);
    } else if (clazz == Double.class) {
      classes.add(double.class);
    } else if (clazz == Character.class) {
      classes.add(char.class);
    } else if (clazz == boolean.class) {
      classes.add(Boolean.class);
    } else if (clazz == byte.class) {
      classes.add(Byte.class);
    } else if (clazz == short.class) {
      classes.add(Short.class);
    } else if (clazz == int.class) {
      classes.add(Integer.class);
    } else if (clazz == long.class) {
      classes.add(Long.class);
    } else if (clazz == float.class) {
      classes.add(Float.class);
    } else if (clazz == double.class) {
      classes.add(Double.class);
    } else if (clazz == char.class) {
      classes.add(Character.class);
    }

    // Add its interfaces
    findInterfaces(classes, clazz);

    // Add its superclasses
    findSuperClasses(classes, clazz);

    // At last, add Object class.
    classes.add(Object.class);

    return classes.toArray(EMPTY);
  }

  public static Object resolveValue(Object value, Class<?> targetType, Object defaultValue) {
    return resolveValue(value, value.getClass(), targetType, defaultValue);
  }

  public static Object resolveValue(Object value, Class<?> sourceType, Class<?> targetType, Object defaultValue) {
    IConverter converter = XWT.findConvertor(sourceType, targetType);
    if (converter != null) {
      return converter.convert(value);
    }
    return defaultValue;
  }

  /**
   * Find compatible constructor for specified class.
   *
   * @param clazz
   *            the specified class.
   * @param argumentTypes
   *            constructor argument types.
   * @return Returns constructor instance. If snot find, returns null.
   */
  public static final Constructor<?> findConstructor(Class<?> clazz, Class<?>... argumentTypes) {

    Class<?>[][] classesArray = new Class[argumentTypes.length][];

    for (int i = 0, len = argumentTypes.length; i < len; i++) {
      Class<?>[] classes = findCompatibleClasses(argumentTypes[i]);
      classesArray[i] = classes;
    }

    int totalPossibles = 1;
    for (int i = 0; i < classesArray.length; i++) {
      totalPossibles *= classesArray[i].length;
    }

    List<Class<?>[]> classList = new ArrayList<Class<?>[]>(totalPossibles);
    computeArguments(classList, classesArray, new Class[classesArray.length], 0);

    for (Class<?>[] arguments : classList) {
      try {
        return clazz.getConstructor(arguments);
      } catch (NoSuchMethodException e) {
        continue;
      }
    }

    return null;
  }

  /**
   * Find compatible public method for specified class.
   *
   * @param clazz
   *            the specified class.
   * @param name
   *            method name.
   * @param argumentTypes
   *            method argument types. If it is a null value, system will find method without argument types.
   * @return Returns method instance. If not find, returns null.
   */
  public static final Method findMethod(Class<?> clazz, String name, Class<?>... argumentTypes) {

    if (argumentTypes != null && argumentTypes.length > 0) {

      Class<?>[][] classesArray = new Class[argumentTypes.length][];

      for (int i = 0, len = argumentTypes.length; i < len; i++) {
        Class<?>[] classes = findCompatibleClasses(argumentTypes[i]);
        classesArray[i] = classes;
      }

      int totalPossibles = 1;
      for (int i = 0; i < classesArray.length; i++) {
        totalPossibles *= classesArray[i].length;
      }

      List<Class<?>[]> classList = new ArrayList<Class<?>[]>(totalPossibles);
      computeArguments(classList, classesArray, new Class[classesArray.length], 0);

      for (Class<?>[] arguments : classList) {
        try {
          return clazz.getDeclaredMethod(name, arguments);
        } catch (NoSuchMethodException e) {
          continue;
        }
      }
    } else {

      // find method without argument types;

      Method[] methods = clazz.getMethods();
      for (Method method : methods) {
        if (method.getName().equals(name)) {
          return method;
        }
      }
    }

    return null;
  }

  /**
   * Find compatible method for specified class.
   *
   * @param clazz
   *            the specified class.
   * @param name
   *            method name.
   * @param argumentTypes
   *            method argument types. If it is a null value, system will find method without argument types.
   * @return Returns method instance. If not find, returns null.
   */
  public static final Method findDeclaredMethod(Class<?> clazz, String name, Class<?>... argumentTypes) {

    if (argumentTypes != null && argumentTypes.length > 0) {

      Class<?>[][] classesArray = new Class[argumentTypes.length][];

      for (int i = 0, len = argumentTypes.length; i < len; i++) {
        Class<?>[] classes = findCompatibleClasses(argumentTypes[i]);
        classesArray[i] = classes;
      }

      int totalPossibles = 1;
      for (int i = 0; i < classesArray.length; i++) {
        totalPossibles *= classesArray[i].length;
      }

      List<Class<?>[]> classList = new ArrayList<Class<?>[]>(totalPossibles);
      computeArguments(classList, classesArray, new Class[classesArray.length], 0);

      for (Class<?>[] arguments : classList) {
        try {
          return clazz.getDeclaredMethod(name, arguments);
        } catch (NoSuchMethodException e) {
          continue;
        }
      }
    } else {

      // find method without argument types;
      Method[] methods = clazz.getDeclaredMethods();
      for (Method method : methods) {
        if (method.getName().equals(name) && method.getParameterTypes().length == 0) {
          return method;
        }
      }
    }
    Class<?> superclass = clazz.getSuperclass();
    if (superclass != null) {
      return findDeclaredMethod(superclass, name, argumentTypes);
    }

    return null;
  }

  /**
   * Find property getter method for specified class.
   *
   * @param clazz
   *            the specified class.
   * @param name
   *            property name
   * @param type
   *            property type. If it is a null value, system will find the suitable method.
   * @return Returns method instance. If not find, returns null.
   */
  public static final Method findGetter(Class<?> clazz, String name, Class<?> type) {
    if (name == null || name.length() == 0) {
      throw new IllegalArgumentException("Invalid getter method name, null value found");
    }

    String getterName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);

    Method method;
    try {
      method = clazz.getMethod(getterName, EMPTY);
    } catch (NoSuchMethodException e1) {

      // :Check if it is a boolean getter
      getterName = "is" + name.substring(0, 1).toUpperCase() + name.substring(1);
      try {
        method = clazz.getMethod(getterName, EMPTY);
        if (method.getReturnType() != Boolean.class && method.getReturnType() != boolean.class) {
          return null;
        }
      } catch (NoSuchMethodException e2) {
        method = findCaseIgnoreGetter(clazz, name, type);
      }
      // :~
    }

    if (type == null) {
      return method;
    } else {
      if (method != null) {
        Class<?> returnType = method.getReturnType();
        Class<?>[] types = findCompatibleClasses(type);
        for (Class<?> t : types) {
          if (t == returnType) {
            return method;
          }
        }
      }
    }

    return null;
  }

  private static Method findCaseIgnoreGetter(Class<?> clazz, String name, Class<?> type) {
    String getterName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
    String isName = "is" + name.substring(0, 1).toUpperCase() + name.substring(1);

    for (Method element : clazz.getMethods()) {
      if (element.getParameterTypes().length != 0) {
        continue;
      }
      if (element.getName().equalsIgnoreCase(getterName)) {
        return element;
      }
      if (element.getName().equalsIgnoreCase(isName) && element.getReturnType() != Boolean.class && element.getReturnType() != boolean.class) {
        return element;
      }
    }
    return null;
 
 
  /**
   * Find superclasses and add them to list.
   */
  private static void findSuperClasses(Set<Class<?>> list, Class<?> clazz) {
    if (clazz != null) {
      Class<?> superClass = clazz.getSuperclass();

      if (superClass != Object.class) {
        list.add(superClass);

        findInterfaces(list, superClass);

        findSuperClasses(list, superClass);
      }
    }
  }

  /**
   * Find interfaces and add them to list.
   */
  private static void findInterfaces(Set<Class<?>> list, Class<?> clazz) {
    if (clazz != null) {
      Class<?>[] interfaces = clazz.getInterfaces();

      for (Class<?> interfac1 : interfaces) {
        list.add(interfac1);
        findInterfaces(list, interfac1);
      }
    }
  }

  /**
   * Combine arithmetic.
   */
  private static void computeArguments(List<Class<?>[]> list, Class<?>[][] arguments, Class<?>[] buffer, int start) {
    if (start >= arguments.length) {
      Class<?>[] classes = new Class<?>[arguments.length];
      for (int i = 0; i < arguments.length; ++i) {
        classes[i] = buffer[i];
      }
      list.add(classes);
      return;
    }

    for (int i = 0; i < arguments[start].length; ++i) {
      buffer[start] = arguments[start][i];
      computeArguments(list, arguments, buffer, start + 1);
    }
  }
}
TOP

Related Classes of org.eclipse.e4.xwt.internal.utils.ObjectUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.