package game.objects; import java.lang.reflect.*; import java.util.Arrays; import java.util.Date; /** * Why have your own initializer? Simple. This makes initialization of objects * much more manageable than just giving control to the JVM. Should the graphics * or actors be loaded first? You decide! Recommended for use when starting the * game. * * @author Link_The_Programmer * @version 1.0 * @ */ @SuppressWarnings("LocalVariableHidesMemberVariable") public final class Initializer extends ClassLoader { private static final String version = "1.0"; private static transient volatile Exception e; private static transient int numOfObjects = 0; private static transient Date date = new Date(); static { System.out.println("~Initializer.java version " + version); System.out.println(); } private Initializer() { } //[Constructor] public Initializer(Object obj) throws ClassNotFoundException, NoSuchFieldException { initialize(obj); System.out.println(obj + " initialized."); } public Initializer(Object[] obj) throws ClassNotFoundException, NoSuchFieldException, Exception { int mill1; int mill2; System.out.println("--[" + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds() + ":" + System.currentTimeMillis() / date.getSeconds() + "] Initializing objects..."); mill1 = (int) (System.currentTimeMillis() / date.getSeconds()); initialize(obj); System.out.println("--[" + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds() + ":" + System.currentTimeMillis() / date.getSeconds() + "] Objects initialized. Total quantity: " + numOfObjects); mill2 = (int) (mill1 - System.currentTimeMillis() / date.getSeconds()); System.out.println("--Time Elapsed: " + Math.abs(mill2) + " millisecond(s)"); System.out.println(); for (Object object : obj) { if (object == null) { System.err.println(e.getStackTrace()[e.getStackTrace().length - 1].getClassName() + ".Field" + Arrays.toString(e.getStackTrace()[e.getStackTrace().length - 1].getClassName().getBytes()) + "] not initialized; value = " + e.getLocalizedMessage()); } } } //[/Constructor] /** * Initializes an object. you must put the fully qualified name as the * parameter (complete package location with name) in order to work. * * @param obj * @return * @throws ClassNotFoundException */ @SuppressWarnings("BoxingBoxedValue") private synchronized void initialize(Object obj) throws NoSuchFieldException, ClassNotFoundException { setDefaultValue(obj); } /** * Initializes an array of objects. This does not actually initialize the * objects, it just checks them. Say you have an Image, perhaps the value * was null! * * * @param obj * @return * @throws ClassNotFoundException * @throws NoSuchFieldException * @throws Exception */ private synchronized void initialize(Object[] obj) throws ClassNotFoundException, NoSuchFieldException, Exception { if (obj != null) { try { throw new Exception(); } catch (Exception e) { for (Object object : obj) { initialize(object); Initializer.e = e; if (object instanceof Field || object instanceof Class) { if (object instanceof Field) { Field.setAccessible((AccessibleObject[]) obj, true); System.out.println(object + " initialized. value: " + getValue(object)); numOfObjects += 1; Field.setAccessible((AccessibleObject[]) obj, false); } else { System.out.println(((Class) object).getCanonicalName() + " initialized."); numOfObjects += 1; } } else { System.out.println(getContainingClass(object) + ".Field" + Arrays.toString(e.getStackTrace()[getStackSize() - 1].getClassName().getBytes()) + "] initialized. value: " + "(" + getInstanceAsString(object) + ")" + object); numOfObjects += 1; } } } } } private void setDefaultValue(Object obj) { if (obj instanceof Integer) { setValue(obj, 0); } else if (obj instanceof Byte) { setValue(obj, (byte) 00000000); } else if (obj instanceof Character) { setValue(obj, 'a'); } else if (obj instanceof String) { setValue(obj, ""); } else if (obj instanceof Boolean) { setValue(obj, false); } else if (obj instanceof Class) { setValue(obj, new Object()); } else if (obj instanceof Double) { setValue(obj, 0.0D); } else if (obj instanceof Float) { setValue(obj, 0.0f); } else if (obj instanceof Long) { setValue(obj, 0L); } else if (obj instanceof Short) { setValue(obj, 0); } else if (obj instanceof Thread) { setValue(obj, new Thread()); } } @SuppressWarnings("UnusedAssignment") private void setValue(Object obj, Object value) { if (getValue(obj) == null) { obj = value; } else { System.out.println(obj + " already has a value."); } } @SuppressWarnings("BoxingBoxedValue") public static Object getValue(Object obj) { Field f = (Field) obj; try { if (f.getType().isPrimitive() || f.getType().isSynthetic()) { return f.get(f); } else if (f.getType() == String.class || f.getType() == Character.class) { return f.get(f); } else if (f.getType() == Boolean.class) { return f.get(f); } else { return f.getType().getCanonicalName(); } } catch (IllegalArgumentException | IllegalAccessException ex) { } return null; } public static Object[] getClasses(Class clss) { return clss.getDeclaredClasses(); } public static Object[] getFields(Class clss) { return clss.getDeclaredFields(); } public static int getNumOfObjects() { return numOfObjects; } /** * Gets the stack object length. The stack object is Initializer.e (private field) * * @return the stack size */ @SuppressWarnings("BoxingBoxedValue") public static int getStackSize() { if (e != null) { return e.getStackTrace().length; } return 0; } /** * Gets the StackTrace context of this object. * * @return Exception e which is the Exception that has the stack being used. */ public static Exception getStackContext() { return Initializer.e; } /** * Gets the type of an object. * @param obj * @return the type of obj * @throws NoSuchFieldException */ public static Object getInstance(Object obj) throws NoSuchFieldException { return ((Class) obj).getTypeName(); } /** * Gets the type of an Object and returns it as a String object. * @param obj * @return the instance as a String object */ public static String getInstanceAsString(Object obj) { if (obj == null) { return "NullType"; } else if (obj instanceof Integer) { return "Integer"; } else if (obj instanceof Byte) { return "Byte"; } else if (obj instanceof Character) { return "Character"; } else if (obj instanceof String) { return "String"; } else if (obj instanceof Boolean) { return "Boolean"; } else if (obj instanceof Class) { return "Class"; } else if (obj instanceof Double) { return "Double"; } else if (obj instanceof Float) { return "Float"; } else if (obj instanceof Long) { return "Long"; } else if (obj instanceof Short) { return "Short"; } else if (obj instanceof Thread) { return "Thread"; } else if (obj instanceof Enum) { return "Enum"; } else if (obj instanceof Object[]) { return "Object[]"; } else { return "Unknown"; } } /** * Gets the class in which the object is declared in. This is equivalent to * @code{object.getClass().getDeclaringClass()} except it uses the stacktrace * in order to find that class. * @param obj * @return the class which the object is declared in. */ public static Class getContainingClass(Object obj) { return e.getStackTrace()[getStackSize() - 1].getClassName().getClass().getDeclaringClass(); } /** * Gets the version of Initializer.java * @return the version */ public static String getVersion() { return version; } }