com.github.ltsopensource.json.bean.JavaBeanSetterInfo Maven / Gradle / Ivy
package com.github.ltsopensource.json.bean;
import java.lang.reflect.*;
import java.security.AccessControlException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* @author Robert HG ([email protected]) on 12/31/15.
*/
public class JavaBeanSetterInfo {
private Class> clazz;
private Constructor> constructor;
private Map methodSetterInfos;
private Map fieldSetterInfos;
public JavaBeanSetterInfo(Class> clazz) {
this.clazz = clazz;
Constructor> constructor = getDefaultConstructor(clazz);
setAccessible(constructor);
this.constructor = constructor;
this.methodSetterInfos = getMethodSettInfos();
this.fieldSetterInfos = getFiledSetterInfos();
}
public Class> getClazz() {
return clazz;
}
public Constructor> getConstructor() {
return constructor;
}
public Collection getMethodSetterInfos() {
if (methodSetterInfos == null) {
return null;
}
return methodSetterInfos.values();
}
public Collection getFieldSetterInfos() {
if (fieldSetterInfos == null) {
return null;
}
return fieldSetterInfos.values();
}
private Constructor> getDefaultConstructor(Class> clazz) {
if (Modifier.isAbstract(clazz.getModifiers())) {
return null;
}
Constructor> defaultConstructor = null;
for (Constructor> constructor : clazz.getDeclaredConstructors()) {
if (constructor.getParameterTypes().length == 0) {
defaultConstructor = constructor;
break;
}
}
if (defaultConstructor == null) {
if (clazz.isMemberClass() && !Modifier.isStatic(clazz.getModifiers())) {
for (Constructor> constructor : clazz.getDeclaredConstructors()) {
if (constructor.getParameterTypes().length == 1
&& constructor.getParameterTypes()[0].equals(clazz.getDeclaringClass())) {
defaultConstructor = constructor;
break;
}
}
}
}
return defaultConstructor;
}
private void setAccessible(AccessibleObject obj) {
if (obj.isAccessible()) {
return;
}
try {
obj.setAccessible(true);
} catch (AccessControlException ignored) {
}
}
private Map getMethodSettInfos() {
Map map = new HashMap();
for (Method method : clazz.getMethods()) {
String methodName = method.getName();
if (methodName.length() < 4) {
continue;
}
if (Modifier.isStatic(method.getModifiers())) {
continue;
}
// support builder set
if (!(method.getReturnType().equals(Void.TYPE) || method.getReturnType().equals(clazz))) {
continue;
}
if (method.getParameterTypes().length != 1) {
continue;
}
if (!methodName.startsWith("set")) {
continue;
}
char c3 = methodName.charAt(3);
String propertyName;
if (Character.isUpperCase(c3)) {
propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
} else if (c3 == '_') {
propertyName = methodName.substring(4);
} else if (c3 == 'f') {
propertyName = methodName.substring(3);
} else if (methodName.length() >= 5 && Character.isUpperCase(methodName.charAt(4))) {
propertyName = decapitalize(methodName.substring(3));
} else {
continue;
}
Field field = getField(clazz, propertyName);
if (field == null && method.getParameterTypes()[0] == boolean.class) {
String isFieldName = "is" + Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1);
field = getField(clazz, isFieldName);
}
if (field != null) {
// 说明该方法是存在的
map.put(propertyName, new MethodInfo(propertyName, method));
}
}
return map;
}
/**
* 返回所有的public方法
*/
public Map getFiledSetterInfos() {
Map map = new HashMap();
for (Field field : clazz.getFields()) {
if (Modifier.isStatic(field.getModifiers())) {
continue;
}
if (Modifier.isFinal(field.getModifiers())) {
continue;
}
if (!Modifier.isPublic(field.getModifiers())) {
continue;
}
String propertyName = field.getName();
// 如果已经暴露了方法,那么就不使用属性设置
if (this.methodSetterInfos.containsKey(propertyName)) {
continue;
}
map.put(propertyName, new FieldSetterInfo(propertyName, field));
}
return map;
}
private String decapitalize(String name) {
if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
Character.isUpperCase(name.charAt(0))) {
return name;
}
char chars[] = name.toCharArray();
chars[0] = Character.toLowerCase(chars[0]);
return new String(chars);
}
private Field getField(Class> clazz, String fieldName) {
for (Field field : clazz.getDeclaredFields()) {
if (fieldName.equals(field.getName())) {
return field;
}
}
Class> superClass = clazz.getSuperclass();
if (superClass != null && superClass != Object.class) {
return getField(superClass, fieldName);
}
return null;
}
}