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 }