/** * Copyright (c) 2002-2005, Simone Bordet * All rights reserved. * * This software is distributable under the BSD license. * See the terms of the BSD license in the documentation provided with this software. */ package foxtrot; import javax.swing.SwingUtilities; import foxtrot.pumps.ConditionalEventPump; import foxtrot.pumps.QueueEventPump; import foxtrot.pumps.SunJDK14ConditionalEventPump; /** * Base class for Foxtrot workers that have synchronous behavior. * @version $Revision: 1.3 $ */ abstract class AbstractSyncWorker extends AbstractWorker { private EventPump eventPump; AbstractSyncWorker() { } /** * Returns the EventPump for this worker, creating it if not already set. <br /> * Uses a C-style getter method to avoid clash with the static getter method * present in subclasses for API compatibility. * @see #createDefaultEventPump * @see #eventPump(EventPump) */ EventPump eventPump() { if (eventPump == null) eventPump(createDefaultEventPump()); return eventPump; } /** * Sets the EventPump for this worker. <br /> * Uses a C-style setter method to avoid clash with the static setter method * present in subclasses for API compatibility. * @throws IllegalArgumentException if eventPump is null * @see #eventPump() */ void eventPump(EventPump eventPump) { if (eventPump == null) throw new IllegalArgumentException("EventPump cannot be null"); this.eventPump = eventPump; if (debug) System.out.println("[AbstractSyncWorker] Initialized EventPump: " + eventPump); } /** * Creates and returns the default EventPump for this worker */ EventPump createDefaultEventPump() { if (JREVersion.isJRE14()) { // Handles also JDK 5.0 return new SunJDK14ConditionalEventPump(); } else if (JREVersion.isJRE13()) { return new ConditionalEventPump(); } else if (JREVersion.isJRE12()) { return new QueueEventPump(); } else { throw new Error("The current JRE is not supported"); } } /** * Executes the given Task using the given workerThread and eventPump. * This method blocks (while dequeuing AWT events) until the Task is finished, * either by returning a result or by throwing. */ Object post(Task task, WorkerThread workerThread, EventPump eventPump) throws Exception { boolean isEventThread = SwingUtilities.isEventDispatchThread(); if (!isEventThread && !workerThread.isWorkerThread()) { throw new IllegalStateException("Method post() can be called only from the AWT Event Dispatch Thread or from a worker thread"); } if (isEventThread) { workerThread.postTask(task); // The following line blocks until the task has been executed eventPump.pumpEvents(task); } else { // Executes the Task in this thread workerThread.runTask(task); } try { return task.getResultOrThrow(); } finally { task.reset(); } } /** * Executes the given Job using the given workerThread and eventPump. * This method has the same behavior of {@link #post(Task, WorkerThread, EventPump)} */ Object post(Job job, WorkerThread workerThread, EventPump eventPump) { try { return post((Task)job, workerThread, eventPump); } catch (RuntimeException x) { throw x; } catch (Exception x) { // If it happens, it's a bug in the compiler if (debug) { System.err.println("[Worker] PANIC: checked exception thrown by a Job !"); x.printStackTrace(); } // I should throw an UndeclaredThrowableException, but that is // available only in JDK 1.3+, so here I use RuntimeException throw new RuntimeException(x.toString()); } catch (Error x) { throw x; } } }