1 22 package org.jboss.beans.info.plugins; 23 24 import java.util.ArrayList ; 25 import java.util.HashMap ; 26 import java.util.HashSet ; 27 import java.util.Iterator ; 28 import java.util.List ; 29 import java.util.Map ; 30 import java.util.Set ; 31 import java.util.WeakHashMap ; 32 33 import org.jboss.beans.info.spi.BeanInfo; 34 import org.jboss.beans.info.spi.BeanInfoFactory; 35 import org.jboss.beans.info.spi.EventInfo; 36 import org.jboss.beans.info.spi.PropertyInfo; 37 import org.jboss.classadapter.spi.ClassAdapter; 38 import org.jboss.reflect.spi.ClassInfo; 39 import org.jboss.reflect.spi.ConstructorInfo; 40 import org.jboss.reflect.spi.MethodInfo; 41 import org.jboss.reflect.spi.PrimitiveInfo; 42 import org.jboss.reflect.spi.TypeInfo; 43 import org.jboss.util.JBossStringBuilder; 44 import org.jboss.util.collection.WeakValueHashMap; 45 46 52 public class AbstractBeanInfoFactory implements BeanInfoFactory 53 { 54 55 protected Map <ClassLoader , Map <String , BeanInfo>> cache = new WeakHashMap <ClassLoader , Map <String , BeanInfo>>(); 56 57 protected static boolean isGetter(MethodInfo minfo) 58 { 59 String name = minfo.getName(); 60 TypeInfo returnType = minfo.getReturnType(); 61 TypeInfo[] parameters = minfo.getParameterTypes(); 62 if ((name.length() > 3 && name.startsWith("get")) || (name.length() > 2 && name.startsWith("is"))) 63 { 64 if (parameters.length == 0 && PrimitiveInfo.VOID.equals(returnType) == false) 65 return true; 66 } 67 return false; 68 } 69 70 protected static boolean isSetter(MethodInfo minfo) 71 { 72 String name = minfo.getName(); 73 TypeInfo returnType = minfo.getReturnType(); 74 TypeInfo[] parameters = minfo.getParameterTypes(); 75 if ((name.length() > 3 && name.startsWith("set"))) 76 { 77 if (parameters.length == 1 && PrimitiveInfo.VOID.equals(returnType)) 78 return true; 79 } 80 return false; 81 } 82 83 protected static String getUpperPropertyName(String name) 84 { 85 int start = 3; 86 if (name.startsWith("is")) 87 start = 2; 88 89 return name.substring(start); 90 } 91 92 protected static String getLowerPropertyName(String name) 93 { 94 if (name.length() > 1) 97 { 98 if (Character.isUpperCase(name.charAt(1))) 99 return name; 100 } 101 102 JBossStringBuilder buffer = new JBossStringBuilder(name.length()); 103 buffer.append(Character.toLowerCase(name.charAt(0))); 104 if (name.length() > 1) 105 buffer.append(name.substring(1)); 106 return buffer.toString(); 107 } 108 109 112 public AbstractBeanInfoFactory() 113 { 114 } 115 116 public BeanInfo getBeanInfo(ClassAdapter classAdapter) 117 { 118 synchronized (cache) 119 { 120 ClassLoader cl = classAdapter.getClassLoader(); 121 ClassInfo classInfo = classAdapter.getClassInfo(); 122 String className = classInfo.getName(); 123 Map <String , BeanInfo> map = cache.get(cl); 124 if (map != null) 125 { 126 BeanInfo info = map.get(className); 127 if (info != null) 128 return info; 129 } 130 131 if (classInfo.isInterface()) 132 throw new IllegalArgumentException (classInfo.getName() + " is an interface"); 133 134 Set <ConstructorInfo> constructors = getConstructors(classInfo); 135 Set <MethodInfo> methods = getMethods(classInfo); 136 Set <PropertyInfo> properties = getProperties(methods); 137 Set <EventInfo> events = getEvents(classInfo); 138 139 BeanInfo result = createBeanInfo(classAdapter, properties, constructors, methods, events); 140 if (map == null) 141 { 142 map = new WeakValueHashMap(); 143 cache.put(cl, map); 144 } 145 map.put(className, result); 146 return result; 147 } 148 } 149 150 160 protected BeanInfo createBeanInfo(ClassAdapter classAdapter, Set <PropertyInfo> properties, Set <ConstructorInfo> constructors, Set <MethodInfo> methods, Set <EventInfo> events) 161 { 162 return new AbstractBeanInfo(this, classAdapter, properties, constructors, methods, events); 163 } 164 165 171 protected Set <ConstructorInfo> getConstructors(ClassInfo classInfo) 172 { 173 ConstructorInfo[] cinfos = classInfo.getDeclaredConstructors(); 174 if (cinfos == null || cinfos.length == 0) 175 return null; 176 177 HashSet <ConstructorInfo> result = new HashSet <ConstructorInfo>(); 178 for (int i = 0; i < cinfos.length; ++i) 179 result.add(cinfos[i]); 180 return result; 181 } 182 183 189 protected Set <MethodInfo> getMethods(ClassInfo classInfo) 190 { 191 HashSet <MethodInfo> result = new HashSet <MethodInfo>(); 192 while (classInfo != null) 193 { 194 MethodInfo[] minfos = classInfo.getDeclaredMethods(); 195 if (minfos != null && minfos.length > 0) 196 { 197 for (int i = 0; i < minfos.length; ++i) 198 { 199 if (result.contains(minfos[i]) == false) 200 result.add(minfos[i]); 201 } 202 } 203 204 classInfo = classInfo.getSuperclass(); 205 } 206 return result; 207 } 208 209 215 protected Set <PropertyInfo> getProperties(Set methods) 216 { 217 HashMap <String , MethodInfo> getters = new HashMap <String , MethodInfo>(); 218 HashMap <String , List <MethodInfo>> setters = new HashMap <String , List <MethodInfo>>(); 219 if (methods.isEmpty() == false) 220 { 221 for (Iterator i = methods.iterator(); i.hasNext();) 222 { 223 MethodInfo methodInfo = (MethodInfo) i.next(); 224 if (methodInfo.isPublic() && methodInfo.isStatic() == false) 225 { 226 String name = methodInfo.getName(); 227 String upperName = getUpperPropertyName(name); 228 if (isGetter(methodInfo)) 229 { 230 getters.put(upperName, methodInfo); 231 } 232 else if (isSetter(methodInfo)) 233 { 234 ArrayList <MethodInfo> list = (ArrayList <MethodInfo>) setters.get(upperName); 235 if (list == null) 236 { 237 list = new ArrayList <MethodInfo>(); 238 setters.put(upperName, list); 239 } 240 list.add(methodInfo); 241 } 242 } 243 } 244 } 245 246 HashSet <PropertyInfo> properties = new HashSet <PropertyInfo>(); 247 if (getters.isEmpty() == false) 248 { 249 for (Iterator i = getters.entrySet().iterator(); i.hasNext();) 250 { 251 Map.Entry entry = (Map.Entry ) i.next(); 252 String name = (String ) entry.getKey(); 253 MethodInfo getter = (MethodInfo) entry.getValue(); 254 MethodInfo setter = null; 255 ArrayList setterList = (ArrayList ) setters.remove(name); 256 if (setterList != null && setterList.size() != 0) 257 { 258 for (int j = 0; j < setterList.size(); ++j) 259 { 260 MethodInfo thisSetter = (MethodInfo) setterList.get(j); 261 TypeInfo pinfo = thisSetter.getParameterTypes()[0]; 262 if (getter.getReturnType().equals(pinfo) == true) 263 { 264 setter = thisSetter; 265 break; 266 } 267 } 268 } 269 String lowerName = getLowerPropertyName(name); 270 properties.add(new AbstractPropertyInfo(lowerName, name, getter.getReturnType(), getter, setter)); 271 } 272 } 273 if (setters.isEmpty() == false) 274 { 275 for (Iterator i = setters.entrySet().iterator(); i.hasNext();) 276 { 277 Map.Entry entry = (Map.Entry ) i.next(); 278 String name = (String ) entry.getKey(); 279 ArrayList setterList = (ArrayList ) entry.getValue(); 280 if (setterList.size() == 1) 282 { 283 MethodInfo setter = (MethodInfo) setterList.get(0); 284 TypeInfo pinfo = setter.getParameterTypes()[0]; 285 String lowerName = getLowerPropertyName(name); 286 properties.add(new AbstractPropertyInfo(lowerName, name, pinfo, null, setter)); 287 } 288 } 289 } 290 return properties; 291 } 292 293 299 protected Set <EventInfo> getEvents(ClassInfo classInfo) 300 { 301 return null; 302 } 303 } 304 | Popular Tags |