1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.seasar.uruma.binding.method;
17
18 import java.lang.reflect.Method;
19
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.core.runtime.IStatus;
22 import org.eclipse.core.runtime.Status;
23 import org.eclipse.core.runtime.jobs.Job;
24 import org.eclipse.swt.widgets.Display;
25 import org.seasar.framework.beans.BeanDesc;
26 import org.seasar.framework.beans.PropertyDesc;
27 import org.seasar.framework.beans.factory.BeanDescFactory;
28 import org.seasar.framework.util.MethodUtil;
29 import org.seasar.uruma.core.UrumaConstants;
30 import org.seasar.uruma.core.UrumaMessageCodes;
31 import org.seasar.uruma.desc.PartActionDesc;
32 import org.seasar.uruma.desc.PartActionDescFactory;
33 import org.seasar.uruma.jobs.ProgressMonitor;
34 import org.seasar.uruma.jobs.impl.RcpProgressMonitor;
35 import org.seasar.uruma.log.UrumaLogger;
36
37
38
39
40
41
42
43
44
45
46
47 public class AsyncMethodBinding extends MethodBinding implements
48 UrumaMessageCodes {
49 private static final UrumaLogger logger = UrumaLogger
50 .getLogger(AsyncMethodBinding.class);
51
52 private String taskNameProperty;
53
54 private boolean cancelable;
55
56
57
58
59
60
61
62
63
64
65
66 AsyncMethodBinding(final Object target, final Method method,
67 final MethodCallback callback) {
68 super(target, method, callback);
69 }
70
71
72
73
74 @Override
75 public Object invoke(final Object[] args) {
76 Object[] filteredArgs = args;
77 for (ArgumentsFilter filter : argumentsFilterList) {
78 filteredArgs = filter.filter(filteredArgs);
79 }
80
81 String taskName = getTaskName(taskNameProperty, target);
82 AsyncJob job = new AsyncJob(taskName, this, filteredArgs, Display
83 .getCurrent());
84 if (cancelable) {
85 job.setUser(true);
86 }
87 job.schedule();
88
89 if (logger.isInfoEnabled()) {
90 logger.log(ASYNC_METHOD_SCHEDULED, UrumaLogger
91 .getObjectDescription(target), method.getName(), args);
92 }
93
94 return null;
95 }
96
97
98
99
100
101
102
103 public void setTaskNameProperty(final String taskNameProperty) {
104 this.taskNameProperty = taskNameProperty;
105 }
106
107
108
109
110
111
112
113 public void setCancelable(final boolean cancelable) {
114 this.cancelable = cancelable;
115 }
116
117 protected String getTaskName(final String propName, final Object target) {
118 if (propName == null) {
119 return UrumaConstants.NULL_STRING;
120 }
121
122 BeanDesc desc = BeanDescFactory.getBeanDesc(target.getClass());
123 if (desc.hasPropertyDesc(propName)) {
124 PropertyDesc pd = desc.getPropertyDesc(propName);
125 if (pd.isReadable()
126 && String.class.isAssignableFrom(pd.getPropertyType())) {
127 return (String) pd.getValue(target);
128 }
129 }
130 return UrumaConstants.NULL_STRING;
131 }
132
133 protected void injectProgressMonitor(final Object target,
134 final IProgressMonitor monitor) {
135 PartActionDesc desc = PartActionDescFactory.getPartActionDesc(target
136 .getClass());
137
138 ProgressMonitor uMonitor = new RcpProgressMonitor(monitor);
139 desc.injectProgressMonitor(target, uMonitor);
140 }
141
142
143
144
145
146
147 class AsyncJob extends Job {
148 private MethodBinding binding;
149
150 private Object[] args;
151
152 private Object returnValue;
153
154 private Display display;
155
156
157
158
159 AsyncJob(final String name, final MethodBinding binding,
160 final Object[] args, final Display display) {
161 super(name);
162 this.binding = binding;
163 this.args = args;
164 this.display = display;
165 }
166
167
168
169
170 @Override
171 protected IStatus run(final IProgressMonitor monitor) {
172 if (logger.isInfoEnabled()) {
173 logger.log(ASYNC_METHOD_START, UrumaLogger
174 .getObjectDescription(target), method.getName(), args);
175 }
176
177 try {
178 injectProgressMonitor(target, monitor);
179 returnValue = MethodUtil.invoke(binding.getMethod(), binding
180 .getTarget(), args);
181
182 if (callback != null) {
183 if (display != null) {
184 display.asyncExec(new Runnable() {
185 public void run() {
186 returnValue = callback.callback(binding, args,
187 returnValue);
188 }
189 });
190 } else {
191 returnValue = callback.callback(binding, args,
192 returnValue);
193 }
194 }
195 } catch (Throwable ex) {
196 logger.log(EXCEPTION_OCCURED_INVOKING_METHOD, ex, binding
197 .toString());
198 } finally {
199 if (logger.isInfoEnabled()) {
200 String desc = UrumaLogger.getObjectDescription(target);
201 if (!monitor.isCanceled()) {
202 logger.log(ASYNC_METHOD_END, desc, method.getName(),
203 returnValue);
204 } else {
205 logger.log(ASYNC_METHOD_CANCELED, desc, method
206 .getName(), returnValue);
207 }
208 }
209 }
210
211 if (!monitor.isCanceled()) {
212 return Status.OK_STATUS;
213 } else {
214 return Status.CANCEL_STATUS;
215 }
216 }
217 }
218 }