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;
}
}
Comments