org.sfm.reflect.SetterFactory Maven / Gradle / Ivy
package org.sfm.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.sfm.jdbc.AsmHelper;
import org.sfm.reflect.asm.AsmFactory;
import org.sfm.reflect.primitive.BooleanFieldSetter;
import org.sfm.reflect.primitive.BooleanMethodSetter;
import org.sfm.reflect.primitive.BooleanSetter;
import org.sfm.reflect.primitive.ByteFieldSetter;
import org.sfm.reflect.primitive.ByteMethodSetter;
import org.sfm.reflect.primitive.ByteSetter;
import org.sfm.reflect.primitive.CharacterFieldSetter;
import org.sfm.reflect.primitive.CharacterMethodSetter;
import org.sfm.reflect.primitive.CharacterSetter;
import org.sfm.reflect.primitive.DoubleFieldSetter;
import org.sfm.reflect.primitive.DoubleMethodSetter;
import org.sfm.reflect.primitive.DoubleSetter;
import org.sfm.reflect.primitive.FloatFieldSetter;
import org.sfm.reflect.primitive.FloatMethodSetter;
import org.sfm.reflect.primitive.FloatSetter;
import org.sfm.reflect.primitive.IntFieldSetter;
import org.sfm.reflect.primitive.IntMethodSetter;
import org.sfm.reflect.primitive.IntSetter;
import org.sfm.reflect.primitive.LongFieldSetter;
import org.sfm.reflect.primitive.LongMethodSetter;
import org.sfm.reflect.primitive.LongSetter;
import org.sfm.reflect.primitive.ShortFieldSetter;
import org.sfm.reflect.primitive.ShortMethodSetter;
import org.sfm.reflect.primitive.ShortSetter;
import org.sfm.utils.PropertyNameMatcher;
public final class SetterFactory {
private final AsmFactory asmFactory;
public SetterFactory(final AsmFactory asmSetterFactory) {
this.asmFactory = asmSetterFactory;
}
public SetterFactory() {
this.asmFactory = AsmHelper.getAsmSetterFactory();
}
public AsmFactory getAsmFactory() {
return asmFactory;
}
public Setter getSetter(final Class target, final String property) {
// first look for method
final Method method = lookForMethod(target, property);
if (method == null) {
return getFieldSetter(target, property);
} else {
return getMethodSetter(method);
}
}
private Setter getMethodSetter(final Method method) {
if (asmFactory != null) {
try {
return asmFactory.createSetter(method);
} catch(Exception e) {
return new MethodSetter(method);
}
} else {
return new MethodSetter(method);
}
}
public FieldSetter getFieldSetter(final Class target, final String property) {
// look for field
final Field field = lookForField(target, property);
if (field != null) {
field.setAccessible(true);
return new FieldSetter(field);
} else {
return null;
}
}
private Method lookForMethod(final Class> target, final String property) {
for(Method m : target.getDeclaredMethods()) {
if(methodModifiersMatches(m.getModifiers())
&& methodNameMatchesProperty(m.getName(), property)) {
return m;
}
}
if (!Object.class.equals(target)) {
return lookForMethod(target.getSuperclass(), property);
}
return null;
}
private Field lookForField(final Class> target, final String property) {
for(Field field : target.getDeclaredFields()) {
if(fieldModifiersMatches(field.getModifiers())
&& fieldNameMatchesProperty(field.getName(), property)) {
return field;
}
}
if (!Object.class.equals(target)) {
return lookForField(target.getSuperclass(), property);
}
return null;
}
private boolean methodModifiersMatches(final int modifiers) {
return !Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers);
}
private boolean methodNameMatchesProperty(final String name, final String property) {
return (isSetter(name) && name.regionMatches(true, 3, property, 0, property.length()))
|| name.equalsIgnoreCase(property);
}
private boolean fieldModifiersMatches(final int modifiers) {
return !Modifier.isStatic(modifiers) && ! Modifier.isFinal(modifiers);
}
private boolean fieldNameMatchesProperty(final String name, final String property) {
return name.equalsIgnoreCase(property);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public BooleanSetter toBooleanSetter(final Setter setter) {
if (setter instanceof BooleanSetter) {
return (BooleanSetter) setter;
} else if (setter instanceof MethodSetter) {
return new BooleanMethodSetter(((MethodSetter) setter).getMethod());
} else if (setter instanceof FieldSetter) {
return new BooleanFieldSetter(((FieldSetter) setter).getField());
} else {
throw new IllegalArgumentException("Invalid type " + setter);
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public ByteSetter toByteSetter(final Setter setter) {
if (setter instanceof ByteSetter) {
return (ByteSetter) setter;
} else if (setter instanceof MethodSetter) {
return new ByteMethodSetter(((MethodSetter) setter).getMethod());
} else if (setter instanceof FieldSetter) {
return new ByteFieldSetter(((FieldSetter) setter).getField());
} else {
throw new IllegalArgumentException("Invalid type " + setter);
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public CharacterSetter toCharacterSetter(final Setter setter) {
if (setter instanceof CharacterSetter) {
return (CharacterSetter) setter;
} else if (setter instanceof MethodSetter) {
return new CharacterMethodSetter(((MethodSetter) setter).getMethod());
} else if (setter instanceof FieldSetter) {
return new CharacterFieldSetter(((FieldSetter) setter).getField());
} else {
throw new IllegalArgumentException("Invalid type " + setter);
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public ShortSetter toShortSetter(final Setter setter) {
if (setter instanceof ShortSetter) {
return (ShortSetter) setter;
} else if (setter instanceof MethodSetter) {
return new ShortMethodSetter(((MethodSetter) setter).getMethod());
} else if (setter instanceof FieldSetter) {
return new ShortFieldSetter(((FieldSetter) setter).getField());
} else {
throw new IllegalArgumentException("Invalid type " + setter);
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public IntSetter toIntSetter(final Setter setter) {
if (setter instanceof IntSetter) {
return (IntSetter) setter;
} else if (setter instanceof MethodSetter) {
return new IntMethodSetter(((MethodSetter) setter).getMethod());
} else if (setter instanceof FieldSetter) {
return new IntFieldSetter(((FieldSetter) setter).getField());
} else {
throw new IllegalArgumentException("Invalid type " + setter);
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public LongSetter toLongSetter(final Setter setter) {
if (setter instanceof LongSetter) {
return (LongSetter) setter;
} else if (setter instanceof MethodSetter) {
return new LongMethodSetter(((MethodSetter) setter).getMethod());
} else if (setter instanceof FieldSetter) {
return new LongFieldSetter(((FieldSetter) setter).getField());
} else {
throw new IllegalArgumentException("Invalid type " + setter);
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public FloatSetter toFloatSetter(final Setter setter) {
if (setter instanceof FloatSetter) {
return (FloatSetter) setter;
} else if (setter instanceof MethodSetter) {
return new FloatMethodSetter(((MethodSetter) setter).getMethod());
} else if (setter instanceof FieldSetter) {
return new FloatFieldSetter(((FieldSetter) setter).getField());
} else {
throw new IllegalArgumentException("Invalid type " + setter);
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public DoubleSetter toDoubleSetter(final Setter setter) {
if (setter instanceof DoubleSetter) {
return (DoubleSetter) setter;
} else if (setter instanceof MethodSetter) {
return new DoubleMethodSetter(((MethodSetter) setter).getMethod());
} else if (setter instanceof FieldSetter) {
return new DoubleFieldSetter(((FieldSetter) setter).getField());
} else {
throw new IllegalArgumentException("Invalid type " + setter);
}
}
public Map> getAllSetters(final Class target) {
final Map> setters = new HashMap>();
visitSetters(new SetterVisitor() {
@Override
public boolean visitSetter(final String property, final Setter setter) {
setters.put(property, setter);
return true;
}
}, target);
return setters;
}
public Setter findSetter(final PropertyNameMatcher matcher, final Class target) {
return visitSetters(new PropertyMatchingSetterVisitor(matcher), target).setter();
}
public > C visitSetters(final C visitor, final Class target) {
final Set properties = new HashSet();
Class> currentClass = target;
while(!Object.class.equals(currentClass)) {
for(Method method : currentClass.getDeclaredMethods()) {
final String name = method.getName();
if (methodModifiersMatches(method.getModifiers()) && isSetter(name)) {
final String propertyName = name.substring(3,4).toLowerCase() + name.substring(4);
if (!properties.contains(propertyName)) {
final Setter setter = getMethodSetter(method);
if (!visitor.visitSetter(propertyName, setter)) {
return visitor;
}
properties.add(propertyName);
}
}
}
for(Field field : currentClass.getDeclaredFields()) {
final String name = field.getName();
if (fieldModifiersMatches(field.getModifiers())) {
if (!properties.contains(name)) {
field.setAccessible(true);
final Setter setter = new FieldSetter(field);
if (!visitor.visitSetter(name, setter)) {
return visitor;
}
properties.add(name);
}
}
}
currentClass = currentClass.getSuperclass();
}
return visitor;
}
private boolean isSetter(final String name) {
return name.length() > 3 && name.startsWith("set");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy