/** * Copyright 2008 biaoping.yin * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.frameworkset.util; import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import org.frameworkset.soa.annotation.ExcludeField; import org.frameworkset.util.annotations.Attribute; import org.frameworkset.util.annotations.CookieValue; import org.frameworkset.util.annotations.DataBind; import org.frameworkset.util.annotations.IgnoreBind; import org.frameworkset.util.annotations.MapKey; import org.frameworkset.util.annotations.PathVariable; import org.frameworkset.util.annotations.RequestBody; import org.frameworkset.util.annotations.RequestHeader; import org.frameworkset.util.annotations.RequestParam; import org.frameworkset.util.annotations.wraper.AttributeWraper; import org.frameworkset.util.annotations.wraper.ColumnWraper; import org.frameworkset.util.annotations.wraper.CookieValueWraper; import org.frameworkset.util.annotations.wraper.PathVariableWraper; import org.frameworkset.util.annotations.wraper.RequestBodyWraper; import org.frameworkset.util.annotations.wraper.RequestHeaderWraper; import org.frameworkset.util.annotations.wraper.RequestParamWraper; import com.frameworkset.orm.annotation.Column; import com.frameworkset.orm.annotation.IgnoreORMapping; import com.frameworkset.orm.annotation.PrimaryKey; import com.frameworkset.util.BeanUtils; import com.frameworkset.util.EditorInf; import com.frameworkset.util.ValueObjectUtil; /** * <p>ClassUtil.java</p> * <p> Description: 需要注意 * boolean 类型属性的get/set方法的生成方式 * 已经boolean变量的命名方式,不要在前面添加is前缀,不要命名成isXXXX,这样处理会有问题的 * </p> * <p> bboss workgroup </p> * <p> Copyright (c) 2009 </p> * * @Date 2011-9-6 * @author biaoping.yin * @version 1.0 */ public class ClassUtil { private static final Logger log = Logger.getLogger(ClassUtil.class); private static final ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer(); public static void destroy() { if(classInfos != null) { classInfos.clear(); classInfos=null; } } public static ParameterNameDiscoverer getParameterNameDiscoverer() { return parameterNameDiscoverer; } public static class Var { private boolean isvar ; private int position; private String name; public int getPosition() { return position; } public void setPosition(int position) { this.position = position; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isIsvar() { return isvar; } public void setIsvar(boolean isvar) { this.isvar = isvar; } } public final static EditorInf getParamEditor(RequestParamWraper param) { if(param == null) return null; String editor = param.editor(); if(editor != null && !editor.equals("")) { return (EditorInf) BeanUtils.instantiateClass(editor); } return null; } public final static RequestParamWraper getWriterMethodRequestParam(Method writeMethod) { if(writeMethod == null) return null; Annotation[] annotations = writeMethod.getAnnotations(); if(annotations == null || annotations.length == 0) return null; for(Annotation annotation:annotations) { if(annotation instanceof RequestParam) { RequestParam param = (RequestParam)annotation; return new RequestParamWraper(param); } } return null; } public static class PropertieDescription { private Class propertyType; private Method writeMethod; private RequestParamWraper writeMethodRequestParam; private EditorInf writeMethodEditor; private Method readMethod; private Field field; private String name; private boolean canwrite = false; private boolean canread = false; private boolean canseriable = true; private Class[] writeMethodPropertyGenericType; private Class propertyGenericType; private Annotation[] annotations; private String requestParamName; private String origineRequestParamName; private boolean namevariabled = false; private RequestParamWraper requestParam ; private AttributeWraper attribute; private PrimaryKey pk; private ColumnWraper column; private CookieValueWraper cookie; private RequestHeaderWraper header; private PathVariableWraper pathVariable; private RequestBodyWraper requestBody; private DataBind dataBind; private IgnoreBind ignoreBind; private IgnoreORMapping ignoreORMapping; private MapKey mapkey; public IgnoreBind getIgnoreBind() { return ignoreBind; } /** * if (field.isAnnotationPresent(RequestBody.class) || field.isAnnotationPresent(DataBind.class) || field.isAnnotationPresent(PathVariable.class) || field.isAnnotationPresent(RequestParam.class) || field.isAnnotationPresent(Attribute.class) || field.isAnnotationPresent(CookieValue.class) || field.isAnnotationPresent(RequestHeader.class)) * @return */ public RequestParamWraper getRequestParam() { return requestParam; } public boolean isNamevariabled() { return namevariabled; } public String getOrigineRequestParamName() { return origineRequestParamName; } /** * 参数名称由常量和变量部分组成,变量var中包含了变量对应的request参数名称和变量在整个参数名称中所处的位置 */ private List<Var> requestParamNameToken; public String toString() { if(this.field != null) return field.toString(); if(this.writeMethod != null) return this.writeMethod.toString(); if(this.readMethod != null) return this.readMethod.toString(); return super.toString(); } private boolean oldAccessible = false; private String uperName; public PropertieDescription(Class propertyType,Field field, Method writeMethod,Method readMethod, String name) { super(); this.propertyType = propertyType; this.writeMethod = writeMethod; this.readMethod = readMethod; if(this.readMethod != null && !ReflectionUtils.isAccessible(readMethod)) { this.readMethod = null; } if(this.writeMethod != null && !ReflectionUtils.isAccessible(writeMethod)) { this.writeMethod = null; } this.name = name; if(name != null) this.uperName = name.toUpperCase(); this.field = field; if(this.field != null) oldAccessible = this.field.isAccessible(); if((writeMethod == null || this.readMethod == null)) { if(this.field != null) { int mode = this.field.getModifiers(); if( !Modifier.isStatic(mode)) { if(!Modifier.isPublic(mode)) { this.field.setAccessible(true); } if(!Modifier.isFinal(mode)) canwrite = true; canread = true; } if(Modifier.isPublic(mode)) { canread = true; if(!Modifier.isFinal(mode)) { canwrite = true; } } } } if(!canread && readMethod != null) this.canread = true; if(!canwrite && writeMethod != null) this.canwrite = true; if(this.field != null ) { int mode = this.field.getModifiers(); if( Modifier.isFinal(mode) || Modifier.isStatic(mode) || Modifier.isTransient(mode) || findAnnotation(ExcludeField.class) != null) { canseriable = false; } } if(canseriable && (readMethod == null || writeMethod == null) && this.field == null) { canseriable = false; } if(this.writeMethod != null) { this.writeMethodPropertyGenericType = ClassUtils.getPropertyGenericTypes(writeMethod); } else if(field != null) { this.writeMethodPropertyGenericType = ClassUtils.genericTypes(this.field); } if(this.writeMethod != null) { writeMethodRequestParam = getWriterMethodRequestParam( writeMethod); try { this.writeMethodEditor = getParamEditor(writeMethodRequestParam); } catch (Exception e) { log.error("get writeMethodEditor error!", e); } } if(this.writeMethod != null) { this.propertyGenericType = ClassUtils.getPropertyGenericType(this.writeMethod); } else if(this.field != null) { this.propertyGenericType = ClassUtils.genericType(this.field); } if(this.field != null) { annotations = this.field.getAnnotations(); initParam(this.field.getAnnotations()); } } private void initParam(Annotation[] annotations) { if(annotations == null || annotations.length == 0) return; for(int i = 0; i < annotations.length; i ++) { Annotation a = annotations[i]; if(a instanceof RequestParam) { requestParam = new RequestParamWraper((RequestParam)a); if(requestParam.name() == null || requestParam.name().equals("")) { this.requestParamName = name; } else { String name = requestParam.name(); this.origineRequestParamName = name; int vstart = name.indexOf("${"); if(vstart < 0) { this.requestParamName = name; } else { this.namevariabled = true; this.requestParamNameToken = ParameterUtil.evalVars(vstart, name); } } break; } else if(a instanceof PrimaryKey) { pk = (PrimaryKey)a; } else if(a instanceof Column ) { column = new ColumnWraper((Column )a); } else if(a instanceof Attribute ) { attribute = new AttributeWraper((Attribute )a); } else if(a instanceof RequestHeader ) { header = new RequestHeaderWraper((RequestHeader )a); } else if(a instanceof PathVariable ) { pathVariable = new PathVariableWraper((PathVariable )a); } else if(a instanceof DataBind ) { dataBind = ((DataBind )a); } else if(a instanceof RequestBody ) { requestBody = new RequestBodyWraper(((RequestBody )a),propertyType); } else if(a instanceof CookieValue ) { cookie = new CookieValueWraper ((CookieValue )a); } else if(a instanceof IgnoreBind) { this.ignoreBind = (IgnoreBind)a; } else if(a instanceof IgnoreORMapping) { this.ignoreORMapping = (IgnoreORMapping)a; } else if(a instanceof MapKey) { this.mapkey = (MapKey)a; } } } public Class[] getPropertyGenericTypes() { // if(this.writeMethod != null) // { // return ClassUtils.getPropertyGenericTypes(writeMethod); // } // else // { // return ClassUtils.genericTypes(this.field); // } return writeMethodPropertyGenericType; } public Class getPropertyGenericType() { // if(this.writeMethod != null) // { // return ClassUtils.getPropertyGenericType(writeMethod); // } // else // { // return ClassUtils.genericType(this.field); // } return this.propertyGenericType; } public <T extends Annotation> T findAnnotation(Class<T> type) { if(this.field != null) return (T)this.field.getAnnotation(type); return null; } // public Annotation[] findAnnotations() // { //// if(this.field != null) //// return this.field.getAnnotations(); //// return null; // return annotations; // } public boolean canread() { return canread; } public boolean canwrite() { return canwrite; } public boolean canseriable() { return canseriable; } public Object getValue(Object po) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { if(po == null) return null; if(this.readMethod != null) return this.readMethod.invoke(po); else if(this.field != null) return this.field.get(po); throw new IllegalAccessException("Get value for property["+this.name+"] failed:get Method or field not exist"); } public void setValue(Object po,Object value) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { if(po == null) return ; if(this.writeMethod != null) { this.writeMethod.invoke(po,value); } else if(this.field != null) { this.field.set(po,value); } else { throw new IllegalAccessException("Set value for property["+this.name+"] failed: set Method or field not exist."); } } public Class getPropertyType(){ return propertyType; } public Method getWriteMethod(){ return this.writeMethod; } public String getName(){ return this.name; } public Method getReadMethod() { return readMethod; } public Field getField() { return field; } public void setWriteMethod(Method writeMethod) { this.writeMethod = writeMethod; } public void setReadMethod(Method readMethod) { this.readMethod = readMethod; } public String getRequestParamName() { return requestParamName; } // public Annotation[] getAnnotations() { // return annotations; // } public List<Var> getRequestParamNameToken() { return requestParamNameToken; } public PrimaryKey getPk() { return pk; } public ColumnWraper getColumn() { return column; } public String getUperName() { return uperName; } public Annotation[] getAnnotations() { return annotations; } public CookieValueWraper getCookie() { return cookie; } public RequestHeaderWraper getHeader() { return header; } public AttributeWraper getAttribute() { return attribute; } public RequestParamWraper getWriteMethodRequestParam() { return writeMethodRequestParam; } public EditorInf getWriteMethodEditor() { return writeMethodEditor; } public PathVariableWraper getPathVariable() { return pathVariable; } public DataBind getDataBind() { return dataBind; } public RequestBodyWraper getRequestBody() { return requestBody; } public MapKey getMapkey() { return mapkey; } public IgnoreORMapping getIgnoreORMapping() { return ignoreORMapping; } } public static class ClassInfo { /** * declaredFields保存了类clazz以及父类中的所有属性字段定义,如果子类中和父类变量 * 重名,则安顺包含在数组中,这种情况是不允许的必须过滤掉,也就是说子类中有了和父类中相同签名的方法,则自动过滤掉 */ private volatile transient Field[] declaredFields; // private volatile transient Map<String ,PropertieDescription> propertyDescriptors; private volatile transient List<PropertieDescription> propertyDescriptors; /** * declaredMethods保存了类clazz以及父类中的所有public方法定义,如果子类中和父类方法定义 * 像同(抽象方法实现,过载等等),则安顺序包含在数组中,这种情况是不允许的必须过滤掉, * 也就是说子类中有了和父类中相同签名的方法,则自动过滤掉 */ private volatile transient Method[] declaredMethods; private volatile transient Constructor defaultConstruction; private volatile transient Constructor[] constructions; private Class<?> clazz; private List<Class> superClasses; /** * 识别class是否是基本数据类型或者基本数据类型数组 */ private boolean primary; /** * 识别class是否是基本数据类型 */ private boolean baseprimary; public Constructor getConstructor(Class... paramTypes ) { try { if(paramTypes == null || paramTypes.length == 0) return this.defaultConstruction; for(int i = 0; constructions != null && i < this.constructions.length; i ++) { Constructor c = constructions[i]; Class[] pt = c.getParameterTypes(); if(pt.length == paramTypes.length) { int j = 0; for(; j < pt.length; j ++) { if(pt[j] != paramTypes[j]) break; } if(j == pt.length) return c; } } // Constructor c = this.clazz.getDeclaredConstructor(paramTypes); //ReflectionUtils.makeAccessible(c); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } public String getName() { return this.clazz.getName(); } private boolean cglib = false; @SuppressWarnings("unchecked") private ClassInfo(Class clazz){ //处理cglib代理类,还原原始类型信息 String name = clazz.getName(); int idx = name.indexOf("$$EnhancerByCGLIB$$") ; if(idx < 0) { idx = name.indexOf("_$$_jvst") ;//fixed hibernate 4.8.0 lazy load bug if(idx < 0) this.clazz = clazz; else { this.clazz = clazz.getSuperclass(); cglib = true; } } else { this.clazz = clazz.getSuperclass(); cglib = true; } try { defaultConstruction = this.clazz.getDeclaredConstructor(); if(defaultConstruction != null) ReflectionUtils.makeAccessible(defaultConstruction); } catch (Exception e) { // // TODO Auto-generated catch block // e.printStackTrace(); } try { constructions = this.clazz.getDeclaredConstructors(); for(int i = 0; constructions != null && i < constructions.length;i ++) { ReflectionUtils.makeAccessible(constructions[i]); } } catch (Exception e) { // // TODO Auto-generated catch block // e.printStackTrace(); } this.init(); } public void setPropertyValue(Object obj,String property, Object value) { try { this.getPropertyDescriptor(property).setValue(obj, value); } catch (IllegalArgumentException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e.getTargetException()); } catch (Exception e) { throw new RuntimeException(e); } } public Object getPropertyValue(Object obj,String property) { try { return this.getPropertyDescriptor(property).getValue(obj); } catch (IllegalArgumentException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e.getTargetException()); } catch (Exception e) { throw new RuntimeException(e); } } private static final Field[] NULL = new Field[0]; private static final Method[] NULL_M = new Method[0]; private static final List<PropertieDescription> NULL_P = new ArrayList<PropertieDescription>(); private Object declaredMethodLock = new Object(); /** * 获取类的公共方法数组,包括类以及父类的public方法 * @return */ public Method[] getDeclaredMethods() { if(declaredMethods != null) { if(declaredMethods == NULL_M) return null; return declaredMethods; } synchronized(declaredMethodLock) { if(declaredMethods != null) { if(declaredMethods == NULL_M) return null; return declaredMethods; } Method[] retmethods = null; try { retmethods = getRecursiveDeclaredMehtods(); } catch(Exception e) { log.error(e.getMessage(),e); } if(retmethods == null) declaredMethods = NULL_M; else declaredMethods = retmethods; } if(declaredMethods == NULL_M) return null; return declaredMethods; } private void init() { this.primary = ValueObjectUtil.isPrimaryType(clazz); this.baseprimary = ValueObjectUtil.isBasePrimaryType(clazz); //初始化所有父类信息: if(superClasses == null) { superClasses = new ArrayList<Class> (); Class superclass = this.clazz.getSuperclass(); while(superclass != null ) { if(superclass == java.lang.Object.class) break; this.superClasses.add(superclass); superclass = superclass.getSuperclass(); } } if(declaredFields == null) { Field[] retfs = null; try { retfs = getRecursiveDeclaredFileds(); } catch(Exception e) { log.error(e.getMessage(),e); // declaredFields =NULL; } List<PropertieDescription> retpropertyDescriptors = null; try { retpropertyDescriptors = initBeaninfo(retfs); } catch(Exception e) { log.error(e.getMessage(),e); retpropertyDescriptors = NULL_P; } this.propertyDescriptors = retpropertyDescriptors; if(retfs == null) declaredFields = NULL; else declaredFields = retfs; } } public Field[] getDeclaredFields() { // init(); if(declaredFields == NULL) return null; return declaredFields; } public List<PropertieDescription> getPropertyDescriptors() { return propertyDescriptors ; } /** * 根据方法名称和方法参数类型判断是否是同一个方法 * @param method * @param other * @return */ private boolean issamemethod(Method method,Method other) { if(!method.getName().equals(other.getName())) return false; Class[] parameterTypes = method.getParameterTypes(); Class[] otherparameterTypes = other.getParameterTypes(); if((parameterTypes == null || parameterTypes.length == 0) && (otherparameterTypes == null || otherparameterTypes.length == 0)) return true; if(parameterTypes == null) { return false; } if(otherparameterTypes == null) { return false; } if(parameterTypes.length != otherparameterTypes.length) return false; for(int i = 0; i < parameterTypes.length; i ++) { if(parameterTypes[i] != otherparameterTypes[i]) return false; } return true; } private boolean containMethod(List<Method> lfs,Method method) { if(lfs == null || lfs.size() == 0) return false; for(Method other:lfs) { if(issamemethod(method,other)) return true; } return false; } private Method[] getRecursiveDeclaredMehtods() { Method[] methods = null; List<Method> lfs = new ArrayList<Method>(); Method m; Class clazz_super = clazz; do { try { methods = clazz_super.getMethods(); if(methods != null && methods.length > 0) { for(Method f:methods) { if(!containMethod(lfs,f))//过滤重载方法和抽象方法,或者接口方法 lfs.add(f); } } clazz_super = clazz_super.getSuperclass(); if(clazz_super == null || clazz_super == Object.class) { break; } } catch(Exception e) { clazz_super = clazz_super.getSuperclass(); if(clazz_super == null) break; } } while(true); if(lfs.size() > 0) { methods = new Method[lfs.size()]; for(int i = 0; i < lfs.size(); i ++) { methods[i] = lfs.get(i); } } return methods; } private boolean issamefield(Field field,Field other) { if(!field.getName().equals(other.getName())) { return false; } if(field.getType() != other.getType()) return false; return true; } private boolean containField(List<Field> lfs,Field field) { if(lfs == null || lfs.size() == 0) return false; for(Field other:lfs) { if(issamefield(field,other)) return true; } return false; } private Field[] getRecursiveDeclaredFileds() { Field[] fields = null; List<Field> lfs = new ArrayList<Field>(); Class clazz_super = clazz; do { try { fields = clazz_super.getDeclaredFields(); if(fields != null && fields.length > 0) { for(Field f:fields) { if(!containField(lfs,f)) lfs.add(f); } } clazz_super = clazz_super.getSuperclass(); if(clazz_super == null) { break; } } catch(Exception e) { clazz_super = clazz_super.getSuperclass(); if(clazz_super == null) break; } } while(true); if(lfs.size() > 0) { fields = new Field[lfs.size()]; for(int i = 0; i < lfs.size(); i ++) { fields[i] = lfs.get(i); } } return fields; } public Method getDeclaredMethod(String name) { Method[] ret = getDeclaredMethods(); if(ret == null) return null; for(Method f:ret) { if(f.getName().equals(name)) return f; } return null; } public Field getDeclaredField(String name) { Field[] ret = this.getDeclaredFields(); if(ret == null) return null; for(Field f:ret) { if(f.getName().equals(name)) return f; } return null; } private Field getDeclaredField(Field[] declaredFields,String name,Class type) { // Field[] declaredFields = this.getDeclaredFields(); if(declaredFields == null) return null; // for(Field f:declaredFields) for(int i = declaredFields.length - 1; i >=0; i --) { Field f = declaredFields[i]; if(f.getName().equals(name) ) { if( f.getType() == type ) return f; } } return null; } private List<Field> copyFields(Field[] declaredFields) { if(declaredFields == null || declaredFields.length == 0) return null; List<Field> copys = new ArrayList<Field>(declaredFields.length); for(int i =0;i < declaredFields.length; i++) { copys.add(declaredFields[i]); } return copys; } /** * 如果包含名称为name的字段,由于该字段在BeanInfo中已经存在,则将该字段从fileds副本中移除,以便将 * 最后剩下的字段生成get/set方法 * @param name * @param fields * @return */ private Field containFieldAndRemove(String name,List<Field> fields) { for(int i = 0; fields != null && i < fields.size(); i ++) { Field p = fields.get(i); if(p.getName().equals(name)) { fields.remove(i); i --; return p; } } return null; } public Class<?> getClazz() { return this.clazz; } private boolean containFieldInPropertyDescriptors(List<PropertieDescription> propertyDescriptors,Field field) { if(propertyDescriptors == null || propertyDescriptors.size() == 0) return false; for(PropertieDescription p:propertyDescriptors) { if(p.getName().equalsIgnoreCase(field.getName())) { return true; } } return false; } private void buildFieldPropertieDescriptions(List<PropertieDescription> propertyDescriptors,Field[] declaredFields) { for(int i = 0; i < declaredFields.length ; i++) { Field f = declaredFields[i]; if(containFieldInPropertyDescriptors(propertyDescriptors,f)) continue; propertyDescriptors.add(buildPropertieDescription( f)); } } private void buildFieldPropertieDescriptions(List<PropertieDescription> propertyDescriptors,List<Field> declaredFields) { for(int i = 0; i < declaredFields.size() ; i++) { Field f = declaredFields.get(i); if(containFieldInPropertyDescriptors(propertyDescriptors,f)) continue; propertyDescriptors.add(buildPropertieDescription( f)); } } private List<PropertieDescription> initBeaninfo(Field[] declaredFields) { List<PropertieDescription> propertyDescriptors = null; BeanInfo beanInfo = null; try { beanInfo = Introspector.getBeanInfo(this.clazz); PropertyDescriptor[] attributes = beanInfo.getPropertyDescriptors(); // List<PropertieDescription> asm = new ArrayList<PropertieDescription>(); if(attributes == null || attributes.length == 0 || (attributes.length == 1 && attributes[0] .getName() .equals("class"))) { if(declaredFields == null || declaredFields.length == 0) { propertyDescriptors = NULL_P; } else { propertyDescriptors = new ArrayList<PropertieDescription>(declaredFields.length); buildFieldPropertieDescriptions( propertyDescriptors,declaredFields); } return propertyDescriptors; } else { List<Field> copyFields = copyFields(declaredFields); propertyDescriptors = new ArrayList<PropertieDescription>(); for(int i = 0; i < attributes.length; i ++) { PropertyDescriptor attr = attributes[i]; if(attr.getName().equals("class")) continue; PropertieDescription p = buildPropertieDescription(declaredFields, copyFields,attr); if(p != null) propertyDescriptors.add( p); } if(copyFields != null && copyFields.size() > 0) { List<PropertieDescription> propertyDescriptors_ = new ArrayList<PropertieDescription>(declaredFields.length); buildFieldPropertieDescriptions( propertyDescriptors_,copyFields); propertyDescriptors.addAll(propertyDescriptors_); } // if(asm.size() > 0) // { // this.clazz = AsmUtil.addGETSETMethodForClass(asm, this.clazz); // } } } catch (Exception e) { propertyDescriptors = NULL_P; log.error("Init Beaninfo[" + clazz.getName() + "] failed:",e); } return propertyDescriptors; } private PropertieDescription buildPropertieDescription(Field[] declaredFields,List<Field> copeFields,PropertyDescriptor attr ) { if(attr.getPropertyType() == null) { return null; } Method wm = attr.getWriteMethod(); Method rm = attr.getReadMethod(); if(rm != null && (rm.getParameterTypes() != null && rm.getParameterTypes().length > 0)) { rm = null; } if(wm != null ) { if(wm.getParameterTypes() == null || wm.getParameterTypes().length != 1) wm = null; } else //增强处理,如果set方法有返回值,jdk会认为set方法不是属性方法,begin { String name = attr.getName(); String uName = name.length() == 1 ? name.substring(0,1).toUpperCase():name.substring(0,1).toUpperCase()+name.substring(1); String wmName = "set"+uName; wm = this.getDeclaredMethod(wmName); if(wm != null) { if(wm.getParameterTypes() == null || wm.getParameterTypes().length != 1) wm = null; if(wm != null){ Class<?> ptype = wm.getParameterTypes()[0]; boolean iswm = attr.getPropertyType().isAssignableFrom(ptype) || ptype.isAssignableFrom(attr.getPropertyType()); if(!iswm) wm = null; } } }//增强处理,如果set方法有返回值,jdk会认为set方法不是属性方法,end Field field = this.getDeclaredField(declaredFields,attr.getName(),attr.getPropertyType()); this.containFieldAndRemove(attr.getName(), copeFields) ; PropertieDescription pd = new PropertieDescription(attr.getPropertyType(), field,wm, rm,attr.getName()); // if(field != null && (wm == null || rm == null)) // asm.add(pd); return pd; } private PropertieDescription buildPropertieDescription(Field field ) { // Method wm = null; // Method rm = null; PropertieDescription pd = new PropertieDescription(field.getType(), field,null, null,field.getName()); // asm.add(pd); return pd; } public PropertieDescription getPropertyDescriptor(String name) { // this.init(); if(propertyDescriptors != NULL_P) { for(int i = 0; i < this.propertyDescriptors.size(); i ++) { PropertieDescription p = this.propertyDescriptors.get(i); if(p.getName().equals(name)) return p; } return null; } else return null; } public Constructor getDefaultConstruction() throws NoSuchMethodException { if(this.defaultConstruction != null) return defaultConstruction; throw new NoSuchMethodException(this.clazz.getName() + " do not define a default construction."); } public boolean isPrimary() { return primary; } public void setPrimary(boolean primary) { this.primary = primary; } public boolean isBaseprimary() { return baseprimary; } public Constructor[] getConstructions() { return constructions; } public List<Class> getSuperClasses() { return superClasses; } public boolean isCglib() { return cglib; } } private static Map<Class,ClassInfo> classInfos = new HashMap<Class,ClassInfo>(); private static Object lock = new Object(); public static Field[] getDeclaredFields(Class clazz) throws SecurityException { ClassInfo classinfo = getClassInfo(clazz); return classinfo.getDeclaredFields(); } public static Field getDeclaredField(Class clazz,String name) throws SecurityException { ClassInfo classinfo = getClassInfo(clazz); return classinfo.getDeclaredField(name); } public static PropertieDescription getPropertyDescriptor(Class clazz,String name) { ClassInfo classinfo = getClassInfo(clazz); return classinfo.getPropertyDescriptor(name); } public static ClassInfo getClassInfo(Class clazz) { ClassInfo classinfo = classInfos.get(clazz); if(classinfo != null) return classinfo; synchronized(lock) { classinfo = classInfos.get(clazz); if(classinfo == null) { classinfo = new ClassInfo(clazz); classInfos.put(clazz, classinfo); } } return classinfo; } public static Method getDeclaredMethod(Class clazz,String name) { ClassInfo csinfo = getClassInfo(clazz); if(csinfo == null) return null; // TODO Auto-generated method stub return csinfo.getDeclaredMethod(name); } public static Method[] getDeclaredMethods(Class target) { ClassInfo csinfo = getClassInfo(target); return csinfo.getDeclaredMethods(); } public static String genJavaName(String tableColumn) { int idx = tableColumn.indexOf('_'); if(idx == -1) return null; String tableColumn_ = tableColumn.toLowerCase(); int length = tableColumn.length(); StringBuffer ret = new StringBuffer(); for(int i = 0; i < length; i ++) { char c = tableColumn_.charAt(i); if(i < idx) { ret.append(c); } else if(i > idx) { if(c == '_') { idx = i; } else if(i == idx + 1) { if(idx != 0) ret.append(String.valueOf(c).toUpperCase()); else ret.append(c); } else { ret.append(c); } } } return ret.toString(); } }