
com.enterprisemath.dao.object.BigEntityObjectCRUDDaoUtils Maven / Gradle / Ivy
package com.enterprisemath.dao.object;
import com.enterprisemath.dao.big.BigEntity;
import com.enterprisemath.dao.big.BigEntityUpdate;
import com.enterprisemath.dao.filter.Criterium;
import com.enterprisemath.dao.filter.Filter;
import com.enterprisemath.dao.filter.Order;
import com.enterprisemath.utils.StringParser;
import com.enterprisemath.utils.ValidationUtils;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
/**
* Utility methods dedicated for the BigEnityObjectCRUDDao.
* This class is here purely as a utility for library and is NOT supposed to be used outside. Please do not do that.
*
* Note: Any change or deleting this class will NOT be considered as breaking binary compatibility.
*
*
* @author radek.hecl
*/
class BigEntityObjectCRUDDaoUtils {
/**
* Prevents construction.
*/
private BigEntityObjectCRUDDaoUtils() {
}
/**
* Returns entity type.
*
* @param class type
* @param clazz class object
* @return entity type
*/
public static String getType(Class clazz) {
String cn = clazz.getSimpleName();
return encodeFieldName(cn).toUpperCase();
}
/**
* Returns class field definitions.
*
* @param class type, must have inner builder class
* @param clazz class object with inner builder class
* @return class field definition, contains all fields and field names are as they are presented within a class
*/
public static Map> getClassFieldDefinitions(Class clazz) {
try {
Class> builderClass = Class.forName(clazz.getName() + "$Builder");
Field[] fields = builderClass.getDeclaredFields();
Map> res = new HashMap>();
for (Field f : fields) {
res.put(f.getName(), f.getType());
}
return res;
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
/**
* Encodes field name.
*
* @param input input name
* @return encoded name
*/
public static String encodeFieldName(String input) {
StringParser parser = new StringParser(input);
StringBuilder res = new StringBuilder();
boolean prevLower = false;
while (parser.hasNext()) {
String c = parser.readCharacter();
if (StringUtils.isAllUpperCase(c)) {
if (prevLower) {
res.append("_");
}
prevLower = false;
res.append(c.toLowerCase());
}
else if (StringUtils.isAllLowerCase(c)) {
prevLower = true;
res.append(c);
}
else {
prevLower = false;
res.append(c);
}
}
return res.toString();
}
/**
* Decodes field name.
*
* @param input decoded name
* @return decoded name
*/
public static String decodeFieldName(String input) {
StringParser parser = new StringParser(StringUtils.lowerCase(input));
StringBuilder res = new StringBuilder();
boolean prevUnder = false;
while (parser.hasNext()) {
String c = parser.readCharacter();
if (c.equals("_")) {
prevUnder = true;
}
else {
if (prevUnder) {
res.append(c.toUpperCase());
}
else {
res.append(c);
}
prevUnder = false;
}
}
return res.toString();
}
/**
* Returns object fields as map.
*
* @param obj entry object
* @return object fields
*/
public static Map getObjectFieldsAsMap(Object obj) {
Map res = new HashMap();
try {
Class> clazz = obj.getClass();
Class> builderClass = Class.forName(obj.getClass().getName() + "$Builder");
Field[] fields = builderClass.getDeclaredFields();
for (Field bf : fields) {
Field f = clazz.getDeclaredField(bf.getName());
String fn = f.getName();
Object val = null;
if (f.isAccessible()) {
val = f.get(obj);
}
else {
f.setAccessible(true);
val = f.get(obj);
f.setAccessible(false);
}
res.put(fn, val);
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (SecurityException e) {
throw new RuntimeException(e);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
return res;
}
/**
* Encodes map into the entity.
*
* @param clazz main object class
* @param map map with fields
* @param fieldFilters field filters
* @return encoded entity
*/
public static BigEntity encodeMapAsBigEntity(Class> clazz, Map map, List fieldFilters) {
BigEntity.Builder res = new BigEntity.Builder();
res.setCode((String) encodeFieldValue(clazz, "code", map.get("code"), fieldFilters));
for (String key : map.keySet()) {
if (key.equals("code")) {
continue;
}
res.addField(encodeFieldName(key), encodeFieldValue(clazz, key, map.get(key), fieldFilters));
}
return res.build();
}
/**
* Encodes big entity update.
*
* @param clazz main object class
* @param fields fields to update
* @param fieldFilters field filters
* @return update
*/
public static BigEntityUpdate encodeMapAsBigEntityUpdate(Class> clazz, Map map,
List fieldFilters) {
BigEntityUpdate.Builder res = new BigEntityUpdate.Builder();
for (String key : map.keySet()) {
res.addUpdateField(encodeFieldName(key), encodeFieldValue(clazz, key, map.get(key), fieldFilters));
}
return res.build();
}
/**
* Decodes big entity as a map.
*
* @param clazz main object class
* @param fieldDefinitions field definitions
* @param bigEntity big entity
* @param fieldFilters field filter
* @return map with data
*/
public static Map decodeBigEntityAsMap(Class> clazz, Map> fieldDefinitions,
BigEntity bigEntity,
List fieldFilters) {
Map res = new HashMap();
for (String name : fieldDefinitions.keySet()) {
if (name.equals("code")) {
res.put("code", bigEntity.getCode());
}
else {
String entityFieldName = encodeFieldName(name);
Class> fieldClazz = fieldDefinitions.get(name);
Object entityField = bigEntity.getFields().get(entityFieldName);
res.put(name, decodeFieldValue(clazz, fieldClazz, name, entityField, fieldFilters));
}
}
return res;
}
/**
* Builds object from map.
*
* @param target class type
* @param clazz class of the target object
* @param map map
* @return result object
*/
public static T buildObjectFromMap(Class clazz, Map map) {
try {
Class> builderClass = Class.forName(clazz.getName() + "$Builder");
Constructor> constructor = builderClass.getConstructor();
Object builder = constructor.newInstance();
Method[] methods = builderClass.getMethods();
for (String key : map.keySet()) {
Object val = map.get(key);
String setterName = "set" + StringUtils.capitalize(key);
Method setter = null;
for (Method candidate : methods) {
if (!candidate.getName().equals(setterName)) {
continue;
}
Class>[] parameters = candidate.getParameterTypes();
if (parameters.length != 1) {
continue;
}
if (val != null && !parameters[0].isAssignableFrom(val.getClass())) {
continue;
}
setter = candidate;
break;
}
ValidationUtils.guardNotNull(setter, "unable to find setter: property = " + key);
setter.invoke(builder, val);
}
Method build = builderClass.getMethod("build");
return (T) build.invoke(builder);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (SecurityException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
/**
* Transforms filter.
*
* @param input filter type
* @param input input filter
* @return transformed filter
*/
public static > Filter transformFilter(Filter input) {
Filter.Builder res = new Filter.Builder();
res.setFrom(input.getFrom());
res.setLimit(input.getLimit());
for (Criterium criterium : input.getCriteria()) {
res.addCriterium(Criterium.create(criterium.getColumn().name().toLowerCase(), criterium.getOperator(), criterium.getValue()));
}
for (Order order : input.getOrders()) {
res.addOrder(Order.create(order.getColumn().name().toLowerCase(), order.getDirection()));
}
return res.build();
}
/**
* Encodes value.
*
* @param clazz main object class
* @param name field name in object notation
* @param val value
* @param fieldFilters field filters
* @return encoded value
*/
private static Object encodeFieldValue(Class> clazz, String name, Object val, List fieldFilters) {
for (FieldFilter ff : fieldFilters) {
val = ff.toBigEntity(clazz, name, val);
}
return val;
}
/**
* Decodes value.
*
* @param clazz main object class
* @param fieldClass requested class for the field
* @param name field name in object notation
* @param val field value
* @return decoded value
*/
private static Object decodeFieldValue(Class> clazz, Class> fieldClass, String name, Object val, List fieldFilters) {
for (int i = fieldFilters.size() - 1; i >= 0; --i) {
FieldFilter ff = fieldFilters.get(i);
val = ff.fromBigEntity(clazz, fieldClass, name, val);
}
return val;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy