Java tutorial
/* * 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