/* * JEF - Copyright 2009-2010 Jiyi (mr.jiyi@gmail.com) * * 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 jef.tools.reflect; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import jef.common.log.LogUtil; import jef.tools.StringUtils; public final class BeanWrapperAsMethod extends BeanWrapper{ private static Map<Class<?>,Map<String, PropertyHolder>> cache=new HashMap<Class<?>,Map<String, PropertyHolder>>(); private Object obj; private Map <String, PropertyHolder> properties=null; public BeanWrapperAsMethod(Object obj) { super(obj); Map<String,MethodEx> methods=new HashMap<String,MethodEx>(); this.obj=obj; Class<?> c=obj.getClass(); if(cache.containsKey(c)){ properties=cache.get(c); return; } properties=new HashMap<String, PropertyHolder>(); List<String> ll=new ArrayList<String>(); for(MethodEx m: new ClassEx(c).getMethods()){ if(Modifier.isStatic(m.getModifiers())){ continue; } String methodName=m.getName(); if("getClass".equals(methodName))continue; if(methodName.startsWith("get")){ if(m.getParameterTypes().length==0){ String mField=StringUtils.uncapitalize(StringUtils.substringAfter(methodName, "get")); methods.put("get"+mField, m); if(!ll.contains(mField))ll.add(mField); } }else if(methodName.startsWith("is")){ if(m.getParameterTypes().length==0){ String mField=StringUtils.uncapitalize(StringUtils.substringAfter(methodName, "is")); methods.put("get"+mField, m); if(!ll.contains(mField))ll.add(mField); } }else if(methodName.startsWith("set")){ String mField=StringUtils.uncapitalize(StringUtils.substringAfter(methodName, "set")); if(m.getParameterTypes().length==1){ mField=StringUtils.uncapitalize(StringUtils.substringAfter(methodName, "set")); methods.put("set"+mField, m); if(!ll.contains(mField))ll.add(mField); } } } for(String mField:ll){ if(StringUtils.isNotEmpty(mField)){ PropertyHolder pp = new PropertyHolder(methods.get("get"+mField),methods.get("set"+mField),null,mField); properties.put(mField,pp); } } cache.put(c, properties); } public boolean isReadableProperty(String fieldName) { PropertyHolder pp=properties.get(fieldName); if(pp==null)return false; return pp.getReadMethod()!=null; } public boolean isWritableProperty(String fieldName) { if(fieldName==null)return false; PropertyHolder pp=properties.get(fieldName); if(pp==null)return false; return pp.getWriteMethod()!=null; } public Object getPropertyValue(String fieldName) { PropertyHolder pp=properties.get(fieldName); if(pp==null)throw new NullPointerException(fieldName + " is not exist!"); Method m=pp.getReadMethod(); if(m==null)throw new NullPointerException(); try { return m.invoke(obj, new Object[]{}); } catch (IllegalArgumentException e) { LogUtil.exception(e); return null; } catch (IllegalAccessException e) { LogUtil.exception(e); return null; } catch (InvocationTargetException e) { LogUtil.exception(e); return null; } } public void setPropertyValue(String fieldName, Object newValue) { PropertyHolder pp=properties.get(fieldName); if(pp==null)throw new NullPointerException("Can not find property '"+fieldName+"' in bean "+ obj.getClass().getName()); Method m=pp.getWriteMethod(); if(m==null)throw new NullPointerException("Can not find set method '"+fieldName+"' in bean "+ obj.getClass().getName()); try { m.invoke(obj, new Object[]{newValue}); } catch (IllegalArgumentException e) { StringBuilder sb=new StringBuilder("IllegalArgumentException:").append(e.getLocalizedMessage()).append('\n'); sb.append(obj.getClass().getName()).append('\t').append(fieldName).append('\t').append(newValue.getClass().getName()); throw new IllegalArgumentException(sb.toString()); } catch (IllegalAccessException e) { StringBuilder sb=new StringBuilder("IllegalAccessException:").append(e.getLocalizedMessage()).append('\n'); sb.append(obj.getClass().getName()).append('\t').append(fieldName).append('\t').append(newValue); throw new IllegalArgumentException(sb.toString()); } catch (InvocationTargetException e) { StringBuilder sb=new StringBuilder("InvocationTargetException:").append(e.getLocalizedMessage()).append('\n'); sb.append(obj.getClass().getName()).append('\t').append(fieldName).append('\t').append(newValue); throw new IllegalArgumentException(sb.toString()); } } @Override public Collection<? extends Property> getProperties() { return properties.values(); } public String getFieldIgnoreCase(String string) { if(properties.containsKey(string))return string; for(String field: properties.keySet()){ if(field.equalsIgnoreCase(string))return field; } return null; } public Class<?> getFieldType(String fieldName) { PropertyHolder pp=properties.get(fieldName); if(pp==null)throw new NullPointerException("Can not find PropertyHolder for field: " + fieldName); Method m=pp.getWriteMethod(); if(m==null)throw new NullPointerException("Can not find WriterMethod for field: " + fieldName); Class<?>[] cs=m.getParameterTypes(); return cs[0]; } @Override public boolean isProperty(String fieldName) { PropertyHolder pp = properties.get(fieldName); return pp != null; } @Override public Type getPropertyType(String fieldName) { PropertyHolder pp = properties.get(fieldName); if (pp == null)throw new NoSuchElementException(fieldName+" not found in bean "+ this.obj.getClass().getName()); return pp.getGenericType(); } @Override public Class<?> getPropertyRawType(String fieldName) { PropertyHolder pp = properties.get(fieldName); if (pp == null)throw new NoSuchElementException(fieldName+" not found in bean "+ this.obj.getClass().getName()); return pp.getType(); } @Override public Object getWrapped() { return obj; } @Override public String getClassName() { return obj.getClass().getName(); } public String findPropertyIgnoreCase(String string) { if (properties.containsKey(string)) return string; for (String field : properties.keySet()) { if (field.equalsIgnoreCase(string)) return field; } return null; } @Override public Collection<String> getPropertyNames() { return this.properties.keySet(); } @Override public Collection<String> getRwPropertyNames() { ArrayList<String> list=new ArrayList<String>(); for(PropertyHolder pp: properties.values()){ if(pp.getReadMethod()!=null && pp.getWriteMethod()!=null){ list.add(pp.getName()); } } return list; } @Override public <T extends Annotation> T getAnnotationOnField(String name, Class<T> clz) { FieldEx field=BeanUtils.getField(obj.getClass(), name); if(field==null)return null; return field.getAnnotation(clz); } @Override public <T extends Annotation> T getAnnotationOnGetter(String name, Class<T> clz) { PropertyHolder pp = properties.get(name); if (pp == null)return null; Method method=pp.getReadMethod(); if(method==null)return null; return method.getAnnotation(clz); } @Override public <T extends Annotation> T getAnnotationOnSetter(String name, Class<T> clz) { PropertyHolder pp = properties.get(name); if (pp == null)return null; Method method=pp.getWriteMethod(); if(method==null)return null; return method.getAnnotation(clz); } @Override public Property getProperty(String name) { return properties.get(name); } }