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.
org.simpleflatmapper.reflect.impl.ParamNameDeductor Maven / Gradle / Ivy
package org.simpleflatmapper.reflect.impl;
import org.simpleflatmapper.reflect.getter.GetterHelper;
import org.simpleflatmapper.reflect.Getter;
import org.simpleflatmapper.reflect.Instantiator;
import org.simpleflatmapper.reflect.InstantiatorDefinition;
import org.simpleflatmapper.reflect.InstantiatorFactory;
import org.simpleflatmapper.reflect.ObjectGetterFactory;
import org.simpleflatmapper.reflect.Parameter;
import org.simpleflatmapper.reflect.ReflectionInstantiatorDefinitionFactory;
import org.simpleflatmapper.reflect.meta.ClassVisitor;
import org.simpleflatmapper.util.TypeHelper;
import org.simpleflatmapper.reflect.getter.ConstantGetter;
import org.simpleflatmapper.reflect.meta.FieldAndMethodCallBack;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ParamNameDeductor {
private static final Map, Object> primitivesMarkValue = new HashMap, Object>();
static {
primitivesMarkValue.put(byte.class, (byte) 1);
primitivesMarkValue.put(char.class, (char) 1);
primitivesMarkValue.put(short.class, (short) 1);
primitivesMarkValue.put(int.class, (int) 1);
primitivesMarkValue.put(long.class, (long) 1);
primitivesMarkValue.put(float.class, (float) 1);
primitivesMarkValue.put(double.class, (double) 1);
}
private static final Map, Object> primitivesNeutralValue = new HashMap, Object>();
static {
primitivesNeutralValue.put(byte.class, (byte) 0);
primitivesNeutralValue.put(char.class, (char) 0);
primitivesNeutralValue.put(short.class, (short) 0);
primitivesNeutralValue.put(int.class, (int) 0);
primitivesNeutralValue.put(long.class, (long) 0);
primitivesNeutralValue.put(float.class, (float) 0);
primitivesNeutralValue.put(double.class, (double) 0);
}
private final Class target;
private List> accessors;
private final InstantiatorFactory instantiatorFactory = new InstantiatorFactory(null);
public ParamNameDeductor(Class target) {
this.target = target;
}
public String findParamName(InstantiatorDefinition instantiatorDefinition, Parameter param, boolean builderIgnoresNullValues) {
if (accessors == null) {
accessors = listAccessors();
}
try {
T value;
Map> parameters = parametersWithExpectedValue(instantiatorDefinition, param, true, builderIgnoresNullValues);
Instantiator instantiator = instantiatorFactory.getInstantiator(instantiatorDefinition, Object.class, parameters, false, builderIgnoresNullValues);
try {
// try with null values
value = instantiator.newInstance(null);
} catch(NullPointerException e) {
// try with non null explicit values
parameters = parametersWithExpectedValue(instantiatorDefinition, param, false, builderIgnoresNullValues);
instantiator = instantiatorFactory.getInstantiator(instantiatorDefinition, Object.class, parameters, false, builderIgnoresNullValues);
value = instantiator.newInstance(null);
}
if (value != null) {
Object expectedPropertyValue = parameters.get(param).get(null);
// iterate through all the accessor to find one that returns a matching value
for (Accessor accessor : accessors) {
try {
final Object propertyValue = accessor.getter.get(value);
if (expectedPropertyValue.equals(propertyValue)) {
return accessor.name;
}
} catch (Exception e) {
// IGNORE
}
}
}
} catch(Exception e) {
// IGNORE
}
return null;
}
private Map> parametersWithExpectedValue(InstantiatorDefinition instantiatorDefinition, Parameter param, boolean allowNull, boolean builderIgnoresNullValues) throws Exception {
Map> parameterGetterMap = parameters(instantiatorDefinition, allowNull, builderIgnoresNullValues);
parameterGetterMap.put(param, new ConstantGetter(markValue(param.getGenericType(), builderIgnoresNullValues)));
return parameterGetterMap;
}
private Map> parameters(InstantiatorDefinition instantiatorDefinition, boolean allowNull, boolean builderIgnoresNullValues) throws Exception {
Map> parameterGetterMap = new HashMap>();
for(Parameter parameter : instantiatorDefinition.getParameters()) {
Object value = neutralValue(parameter.getGenericType(), allowNull, builderIgnoresNullValues);
parameterGetterMap.put(parameter, new ConstantGetter(value));
}
return parameterGetterMap;
}
@SuppressWarnings("unchecked")
private V markValue(Type type, boolean builderIgnoresNullValues) throws Exception {
if (TypeHelper.isPrimitive(type)) {
return (V) primitivesMarkValue.get(type);
}
else if (TypeHelper.areEquals(type, String.class)) {
return (V) "1";
} else if (TypeHelper.isAssignable(Enum.class, type)) {
Enum[] values = TypeHelper.toClass(type).getEnumConstants();
return (V) (values.length > 1 ? values[1] : values[0]);
} else {
return createValueFromInstantiator(type, builderIgnoresNullValues);
}
}
@SuppressWarnings("unchecked")
private V neutralValue(Type type, boolean allowNull, boolean builderIgnoresNullValues) throws Exception {
if (TypeHelper.isPrimitive(type)) {
return (V) primitivesNeutralValue.get(type);
}
if (allowNull) return null;
if (TypeHelper.areEquals(type, String.class)) {
return (V) "0";
} else if (TypeHelper.isAssignable(Enum.class, type)) {
Enum[] values = TypeHelper.toClass(type).getEnumConstants();
return (V) values[0];
} else {
return createValueFromInstantiator(type, builderIgnoresNullValues);
}
}
private V createValueFromInstantiator(Type type, boolean builderIgnoresNullValues) throws Exception {
InstantiatorDefinition instantiatorDefinition = InstantiatorFactory.getSmallerConstructor(ReflectionInstantiatorDefinitionFactory.extractDefinitions(type), Collections.emptySet());
Instantiator instantiator = instantiatorFactory.getInstantiator(instantiatorDefinition, Object.class, parameters(instantiatorDefinition, true, builderIgnoresNullValues), false, builderIgnoresNullValues);
try {
return instantiator.newInstance(null);
} catch (NullPointerException e) {
instantiator = instantiatorFactory.getInstantiator(instantiatorDefinition, Object.class, parameters(instantiatorDefinition, false, builderIgnoresNullValues), false, builderIgnoresNullValues);
return instantiator.newInstance(null);
}
}
private List> listAccessors() {
final List> list = new ArrayList>();
ClassVisitor.visit(target, new FieldAndMethodCallBack() {
ObjectGetterFactory objectGetterFactory = new ObjectGetterFactory(null);
@Override
public void method(Method method) {
if (GetterHelper.isGetter(method)) {
Getter methodGetter = objectGetterFactory.getMethodGetter(method);
list.add(new Accessor(GetterHelper.getPropertyNameFromMethodName(method.getName()), methodGetter));
}
}
@Override
public void field(Field field) {
Getter fieldGetter = objectGetterFactory.getFieldGetter(field);
list.add(new Accessor(field.getName(), fieldGetter));
}
});
return list;
}
private static class Accessor {
private final Getter getter;
private final String name;
private Accessor(String name, Getter getter) {
this.getter = getter;
this.name = name;
}
}
}