ips1ap101.lib.core.util.ClassX.java Source code

Java tutorial

Introduction

Here is the source code for ips1ap101.lib.core.util.ClassX.java

Source

/*
 * Este programa es software libre; usted puede redistribuirlo y/o modificarlo bajo los trminos
 * de la licencia "GNU General Public License" publicada por la Fundacin "Free Software Foundation".
 * Este programa se distribuye con la esperanza de que pueda ser til, pero SIN NINGUNA GARANTIA;
 * vea la licencia "GNU General Public License" para obtener mas informacin.
 */
package ips1ap101.lib.core.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import ips1ap101.lib.core.CoreBundle;
import ips1ap101.lib.core.app.Bitacora;
import org.apache.commons.lang.StringUtils;

/**
 * @author Jorge Campins
 */
public class ClassX {

    private static final ClassX me;

    static {
        me = new ClassX();
    }

    public static ClassX get() {
        return me;
    }

    private Map<String, Class<?>> cache;

    private String PACKAGE;

    private String SUFFIX;

    private String SIMPLE;

    protected ClassX() {
        cache = Collections.synchronizedMap(new HashMap<String, Class<?>>());
        PACKAGE = "subclass_package";
        SUFFIX = "subclass_suffix";
        SIMPLE = ClassX.class.getSimpleName();
    }

    protected Class<?> forName(String className) {
        Bitacora.trace(ClassX.class, "forName", className);
        try {
            return Class.forName(className);
        } catch (ClassNotFoundException ex) {
            Bitacora.logTrace(ex.toString());
            return null;
        }
    }

    public synchronized Object newInstance(Class<?> baseClass) {
        return newInstance(baseClass, "");
    }

    public synchronized Object newInstance(Class<?> baseClass, String subclassName) {
        return newInstance(baseClass, subclassName, new TypeValuePair[] {});
    }

    public synchronized Object newInstance(Class<?> baseClass, TypeValuePair... typeValuePairs) {
        return newInstance(baseClass, "", typeValuePairs);
    }

    public synchronized Object newInstance(Class<?> baseClass, String subclassName,
            TypeValuePair... typeValuePairs) {
        Bitacora.trace(ClassX.class, "newInstance", baseClass, subclassName);
        if (baseClass == null) {
            throw new IllegalArgumentException();
        }
        Class<?> classX = getClassX(baseClass, subclassName);
        try {
            if (typeValuePairs == null || typeValuePairs.length == 0) {
                return classX.newInstance();
            }
            Class<?>[] parameterTypes = getTypes(typeValuePairs);
            Object[] initargs = getValues(typeValuePairs);
            Constructor<?> constructor = classX.getConstructor(parameterTypes);
            return constructor.newInstance(initargs);
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException
                | IllegalArgumentException | InvocationTargetException ex) {
            throw new RuntimeException(ex);
        }
    }

    private Class<?> getClassX(Class<?> baseClass, String subclassName) {
        Class<?> classX;
        String name = baseClass.getName();
        if (cache.containsKey(name)) {
            classX = cache.get(name);
        } else {
            classX = getClassX(subclassName, baseClass);
            cache.put(name, classX);
        }
        return classX;
    }

    private Class<?> getClassX(String subclassName, Class<?> baseClass) {
        String sc = StringUtils.isBlank(subclassName) ? subclassName(baseClass) : subclassName;
        Class<?> subclass = forName(sc);
        return subclass != null && baseClass.isAssignableFrom(subclass) ? subclass : baseClass;
    }

    private Class<?>[] getTypes(TypeValuePair... typeValuePairs) {
        Class<?>[] types = new Class<?>[typeValuePairs.length];
        for (int i = 0; i < typeValuePairs.length; i++) {
            if (typeValuePairs[i] != null) {
                types[i] = typeValuePairs[i].getType();
            }
        }
        return types;
    }

    private Object[] getValues(TypeValuePair... typeValuePairs) {
        Object[] values = new Object[typeValuePairs.length];
        for (int i = 0; i < typeValuePairs.length; i++) {
            if (typeValuePairs[i] != null) {
                values[i] = typeValuePairs[i].getValue();
            }
        }
        return values;
    }

    public String subclassName(Class<?> baseClass) {
        return subclassName(baseClass, null);
    }

    public String subclassName(Class<?> baseClass, String subclassType) {
        Bitacora.trace(ClassX.class, "subclassName", baseClass, subclassType);
        if (baseClass == null) {
            throw new IllegalArgumentException();
        }
        String sp, ss;
        String st = StringUtils.trimToNull(subclassType);
        if (st == null) {
            sp = PACKAGE;
            ss = SUFFIX;
        } else {
            sp = st + "_" + PACKAGE;
            ss = st + "_" + SUFFIX;
        }
        sp = CoreBundle.getString(SIMPLE, sp);
        ss = CoreBundle.getString(SIMPLE, ss);
        return baseClass.getPackage().getName() + "." + sp + "." + baseClass.getSimpleName() + ss;
    }

} // ClassX