package dev.easyref.util;
import java.text.*;
import java.util.*;
import java.lang.reflect.*;
class Argument {
protected Object array;
protected Argument(Class objClass) {
verifyClass(objClass);
}
protected void verifyClass(Class objClass) {
if ((array == null) || (!objClass.equals(Array.get(array, 0).getClass()))) {
array = Array.newInstance(objClass, 1);
}
}
protected Object getData(boolean nullAsClass) {
Object result = Array.get(array, 0);
if (!nullAsClass && (result instanceof Class)) {
result = null;
}
return result;
}
}
public class Arguments extends Vector {
protected boolean nullAsClass;
protected boolean methodError;
protected boolean showExceptions;
protected SimpleDateFormat sdfTranslator;
protected final static String[][] booleanStrings = new String[][] {
new String[] {"true", "false"},
new String[] {"yes", "no"},
new String[] {"1", "0"}
};
public Arguments() {
super();
nullAsClass = false;
displayExceptions();
forceEmpty();
setDateFormat("dd/MM/yyyy HH:mm:ss");
}
public Arguments(Object collectee) {
this();
collectData(collectee);
}
public void setDateFormat(String dateFormat) {
sdfTranslator = new SimpleDateFormat(dateFormat);
}
public void displayExceptions() {
showExceptions = true;
}
public void hideExceptions() {
showExceptions = false;
}
public void forceEmpty() {
methodError = false;
removeAllElements();
trimToSize();
}
public void collectData(Object dataObj) {
Object data = null;
Class c = dataObj.getClass();
Field[] fList = c.getDeclaredFields();
boolean af = false;
try {
for (int i = 0; i < fList.length; i++) {
Field f = fList[i];
af = f.isAccessible();
if (!af) {
f.setAccessible(true);
}
data = f.get(dataObj);
if (!af) {
f.setAccessible(false);
}
if (data != null) {
addElement(data);
} else {
addNull(f.getType());
}
}
} catch (Exception ex) {
forceEmpty();
ex.printStackTrace();
}
}
public Class[] getArgumentsTypes() {
Class[] result = null;
if (!isEmpty()) {
result = new Class[size()];
int count = 0;
Class classType = null;
Enumeration enum = elements();
Object obj = null;
Argument arg = null;
while (enum.hasMoreElements()) {
obj = enum.nextElement();
try {
classType = obj.getClass();
if (obj instanceof Argument) {
arg = (Argument)obj;
obj = arg.array;
if (arg.getData(nullAsClass) == null) {
classType = (Class)Array.get(obj, 0);
} else {
classType = obj.getClass().getComponentType();
}
}
} catch (Exception ex) {
}
result[count++] = classType;
classType = null;
}
}
return result;
}
public String toString() {
Object[] array = getArguments();
Object obj = null;
if (array == null) {
return "[NULL]";
} else {
int length = Array.getLength(array);
int lastItem = length - 1;
StringBuffer sb = new StringBuffer("[");
for (int i = 0; i < length; i++) {
obj = Array.get(array, i);
if (obj != null) {
sb.append(obj);
} else {
sb.append("[NULL]");
}
if (i < lastItem) {
sb.append(", ");
}
}
sb.append("]");
return sb.toString();
}
}
public Object[] getArguments() {
Object[] result = null;
if (!isEmpty()) {
result = new Object[size()];
int count = 0;
Object classData = null;
Enumeration enum = elements();
Object obj = null;
while (enum.hasMoreElements()) {
obj = enum.nextElement();
try {
classData = unWrapObject(obj);
} catch (Exception ex) {
}
result[count++] = classData;
classData = null;
}
}
return result;
}
public long[] getLongArray() {
long[] result = new long[size()];
try {
int i = 0;
Enumeration eId = elements();
Object xObj = null;
while (eId.hasMoreElements()) {
xObj = unWrapObject(eId.nextElement());
if (xObj instanceof Number) {
result[i++] = ((Number)xObj).longValue();
} else if (xObj instanceof String) {
result[i++] = Long.parseLong((String)xObj);
}
}
} catch (Exception ex) {
result = null;
}
return result;
}
public Object getInstance(String objClassName) {
Exception ex = null;
Object result = null;
Object[] args = null;
Class[] argTypes = null;
try {
args = getArguments();
argTypes = getArgumentsTypes();
Class objClass = Class.forName(objClassName);
Constructor con = objClass.getDeclaredConstructor(argTypes);
boolean ia = con.isAccessible();
if (!ia) {
con.setAccessible(true);
}
result = con.newInstance(args);
con.setAccessible(ia);
} catch (Exception ex0) {
ex = ex0;
methodError = true;
if (showExceptions) {
ex.printStackTrace();
}
} finally {
if (ex != null) {
// Report failure..
methodError = true;
String pType = null;
System.err.println("Constructor not found for class [" + objClassName + "] {");
System.err.print("\t" + objClassName.substring(objClassName.lastIndexOf(".") + 1) + " (");
for (int i = 0; i < argTypes.length; i++) {
pType = argTypes[i].getName();
pType = pType.substring(pType.lastIndexOf(".") + 1);
System.err.print(pType + " " + "p" + i);
if (i < argTypes.length - 1) {
System.err.print(", ");
}
}
System.err.println(");\r\n}");
if (showExceptions) {
ex.printStackTrace();
}
}
return result;
}
}
public Method getMethod(Object obj, String methodName) {
return getMethod(obj.getClass(), methodName);
}
public Method getMethod(Class objClass, String methodName) {
Exception ex = null;
Method result = null;
Class[] argTypes = null;
try {
argTypes = getArgumentsTypes();
// Get the method directly declared by the instance's class..
result = objClass.getDeclaredMethod(methodName, argTypes);
} catch (NoSuchMethodException nmsex) {
try {
// Get the method inherited by the instance's class from its parents..
result = objClass.getMethod(methodName, argTypes);
} catch (NoSuchMethodException nmsex0) {
ex = nmsex0;
} catch (Exception ex0) {
ex = ex0;
}
} catch (Exception ex1) {
ex = ex1;
} finally {
if (ex != null) {
// Report failure..
methodError = true;
String pType = null;
System.err.println("Method not found for class [" + objClass.getName() + "] {");
System.err.print("\t" + methodName + "(");
if (argTypes != null) {
for (int i = 0; i < argTypes.length; i++) {
pType = argTypes[i].getName();
pType = pType.substring(pType.lastIndexOf(".") + 1);
System.err.print(pType + " " + "p" + i);
if (i < argTypes.length - 1) {
System.err.print(", ");
}
}
}
System.err.println(");\r\n}");
if (showExceptions) {
ex.printStackTrace();
}
}
return result;
}
}
public Object runMethod(Object obj, String methodName) {
return runMethod(obj, getMethod(obj, methodName));
}
public boolean hadMethodError() {
return methodError;
}
public Object runMethod(Object obj, Method method) {
Object result = null;
try {
Class[] mTypes = method.getParameterTypes();
Class[] aTypes = getArgumentsTypes();
if (aTypes == null) {
aTypes = new Class[0];
}
if (mTypes.length == aTypes.length) {
for (int i = 0; i < aTypes.length; i++) {
if (!mTypes[i].equals(aTypes[i])) {
methodError = true;
return null;
}
}
Object[] args = getArguments();
boolean ia = method.isAccessible();
if (!ia) {
method.setAccessible(true);
}
result = method.invoke(obj, args);
method.setAccessible(ia);
} else {
methodError = true;
}
} catch (NullPointerException npe) {
methodError = true;
} catch (Exception ex) {
ex.printStackTrace();
} finally {
return result;
}
}
private boolean translateBoolean(String value) {
for (int i = 0; i < booleanStrings.length; i++) {
if (booleanStrings[i][0].equalsIgnoreCase(value)) {
return true;
} else if (booleanStrings[i][1].equalsIgnoreCase(value)) {
return false;
}
}
return false;
}
public void addElement(Object value, Class caster) {
if (caster == Date.class) {
try {
super.addElement(sdfTranslator.parse(value.toString()));
} catch (ParseException ex) {
}
} else if ((caster == boolean.class) || (caster == Boolean.class)) {
addElement(translateBoolean(value.toString()));
} else if ((caster == byte.class) || (caster == Byte.class)) {
addElement(Byte.parseByte(value.toString()));
} else if ((caster == double.class) || (caster == Double.class)) {
addElement(Double.parseDouble(value.toString()));
} else if ((caster == float.class) || (caster == Float.class)) {
addElement(Float.parseFloat(value.toString()));
} else if ((caster == int.class) || (caster == Integer.class)) {
addElement(Integer.parseInt(value.toString()));
} else if ((caster == long.class) || (caster == Long.class)) {
addElement(Long.parseLong(value.toString()));
} else if ((caster == short.class) || (caster == Short.class)) {
addElement(Short.parseShort(value.toString()));
} else {
addElement(value);
}
}
public void addElement(Object data) {
Class caster = data.getClass();
String value = String.valueOf(data);
if ((caster == boolean.class) || (caster == Boolean.class)) {
addElement(translateBoolean(value));
} else if ((caster == byte.class) || (caster == Byte.class)) {
addElement(Byte.parseByte(value));
} else if ((caster == double.class) || (caster == Double.class)) {
addElement(Double.parseDouble(value));
} else if ((caster == float.class) || (caster == Float.class)) {
addElement(Float.parseFloat(value));
} else if ((caster == int.class) || (caster == Integer.class)) {
addElement(Integer.parseInt(value));
} else if ((caster == long.class) || (caster == Long.class)) {
addElement(Long.parseLong(value));
} else if ((caster == short.class) || (caster == Short.class)) {
addElement(Short.parseShort(value));
} else {
super.addElement(data);
}
}
public static char unWrapChar(Object obj) {
return ((Character)unWrap(obj)).charValue();
}
public static boolean unWrapBoolean(Object obj) {
return ((Boolean)unWrap(obj)).booleanValue();
}
public static byte unWrapByte(Object obj) {
return ((Byte)unWrap(obj)).byteValue();
}
public static double unWrapDouble(Object obj) {
return ((Double)unWrap(obj)).doubleValue();
}
public static float unWrapFloat(Object obj) {
return ((Float)unWrap(obj)).floatValue();
}
public static int unWrapInteger(Object obj) {
return ((Integer)unWrap(obj)).intValue();
}
public static long unWrapLong(Object obj) {
return ((Long)unWrap(obj)).longValue();
}
public static short unWrapShort(Object obj) {
return ((Short)unWrap(obj)).shortValue();
}
public static Object unWrap(Object obj) {
return (obj instanceof Argument) ? ((Argument)obj).getData(false) : obj;
}
private Object unWrapObject(Object obj) {
return (obj instanceof Argument) ? ((Argument)obj).getData(nullAsClass) : obj;
}
public void addElement(boolean value) {
Argument o = createArrayObject(boolean.class);
Array.setBoolean(o.array, 0, value);
addElement(o);
}
public void addElement(byte value) {
Argument o = createArrayObject(byte.class);
Array.setByte(o.array, 0, value);
addElement(o);
}
public void addElement(char value) {
Argument o = createArrayObject(char.class);
Array.setChar(o.array, 0, value);
addElement(o);
}
public void addElement(double value) {
Argument o = createArrayObject(double.class);
Array.setDouble(o.array, 0, value);
addElement(o);
}
public void addElement(float value) {
Argument o = createArrayObject(float.class);
Array.setFloat(o.array, 0, value);
addElement(o);
}
public void addElement(int value) {
Argument o = createArrayObject(int.class);
Array.setInt(o.array, 0, value);
addElement(o);
}
public void addElement(long value) {
Argument o = createArrayObject(long.class);
Array.setLong(o.array, 0, value);
addElement(o);
}
public void addElement(short value) {
Argument o = createArrayObject(short.class);
Array.setShort(o.array, 0, value);
addElement(o);
}
public void setElementAt(boolean value, int index) {
Argument o = createArrayObject(boolean.class, this, index);
Array.setBoolean(o.array, 0, value);
}
public void setElementAt(byte value, int index) {
Argument o = createArrayObject(byte.class, this, index);
Array.setByte(o.array, 0, value);
}
public void setElementAt(char value, int index) {
Argument o = createArrayObject(char.class, this, index);
Array.setChar(o.array, 0, value);
}
public void setElementAt(double value, int index) {
Argument o = createArrayObject(double.class, this, index);
Array.setDouble(o.array, 0, value);
}
public void setElementAt(float value, int index) {
Argument o = createArrayObject(float.class, this, index);
Array.setFloat(o.array, 0, value);
}
public void setElementAt(int value, int index) {
Argument o = createArrayObject(int.class, this, index);
Array.setInt(o.array, 0, value);
}
public void setElementAt(long value, int index) {
Argument o = createArrayObject(long.class, this, index);
Array.setLong(o.array, 0, value);
}
public void setElementAt(short value, int index) {
Argument o = createArrayObject(short.class, this, index);
Array.setShort(o.array, 0, value);
}
public void insertElementAt(boolean value, int index) {
Argument o = createArrayObject(boolean.class);
Array.setBoolean(o.array, 0, value);
insertElementAt(o, index);
}
public void insertElementAt(byte value, int index) {
Argument o = createArrayObject(byte.class);
Array.setByte(o.array, 0, value);
insertElementAt(o, index);
}
public void insertElementAt(char value, int index) {
Argument o = createArrayObject(char.class);
Array.setChar(o.array, 0, value);
insertElementAt(o, index);
}
public void insertElementAt(double value, int index) {
Argument o = createArrayObject(double.class);
Array.setDouble(o.array, 0, value);
insertElementAt(o, index);
}
public void insertElementAt(float value, int index) {
Argument o = createArrayObject(float.class);
Array.setFloat(o.array, 0, value);
insertElementAt(o, index);
}
public void insertElementAt(int value, int index) {
Argument o = createArrayObject(int.class);
Array.setInt(o.array, 0, value);
insertElementAt(o, index);
}
public void insertElementAt(long value, int index) {
Argument o = createArrayObject(long.class);
Array.setLong(o.array, 0, value);
insertElementAt(o, index);
}
public void insertElementAt(short value, int index) {
Argument o = createArrayObject(short.class);
Array.setShort(o.array, 0, value);
insertElementAt(o, index);
}
public void addNull(Class classType) {
Argument o = createArrayObject(Class.class);
Array.set(o.array, 0, classType);
addElement(o);
}
public void setNullAt(Class classType, int index) {
Argument o = createArrayObject(Class.class);
Array.set(o.array, 0, classType);
setElementAt(o, index);
}
public void insertNullAt(Class classType, int index) {
Argument o = createArrayObject(Class.class);
Array.set(o.array, 0, classType);
insertElementAt(o, index);
}
private static Argument createArrayObject(Class objClass, Arguments args, int index) {
Argument result = null;
Object x = args.elementAt(index);
if (x instanceof Argument) {
result = (Argument)x;
result.verifyClass(objClass);
} else {
result = createArrayObject(objClass);
}
return result;
}
private static Argument createArrayObject(Class objClass) {
return new Argument(objClass);
}
}