1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package net.ep.db4o.factories;
18
19 import java.lang.reflect.Constructor;
20 import java.lang.reflect.InvocationHandler;
21 import java.lang.reflect.Method;
22 import java.util.HashMap;
23 import java.util.Map;
24
25 public class FactoryInvocationHandler implements InvocationHandler {
26
27 private Map<Method, Constructor<?>> _constructors = new HashMap<Method, Constructor<?>>();
28 private Factories _factories;
29
30 public FactoryInvocationHandler(Class<?> factory, Class<?> targetType, Class<?> realType, Factories basicFactories) {
31 for (Method method:factory.getDeclaredMethods()) {
32 Constructor<?> cons = findConstructor(method, realType);
33 if (cons == null)
34 throw new InvalidFactoryException("No matching constructor found in " + targetType.getName() + " for method " + method.getName());
35 _constructors.put(method, cons);
36 }
37 _factories = basicFactories;
38 }
39
40 private Constructor<?> findConstructor(Method main, Class<?> targetType) {
41 for (Constructor<?> cons:targetType.getDeclaredConstructors()) {
42 cons.setAccessible(true);
43 if (cons.getParameterTypes() != null && main.getParameterTypes() != null) {
44 if (cons.getParameterTypes().length == main.getParameterTypes().length) {
45 boolean found = true;
46 for (int il = 0;il < cons.getParameterTypes().length;il++) {
47 found = found && cons.getParameterTypes()[il] == main.getParameterTypes()[il];
48 }
49 if (found)
50 return cons;
51 }
52 } else {
53 if (main.getParameterTypes() == null)
54 return cons;
55 }
56 }
57 return null;
58 }
59
60 public Object invoke(Object proxy, Method method, Object[] args)
61 throws Throwable {
62 Object inst = _constructors.get(method).newInstance(args);
63 _factories.onNewInstance(inst);
64 return inst;
65 }
66
67 }