Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.codetaco.cli.impl.variables.VariableAssigner Maven / Gradle / Ivy
package com.codetaco.cli.impl.variables;
import com.codetaco.cli.CliException;
import com.codetaco.cli.impl.CmdLineImpl;
import com.codetaco.cli.impl.type.CmdLineCLA;
import com.codetaco.cli.impl.type.EnumCLA;
import com.codetaco.cli.impl.type.ICmdLineArg;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
public class VariableAssigner implements IVariableAssigner {
static private IVariableAssigner instance;
static private void assign(Field field,
ICmdLineArg> arg,
Object target)
throws ParseException {
if (arg.getVariable() == null) {
return;
}
if (arg.getValue() == null) {
return;
}
if (field == null) {
return;
}
/*
* Allows access to non-public fields.
*/
field.setAccessible(true);
if (!(arg instanceof CmdLineCLA) && arg.getFactoryMethodName() != null) {
assignWithInstantiator(field, arg, target);
} else {
assignStandard(field, arg, target);
}
}
/**
* This value may not be appropriate for the list. But since this is at
* runtime we can't make use of the generics definition they may have
* provided on the field. If the value is not what they expect then they
* need to provide a --factory set of methods.
*/
private static void assignList(Field field,
ICmdLineArg> arg,
Object target) throws IllegalAccessException {
Collection alist = (Collection) field.get(target);
if (alist == null) {
alist = new ArrayList<>();
field.set(target, alist);
}
for (int v = 0; v < arg.size(); v++) {
alist.add(arg.getDelegateOrValue(v));
}
}
static private void assignStandard(Field field,
ICmdLineArg> arg,
Object target) throws ParseException {
String errMsg = "expected: public "
+ arg.getValue().getClass().getName()
+ " "
+ arg.getVariable()
+ " on "
+ target.getClass().getName();
try {
if (isStringArray(field)) {
field.set(target, arg.getValueAsStringArray());
} else if (isIntegerArray(field)) {
field.set(target, arg.getValueAsIntegerArray());
} else if (isintArray(field)) {
field.set(target, arg.getValueAsintArray());
} else if (isDoubleArray(field)) {
field.set(target, arg.getValueAsDoubleArray());
} else if (isdoubleArray(field)) {
field.set(target, arg.getValueAsdoubleArray());
} else if (isLongArray(field)) {
field.set(target, arg.getValueAsLongArray());
} else if (islongArray(field)) {
field.set(target, arg.getValueAslongArray());
} else if (isbyteArray(field)) {
field.set(target, arg.getValueAsbyteArray());
} else if (ischarArray(field)) {
field.set(target, arg.getValueAscharArray());
} else if (isfloatArray(field)) {
field.set(target, arg.getValueAsfloatArray());
} else if (isFloatArray(field)) {
field.set(target, arg.getValueAsFloatArray());
} else if (isPatternArray(field)) {
field.set(target, arg.getValueAsPatternArray());
} else if (isPattern(field)) {
field.set(target, arg.getValueAsPattern());
} else if (isDateTimeFormatterArray(field)) {
field.set(target, arg.getValueAsDateTimeFormatterArray());
} else if (isDateTimeFormatter(field)) {
field.set(target, arg.getValueAsDateTimeFormatter());
} else if (isSimpleDateFormatArray(field)) {
field.set(target, arg.getValueAsSimpleDateFormatArray());
} else if (isSimpleDateFormat(field)) {
field.set(target, arg.getValueAsSimpleDateFormat());
} else if (isEquationArray(field)) {
field.set(target, arg.getValueAsEquationArray());
} else if (isEquation(field)) {
field.set(target, arg.getValueAsEquation());
} else if (isDateArray(field)) {
field.set(target, arg.getValueAsDateArray());
} else if (isCalendarArray(field)) {
field.set(target, arg.getValueAsCalendarArray());
} else if (isLocalDateTimeArray(field)) {
field.set(target, arg.getValueAsLocalDateTimeArray());
} else if (isZonedDateTimeArray(field)) {
field.set(target, arg.getValueAsZonedDateTimeArray());
} else if (isLocalDateArray(field)) {
field.set(target, arg.getValueAsLocalDateArray());
} else if (isLocalTimeArray(field)) {
field.set(target, arg.getValueAsLocalTimeArray());
} else if (isByteArray(field)) {
field.set(target, arg.getValueAsByteArray());
} else if (isCharacterArray(field)) {
field.set(target, arg.getValueAsCharacterArray());
} else if (isFileArray(field)) {
field.set(target, arg.getValueAsFileArray());
} else if (isURLArray(field)) {
field.set(target, arg.getValueAsURLArray());
} else if (isEnum(field)) {
field.set(target, arg.asEnum(field.getName(), field.getType().getEnumConstants()));
} else if (isEnumArray(field)) {
throw new ParseException("enum[] is not support at this time. Use String[] and @Arg(inEnum=\"fully qualified enum class name\")", -1);
// field.set(target,
// arg.asEnumArray(field.getName(), field.getType().getComponentType().getEnumConstants()));
} else if (isList(field)) {
assignList(field, arg, target);
} else {
field.set(target, arg.getDelegateOrValue());
}
} catch (SecurityException e) {
throw new ParseException("SecurityException: " + errMsg, -1);
} catch (IllegalArgumentException e) {
throw new ParseException(e.toString() + ": " + errMsg, -1);
} catch (IllegalAccessException e) {
throw new ParseException("IllegalAccessException: " + errMsg, -1);
}
}
static private void assignWithInstantiator(Field field,
ICmdLineArg> arg,
Object target) throws ParseException {
Class> clazz = null;
Method method = null;
String baseClassName;
if (field.getType().getName().charAt(0) == '[') {
baseClassName = field.getType().getName().substring(2, field.getType().getName().length() - 1);
} else if (arg.getInstanceClass() != null) {
baseClassName = arg.getInstanceClass();
} else {
baseClassName = field.getType().getName();
}
String errMsg = null;
try {
int methodPvt = arg.getFactoryMethodName().lastIndexOf('.');
Class> parmClass = arg.getValue(0).getClass();
if (methodPvt < 0) {
/*
* It is too bad that the generic info on a field is not public.
* So here we can't determine the generic type of a list. To addPattern
* multi value items to a list the --class parameter must be
* used.
*/
/*-
if (field.getType().getPackage().getName().startsWith("java."))
throw new ParseException("Generics with a factory method must use --class", 0);
*/
errMsg = "expected: public static "
+ baseClassName
+ " "
+ arg.getFactoryMethodName()
+ "("
+ parmClass.getName()
+ ") on "
+ baseClassName;
clazz = CmdLineImpl.ClassLoader.loadClass(baseClassName);
method = clazz.getDeclaredMethod(arg.getFactoryMethodName(), parmClass);
} else {
errMsg = "expected: public static "
+ arg.getFactoryMethodName().substring(0, methodPvt)
+ " "
+ arg.getFactoryMethodName().substring(methodPvt + 1)
+ "("
+ parmClass.getName()
+ ") on "
+ arg.getFactoryMethodName().substring(0, methodPvt);
clazz = CmdLineImpl.ClassLoader.loadClass(arg.getFactoryMethodName().substring(0, methodPvt));
method = clazz.getDeclaredMethod(arg.getFactoryMethodName().substring(methodPvt + 1), parmClass);
}
if (arg.isMultiple()) {
if (field.getType().getName().charAt(0) == '[') {
for (int r = 0; r < arg.size(); r++) {
Object[] array = newArray(target, field);
array[array.length - 1] = method.invoke(null, arg.getValue(r));
}
} else {
for (int r = 0; r < arg.size(); r++) {
ArrayList arrayList = newList(target, field);
arrayList.add(method.invoke(null, arg.getValue(r)));
}
}
} else {
field.set(target, method.invoke(null, arg.getValue()));
}
} catch (InstantiationException e) {
throw new ParseException("InstantiationException " + errMsg, -1);
} catch (ClassNotFoundException e) {
throw new ParseException("ClassNotFoundException " + errMsg, -1);
} catch (InvocationTargetException e) {
throw new ParseException("InvocationTargetException " + errMsg, -1);
} catch (IllegalAccessException e) {
throw new ParseException("IllegalAccessException " + errMsg, -1);
} catch (IllegalArgumentException e) {
e.printStackTrace();
throw new ParseException("IllegalArgumentException " + errMsg, -1);
} catch (SecurityException e) {
throw new ParseException("SecurityException " + errMsg, -1);
} catch (NoSuchMethodException e) {
throw new ParseException("NoSuchMethodException " + errMsg, -1);
}
}
static private String factoryArgValue(ICmdLineArg> arg) {
try {
if (arg == null) {
return null;
}
if (!arg.isParsed()) {
return null;
}
if (arg instanceof EnumCLA) {
Class> clazz = CmdLineImpl.ClassLoader.loadClass(arg.getInstanceClass());
Object[] possibleConstants = clazz.getEnumConstants();
return arg.asEnum((String) arg.getValue(), possibleConstants).toString();
}
return (String) arg.getValue();
} catch (ClassNotFoundException | CliException e) {
e.printStackTrace();
return (String) arg.getValue();
}
}
static public Field findFieldInAnyParentOrMyself(ICmdLineArg> arg,
Class> targetClass,
String errMsg) throws ParseException {
Field field = null;
try {
field = targetClass.getDeclaredField(arg.getVariable());
} catch (SecurityException e) {
throw new ParseException("SecurityException " + errMsg, -1);
} catch (NoSuchFieldException e) {
if (targetClass.getSuperclass() == null) {
throw new ParseException("NoSuchFieldException " + errMsg, -1);
}
/*
* recursive from here
*/
return findFieldInAnyParentOrMyself(arg, targetClass.getSuperclass(), errMsg);
}
return field;
}
static public IVariableAssigner getInstance() {
if (instance == null) {
instance = new VariableAssigner();
}
return instance;
}
private static boolean isbyteArray(Field field) {
return "[B".equals(field.getType().getName());
}
private static boolean isByteArray(Field field) {
return "[Ljava.lang.Byte;".equals(field.getType().getName());
}
private static boolean isCalendarArray(Field field) {
return "[Ljava.util.Calendar;".equals(field.getType().getName());
}
private static boolean isCharacterArray(Field field) {
return "[Ljava.lang.Character;".equals(field.getType().getName());
}
private static boolean ischarArray(Field field) {
return "[C".equals(field.getType().getName());
}
private static boolean isDateArray(Field field) {
return "[Ljava.util.Date;".equals(field.getType().getName());
}
private static boolean isDateTimeFormatter(Field field) {
return "java.time.format.DateTimeFormatter".equals(field.getType().getName());
}
private static boolean isDateTimeFormatterArray(Field field) {
return "[Ljava.time.format.DateTimeFormatter;".equals(field.getType().getName());
}
private static boolean isdoubleArray(Field field) {
return "[D".equals(field.getType().getName());
}
private static boolean isDoubleArray(Field field) {
return "[Ljava.lang.Double;".equals(field.getType().getName());
}
static private boolean isEnum(Field field) {
return field.getType().isEnum();
}
static private boolean isEnumArray(Field field) {
return field.getType().isArray() && field.getType().getComponentType().isEnum();
}
private static boolean isEquation(Field field) {
return "com.codetaco.math.Equ".equals(field.getType().getName());
}
private static boolean isEquationArray(Field field) {
return "[Lcom.codetaco.math.Equ;".equals(field.getType().getName());
}
private static boolean isFileArray(Field field) {
return "[Ljava.io.File;".equals(field.getType().getName());
}
private static boolean isURLArray(Field field) {
return "[Ljava.net.URL;".equals(field.getType().getName());
}
private static boolean isfloatArray(Field field) {
return "[F".equals(field.getType().getName());
}
private static boolean isFloatArray(Field field) {
return "[Ljava.lang.Float;".equals(field.getType().getName());
}
private static boolean isintArray(Field field) {
return "[I".equals(field.getType().getName());
}
private static boolean isIntegerArray(Field field) {
return "[Ljava.lang.Integer;".equals(field.getType().getName());
}
static private boolean isList(Field field) {
Class>[] interfaces = field.getType().getInterfaces();
if (interfaces.length == 0) {
return false;
}
for (Class> iface : interfaces) {
if (Collection.class.getName().equals(iface.getName())) {
return true;
}
}
return false;
}
private static boolean isLocalDateArray(Field field) {
return "[Ljava.time.LocalDate;".equals(field.getType().getName());
}
private static boolean isLocalDateTimeArray(Field field) {
return "[Ljava.time.LocalDateTime;".equals(field.getType().getName());
}
private static boolean isZonedDateTimeArray(Field field) {
return "[Ljava.time.ZonedDateTime;".equals(field.getType().getName());
}
private static boolean isLocalTimeArray(Field field) {
return "[Ljava.time.LocalTime;".equals(field.getType().getName());
}
private static boolean islongArray(Field field) {
return "[J".equals(field.getType().getName());
}
private static boolean isLongArray(Field field) {
return "[Ljava.lang.Long;".equals(field.getType().getName());
}
private static boolean isPattern(Field field) {
return "java.util.regex.Pattern".equals(field.getType().getName());
}
private static boolean isPatternArray(Field field) {
return "[Ljava.util.regex.Pattern;".equals(field.getType().getName());
}
private static boolean isSimpleDateFormat(Field field) {
return "java.text.SimpleDateFormat".equals(field.getType().getName());
}
private static boolean isSimpleDateFormatArray(Field field) {
return "[Ljava.text.SimpleDateFormat;".equals(field.getType().getName());
}
private static boolean isStringArray(Field field) {
return "[Ljava.lang.String;".equals(field.getType().getName());
}
static private Object[] newArray(Object target,
Field field)
throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Object[] oldinstance = (Object[]) field.get(target);
int oldsize = 0;
if (oldinstance != null) {
oldsize = oldinstance.length;
}
Object[] arrayinstance = (Object[]) Array.newInstance(field.getType().getComponentType(), oldsize + 1);
int i = 0;
if (oldinstance != null) {
for (; i < oldsize; i++) {
arrayinstance[i] = oldinstance[i];
}
}
field.set(target, arrayinstance);
return arrayinstance;
}
static private Object newInstanceForGroup(CmdLineCLA group,
Object target,
Field field,
String _baseClassName,
ICmdLineArg> factoryValueArg,
boolean reusable)
throws ClassNotFoundException,
InstantiationException,
IllegalAccessException,
SecurityException,
NoSuchMethodException,
IllegalArgumentException,
InvocationTargetException,
ParseException {
String baseClassName = _baseClassName;
Object groupInstance;
if (baseClassName == null) {
if (group.getInstanceClass() != null) {
baseClassName = group.getInstanceClass();
} else {
baseClassName = field.getType().getName();
}
}
/*
* Allow an instantiated instance variable to be used rather than
* replaced.
*/
if (reusable && field.get(target) != null) {
Object value = field.get(target);
if (!value.getClass().getName().equals(baseClassName)) {
throw new ParseException("Error in instance creation for \"" + group.toString() + "\", "
+ value.getClass().getName() + " can not be reassigned to " + baseClassName, 0);
}
return value;
}
Class> clazz;
Method method;
/*
* Get the proper constructor and possible cli to create the
* instance
*/
if (group.getFactoryMethodName() != null) {
int methodPvt = group.getFactoryMethodName().lastIndexOf('.');
String factoryValue = factoryArgValue(factoryValueArg);
if (methodPvt < 0) {
clazz = CmdLineImpl.ClassLoader.loadClass(baseClassName);
if (factoryValue == null) {
method = clazz.getDeclaredMethod(group.getFactoryMethodName());
} else {
method = clazz.getDeclaredMethod(group.getFactoryMethodName(), String.class);
}
} else {
clazz = CmdLineImpl.ClassLoader.loadClass(group.getFactoryMethodName().substring(0, methodPvt));
if (factoryValue == null) {
method = clazz.getDeclaredMethod(group.getFactoryMethodName().substring(methodPvt + 1));
} else {
method = clazz
.getDeclaredMethod(group.getFactoryMethodName().substring(methodPvt + 1), String.class);
}
}
if (factoryValue == null) {
groupInstance = method.invoke(clazz);
} else {
groupInstance = method.invoke(clazz, factoryValue);
}
} else {
clazz = CmdLineImpl.ClassLoader.loadClass(baseClassName);
groupInstance = clazz.newInstance();
}
return groupInstance;
}
static private ArrayList newList(Object target,
Field field)
throws ClassNotFoundException, IllegalAccessException, InstantiationException {
ArrayList oldinstance = (ArrayList) field.get(target);
if (oldinstance == null) {
oldinstance = new ArrayList<>();
field.set(target, oldinstance);
}
return oldinstance;
}
static public IVariableAssigner setInstance(IVariableAssigner newInstance) {
IVariableAssigner previousAssigner = instance;
instance = newInstance;
return previousAssigner;
}
@Override
public void assign(ICmdLineArg> arg,
Object target) throws ParseException {
if (arg == null) {
return;
}
if (target == null) {
return;
}
String errMsg = "expected: "
+ arg.getValue().getClass().getName()
+ " "
+ arg.getVariable()
+ " on "
+ target.getClass().getName();
Field field = findFieldInAnyParentOrMyself(arg, target.getClass(), errMsg);
assign(field, arg, target);
}
@Override
public Object newGroupVariable(CmdLineCLA group,
Object target,
ICmdLineArg> factoryValueArg) throws ParseException {
try {
if (group.getVariable() == null) {
return null;
}
if (target == null) {
return null;
}
Field field = target.getClass().getDeclaredField(group.getVariable());
/*
* Allows access to non-public fields.
*/
field.setAccessible(true);
Object groupInstance = null;
if (group.isMultiple()) {
String baseClassName;
if (group.getInstanceClass() != null) {
if (field.getType().getName().charAt(0) == '[') {
baseClassName = group.getInstanceClass();
Object[] array = newArray(target, field);
array[array.length - 1] = newInstanceForGroup(group, target, field, baseClassName,
factoryValueArg, false);
groupInstance = array[array.length - 1];
} else {
ArrayList arrayList = newList(target, field);
groupInstance = newInstanceForGroup(group, target, field, null, factoryValueArg, false);
arrayList.add(groupInstance);
}
} else if (field.getType().getName().charAt(0) == '[') {
baseClassName = field.getType().getName().substring(2, field.getType().getName().length() - 1);
Object[] array = newArray(target, field);
array[array.length - 1] = newInstanceForGroup(group, target, field, baseClassName, factoryValueArg,
false);
groupInstance = array[array.length - 1];
} else {
ArrayList arrayList = newList(target, field);
groupInstance = newInstanceForGroup(group, target, field, null, factoryValueArg, false);
arrayList.add(groupInstance);
}
} else {
groupInstance = newInstanceForGroup(group, target, field, null, factoryValueArg, true);
field.set(target, groupInstance);
}
return groupInstance;
} catch (ClassNotFoundException e) {
throw new ParseException("ClassNotFoundException (" + group.getVariable() + ")", -1);
} catch (InstantiationException e) {
e.printStackTrace();
throw new ParseException("InstantiationException (" + group.getVariable() + ")", -1);
} catch (IllegalAccessException e) {
throw new ParseException("IllegalAccessException (" + group.getVariable() + ")", -1);
} catch (SecurityException e) {
throw new ParseException("SecurityException (" + group.getVariable() + ")", -1);
} catch (NoSuchFieldException e) {
throw new ParseException("NoSuchFieldException ("
+ target.getClass().getSimpleName()
+ " "
+ group.getVariable()
+ ")", -1);
} catch (IllegalArgumentException e) {
throw new ParseException("IllegalArgumentException (" + group.getVariable() + ")", -1);
} catch (NoSuchMethodException e) {
throw new ParseException("NoSuchMethodException ("
+ target.getClass().getSimpleName()
+ " "
+ group.getVariable()
+ " "
+ group.getFactoryMethodName()
+ ")", -1);
} catch (InvocationTargetException e) {
throw new ParseException("InvocationTargetException (" + group.getVariable() + ")", -1);
}
}
}