001: /*
002: * ============================================================================
003: * GNU Lesser General Public License
004: * ============================================================================
005: *
006: * JasperReports - Free Java report-generating library.
007: * Copyright (C) 2001-2006 JasperSoft Corporation http://www.jaspersoft.com
008: *
009: * This library is free software; you can redistribute it and/or
010: * modify it under the terms of the GNU Lesser General Public
011: * License as published by the Free Software Foundation; either
012: * version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017: * Lesser General Public License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
022: *
023: * JasperSoft Corporation
024: * 303 Second Street, Suite 450 North
025: * San Francisco, CA 94107
026: * http://www.jaspersoft.com
027: */
028: package net.sf.jasperreports.engine.fill;
029:
030: import org.apache.commons.logging.Log;
031: import org.apache.commons.logging.LogFactory;
032:
033: import net.sf.jasperreports.engine.JRException;
034: import net.sf.jasperreports.engine.JRRuntimeException;
035:
036: /**
037: * Thread-based {@link net.sf.jasperreports.engine.fill.JRSubreportRunner JRSubreportRunner}
038: * implementation.
039: * <p>
040: * The subreport fill is launched in a new thread which coordinates suspend/resume actions with
041: * the master thread.
042: *
043: * @author Lucian Chirita (lucianc@users.sourceforge.net)
044: * @version $Id: JRThreadSubreportRunner.java 1621 2007-03-06 13:55:00Z lucianc $
045: */
046: public class JRThreadSubreportRunner extends JRSubreportRunnable
047: implements JRSubreportRunner {
048:
049: private static final Log log = LogFactory
050: .getLog(JRThreadSubreportRunner.class);
051:
052: private final JRBaseFiller subreportFiller;
053:
054: private Thread fillThread;
055:
056: public JRThreadSubreportRunner(JRFillSubreport fillSubreport,
057: JRBaseFiller subreportFiller) {
058: super (fillSubreport);
059: this .subreportFiller = subreportFiller;
060: }
061:
062: public boolean isFilling() {
063: return fillThread != null;
064: }
065:
066: public JRSubreportRunResult start() {
067: fillThread = new Thread(this , subreportFiller.getJasperReport()
068: .getName()
069: + " subreport filler");
070:
071: if (log.isDebugEnabled()) {
072: log.debug("Fill " + subreportFiller.fillerId
073: + ": starting thread " + fillThread);
074: }
075:
076: fillThread.start();
077:
078: return waitResult();
079: }
080:
081: public JRSubreportRunResult resume() {
082: if (log.isDebugEnabled()) {
083: log.debug("Fill " + subreportFiller.fillerId
084: + ": notifying to continue");
085: }
086:
087: //notifing the subreport fill thread that it can continue on the next page
088: subreportFiller.notifyAll();
089:
090: return waitResult();
091: }
092:
093: protected JRSubreportRunResult waitResult() {
094: if (log.isDebugEnabled()) {
095: log.debug("Fill " + subreportFiller.fillerId
096: + ": waiting for fill result");
097: }
098:
099: try {
100: // waiting for the subreport fill thread to fill the current page
101: subreportFiller.wait(); // FIXME maybe this is useless since you cannot enter
102: // the synchornized bloc if the subreport filler hasn't
103: // finished the page and passed to the wait state.
104: } catch (InterruptedException e) {
105: if (log.isErrorEnabled()) {
106: log.error("Fill " + subreportFiller.fillerId
107: + ": exception", e);
108: }
109:
110: throw new JRRuntimeException(
111: "Error encountered while waiting on the report filling thread.",
112: e);
113: }
114:
115: if (log.isDebugEnabled()) {
116: log.debug("Fill " + subreportFiller.fillerId
117: + ": notified of fill result");
118: }
119:
120: return runResult();
121: }
122:
123: public void reset() {
124: fillThread = null;
125: }
126:
127: public void cancel() throws JRException {
128: if (log.isDebugEnabled()) {
129: log.debug("Fill " + subreportFiller.fillerId
130: + ": notifying to continue on cancel");
131: }
132:
133: // notifying the subreport filling thread that it can continue.
134: // it will stop anyway when trying to fill the current band
135: subreportFiller.notifyAll();
136:
137: if (isRunning()) {
138: if (log.isDebugEnabled()) {
139: log.debug("Fill " + subreportFiller.fillerId
140: + ": still running, waiting");
141: }
142:
143: try {
144: //waits until the master filler notifies it that can continue with the next page
145: subreportFiller.wait();
146: } catch (InterruptedException e) {
147: if (log.isErrorEnabled()) {
148: log.error("Fill " + subreportFiller.fillerId
149: + ": exception", e);
150: }
151:
152: throw new JRException(
153: "Error encountered while waiting on the subreport filling thread.",
154: e);
155: }
156:
157: if (log.isDebugEnabled()) {
158: log.debug("Fill " + subreportFiller.fillerId
159: + ": wait ended");
160: }
161: }
162: }
163:
164: public void suspend() throws JRException {
165: if (log.isDebugEnabled()) {
166: log.debug("Fill " + subreportFiller.fillerId
167: + ": notifying on suspend");
168: }
169:
170: //signals to the master filler that is has finished the page
171: subreportFiller.notifyAll();
172:
173: if (log.isDebugEnabled()) {
174: log.debug("Fill " + subreportFiller.fillerId
175: + ": waiting to continue");
176: }
177:
178: try {
179: //waits until the master filler notifies it that can continue with the next page
180: subreportFiller.wait();
181: } catch (InterruptedException e) {
182: if (log.isErrorEnabled()) {
183: log.error("Fill " + subreportFiller.fillerId
184: + ": exception", e);
185: }
186:
187: throw new JRException(
188: "Error encountered while waiting on the subreport filling thread.",
189: e);
190: }
191:
192: if (log.isDebugEnabled()) {
193: log.debug("Fill " + subreportFiller.fillerId
194: + ": notified to continue");
195: }
196: }
197:
198: public void run() {
199: super .run();
200:
201: if (log.isDebugEnabled()) {
202: log.debug("Fill " + subreportFiller.fillerId
203: + ": notifying of completion");
204: }
205:
206: synchronized (subreportFiller) {
207: //main filler notified that the subreport has finished
208: subreportFiller.notifyAll();
209: }
210:
211: /*
212: if (error != null)
213: {
214: synchronized (subreportFiller)
215: {
216: //if an exception occured then we should notify the main filler that we have finished the subreport
217: subreportFiller.notifyAll();
218: }
219: }
220: */
221: }
222: }
|