1
24 package net.sf.jasperreports.engine.fill;
25
26 import net.sf.jasperreports.engine.JRException;
27 import net.sf.jasperreports.engine.JRRuntimeException;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31
32
33
36 public abstract class AbstractThreadSubreportRunner extends JRSubreportRunnable implements JRSubreportRunner
37 {
38
39 private static final Log log = LogFactory.getLog(AbstractThreadSubreportRunner.class);
40 public static final String EXCEPTION_MESSAGE_KEY_THREAD_REPORT_RUNNER_WAIT_ERROR = "fill.thread.report.runner.wait.error";
41 public static final String EXCEPTION_MESSAGE_KEY_THREAD_SUBREPORT_RUNNER_WAIT_ERROR = "fill.thread.subreport.runner.wait.error";
42
43 protected final JRBaseFiller subreportFiller;
44
45 public AbstractThreadSubreportRunner(JRFillSubreport fillSubreport, JRBaseFiller subreportFiller)
46 {
47 super(fillSubreport);
48 this.subreportFiller = subreportFiller;
49 }
50
51 @Override
52 public JRSubreportRunResult start()
53 {
54 doStart();
55 return waitResult();
56 }
57
58 protected abstract void doStart();
59
60 @Override
61 public JRSubreportRunResult resume()
62 {
63 if (log.isDebugEnabled())
64 {
65 log.debug("Fill " + subreportFiller.fillerId + ": notifying to continue");
66 }
67
68
69 subreportFiller.notifyAll();
70
71 return waitResult();
72 }
73
74 protected JRSubreportRunResult waitResult()
75 {
76 if (log.isDebugEnabled())
77 {
78 log.debug("Fill " + subreportFiller.fillerId + ": waiting for fill result");
79 }
80
81 try
82 {
83
84 subreportFiller.wait();
85
86
87 }
88 catch (InterruptedException e)
89 {
90 if (subreportFiller.fillContext.isCanceled())
91 {
92
93 if (log.isDebugEnabled())
94 {
95 log.debug("Fill " + subreportFiller.fillerId + ": exception", e);
96 }
97 }
98 else
99 {
100 if (log.isErrorEnabled())
101 {
102 log.error("Fill " + subreportFiller.fillerId + ": exception", e);
103 }
104 }
105
106 throw
107 new JRRuntimeException(
108 EXCEPTION_MESSAGE_KEY_THREAD_REPORT_RUNNER_WAIT_ERROR,
109 (Object[])null,
110 e);
111 }
112
113 if (log.isDebugEnabled())
114 {
115 log.debug("Fill " + subreportFiller.fillerId + ": notified of fill result");
116 }
117
118 return runResult();
119 }
120
121 @Override
122 public void cancel() throws JRException
123 {
124 if (log.isDebugEnabled())
125 {
126 log.debug("Fill " + subreportFiller.fillerId + ": notifying to continue on cancel");
127 }
128
129
130
131 subreportFiller.notifyAll();
132
133 if (isRunning())
134 {
135 if (log.isDebugEnabled())
136 {
137 log.debug("Fill " + subreportFiller.fillerId + ": still running, waiting");
138 }
139
140 try
141 {
142
143 subreportFiller.wait();
144 }
145 catch(InterruptedException e)
146 {
147 if (log.isErrorEnabled())
148 {
149 log.error("Fill " + subreportFiller.fillerId + ": exception", e);
150 }
151
152 throw
153 new JRException(
154 EXCEPTION_MESSAGE_KEY_THREAD_SUBREPORT_RUNNER_WAIT_ERROR,
155 null,
156 e);
157 }
158
159 if (log.isDebugEnabled())
160 {
161 log.debug("Fill " + subreportFiller.fillerId + ": wait ended");
162 }
163 }
164 }
165
166 @Override
167 public void suspend() throws JRException
168 {
169 if (log.isDebugEnabled())
170 {
171 log.debug("Fill " + subreportFiller.fillerId + ": notifying on suspend");
172 }
173
174
175 subreportFiller.notifyAll();
176
177 if (log.isDebugEnabled())
178 {
179 log.debug("Fill " + subreportFiller.fillerId + ": waiting to continue");
180 }
181
182 try
183 {
184
185 subreportFiller.wait();
186 }
187 catch(InterruptedException e)
188 {
189 if (subreportFiller.fillContext.isCanceled() || subreportFiller.isDeliberatelyInterrupted())
190 {
191
192 if (log.isDebugEnabled())
193 {
194 log.debug("Fill " + subreportFiller.fillerId + ": exception", e);
195 }
196 }
197 else
198 {
199 if (log.isErrorEnabled())
200 {
201 log.error("Fill " + subreportFiller.fillerId + ": exception", e);
202 }
203 }
204
205 throw
206 new JRException(
207 EXCEPTION_MESSAGE_KEY_THREAD_SUBREPORT_RUNNER_WAIT_ERROR,
208 null,
209 e);
210 }
211
212 if (log.isDebugEnabled())
213 {
214 log.debug("Fill " + subreportFiller.fillerId + ": notified to continue");
215 }
216 }
217
218 @Override
219 public void run()
220 {
221 super.run();
222
223 if (log.isDebugEnabled())
224 {
225 log.debug("Fill " + subreportFiller.fillerId + ": notifying of completion");
226 }
227
228 synchronized (subreportFiller)
229 {
230
231 subreportFiller.notifyAll();
232 }
233
234
244 }
245
246 @Override
247 public void abort()
248 {
249 if (subreportFiller.fillingThread != null)
250 {
251 if (log.isDebugEnabled())
252 {
253 log.debug("Interrupting subfiller thread " + subreportFiller.fillingThread);
254 }
255
256 subreportFiller.fillingThread.interrupt();
257 }
258 }
259 }
260