/** * Get properties of the given type. Results are cached, so call as often as you want. * * @param klass The class to examine for properties. * @return A map of the property name, to an instance of the helper. */ public static Map<String, PropertyHelper> getFromClass(final Class<?> klass) { if (GLOBAL_PROPERTY_MAP.containsKey(klass)) { return GLOBAL_PROPERTY_MAP.get(klass); } final Map<String, PropertyHelper> propertyList = new LinkedHashMap<String, PropertyHelper>(); addHelpersFromFields(klass, propertyList, true); // but if there is a getter or setter in the super class for the private // field, it will be // detected in these // loops for (final Method method : klass.getMethods()) { final String methodName = method.getName(); if (methodName.startsWith("get") && method.getParameterTypes().length == 0) { final String propertyName = getPropertyNameFromMethodName(methodName); PropertyHelper prop = propertyList.get(propertyName); // make an attempt to look for the field final Field field = getField(klass, propertyName); if (prop == null) { prop = new PropertyHelper(field, method, null); propertyList.put(propertyName, prop); } else { prop.getter = method; prop.field = field; } } if (methodName.startsWith("set") && method.getParameterTypes().length == 1) { final String propertyName = getPropertyNameFromMethodName(methodName); PropertyHelper prop = propertyList.get(propertyName); // make an attempt to look for the field final Field field = getField(klass, propertyName); if (prop == null) { prop = new PropertyHelper(field, null, method); propertyList.put(propertyName, prop); } else { prop.setter = method; prop.field = field; } } } synchronized (GLOBAL_PROPERTY_MAP) { GLOBAL_PROPERTY_MAP.put(klass, propertyList); } return propertyList; }
private static void addHelpersFromFields( final Class<?> klass, final Map<String, PropertyHelper> propertyList, final boolean climb) { // this loop will not discover super private fields! for (final Field field : klass.getDeclaredFields()) { if ((field.getModifiers() & (Modifier.STATIC | Modifier.FINAL)) != 0) { // don't process static or final fields continue; } final String fieldName = field.getName(); final String methodSuffix = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); try { final Method getter = klass.getMethod("get" + methodSuffix, (Class[]) null); final Method setter = klass.getMethod("set" + methodSuffix, getter.getReturnType()); // don't map getClass(), it's pretty useless // if you have a PropertyHelper, you know the Class anyway. if (!getter.getName().equals("getClass")) { propertyList.put(fieldName, new PropertyHelper(field, getter, setter)); } } catch (final NoSuchMethodException e) { if ((field.getModifiers() & Modifier.PUBLIC) > 0) { propertyList.put(fieldName, new PropertyHelper(field)); } } } if (climb) { final Class<?> superclass = klass.getSuperclass(); if (!superclass.equals(Object.class)) { addHelpersFromFields(klass.getSuperclass(), propertyList, true); } } }