1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| |
8 |
| |
9 |
| |
10 |
| |
11 |
| |
12 |
| |
13 |
| |
14 |
| |
15 |
| |
16 |
| package org.ini4j; |
17 |
| |
18 |
| import java.beans.*; |
19 |
| import java.lang.reflect.*; |
20 |
| import java.io.*; |
21 |
| import java.net.URL; |
22 |
| import java.net.URI; |
23 |
| import java.util.*; |
24 |
| |
25 |
| abstract class AbstractBeanInvocationHandler implements InvocationHandler |
26 |
| { |
27 |
| private static final String PARSE_METHOD = "valueOf"; |
28 |
| private static final String ADD_PREFIX = "add"; |
29 |
| private static final int ADD_PREFIX_LEN = ADD_PREFIX.length(); |
30 |
| private static final String REMOVE_PREFIX = "remove"; |
31 |
| private static final int REMOVE_PREFIX_LEN = REMOVE_PREFIX.length(); |
32 |
| private static final String PROPERTY_CHANGE_LISTENER = "PropertyChangeListener"; |
33 |
| private static final String VETOABLE_CHANGE_LISTENER = "VetoableChangeListener"; |
34 |
| private static final String READ_PREFIX = "get"; |
35 |
| private static final String READ_BOOLEAN_PREFIX = "is"; |
36 |
| private static final String WRITE_PREFIX = "set"; |
37 |
| private static final String HAS_PREFIX = "has"; |
38 |
| private static final int READ_PREFIX_LEN = READ_PREFIX.length(); |
39 |
| private static final int READ_BOOLEAN_PREFIX_LEN = READ_BOOLEAN_PREFIX.length(); |
40 |
| private static final int WRITE_PREFIX_LEN = WRITE_PREFIX.length(); |
41 |
| private static final int HAS_PREFIX_LEN = HAS_PREFIX.length(); |
42 |
| |
43 |
| private PropertyChangeSupport _pcSupport; |
44 |
| private VetoableChangeSupport _vcSupport; |
45 |
| private Object _proxy; |
46 |
| |
47 |
119
| protected AbstractBeanInvocationHandler()
|
48 |
| { |
49 |
| ; |
50 |
| } |
51 |
| |
52 |
1083
| public Object invoke(Object proxy, Method method, Object[] args) throws PropertyVetoException
|
53 |
| { |
54 |
1083
| Object ret = null;
|
55 |
1083
| String name = method.getName();
|
56 |
1083
| String property;
|
57 |
| |
58 |
1083
| synchronized (this)
|
59 |
| { |
60 |
1083
| if ( _proxy == null )
|
61 |
| { |
62 |
114
| _proxy = proxy;
|
63 |
| } |
64 |
| } |
65 |
| |
66 |
1083
| if ( name.startsWith(READ_PREFIX) )
|
67 |
| { |
68 |
585
| property = Introspector.decapitalize(name.substring(READ_PREFIX_LEN));
|
69 |
585
| ret = getProperty(property, method.getReturnType());
|
70 |
| } |
71 |
498
| else if ( name.startsWith(READ_BOOLEAN_PREFIX) )
|
72 |
| { |
73 |
1
| property = Introspector.decapitalize(name.substring(READ_BOOLEAN_PREFIX_LEN));
|
74 |
1
| ret = getProperty(property, method.getReturnType());
|
75 |
| } |
76 |
497
| else if ( name.startsWith(WRITE_PREFIX) )
|
77 |
| { |
78 |
69
| property = Introspector.decapitalize(name.substring(WRITE_PREFIX_LEN));
|
79 |
69
| setProperty(property, args[0], method.getParameterTypes()[0]);
|
80 |
| } |
81 |
428
| else if ( name.startsWith(ADD_PREFIX) )
|
82 |
| { |
83 |
7
| String listener = name.substring(ADD_PREFIX_LEN);
|
84 |
| |
85 |
7
| if ( listener.equals(PROPERTY_CHANGE_LISTENER) )
|
86 |
| { |
87 |
3
| addPropertyChangeListener((String)args[0], (PropertyChangeListener)args[1]);
|
88 |
| } |
89 |
4
| else if ( listener.equals(VETOABLE_CHANGE_LISTENER) )
|
90 |
| { |
91 |
3
| addVetoableChangeListener((String)args[0], (VetoableChangeListener)args[1]);
|
92 |
| } |
93 |
| } |
94 |
421
| else if ( name.startsWith(REMOVE_PREFIX) )
|
95 |
| { |
96 |
11
| String listener = name.substring(REMOVE_PREFIX_LEN);
|
97 |
| |
98 |
11
| if ( listener.equals(PROPERTY_CHANGE_LISTENER) )
|
99 |
| { |
100 |
5
| removePropertyChangeListener((String)args[0], (PropertyChangeListener)args[1]);
|
101 |
| } |
102 |
6
| else if ( listener.equals(VETOABLE_CHANGE_LISTENER) )
|
103 |
| { |
104 |
5
| removeVetoableChangeListener((String)args[0], (VetoableChangeListener)args[1]);
|
105 |
| } |
106 |
| } |
107 |
410
| else if ( name.startsWith(HAS_PREFIX) )
|
108 |
| { |
109 |
367
| property = Introspector.decapitalize(name.substring(HAS_PREFIX_LEN));
|
110 |
367
| ret = Boolean.valueOf(hasProperty(property));
|
111 |
| } |
112 |
| |
113 |
1082
| return ret;
|
114 |
| } |
115 |
| |
116 |
594
| protected synchronized Object getProperty(String property, Class<?> clazz)
|
117 |
| { |
118 |
594
| Object o;
|
119 |
| |
120 |
594
| try
|
121 |
| { |
122 |
594
| o = getPropertySpi(property, clazz);
|
123 |
| |
124 |
594
| if ( o == null )
|
125 |
| { |
126 |
2
| o = zero(clazz);
|
127 |
| } |
128 |
592
| else if ( (o instanceof String) && ! clazz.equals(String.class) )
|
129 |
| { |
130 |
454
| o = parseValue((String)o, clazz);
|
131 |
| } |
132 |
| } |
133 |
| catch (Exception x) |
134 |
| { |
135 |
1
| o = zero(clazz);
|
136 |
| } |
137 |
| |
138 |
594
| return o;
|
139 |
| } |
140 |
| |
141 |
| protected abstract Object getPropertySpi(String property, Class<?> clazz); |
142 |
| |
143 |
70
| protected synchronized void setProperty(String property, Object value, Class<?> clazz) throws PropertyVetoException
|
144 |
| { |
145 |
70
| try
|
146 |
| { |
147 |
70
| boolean pc = (_pcSupport != null) && _pcSupport.hasListeners(property);
|
148 |
70
| boolean vc = (_vcSupport != null) && _vcSupport.hasListeners(property);
|
149 |
70
| Object old = ( pc || vc ) ? getProperty(property, clazz) : null;
|
150 |
| |
151 |
70
| if ( vc )
|
152 |
| { |
153 |
2
| fireVetoableChange(property,old, value);
|
154 |
| } |
155 |
| |
156 |
69
| if ( clazz.equals(String.class) && !(value instanceof String) )
|
157 |
| { |
158 |
1
| value = value.toString();
|
159 |
| } |
160 |
| |
161 |
69
| setPropertySpi(property, value, clazz);
|
162 |
| |
163 |
68
| if ( pc )
|
164 |
| { |
165 |
2
| firePropertyChange(property,old,value);
|
166 |
| } |
167 |
| } |
168 |
| catch (PropertyVetoException x) |
169 |
| { |
170 |
1
| throw x;
|
171 |
| } |
172 |
| catch (Exception x) |
173 |
| { |
174 |
| ; |
175 |
| } |
176 |
| } |
177 |
| |
178 |
| protected abstract void setPropertySpi(String property, Object value, Class<?> clazz); |
179 |
| |
180 |
370
| protected synchronized boolean hasProperty(String property)
|
181 |
| { |
182 |
370
| boolean ret;
|
183 |
| |
184 |
370
| try
|
185 |
| { |
186 |
370
| ret = hasPropertySpi(property);
|
187 |
| } |
188 |
| catch (Exception x) |
189 |
| { |
190 |
1
| ret = false;
|
191 |
| } |
192 |
| |
193 |
370
| return ret;
|
194 |
| } |
195 |
| |
196 |
| protected abstract boolean hasPropertySpi(String property); |
197 |
| |
198 |
3
| protected synchronized void addPropertyChangeListener(String property, PropertyChangeListener listener)
|
199 |
| { |
200 |
3
| if ( _pcSupport == null )
|
201 |
| { |
202 |
1
| _pcSupport = new PropertyChangeSupport(_proxy);
|
203 |
| } |
204 |
| |
205 |
3
| _pcSupport.addPropertyChangeListener(property, listener);
|
206 |
| } |
207 |
| |
208 |
5
| protected synchronized void removePropertyChangeListener(String property, PropertyChangeListener listener)
|
209 |
| { |
210 |
5
| if ( _pcSupport != null )
|
211 |
| { |
212 |
4
| _pcSupport.removePropertyChangeListener(property, listener);
|
213 |
| } |
214 |
| } |
215 |
| |
216 |
3
| protected synchronized void addVetoableChangeListener(String property, VetoableChangeListener listener)
|
217 |
| { |
218 |
3
| if ( _vcSupport == null )
|
219 |
| { |
220 |
1
| _vcSupport = new VetoableChangeSupport(_proxy);
|
221 |
| } |
222 |
3
| _vcSupport.addVetoableChangeListener(property, listener);
|
223 |
| } |
224 |
| |
225 |
5
| protected synchronized void removeVetoableChangeListener(String property, VetoableChangeListener listener)
|
226 |
| { |
227 |
5
| if ( _vcSupport != null )
|
228 |
| { |
229 |
4
| _vcSupport.removeVetoableChangeListener(property, listener);
|
230 |
| } |
231 |
| } |
232 |
| |
233 |
3
| protected synchronized void firePropertyChange(String property, Object oldValue, Object newValue)
|
234 |
| { |
235 |
3
| if ( _pcSupport != null )
|
236 |
| { |
237 |
2
| _pcSupport.firePropertyChange(property, oldValue, newValue);
|
238 |
| } |
239 |
| } |
240 |
| |
241 |
3
| protected synchronized void fireVetoableChange(String property, Object oldValue, Object newValue) throws PropertyVetoException
|
242 |
| { |
243 |
3
| if ( _vcSupport != null )
|
244 |
| { |
245 |
2
| _vcSupport.fireVetoableChange(property, oldValue, newValue);
|
246 |
| } |
247 |
| } |
248 |
| |
249 |
2
| protected synchronized Object getProxy()
|
250 |
| { |
251 |
2
| return _proxy;
|
252 |
| } |
253 |
| |
254 |
14
| protected static Object zero(Class clazz)
|
255 |
| { |
256 |
14
| Object o = null;
|
257 |
| |
258 |
14
| if ( clazz.isPrimitive() )
|
259 |
| { |
260 |
10
| if (clazz == Boolean.TYPE)
|
261 |
| { |
262 |
2
| o = Boolean.FALSE;
|
263 |
| } |
264 |
8
| else if (clazz == Byte.TYPE)
|
265 |
| { |
266 |
2
| o = new Byte((byte)0);
|
267 |
| } |
268 |
6
| else if (clazz == Character.TYPE)
|
269 |
| { |
270 |
1
| o = new Character('\0');
|
271 |
| } |
272 |
5
| else if (clazz == Double.TYPE)
|
273 |
| { |
274 |
1
| o = new Double(0.0);
|
275 |
| } |
276 |
4
| else if (clazz == Float.TYPE)
|
277 |
| { |
278 |
1
| o = new Float(0.0f);
|
279 |
| } |
280 |
3
| else if (clazz == Integer.TYPE)
|
281 |
| { |
282 |
1
| o = new Integer(0);
|
283 |
| } |
284 |
2
| else if (clazz == Long.TYPE)
|
285 |
| { |
286 |
1
| o = new Long(0L);
|
287 |
| } |
288 |
1
| else if (clazz == Short.TYPE)
|
289 |
| { |
290 |
1
| o = new Short((short)0);
|
291 |
| } |
292 |
| } |
293 |
14
| return o;
|
294 |
| } |
295 |
| |
296 |
474
| protected static Object parseValue(String value, Class clazz) throws IllegalArgumentException
|
297 |
| { |
298 |
474
| if (clazz == null)
|
299 |
| { |
300 |
1
| throw new IllegalArgumentException("null argument");
|
301 |
| } |
302 |
| |
303 |
473
| Object o = null;
|
304 |
| |
305 |
473
| if ( value == null )
|
306 |
| { |
307 |
1
| o = zero(clazz);
|
308 |
| } |
309 |
472
| else if (clazz.isPrimitive())
|
310 |
| { |
311 |
351
| try
|
312 |
| { |
313 |
351
| if (clazz == Boolean.TYPE)
|
314 |
| { |
315 |
2
| o = Boolean.valueOf(value);
|
316 |
| } |
317 |
349
| else if (clazz == Byte.TYPE)
|
318 |
| { |
319 |
1
| o = Byte.valueOf(value);
|
320 |
| } |
321 |
348
| else if (clazz == Character.TYPE)
|
322 |
| { |
323 |
1
| o = new Character(value.charAt(0));
|
324 |
| } |
325 |
347
| else if (clazz == Double.TYPE)
|
326 |
| { |
327 |
245
| o = Double.valueOf(value);
|
328 |
| } |
329 |
102
| else if (clazz == Float.TYPE)
|
330 |
| { |
331 |
1
| o = Float.valueOf(value);
|
332 |
| } |
333 |
101
| else if (clazz == Integer.TYPE)
|
334 |
| { |
335 |
99
| o = Integer.valueOf(value);
|
336 |
| } |
337 |
2
| else if (clazz == Long.TYPE)
|
338 |
| { |
339 |
1
| o = Long.valueOf(value);
|
340 |
| } |
341 |
1
| else if (clazz == Short.TYPE)
|
342 |
| { |
343 |
1
| o = Short.valueOf(value);
|
344 |
| } |
345 |
| } |
346 |
| catch (Exception x) |
347 |
| { |
348 |
1
| throw (IllegalArgumentException) new IllegalArgumentException().initCause(x);
|
349 |
| } |
350 |
| } |
351 |
| else |
352 |
| { |
353 |
121
| if (clazz == String.class)
|
354 |
| { |
355 |
1
| o = value;
|
356 |
| } |
357 |
120
| else if (clazz == Character.class)
|
358 |
| { |
359 |
1
| o = new Character(value.charAt(0));
|
360 |
| } |
361 |
| else |
362 |
| { |
363 |
119
| o = parseSpecialValue(value, clazz);
|
364 |
| } |
365 |
| } |
366 |
| |
367 |
470
| return o;
|
368 |
| } |
369 |
| |
370 |
119
| protected static Object parseSpecialValue(String value, Class clazz) throws IllegalArgumentException
|
371 |
| { |
372 |
119
| Object o;
|
373 |
| |
374 |
119
| try
|
375 |
| { |
376 |
119
| if (clazz == File.class)
|
377 |
| { |
378 |
1
| o = new File(value);
|
379 |
| } |
380 |
118
| else if (clazz == URL.class)
|
381 |
| { |
382 |
2
| o = new URL(value);
|
383 |
| } |
384 |
116
| else if (clazz == URI.class)
|
385 |
| { |
386 |
111
| o = new URI(value);
|
387 |
| } |
388 |
5
| else if (clazz == Class.class)
|
389 |
| { |
390 |
1
| o = Class.forName(value);
|
391 |
| } |
392 |
4
| else if (clazz == TimeZone.class)
|
393 |
| { |
394 |
1
| o = TimeZone.getTimeZone(value);
|
395 |
| } |
396 |
| else |
397 |
| { |
398 |
| |
399 |
3
| Method parser = clazz.getMethod(PARSE_METHOD, new Class[] {String.class});
|
400 |
3
| o = parser.invoke(null, new Object[] {value});
|
401 |
| } |
402 |
| } |
403 |
| catch (Exception x) |
404 |
| { |
405 |
2
| throw (IllegalArgumentException) new IllegalArgumentException().initCause(x);
|
406 |
| } |
407 |
117
| return o;
|
408 |
| } |
409 |
| } |