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.bld.commons.reflection.utils.ReflectionCommons Maven / Gradle / Ivy
/**
* @author Francesco Baldi
* @mail [email protected]
* @class bld.commons.persistence.reflection.utils.ReflectionCommons.java
*/
package com.bld.commons.reflection.utils;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.beanutils.ConvertUtilsBean;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.query.BindableType;
import org.hibernate.query.TypedParameterValue;
import org.hibernate.type.StandardBasicTypes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import com.bld.commons.reflection.annotations.ConditionsZones;
import com.bld.commons.reflection.annotations.DateFilter;
import com.bld.commons.reflection.annotations.FieldMapping;
import com.bld.commons.reflection.annotations.FilterNullValue;
import com.bld.commons.reflection.annotations.IgnoreMapping;
import com.bld.commons.reflection.annotations.IgnoreResultSet;
import com.bld.commons.reflection.annotations.LikeString;
import com.bld.commons.reflection.annotations.ListFilter;
import com.bld.commons.reflection.annotations.ResultMapping;
import com.bld.commons.reflection.annotations.TupleComparison;
import com.bld.commons.reflection.model.BaseParameter;
import com.bld.commons.reflection.model.NativeQueryParameter;
import com.bld.commons.reflection.model.QueryParameter;
import com.bld.commons.reflection.model.TupleParameter;
import com.bld.commons.reflection.type.GetSetType;
import com.bld.commons.utils.CamelCaseUtils;
import com.bld.commons.utils.DateUtils;
/**
* The Class ReflectionCommons.
*/
@Component
@SuppressWarnings("unchecked")
public class ReflectionCommons {
/** The Constant PK. */
public static final String PK = "PK";
/** The context. */
@Autowired
private ApplicationContext applicationContext;
/** The logger. */
private final static Log logger = LogFactory.getLog(ReflectionCommons.class);
/** The Constant SERVICE_IMPL. */
public static final String SERVICE_IMPL = "ServiceImpl";
/** The Constant UPDATE. */
public static final String UPDATE = "update";
/** The Constant SAVE. */
public static final String SAVE = "save";
/** The Constant mapPrimitiveToObject. */
public final static Map, Class>> mapPrimitiveToObject = mapFromPrimitiveToObject();
/** The Constant mapType. */
public final static Map, BindableType>> mapType = getMapType();
/** The Constant pattern. */
private final static Pattern pattern = Pattern.compile("\\$\\{([^}]+)\\}");
/**
* Save generic.
*
* @param valore the valore
* @param classCampoDestinatario the class campo destinatario
* @throws NoSuchMethodException the no such method exception
* @throws IllegalAccessException the illegal access exception
* @throws InvocationTargetException the invocation target exception
*/
public void saveGeneric(Object valore, Class> classCampoDestinatario) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
String nomeClasse = classCampoDestinatario.getSimpleName();
String nomeClasseServiceImpl = getBeanName(nomeClasse, SERVICE_IMPL);
Object oggettoServiceImpl = applicationContext.getBean(nomeClasseServiceImpl);
Method metodo = oggettoServiceImpl.getClass().getMethod(SAVE, valore.getClass());
metodo.invoke(oggettoServiceImpl, valore);
}
/**
* Gets the map type.
*
* @return the map type
*/
private static Map, BindableType>> getMapType() {
Map, BindableType>> map = new HashMap<>();
map.put(Boolean.class, StandardBasicTypes.BOOLEAN);
map.put(String.class, StandardBasicTypes.STRING);
map.put(Long.class, StandardBasicTypes.LONG);
map.put(BigInteger.class, StandardBasicTypes.BIG_INTEGER);
map.put(Integer.class, StandardBasicTypes.INTEGER);
map.put(Short.class, StandardBasicTypes.SHORT);
map.put(BigDecimal.class, StandardBasicTypes.BIG_DECIMAL);
map.put(Double.class, StandardBasicTypes.DOUBLE);
map.put(Float.class, StandardBasicTypes.FLOAT);
map.put(Byte.class, StandardBasicTypes.BYTE);
map.put(Character.class, StandardBasicTypes.CHARACTER);
map.put(Date.class, StandardBasicTypes.DATE);
map.put(Calendar.class, StandardBasicTypes.CALENDAR);
map.put(Locale.class, StandardBasicTypes.LOCALE);
map.put(TimeZone.class, StandardBasicTypes.TIMEZONE);
map.put(Clob.class, StandardBasicTypes.CLOB);
map.put(Blob.class, StandardBasicTypes.BLOB);
return map;
}
/**
* Map from primitive to object.
*
* @return the map
*/
private static Map, Class>> mapFromPrimitiveToObject() {
Map, Class>> map = new HashMap<>();
map.put(int.class, Integer.class);
map.put(byte.class, Byte.class);
map.put(char.class, Character.class);
map.put(boolean.class, Boolean.class);
map.put(double.class, Double.class);
map.put(float.class, Float.class);
map.put(long.class, Long.class);
map.put(short.class, Short.class);
map.put(void.class, Void.class);
return map;
}
/**
* Data to map.
*
* @param the generic type
* @param the generic type
* @param queryParameter the query parameter
* @return the query parameter
*/
public QueryParameter dataToMap(QueryParameter queryParameter) {
BaseParameter obj = queryParameter.getBaseParameter();
if (obj != null) {
Set fields = ReflectionCommons.fields(obj.getClass());
Map> mapMethod = ReflectionCommons.mapMethods(obj.getClass());
for (Field field : fields) {
Method method = ReflectionCommons.getMethod(mapMethod, field, GetSetType.get);
if (method != null) {
IgnoreMapping ignoreMapping = method.isAnnotationPresent(IgnoreMapping.class) ? method.getAnnotation(IgnoreMapping.class) : field.getAnnotation(IgnoreMapping.class);
if (ignoreMapping == null || !ignoreMapping.value()) {
try {
Object value = PropertyUtils.getProperty(obj, field.getName());
if (value instanceof Collection && CollectionUtils.isEmpty((Collection>) value))
value = null;
if (value != null && value instanceof String && StringUtils.isBlank((String) value))
value = null;
if (value != null) {
value = getValue(field, method, value);
if (field.isAnnotationPresent(TupleComparison.class)) {
TupleParameter tupleParameter=this.getTupleParameter(field, value);
queryParameter.addParameter(field.getName(), tupleParameter);
} else if (value instanceof Boolean && (Boolean) value && field.isAnnotationPresent(ListFilter.class))
queryParameter.addNullable(field.getName());
else if (value.getClass().isArray()) {
Object[] array = (Object[]) value;
queryParameter.addParameter(field.getName(), Arrays.asList(array));
} else
queryParameter.addParameter(field.getName(), value);
} else if (field.isAnnotationPresent(FilterNullValue.class) && field.getAnnotation(FilterNullValue.class).value() || method.isAnnotationPresent(FilterNullValue.class) && method.getAnnotation(FilterNullValue.class).value())
queryParameter.addParameter(field.getName(), initTypedParameterValue(mapType.get(field.getType()), value));
} catch (Exception e) {
logger.warn("Error converting data to map");
}
}
}
}
}
return queryParameter;
}
private TupleParameter getTupleParameter(Field field, Object value) {
TupleComparison tupleComparison = field.getAnnotation(TupleComparison.class);
TupleParameter tuple = new TupleParameter(tupleComparison.value());
if (value instanceof Collection)
tuple.setObjects((Collection) value);
else
tuple.setObjects(value);
return tuple;
}
/**
* Inits the typed parameter value.
*
* @param the generic type
* @param bindableType the bindable type
* @param value the value
* @return the typed parameter value
*/
public static TypedParameterValue initTypedParameterValue(BindableType bindableType, Object value) {
return new TypedParameterValue(bindableType, (J) value);
}
/**
* Gets the value.
*
* @param field the field
* @param method the method
* @param value the value
* @return the value
*/
private Object getValue(Field field, Method method, Object value) {
DateFilter dateFilter = method.isAnnotationPresent(DateFilter.class) ? method.getAnnotation(DateFilter.class) : field.getAnnotation(DateFilter.class);
LikeString likeString = method.isAnnotationPresent(LikeString.class) ? method.getAnnotation(LikeString.class) : field.getAnnotation(LikeString.class);
return value(value, dateFilter, likeString);
}
public static Object value(Object value, DateFilter dateFilter, LikeString likeString) {
if (dateFilter != null) {
if (value instanceof Calendar)
value = DateUtils.sumDate((Calendar) value, dateFilter.addYear(), dateFilter.addMonth(), dateFilter.addWeek(), dateFilter.addDay(), dateFilter.addHour(), dateFilter.addMinute(), dateFilter.addSecond());
else if (value instanceof Date)
value = DateUtils.sumDate((Date) value, dateFilter.addYear(), dateFilter.addMonth(), dateFilter.addWeek(), dateFilter.addDay(), dateFilter.addHour(), dateFilter.addMinute(), dateFilter.addSecond());
else if (value instanceof Timestamp)
value = DateUtils.sumDate((Timestamp) value, dateFilter.addYear(), dateFilter.addMonth(), dateFilter.addWeek(), dateFilter.addDay(), dateFilter.addHour(), dateFilter.addMinute(), dateFilter.addSecond());
} else if (likeString != null && value instanceof String) {
switch (likeString.likeType()) {
case LEFT_RIGHT:
value = "%" + value + "%";
break;
case NONE:
break;
case LEFT:
value = "%" + value;
break;
case RIGHT:
value = value + "%";
break;
default:
value = "%" + value + "%";
break;
}
switch (likeString.upperLowerType()) {
case LOWER:
value = ((String) value).toLowerCase();
break;
case UPPER:
value = ((String) value).toUpperCase();
break;
case NONE:
default:
break;
}
}
return value;
}
/**
* Data to map.
*
* @param the generic type
* @param the generic type
* @param queryParameter the query parameter
* @return the native query parameter
*/
public NativeQueryParameter dataToMap(NativeQueryParameter queryParameter) {
BaseParameter obj = queryParameter.getBaseParameter();
if (obj != null) {
Set fields = ReflectionCommons.fields(obj.getClass());
Map> mapMethod = ReflectionCommons.mapMethods(obj.getClass());
for (Field field : fields) {
Method method = ReflectionCommons.getMethod(mapMethod, field, GetSetType.get);
if (method != null) {
IgnoreMapping ignoreMapping = method.isAnnotationPresent(IgnoreMapping.class) ? method.getAnnotation(IgnoreMapping.class) : field.getAnnotation(IgnoreMapping.class);
if (ignoreMapping == null || !ignoreMapping.value()) {
try {
Object value = PropertyUtils.getProperty(obj, field.getName());
ConditionsZones conditionsZones = method.isAnnotationPresent(ConditionsZones.class) ? method.getAnnotation(ConditionsZones.class) : field.getAnnotation(ConditionsZones.class);
if (value instanceof Collection && CollectionUtils.isEmpty((Collection>) value))
value = null;
if (value != null && value instanceof String && StringUtils.isBlank((String) value))
value = null;
if (value != null) {
value = getValue(field, method, value);
if (field.isAnnotationPresent(TupleComparison.class)) {
TupleParameter tupleParameter=this.getTupleParameter(field, value);
queryParameter.addParameter(field.getName(), tupleParameter, conditionsZones);
} else if (value instanceof Boolean && (Boolean) value && field.isAnnotationPresent(ListFilter.class))
queryParameter.addNullable(field.getName(), conditionsZones);
else if (value.getClass().isArray()) {
Object[] array = (Object[]) value;
queryParameter.addParameter(field.getName(), Arrays.asList(array), conditionsZones);
} else
queryParameter.addParameter(field.getName(), value, conditionsZones);
} else if (field.isAnnotationPresent(FilterNullValue.class) && field.getAnnotation(FilterNullValue.class).value() || method.isAnnotationPresent(FilterNullValue.class) && method.getAnnotation(FilterNullValue.class).value())
queryParameter.addParameter(field.getName(), initTypedParameterValue(mapType.get(field.getType()), value), conditionsZones);
else if (conditionsZones != null)
queryParameter.addEmptyZones(conditionsZones);
} catch (Exception e) {
logger.warn("Error converting data to map");
}
}
}
}
}
return queryParameter;
}
/**
* Reflection.
*
* @param the generic type
* @param classT the class T
* @param mapResult the map result
* @return the t
*/
public T reflection(Class classT, Map mapResult) {
Map mapRow = new HashMap<>();
BeanUtilsBean beanUtils = new BeanUtilsBean(new ConvertUtilsBean() {
@Override
public Object convert(String value, @SuppressWarnings("rawtypes") Class clazz) {
if (clazz.isEnum()) {
return Enum.valueOf(clazz, value);
} else {
return super.convert(value, clazz);
}
}
});
beanUtils.getConvertUtils().register(false, false, 0);
for (String keyResult : mapResult.keySet()) {
String nameField = CamelCaseUtils.camelCase(keyResult, true);
mapRow.put(nameField, mapResult.get(keyResult));
}
T t = null;
try {
t = mapResultSet(classT, mapRow, beanUtils);
} catch (Exception e) {
throw new RuntimeException(e);
}
return t;
}
/**
* Map result set.
*
* @param the generic type
* @param classT the class T
* @param mapRow the map row
* @param beanUtils the bean utils
* @return the t
* @throws InstantiationException the instantiation exception
* @throws IllegalAccessException the illegal access exception
* @throws IllegalArgumentException the illegal argument exception
* @throws InvocationTargetException the invocation target exception
* @throws NoSuchMethodException the no such method exception
* @throws SecurityException the security exception
*/
private T mapResultSet(Class classT, Map mapRow, BeanUtilsBean beanUtils)
throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
T t = classT.getConstructor().newInstance();
Set fields = fields(classT);
boolean isEmpty = true;
for (Field field : fields) {
if (!field.isAnnotationPresent(IgnoreResultSet.class)) {
Object value = null;
if (field.isAnnotationPresent(ResultMapping.class)) {
value = mapResultSet(field.getType(), mapRow, beanUtils);
if (value != null) {
isEmpty = false;
beanUtils.setProperty(t, field.getName(), value);
}
} else {
String key = field.getName();
if (field.isAnnotationPresent(FieldMapping.class))
key = field.getAnnotation(FieldMapping.class).value();
if (mapRow.containsKey(key)) {
value = mapRow.get(key);
if (value != null) {
isEmpty = false;
beanUtils.setProperty(t, field.getName(), value);
}
}
}
}
}
if (isEmpty)
return null;
return t;
}
/**
* Gets the bean name.
*
* @param nomeClasse the nome classe
* @param rightConcat the right concat
* @return the bean name
*/
public static String getBeanName(String nomeClasse, String rightConcat) {
nomeClasse = Character.toLowerCase(nomeClasse.charAt(0)) + nomeClasse.substring(1);
rightConcat = rightConcat != null ? rightConcat : "";
return nomeClasse + rightConcat;
}
/**
* Check empty.
*
* @param obj the obj
* @return the object
*/
public static Object checkEmpty(Object obj) {
Set campi = new HashSet(Arrays.asList(obj.getClass().getDeclaredFields()));
for (Field f : campi) {
try {
Object value = PropertyUtils.getProperty(obj, f.getName());
if (value != null) {
return obj;
}
} catch (Exception e) {
logger.warn("-XXX- errore durante la lettura del campo -XXX");
logger.warn(ExceptionUtils.getStackTrace(e));
}
}
return null;
}
/**
* Gets the generic type class.
*
* @param the generic type
* @param entity the entity
* @return the generic type class
*/
public static Class getGenericTypeClass(Object entity) {
return getGenericTypeClass(entity.getClass(), 0);
}
/**
* Gets the generic type class.
*
* @param the generic type
* @param clazz the clazz
* @return the generic type class
*/
public static Class getGenericTypeClass(Class> clazz) {
return getGenericTypeClass(clazz, 0);
}
/**
* Gets the generic type class.
*
* @param the generic type
* @param clazz the clazz
* @param i the i
* @return the generic type class
*/
public static Class getGenericTypeClass(Class> clazz, int i) {
ParameterizedType parameterizedType = null;
try {
parameterizedType = (ParameterizedType) clazz.getGenericSuperclass();
} catch (Exception e) {
parameterizedType = (ParameterizedType) clazz.getSuperclass().getGenericSuperclass();
}
Class clazzType = (Class) parameterizedType.getActualTypeArguments()[i];
return clazzType;
}
/**
* Gets the generic type class.
*
* @param the generic type
* @param entity the entity
* @param i the i
* @return the generic type class
*/
public static Class getGenericTypeClass(Object entity, int i) {
return getGenericTypeClass(entity.getClass(), i);
}
/**
* Gets the generic type field.
*
* @param the generic type
* @param field the field
* @return the generic type field
*/
public static Class getGenericTypeField(Field field) {
return getGenericTypeField(field, 0);
}
/**
* Gets the generic type field.
*
* @param the generic type
* @param field the field
* @param i the i
* @return the generic type field
*/
public static Class getGenericTypeField(Field field, int i) {
ParameterizedType parameterizedType = null;
parameterizedType = (ParameterizedType) field.getGenericType();
Class clazz = (Class) parameterizedType.getActualTypeArguments()[i];
return clazz;
}
/**
* Removes the extra space.
*
* @param join the join
* @return the string
*/
public static String removeExtraSpace(String join) {
join = join.trim();
if (join.contains(" "))
join = removeExtraSpace(join.replace(" ", " "));
return join;
}
/**
* Fields.
*
* @param classApp the class app
* @return the sets the
*/
public static Set fields(Class> classApp) {
Set listField = new HashSet<>();
do {
for (Field field : classApp.getDeclaredFields())
if (!listField.contains(field))
listField.add(field);
classApp = classApp.getSuperclass();
} while (classApp != null && !classApp.getName().equals(Object.class.getName()));
return listField;
}
/**
* Fields.
*
* @param classApp the class app
* @param annotation the annotation
* @return the sets the
*/
public static Set fields(Class> classApp, Class extends Annotation> annotation) {
Set listField = new HashSet<>();
Set skipField = new HashSet<>();
do {
for (Field field : classApp.getDeclaredFields()) {
if (field.isAnnotationPresent(annotation) && !skipField.contains(field))
listField.add(field);
skipField.add(field);
}
classApp = classApp.getSuperclass();
} while (classApp != null && !classApp.getName().equals(Object.class.getName()));
return listField;
}
/**
* Map fields.
*
* @param classApp the class app
* @return the map
*/
public static Map mapFields(Class> classApp) {
Map mapField = new HashMap<>();
do {
for (Field field : classApp.getDeclaredFields())
if (!mapField.containsKey(field.getName()))
mapField.put(field.getName(), field);
classApp = classApp.getSuperclass();
} while (classApp != null && !classApp.getName().equals(Object.class.getName()));
return mapField;
}
/**
* Map methods.
*
* @param classApp the class app
* @return the map
*/
public static Map> mapMethods(Class> classApp) {
Map> mapMethod = new HashMap<>();
do {
for (Method method : classApp.getMethods()) {
if (!mapMethod.containsKey(method.getName()))
mapMethod.put(method.getName(), new LinkedHashSet<>());
mapMethod.get(method.getName()).add(method);
}
classApp = classApp.getSuperclass();
} while (classApp != null && !classApp.getName().equals(Object.class.getName()));
return mapMethod;
}
/**
* Methods.
*
* @param classApp the class app
* @return the sets the
*/
public static Set methods(Class> classApp) {
Set methods = new HashSet<>();
Set methodsOverride = new HashSet<>();
do {
for (Method method : classApp.getMethods()) {
MethodOverride methodOverride = new MethodOverride(method.getName(), method.getParameterTypes());
if (!methodsOverride.contains(methodOverride)) {
methods.add(method);
methodsOverride.add(methodOverride);
}
}
classApp = classApp.getSuperclass();
} while (classApp != null && !classApp.getName().equals(Object.class.getName()));
return methods;
}
/**
* Gets the method.
*
* @param mapMethod the map method
* @param methodName the method name
* @param classParameter the class parameter
* @return the method
*/
public static Method getMethod(Map> mapMethod, String methodName, Class>... classParameter) {
Set methods = mapMethod.get(methodName);
if (CollectionUtils.isNotEmpty(methods)) {
for (Method method : methods) {
Class>[] parameterTypes = method.getParameterTypes();
if (ArrayUtils.isEmpty(parameterTypes) && ArrayUtils.isEmpty(classParameter))
return method;
boolean check = true;
if (ArrayUtils.isNotEmpty(parameterTypes) && ArrayUtils.isNotEmpty(classParameter) && parameterTypes.length == classParameter.length) {
for (int i = 0; i < parameterTypes.length; i++)
if (!parameterTypes[i].isAssignableFrom(classParameter[i])) {
check = false;
break;
}
} else
continue;
if (check)
return method;
}
}
return null;
}
/**
* Gets the method.
*
* @param mapMethod the map method
* @param field the field
* @param getSetType the get set type
* @param classParameter the class parameter
* @return the method
*/
public static Method getMethod(Map> mapMethod, Field field, GetSetType getSetType, Class>... classParameter) {
String methodName = getSetType.name() + Character.toUpperCase(field.getName().charAt(0)) + field.getName().substring(1);
return ReflectionCommons.getMethod(mapMethod, methodName, classParameter);
}
/**
* Extract variables.
*
* @param input the input
* @return the sets the
*/
public static Set extractVariables(String input) {
Matcher matcher = pattern.matcher(input);
Set variables = new HashSet<>();
while (matcher.find())
variables.add(matcher.group(1));
return variables;
}
}