TypeConverterFactory.java :  » OSGi » nucleus8583 » org » nucleus8583 » oim » xml » Java Open Source

Java Open Source » OSGi » nucleus8583 
nucleus8583 » org » nucleus8583 » oim » xml » TypeConverterFactory.java
package org.nucleus8583.oim.xml;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

import org.nucleus8583.oim.converter.TypeConverter;
import org.nucleus8583.oim.util.ElExpression;
import org.nucleus8583.oim.util.StringUtil;
import org.w3c.dom.Element;

public abstract class TypeConverterFactory {
  private static final Map<Class<?>, String> primitives;

  static {
    primitives = new HashMap<Class<?>, String>();

    primitives.put(Byte.TYPE, "byte");
    primitives.put(Byte.class, "byte");

    primitives.put(Short.TYPE, "short");
    primitives.put(Short.class, "short");

    primitives.put(Integer.TYPE, "int");
    primitives.put(Integer.class, "int");

    primitives.put(Long.TYPE, "long");
    primitives.put(Long.class, "long");

    primitives.put(Float.TYPE, "float");
    primitives.put(Float.class, "float");

    primitives.put(Double.TYPE, "double");
    primitives.put(Double.class, "double");

    primitives.put(Void.TYPE, "void");
    primitives.put(Void.class, "void");

    primitives.put(Character.TYPE, "char");
    primitives.put(Character.class, "char");
  }

  private static boolean primitiveEquals(Class<?> a, Class<?> b) {
    String pa = primitives.get(a);
    String pb = primitives.get(b);

    if ((pa == null) || (pb == null)) {
      return false;
    }

    return pa.equals(pb);
  }

  private static boolean arrayEquals(Class<?>[] expected, Class<?>[] actual,
      boolean skipNull, boolean canBeInherited) {
    if (expected == actual) {
      return true;
    }

    if (expected == null) {
      return actual == null;
    }
    if (actual == null) {
      return expected == null;
    }

    if (expected.length != actual.length) {
      return false;
    }

    Class<?> exp, act;

    for (int i = expected.length - 1; i >= 0; --i) {
      exp = expected[i];
      act = actual[i];

      if ((exp == null) && (act != null) && !skipNull) {
        return false;
      }
      if ((exp != null) && (act == null) && !skipNull) {
        return false;
      }

      if ((exp != null) && (act != null)) {
        if (!primitiveEquals(exp, act)) {
          if (canBeInherited) {
            if (!act.isAssignableFrom(exp)) {
              return false;
            }
          } else {
            if (!act.equals(exp)) {
              return false;
            }
          }
        }
      }
    }

    return true;
  }

  public static TypeConverter parse(Element node) {
    String name = node.getAttribute("name");
    String className = node.getAttribute("class");
    String ctorArguments = node.getAttribute("constructor-args");

    // name
    if (!StringUtil.hasText(name)) {
      throw new IllegalArgumentException("name required");
    }

    name = name.trim();

    // class
    if (!StringUtil.hasText(className)) {
      throw new IllegalArgumentException("class name required");
    }

    // constructor-args
    Object[] args = null;

    if (StringUtil.hasText(ctorArguments)) {
      args = (Object[]) ElExpression.eval(ctorArguments);
    }

    // create instance
    Class<?> _class;

    try {
      _class = Class.forName(className, true, Thread.currentThread()
          .getContextClassLoader());
    } catch (ClassNotFoundException e) {
      throw new RuntimeException("unable to find class " + className);
    }

    Object instance;

    if ((args == null) || (args.length == 0)) {
      try {
        instance = _class.newInstance();
      } catch (InstantiationException e) {
        throw new RuntimeException("unable to instantiate class "
            + className + " using default constructor", e);
      } catch (IllegalAccessException e) {
        throw new RuntimeException("unable to instantiate class "
            + className + " using default constructor", e);
      }
    } else {
      Class<?>[] argsTypes = new Class<?>[args.length];

      for (int i = args.length - 1; i >= 0; --i) {
        Object obj = args[i];

        if (obj == null) {
          argsTypes[i] = null;
        } else {
          argsTypes[i] = obj.getClass();
        }
      }

      Constructor<?>[] ctors = _class.getConstructors();
      instance = null;

      for (int i = ctors.length - 1; i >= 0; --i) {
        Constructor<?> ctor = ctors[i];

        if (arrayEquals(argsTypes, ctor.getParameterTypes(), true, true)) {
          try {
            instance = ctor.newInstance(args);
          } catch (IllegalArgumentException e) {
            throw new RuntimeException(
                "unable to instantiate class " + className
                    + " using matched constructor", e);
          } catch (InstantiationException e) {
            throw new RuntimeException(
                "unable to instantiate class " + className
                    + " using matched constructor", e);
          } catch (IllegalAccessException e) {
            throw new RuntimeException(
                "unable to instantiate class " + className
                    + " using matched constructor", e);
          } catch (InvocationTargetException e) {
            throw new RuntimeException(
                "unable to instantiate class " + className
                    + " using matched constructor", e);
          }
          break;
        }

        if (instance == null) {
          throw new RuntimeException(
              "no matched constructor found in class "
                  + className);
        }
      }
    }

    if (!TypeConverter.class.isInstance(instance)) {
      throw new ClassCastException(className + " is not a converter");
    }

    TypeConverter converter = (TypeConverter) instance;
    converter.setName(name);

    return converter;
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.