1 15 package org.apache.tapestry.listener; 16 17 import java.lang.reflect.Method ; 18 import java.lang.reflect.Modifier ; 19 import java.util.ArrayList ; 20 import java.util.Arrays ; 21 import java.util.Comparator ; 22 import java.util.HashMap ; 23 import java.util.Iterator ; 24 import java.util.List ; 25 import java.util.Map ; 26 27 import org.apache.hivemind.util.Defense; 28 import org.apache.tapestry.IPage; 29 import org.apache.tapestry.event.ResetEventListener; 30 31 35 public class ListenerMapSourceImpl implements ListenerMapSource, ResetEventListener 36 { 37 40 41 private static class ParameterCountComparator implements Comparator 42 { 43 public int compare(Object o1, Object o2) 44 { 45 Method m1 = (Method ) o1; 46 Method m2 = (Method ) o2; 47 48 return m2.getParameterTypes().length - m1.getParameterTypes().length; 49 } 50 51 } 52 53 57 58 private final Map _classToInvokerMap = new HashMap (); 59 60 public ListenerMap getListenerMapForObject(Object object) 61 { 62 Defense.notNull(object, "object"); 63 64 Class objectClass = object.getClass(); 65 66 Map invokerMap = findInvokerMap(objectClass); 67 68 return new ListenerMapImpl(object, invokerMap); 69 } 70 71 public synchronized void resetEventDidOccur() 72 { 73 _classToInvokerMap.clear(); 74 } 75 76 private synchronized Map findInvokerMap(Class targetClass) 77 { 78 Map result = (Map ) _classToInvokerMap.get(targetClass); 79 80 if (result == null) 81 { 82 result = buildInvokerMapForClass(targetClass); 83 _classToInvokerMap.put(targetClass, result); 84 } 85 86 return result; 87 } 88 89 private Map buildInvokerMapForClass(Class targetClass) 90 { 91 95 Map map = new HashMap (); 96 97 Method [] methods = targetClass.getMethods(); 98 99 103 Arrays.sort(methods, new ParameterCountComparator()); 104 105 for (int i = 0; i < methods.length; i++) 106 { 107 Method m = methods[i]; 108 109 if (!isAcceptibleListenerMethodReturnType(m)) 110 continue; 111 112 if (Modifier.isStatic(m.getModifiers())) 113 continue; 114 115 String name = m.getName(); 116 117 addMethodToMappedList(map, m, name); 118 } 119 120 return convertMethodListMapToInvokerMap(map); 121 } 122 123 boolean isAcceptibleListenerMethodReturnType(Method m) 124 { 125 Class returnType = m.getReturnType(); 126 127 if (returnType == void.class || returnType == String .class) 128 return true; 129 130 return IPage.class.isAssignableFrom(returnType); 131 } 132 133 private Map convertMethodListMapToInvokerMap(Map map) 134 { 135 Map result = new HashMap (); 136 137 Iterator i = map.entrySet().iterator(); 138 while (i.hasNext()) 139 { 140 Map.Entry e = (Map.Entry ) i.next(); 141 142 String name = (String ) e.getKey(); 143 List methodList = (List ) e.getValue(); 144 145 Method [] methods = convertMethodListToArray(methodList); 146 147 ListenerMethodInvoker invoker = createListenerMethodInvoker(name, methods); 148 149 result.put(name, invoker); 150 } 151 152 return result; 153 } 154 155 160 161 protected ListenerMethodInvokerImpl createListenerMethodInvoker(String name, Method [] methods) 162 { 163 return new ListenerMethodInvokerImpl(name, methods); 164 } 165 166 private Method [] convertMethodListToArray(List methodList) 167 { 168 int size = methodList.size(); 169 Method [] result = new Method [size]; 170 171 return (Method []) methodList.toArray(result); 172 } 173 174 private void addMethodToMappedList(Map map, Method m, String name) 175 { 176 List l = (List ) map.get(name); 177 178 if (l == null) 179 { 180 l = new ArrayList (); 181 map.put(name, l); 182 } 183 184 l.add(m); 185 } 186 } | Popular Tags |