
net.alantea.viewml.VmlUtils Maven / Gradle / Ivy
package net.alantea.viewml;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import net.alantea.liteprops.Property;
import net.alantea.utils.MultiMessages;
import net.alantea.viewml.handlers.ModelHandler;
import net.alantea.viewml.internal.ActionsLoader;
import net.alantea.viewml.internal.ModelsLoader;
import net.alantea.viewml.internal.Referencer;
/**
* The Class TxmlUtils.
*/
public final class VmlUtils
{
/**
* The Enum DIRECTION.
*/
public static enum LinkDirection
{
/** The To. */
To,
/** The From. */
From,
/** The Both. */
Both
}
/**
* Instantiates a new txml utils.
*/
private VmlUtils()
{
}
/**
* Do binding.
*
* @param parser the parser
* @param sourceClass the source class
* @param sourcePropertyName the source property name
* @param targetObject the target object
* @param targetClassName the target class name
* @param targetPropertyName the target property name
* @param direction the direction
* @throws VmlException the TXML exception
*/
public static void doClassBinding(VmlParser parser, String sourceClass, String sourcePropertyName, Object targetObject,
String targetClassName, String targetPropertyName, LinkDirection direction) throws VmlException
{
Class> cl;
try
{
cl = VmlUtils.class.getClassLoader().loadClass(sourceClass);
Property> sourceProperty = getProperty(null, sourcePropertyName, cl);
doInternalBinding(parser, sourceProperty, sourcePropertyName, targetObject,
targetClassName, targetPropertyName, direction);
}
catch (ClassNotFoundException e)
{
throw new VmlException(MultiMessages.get("VmlException.binding.unable", sourcePropertyName,
sourceClass, direction.name(), targetPropertyName, targetClassName));
}
}
/**
* Do listen.
*
* @param parser the parser
* @param sourceObject the source object
* @param sourcePropertyName the source property name
* @param action the action
* @throws VmlException the TXML exception
*/
public static void doListen(VmlParser parser, Object sourceObject, String sourcePropertyName, String action) throws VmlException
{
Property> sourceProperty = getProperty(sourceObject, sourcePropertyName, sourceObject.getClass());
VmlAction listener = ActionsLoader.getAction(action);
if (listener != null)
{
sourceProperty.addListener((o, n) -> listener.invoke());
}
}
/**
* Do binding.
*
* @param parser the parser
* @param sourceObject the source object
* @param sourcePropertyName the source property name
* @param targetObject the target object
* @param targetClassName the target class name
* @param targetPropertyName the target property name
* @param direction the direction
* @throws VmlException the TXML exception
*/
public static void doBinding(VmlParser parser, Object sourceObject, String sourcePropertyName, Object targetObject,
String targetClassName, String targetPropertyName, LinkDirection direction) throws VmlException
{
Property> sourceProperty = getProperty(sourceObject, sourcePropertyName, sourceObject.getClass());
doInternalBinding(parser, sourceProperty, sourcePropertyName, targetObject,
targetClassName, targetPropertyName, direction);
}
/**
* Do binding.
*
* @param parser the parser
* @param sourceProperty the source property
* @param sourcePropertyName the source property name
* @param targetObject the target object
* @param targetClassName the target class name
* @param targetPropertyName the target property name
* @param direction the direction
* @throws VmlException the TXML exception
*/
private static void doInternalBinding(VmlParser parser, Property> sourceProperty, String sourcePropertyName, Object targetObject,
String targetClassName, String targetPropertyName, LinkDirection direction) throws VmlException
{
boolean done = false;
String targetClName = targetClassName;
Property> targetProperty = null;
if (targetObject != null)
{
if (targetObject instanceof ModelHandler)
{
targetProperty = ((ModelHandler)targetObject).getProperty(targetPropertyName);
}
else
{
targetProperty = VmlUtils.getProperty(targetObject, targetPropertyName, targetObject.getClass());
}
targetClName = targetObject.getClass().getName();
}
else if (targetClName != null)
{
try
{
Class> realClass = VmlUtils.class.getClassLoader().loadClass(targetClassName);
targetProperty = VmlUtils.getProperty(null, targetPropertyName, realClass);
}
catch (ClassNotFoundException e)
{
throw new VmlException(MultiMessages.get("TXMLException.binding.unable", sourcePropertyName,
targetClassName, direction.name(), targetPropertyName, targetClassName));
}
}
else if (targetPropertyName != null)
{
targetProperty = (Property>) Referencer.getReference(targetPropertyName);
}
if ((targetProperty != null) && (sourceProperty != null))
{
done = doLink(sourceProperty, targetProperty, direction);
}
if (!done)
{
throw new VmlException(MultiMessages.get("TXMLException.binding.unable", sourcePropertyName,
direction.name(), targetPropertyName, targetClName));
}
}
/**
* Do link.
*
* @param sourceProperty the source property
* @param targetProperty the target property
* @param direction the direction
* @return true, if successful
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static boolean doLink(Property sourceProperty, Property targetProperty, LinkDirection direction)
{
boolean done = false;
Object targetBean = targetProperty.get();
Object sourceBean = targetProperty.get();
boolean valid = (sourceBean == null) || (targetBean == null) || (sourceBean.getClass().isAssignableFrom(targetBean.getClass()));
switch (direction)
{
case To :
targetProperty.unbind();
targetProperty.link(sourceProperty);
done = true;
break;
case From :
if (valid)
{
sourceProperty.unbind();
sourceProperty.link(targetProperty);
done = true;
}
break;
case Both :
if (valid)
{
sourceProperty.bind(targetProperty);
done = true;
}
break;
default :
// nothing
}
return done;
}
/**
* Gets the property.
*
* @param object the object
* @param propertyName the property name
* @return the property
* @throws VmlException the TXML exception
*/
public static Property> getProperty(Object object, String propertyName) throws VmlException
{
if (object instanceof Class)
{
return getProperty(null, propertyName, (Class>) object);
}
else
{
return getProperty(object, propertyName, object.getClass());
}
}
/**
* Gets the property.
*
* @param object the object
* @param property the property name
* @param theClass the class
* @return the property
* @throws VmlException the TXML exception
*/
public static Property> getProperty(Object object, String property, Class> theClass) throws VmlException
{
if (object instanceof ModelHandler)
{
return ((ModelHandler) object).getProperty(property);
}
Class> cl = theClass;
Property> prop = null;
if (cl == null)
{
cl = object.getClass();
}
try
{
Field field = cl.getDeclaredField(property);
field.setAccessible(true);
prop = (Property>) field.get(object);
}
catch (NoSuchFieldException e0)
{
try
{
Field field = cl.getDeclaredField(property + "Property");
field.setAccessible(true);
prop = (Property>) field.get(object);
}
catch (NoSuchFieldException e)
{
if (!Object.class.equals(cl))
{
prop = getProperty(object, property, cl.getSuperclass());
if (prop == null)
{
for (Class> c : cl.getInterfaces())
{
if (prop == null)
{
prop = getProperty(object, property, c);
}
}
}
}
}
catch (IllegalArgumentException | IllegalAccessException | SecurityException e)
{
// nothing
}
}
catch (IllegalArgumentException | IllegalAccessException | SecurityException e)
{
// nothing
}
if (prop == null)
{
throw new VmlException(MultiMessages.get("TXMLException.find.property.unable", property, cl.getName()));
}
return prop;
}
/**
* Gets the property from the model name.
*
* @param modelName the model name
* @return the property
* @throws VmlException the TXML exception
*/
public static Property> getProperty(String modelName) throws VmlException
{
String[] tokens = modelName.split("::");
if (tokens.length == 2)
{
return getProperty(null, ModelsLoader.getModelClassName(tokens[0]), tokens[1]);
}
else
{
return null;
}
}
/**
* Gets the property from the class hierarchy.
*
* @param target the target
* @param className the class name
* @param propertyName the property name
* @return the property
* @throws VmlException the TXML exception
*/
public static Property> getProperty(Object target, String className, String propertyName) throws VmlException
{
return getProperty(target, className, propertyName, null);
}
/**
* Gets the property from the class hierarchy.
*
* @param theTarget the the target
* @param className the class name
* @param propertyName the property name
* @param baseClass the base class or null for initialization
* @return the property
* @throws VmlException the TXML exception
*/
private static Property> getProperty(Object theTarget, String className, String propertyName, Class> baseClass) throws VmlException
{
Object target = theTarget;
Class> cl = baseClass;
if ((cl == null) && (className != null))
{
Object ref = Referencer.getReference(className);
if (ref == null)
{
try
{
cl = VmlUtils.class.getClassLoader().loadClass(className);
}
catch (ClassNotFoundException e)
{
return null;
}
}
else
{
target = ref;
}
}
Property> prop = null;
try
{
Field field = cl.getDeclaredField(propertyName);
field.setAccessible(true);
prop = (Property>) field.get(target);
}
catch (NoSuchFieldException e)
{
if (!Object.class.equals(cl))
{
prop = getProperty(target, className, propertyName, cl.getSuperclass());
}
}
catch (IllegalArgumentException | IllegalAccessException | SecurityException e)
{
// nothing;
}
if (prop == null)
{
throw new VmlException(MultiMessages.get("TXMLException.find.property.unable", propertyName, cl.getName()));
}
return prop;
}
/**
* Gets the boolean value.
*
* @param value the value
* @return the boolean value
*/
public static boolean getBooleanValue(String value)
{
boolean ret = false;
Property> property = null;
try
{
property = VmlUtils.getProperty(value);
}
catch (VmlException e)
{
return false;
}
if (property != null)
{
ret = getBooleanValue(property);
}
return ret;
}
/**
* Gets the boolean value.
*
* @param property the property
* @return the boolean value
*/
public static boolean getBooleanValue(Property> property)
{
boolean ret = false;
if (property != null)
{
ret = VmlUtils.getBooleanValue(property);
}
return ret;
}
/**
* Type value.
*
* @param method the method
* @param valueText the value text
* @return the object
* @throws VmlException the vml exception
*/
public static Object typeValue(Method method, String valueText) throws VmlException
{
Class> targetClass = method.getParameterTypes()[method.getParameterCount() - 1];
return typeValue(targetClass, valueText);
}
/**
* Type value.
*
* @param targetClass the target class
* @param valueText the value text
* @return the object
* @throws VmlException the TXML exception
*/
public static Object typeValue(Class> targetClass, String valueText) throws VmlException
{
Object value = null;
if ((Boolean.class.equals(targetClass)) || (Boolean.TYPE.equals(targetClass)))
{
value = Boolean.parseBoolean(valueText);
}
else if ((Integer.class.equals(targetClass)) || (Integer.TYPE.equals(targetClass)))
{
value = Integer.parseInt(valueText);
}
else if ((Long.class.equals(targetClass)) || (Long.TYPE.equals(targetClass)))
{
value = Long.parseLong(valueText);
}
else if ((Float.class.equals(targetClass)) || (Float.TYPE.equals(targetClass)))
{
value = Float.parseFloat(valueText);
}
else
{
value = typeValue1(targetClass, valueText);
}
return value;
}
/**
* Type value 1.
*
* @param targetClass the target class
* @param valueText the value text
* @return the object
* @throws VmlException the TXML exception
*/
private static Object typeValue1(Class> targetClass, String valueText) throws VmlException
{
Object value = null;
if ((Double.class.equals(targetClass)) || (Double.TYPE.equals(targetClass)))
{
value = Double.parseDouble(valueText);
}
else if (String.class.equals(targetClass))
{
value = MultiMessages.get(valueText);
}
else if ((Byte.class.equals(targetClass)) || (Byte.TYPE.equals(targetClass)))
{
value = Byte.decode(valueText);
}
else
{
value = typeValue2(targetClass, valueText);
}
return value;
}
/**
* Type value 2.
*
* @param targetClass the target class
* @param valueText the value text
* @return the object
* @throws VmlException the TXML exception
*/
private static Object typeValue2(Class> targetClass, String valueText) throws VmlException
{
Object value = null;
if (targetClass.isEnum())
{
Method meth;
try
{
meth = targetClass.getMethod("valueOf", String.class);
meth.setAccessible(true);
value = meth.invoke(null, valueText);
}
catch (NoSuchMethodException | SecurityException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException e)
{
throw new VmlException("can not convert value : " + valueText + " to " + targetClass.getName());
}
}
else
{
Constructor> con;
try
{
con = targetClass.getConstructor(String.class);
if (con != null)
{
value = con.newInstance(valueText);
}
}
catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException e)
{
throw new VmlException("can not convert value : " + valueText + " to " + targetClass.getName());
}
}
return value;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy