Mercurial > hg > Members > sugi > MessagePack-java
comparison src/main/java/org/msgpack/template/builder/beans/EventSetDescriptor.java @ 0:cb825acd883a
first commit
author | sugi |
---|---|
date | Sat, 18 Oct 2014 15:06:15 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:cb825acd883a |
---|---|
1 // MODIFIED FOR THE MSGPACK PROJECT | |
2 // Licensed to the Apache Software Foundation (ASF) under one or more | |
3 // contributor license agreements. See the NOTICE file distributed with | |
4 // this work for additional information regarding copyright ownership. | |
5 // The ASF licenses this file to You under the Apache License, Version 2.0 | |
6 // (the "License"); you may not use this file except in compliance with | |
7 // the License. You may obtain a copy of the License at | |
8 // | |
9 // http://www.apache.org/licenses/LICENSE-2.0 | |
10 // | |
11 // Unless required by applicable law or agreed to in writing, software | |
12 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
13 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
14 // License for the specific language governing permissions and limitations under | |
15 // the License. | |
16 // | |
17 | |
18 package org.msgpack.template.builder.beans; | |
19 | |
20 import java.lang.reflect.Method; | |
21 import java.util.ArrayList; | |
22 import java.util.TooManyListenersException; | |
23 import org.apache.harmony.beans.internal.nls.Messages; | |
24 | |
25 public class EventSetDescriptor extends FeatureDescriptor { | |
26 private Class<?> listenerType; | |
27 | |
28 private ArrayList<MethodDescriptor> listenerMethodDescriptors; | |
29 | |
30 private Method[] listenerMethods; | |
31 | |
32 private Method getListenerMethod; | |
33 | |
34 private Method addListenerMethod; | |
35 | |
36 private Method removeListenerMethod; | |
37 | |
38 private boolean unicast; | |
39 | |
40 private boolean inDefaultEventSet = true; | |
41 | |
42 public EventSetDescriptor(Class<?> sourceClass, String eventSetName, | |
43 Class<?> listenerType, String listenerMethodName) | |
44 throws IntrospectionException { | |
45 checkNotNull(sourceClass, eventSetName, listenerType, | |
46 listenerMethodName); | |
47 setName(eventSetName); | |
48 this.listenerType = listenerType; | |
49 | |
50 Method method = findListenerMethodByName(listenerMethodName); | |
51 checkEventType(eventSetName, method); | |
52 listenerMethodDescriptors = new ArrayList<MethodDescriptor>(); | |
53 listenerMethodDescriptors.add(new MethodDescriptor(method)); | |
54 addListenerMethod = findMethodByPrefix(sourceClass, "add", ""); //$NON-NLS-1$ //$NON-NLS-2$ | |
55 removeListenerMethod = findMethodByPrefix(sourceClass, "remove", ""); //$NON-NLS-1$ //$NON-NLS-2$ | |
56 | |
57 if (addListenerMethod == null || removeListenerMethod == null) { | |
58 throw new IntrospectionException(Messages.getString("custom.beans.38")); //$NON-NLS-1$ | |
59 } | |
60 | |
61 getListenerMethod = findMethodByPrefix(sourceClass, "get", "s"); //$NON-NLS-1$ //$NON-NLS-2$ | |
62 unicast = isUnicastByDefault(addListenerMethod); | |
63 } | |
64 | |
65 public EventSetDescriptor(Class<?> sourceClass, String eventSetName, | |
66 Class<?> listenerType, String[] listenerMethodNames, | |
67 String addListenerMethodName, String removeListenerMethodName) | |
68 throws IntrospectionException { | |
69 this(sourceClass, eventSetName, listenerType, listenerMethodNames, | |
70 addListenerMethodName, removeListenerMethodName, null); | |
71 | |
72 } | |
73 | |
74 public EventSetDescriptor(Class<?> sourceClass, String eventSetName, | |
75 Class<?> listenerType, String[] listenerMethodNames, | |
76 String addListenerMethodName, String removeListenerMethodName, | |
77 String getListenerMethodName) throws IntrospectionException { | |
78 | |
79 checkNotNull(sourceClass, eventSetName, listenerType, | |
80 listenerMethodNames); | |
81 | |
82 setName(eventSetName); | |
83 this.listenerType = listenerType; | |
84 | |
85 listenerMethodDescriptors = new ArrayList<MethodDescriptor>(); | |
86 for (String element : listenerMethodNames) { | |
87 Method m = findListenerMethodByName(element); | |
88 | |
89 // checkEventType(eventSetName, m); | |
90 listenerMethodDescriptors.add(new MethodDescriptor(m)); | |
91 } | |
92 | |
93 if (addListenerMethodName != null) { | |
94 this.addListenerMethod = findAddRemoveListenerMethod(sourceClass, | |
95 addListenerMethodName); | |
96 } | |
97 if (removeListenerMethodName != null) { | |
98 this.removeListenerMethod = findAddRemoveListenerMethod( | |
99 sourceClass, removeListenerMethodName); | |
100 } | |
101 if (getListenerMethodName != null) { | |
102 this.getListenerMethod = findGetListenerMethod(sourceClass, | |
103 getListenerMethodName); | |
104 } | |
105 this.unicast = isUnicastByDefault(addListenerMethod); | |
106 } | |
107 | |
108 private Method findListenerMethodByName(String listenerMethodName) | |
109 throws IntrospectionException { | |
110 Method result = null; | |
111 Method[] methods = listenerType.getMethods(); | |
112 for (Method method : methods) { | |
113 if (listenerMethodName.equals(method.getName())) { | |
114 Class<?>[] paramTypes = method.getParameterTypes(); | |
115 if (paramTypes.length == 1 | |
116 && paramTypes[0].getName().endsWith("Event")) { //$NON-NLS-1$ | |
117 result = method; | |
118 break; | |
119 } | |
120 | |
121 } | |
122 } | |
123 if (null == result) { | |
124 throw new IntrospectionException(Messages.getString("custom.beans.31", //$NON-NLS-1$ | |
125 listenerMethodName, listenerType.getName())); | |
126 } | |
127 return result; | |
128 } | |
129 | |
130 public EventSetDescriptor(String eventSetName, Class<?> listenerType, | |
131 Method[] listenerMethods, Method addListenerMethod, | |
132 Method removeListenerMethod) throws IntrospectionException { | |
133 | |
134 this(eventSetName, listenerType, listenerMethods, addListenerMethod, | |
135 removeListenerMethod, null); | |
136 } | |
137 | |
138 public EventSetDescriptor(String eventSetName, Class<?> listenerType, | |
139 Method[] listenerMethods, Method addListenerMethod, | |
140 Method removeListenerMethod, Method getListenerMethod) | |
141 throws IntrospectionException { | |
142 | |
143 setName(eventSetName); | |
144 this.listenerType = listenerType; | |
145 | |
146 this.listenerMethods = listenerMethods; | |
147 if (listenerMethods != null) { | |
148 listenerMethodDescriptors = new ArrayList<MethodDescriptor>(); | |
149 | |
150 for (Method element : listenerMethods) { | |
151 // XXX do we need this check? | |
152 // checkEventType(eventSetName, element); | |
153 // if (checkMethod(listenerType, element)) { | |
154 this.listenerMethodDescriptors | |
155 .add(new MethodDescriptor(element)); | |
156 // } | |
157 } | |
158 } | |
159 | |
160 this.addListenerMethod = addListenerMethod; | |
161 this.removeListenerMethod = removeListenerMethod; | |
162 this.getListenerMethod = getListenerMethod; | |
163 this.unicast = isUnicastByDefault(addListenerMethod); | |
164 } | |
165 | |
166 public EventSetDescriptor(String eventSetName, Class<?> listenerType, | |
167 MethodDescriptor[] listenerMethodDescriptors, | |
168 Method addListenerMethod, Method removeListenerMethod) | |
169 throws IntrospectionException { | |
170 | |
171 this(eventSetName, listenerType, null, addListenerMethod, | |
172 removeListenerMethod, null); | |
173 | |
174 if (listenerMethodDescriptors != null) { | |
175 this.listenerMethodDescriptors = new ArrayList<MethodDescriptor>(); | |
176 | |
177 for (MethodDescriptor element : listenerMethodDescriptors) { | |
178 this.listenerMethodDescriptors.add(element); | |
179 } | |
180 } | |
181 } | |
182 | |
183 // ensures that there is no nulls | |
184 @SuppressWarnings("nls") | |
185 private void checkNotNull(Object sourceClass, Object eventSetName, | |
186 Object alistenerType, Object listenerMethodName) { | |
187 if (sourceClass == null) { | |
188 throw new NullPointerException(Messages.getString("custom.beans.0C")); | |
189 } | |
190 if (eventSetName == null) { | |
191 throw new NullPointerException(Messages.getString("custom.beans.53")); | |
192 } | |
193 if (alistenerType == null) { | |
194 throw new NullPointerException(Messages.getString("custom.beans.54")); | |
195 } | |
196 if (listenerMethodName == null) { | |
197 throw new NullPointerException(Messages.getString("custom.beans.52")); | |
198 } | |
199 } | |
200 | |
201 /** | |
202 * Checks that given listener method has an argument of the valid type. | |
203 * | |
204 * @param eventSetName | |
205 * event set name | |
206 * @param listenerMethod | |
207 * listener method | |
208 * @throws IntrospectionException | |
209 * if check fails | |
210 */ | |
211 private static void checkEventType(String eventSetName, | |
212 Method listenerMethod) throws IntrospectionException { | |
213 Class<?>[] params = listenerMethod.getParameterTypes(); | |
214 String firstParamTypeName = null; | |
215 String eventTypeName = prepareEventTypeName(eventSetName); | |
216 | |
217 if (params.length > 0) { | |
218 firstParamTypeName = extractShortClassName(params[0] | |
219 .getName()); | |
220 } | |
221 | |
222 if (firstParamTypeName == null | |
223 || !firstParamTypeName.equals(eventTypeName)) { | |
224 throw new IntrospectionException(Messages.getString("custom.beans.51", //$NON-NLS-1$ | |
225 listenerMethod.getName(), eventTypeName)); | |
226 } | |
227 } | |
228 | |
229 /** | |
230 * @param fullClassName full name of the class | |
231 * @return name with package and encapsulating class info omitted | |
232 */ | |
233 private static String extractShortClassName(String fullClassName) { | |
234 int k = fullClassName.lastIndexOf('$'); | |
235 k = (k == -1 ? fullClassName.lastIndexOf('.') : k); | |
236 return fullClassName.substring(k + 1); | |
237 } | |
238 | |
239 private static String prepareEventTypeName(String eventSetName) { | |
240 StringBuilder sb = new StringBuilder(); | |
241 | |
242 if (eventSetName != null && eventSetName.length() > 0) { | |
243 sb.append(Character.toUpperCase(eventSetName.charAt(0))); | |
244 | |
245 if (eventSetName.length() > 1) { | |
246 sb.append(eventSetName.substring(1)); | |
247 } | |
248 } | |
249 | |
250 sb.append("Event"); //$NON-NLS-1$ | |
251 return sb.toString(); | |
252 } | |
253 | |
254 public Method[] getListenerMethods() { | |
255 if (listenerMethods != null) { | |
256 return listenerMethods; | |
257 } | |
258 | |
259 if (listenerMethodDescriptors != null) { | |
260 listenerMethods = new Method[listenerMethodDescriptors.size()]; | |
261 int index = 0; | |
262 for (MethodDescriptor md : listenerMethodDescriptors) { | |
263 listenerMethods[index++] = md.getMethod(); | |
264 } | |
265 return listenerMethods; | |
266 } | |
267 return null; | |
268 } | |
269 | |
270 public MethodDescriptor[] getListenerMethodDescriptors() { | |
271 return listenerMethodDescriptors == null ? null | |
272 : listenerMethodDescriptors.toArray(new MethodDescriptor[0]); | |
273 } | |
274 | |
275 public Method getRemoveListenerMethod() { | |
276 return removeListenerMethod; | |
277 } | |
278 | |
279 public Method getGetListenerMethod() { | |
280 return getListenerMethod; | |
281 } | |
282 | |
283 public Method getAddListenerMethod() { | |
284 return addListenerMethod; | |
285 } | |
286 | |
287 public Class<?> getListenerType() { | |
288 return listenerType; | |
289 } | |
290 | |
291 public void setUnicast(boolean unicast) { | |
292 this.unicast = unicast; | |
293 } | |
294 | |
295 public void setInDefaultEventSet(boolean inDefaultEventSet) { | |
296 this.inDefaultEventSet = inDefaultEventSet; | |
297 } | |
298 | |
299 public boolean isUnicast() { | |
300 return unicast; | |
301 } | |
302 | |
303 public boolean isInDefaultEventSet() { | |
304 return inDefaultEventSet; | |
305 } | |
306 | |
307 /** | |
308 * Searches for {add|remove}Listener methods in the event source. Parameter | |
309 * check is also performed. | |
310 * | |
311 * @param sourceClass | |
312 * event source class | |
313 * @param methodName | |
314 * method name to search | |
315 * @return found method | |
316 * @throws IntrospectionException | |
317 * if no valid method found | |
318 */ | |
319 private Method findAddRemoveListenerMethod(Class<?> sourceClass, | |
320 String methodName) throws IntrospectionException { | |
321 try { | |
322 return sourceClass.getMethod(methodName, listenerType); | |
323 } catch (NoSuchMethodException e) { | |
324 return findAddRemoveListnerMethodWithLessCheck(sourceClass, | |
325 methodName); | |
326 } catch (Exception e) { | |
327 throw new IntrospectionException(Messages.getString("custom.beans.31", //$NON-NLS-1$ | |
328 methodName, listenerType.getName())); | |
329 } | |
330 } | |
331 | |
332 private Method findAddRemoveListnerMethodWithLessCheck( | |
333 Class<?> sourceClass, String methodName) | |
334 throws IntrospectionException { | |
335 Method[] methods = sourceClass.getMethods(); | |
336 Method result = null; | |
337 for (Method method : methods) { | |
338 if (method.getName().equals(methodName)) { | |
339 Class<?>[] paramTypes = method.getParameterTypes(); | |
340 if (paramTypes.length == 1) { | |
341 result = method; | |
342 break; | |
343 } | |
344 } | |
345 } | |
346 if (null == result) { | |
347 throw new IntrospectionException(Messages.getString("custom.beans.31", //$NON-NLS-1$ | |
348 methodName, listenerType.getName())); | |
349 } | |
350 return result; | |
351 } | |
352 | |
353 /** | |
354 * @param sourceClass | |
355 * class of event source | |
356 * @param methodName | |
357 * name of the custom getListeners() method | |
358 * @return found Method object for custom getListener or null if nothing is | |
359 * found | |
360 */ | |
361 private Method findGetListenerMethod(Class<?> sourceClass, String methodName) { | |
362 try { | |
363 return sourceClass.getMethod(methodName); | |
364 } catch (Exception e) { | |
365 // RI keeps silence here and just returns null | |
366 return null; | |
367 } | |
368 } | |
369 | |
370 private Method findMethodByPrefix(Class<?> sourceClass, String prefix, | |
371 String postfix) { | |
372 String shortName = listenerType.getName(); | |
373 if (listenerType.getPackage() != null) { | |
374 shortName = shortName.substring(listenerType.getPackage().getName() | |
375 .length() + 1); | |
376 } | |
377 String methodName = prefix + shortName + postfix; | |
378 try { | |
379 if ("get".equals(prefix)) { //$NON-NLS-1$ | |
380 return sourceClass.getMethod(methodName); | |
381 } | |
382 } catch (NoSuchMethodException nsme) { | |
383 return null; | |
384 } | |
385 Method[] methods = sourceClass.getMethods(); | |
386 for (int i = 0; i < methods.length; i++) { | |
387 if (methods[i].getName().equals(methodName)) { | |
388 Class<?>[] paramTypes = methods[i].getParameterTypes(); | |
389 if (paramTypes.length == 1) { | |
390 return methods[i]; | |
391 } | |
392 } | |
393 } | |
394 return null; | |
395 } | |
396 | |
397 private static boolean isUnicastByDefault(Method addMethod) { | |
398 if (addMethod != null) { | |
399 Class<?>[] exceptionTypes = addMethod.getExceptionTypes(); | |
400 for (Class<?> element : exceptionTypes) { | |
401 if (element.equals(TooManyListenersException.class)) { | |
402 return true; | |
403 } | |
404 } | |
405 } | |
406 return false; | |
407 } | |
408 | |
409 void merge(EventSetDescriptor event) { | |
410 super.merge(event); | |
411 if (addListenerMethod == null) { | |
412 addListenerMethod = event.addListenerMethod; | |
413 } | |
414 if (getListenerMethod == null) { | |
415 getListenerMethod = event.getListenerMethod; | |
416 } | |
417 if (listenerMethodDescriptors == null) { | |
418 listenerMethodDescriptors = event.listenerMethodDescriptors; | |
419 } | |
420 if (listenerMethods == null) { | |
421 listenerMethods = event.listenerMethods; | |
422 } | |
423 if (listenerType == null) { | |
424 listenerType = event.listenerType; | |
425 } | |
426 | |
427 if (removeListenerMethod == null) { | |
428 removeListenerMethod = event.removeListenerMethod; | |
429 } | |
430 inDefaultEventSet &= event.inDefaultEventSet; | |
431 } | |
432 } |