001 package net.sourceforge.javajson.converter;
002
003 import java.lang.reflect.InvocationTargetException;
004 import java.lang.reflect.Method;
005 import java.util.HashMap;
006 import java.util.LinkedList;
007 import java.util.List;
008 import java.util.Map;
009 import java.util.regex.Matcher;
010 import java.util.regex.Pattern;
011
012 /**
013 * A set of utility functions for reflection related things used in this json
014 * package
015 */
016 public class Reflection {
017
018 private static Pattern setterPattern = Pattern.compile("^set[A-Z].*");
019
020 private static Pattern getterPattern = Pattern.compile("^(is|get)[A-Z].*");
021
022 public static List<Method> getSetterFieldMethods(Class cls) {
023 List<Method> methods = new LinkedList<Method>();
024
025 Method[] a = cls.getMethods();
026 for (int i = 0; i < a.length; i++) {
027
028 if (a[i].getParameterTypes().length == 1
029 && isSetterMethod(a[i].getName())) {
030 // TODO: make sure method isn't static or protected/private
031 methods.add(a[i]);
032 }
033 }
034
035 return methods;
036 }
037
038 /**
039 * Returns the public getter methods that are normal getters, this includes
040 * getX and isX methods as long as the isX methods return a boolean.
041 *
042 * @param cls
043 * @return
044 */
045 static List<Method> getGetterFieldMethods(Class cls) {
046 List<Method> methods = new LinkedList<Method>();
047
048 Method[] a = cls.getMethods();
049 for (int i = 0; i < a.length; i++) {
050
051 if (a[i].getParameterTypes().length == 0
052 && isGetterMethod(a[i].getName())) {
053 // TODO: check that 'is' methods are boolean
054 // TODO: make sure method isn't static or protected/private
055 methods.add(a[i]);
056 }
057 }
058
059 return methods;
060 }
061
062 static Map<String, Object> getFields(Object o)
063 throws IllegalArgumentException, IllegalAccessException,
064 InvocationTargetException {
065 List<Method> methods = getGetterFieldMethods(o.getClass());
066 Map<String, Object> ret = new HashMap<String, Object>();
067
068 Object[] ARGS = new Object[0];
069 for (Method m : methods) {
070 String name = m.getName();
071 Object value = m.invoke(o, ARGS);
072 ret.put(name, value);
073 }
074
075 return ret;
076 }
077
078 /**
079 * Converts a methodname into a field name. Return null if its not a
080 * proper/normal method name that starts with get/set/is.
081 *
082 * @param methodName
083 * @return
084 */
085 static String getFieldName(String methodName) {
086 int l = methodName.length();
087 if (l >= 2 && Character.isUpperCase(methodName.charAt(2))) {
088 if (methodName.startsWith("is")) {
089 return Character.toLowerCase(methodName.charAt(2))
090 + methodName.substring(3);
091 }
092 }
093 if (l >= 3 && Character.isUpperCase(methodName.charAt(3))) {
094 if (methodName.startsWith("get") || methodName.startsWith("set")) {
095 return Character.toLowerCase(methodName.charAt(3))
096 + methodName.substring(4);
097 }
098 }
099
100 return null;
101 }
102
103 /**
104 * Returns true if the name starts with get or is followed by a capital
105 * letter
106 */
107 private static boolean isGetterMethod(String name) {
108 Matcher m = getterPattern.matcher(name);
109 return m.matches();
110 }
111
112 private static boolean isSetterMethod(String name) {
113 Matcher m = setterPattern.matcher(name);
114 return m.matches();
115 }
116 }