1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.ibatis.sqlmap.engine.mapping.result.loader;
17
18 import com.ibatis.common.beans.ClassInfo;
19 import com.ibatis.sqlmap.engine.impl.SqlMapClientImpl;
20
21 import java.lang.reflect.InvocationHandler;
22 import java.lang.reflect.InvocationTargetException;
23 import java.lang.reflect.Method;
24 import java.lang.reflect.Proxy;
25 import java.sql.SQLException;
26 import java.util.Collection;
27 import java.util.List;
28 import java.util.Set;
29
30
31
32
33 public class LazyResultLoader implements InvocationHandler {
34
35
36 private static final Class[] SET_INTERFACES = { Set.class };
37
38
39 private static final Class[] LIST_INTERFACES = { List.class };
40
41
42 protected SqlMapClientImpl client;
43
44
45 protected String statementName;
46
47
48 protected Object parameterObject;
49
50
51 protected Class targetType;
52
53
54 protected boolean loaded;
55
56
57 protected Object resultObject;
58
59
60
61
62
63
64
65
66
67
68
69
70
71 public LazyResultLoader(SqlMapClientImpl client, String statementName, Object parameterObject, Class targetType) {
72 this.client = client;
73 this.statementName = statementName;
74 this.parameterObject = parameterObject;
75 this.targetType = targetType;
76 }
77
78
79
80
81
82
83
84
85
86 public Object loadResult() throws SQLException {
87 if (!Collection.class.isAssignableFrom(targetType)) {
88 return ResultLoader.getResult(client, statementName, parameterObject, targetType);
89 }
90 InvocationHandler handler = new LazyResultLoader(client, statementName, parameterObject, targetType);
91 ClassLoader cl = targetType.getClassLoader();
92 if (Set.class.isAssignableFrom(targetType)) {
93 return Proxy.newProxyInstance(cl, SET_INTERFACES, handler);
94 }
95 return Proxy.newProxyInstance(cl, LIST_INTERFACES, handler);
96 }
97
98 @Override
99 public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
100 if ("finalize".hashCode() == method.getName().hashCode() && "finalize".equals(method.getName())) {
101 return null;
102 }
103 loadObject();
104 if (resultObject == null) {
105 return null;
106 }
107 try {
108 return method.invoke(resultObject, objects);
109 } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
110 throw ClassInfo.unwrapThrowable(e);
111 }
112 }
113
114
115
116
117 private synchronized void loadObject() {
118 if (!loaded) {
119 try {
120 loaded = true;
121 resultObject = ResultLoader.getResult(client, statementName, parameterObject, targetType);
122 } catch (SQLException e) {
123 throw new RuntimeException("Error lazy loading result. Cause: " + e, e);
124 }
125 }
126 }
127
128 }