savant.sql.SQLWorker.java Source code

Java tutorial

Introduction

Here is the source code for savant.sql.SQLWorker.java

Source

/**
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package savant.sql;

import javax.swing.SwingWorker;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import savant.api.util.DialogUtils;
import savant.util.MiscUtils;

/**
 * Like a SwingWorker, but with built-in error handling and progress dialog.
 *
 * @author tarkvara
 */
public abstract class SQLWorker<T> {
    private static final Log LOG = LogFactory.getLog(SQLWorker.class);

    /**
     * Delay in milliseconds before we put up a progress dialog.
     */
    private static final int PROGRESS_DELAY = 1000;

    private SwingWorker innerWorker;
    protected String progressMessage;
    protected String failureMessage;
    private boolean workerDone = false;
    private final Object waiter = new Object();

    public SQLWorker(String prog, String fail) {
        this.progressMessage = prog;
        this.failureMessage = fail;
        innerWorker = new SwingWorker() {
            private T result;

            @Override
            public Object doInBackground() {
                try {
                    result = SQLWorker.this.doInBackground();
                } catch (final Exception x) {
                    MiscUtils.invokeLaterIfNecessary(new Runnable() {
                        @Override
                        public void run() {
                            showProgress(1.0);
                            DialogUtils.displayException("SQL Error", failureMessage, x);
                        }
                    });
                }
                return null;
            }

            @Override
            public void done() {
                try {
                    synchronized (waiter) {
                        workerDone = true;
                        waiter.notifyAll();
                    }
                    showProgress(1.0);
                    SQLWorker.this.done(result);
                } catch (Exception x) {
                    DialogUtils.displayException("SQL Error", failureMessage, x);
                }
            }
        };
    }

    public void execute() {
        innerWorker.execute();
        synchronized (waiter) {
            try {
                waiter.wait(PROGRESS_DELAY);
            } catch (InterruptedException ignored) {
            }
        }
        if (!workerDone) {
            showProgress(-1.0);
        }
    }

    public abstract T doInBackground() throws Exception;

    /**
     * Perform whatever processing is appropriate upon successful completion.
     * Will be invoked on the AWT thread.
     *
     * @param value the progress value between 0.0 and 1.0 (-1.0 to indicate indefinite progress)
     */
    public abstract void done(T value) throws Exception;

    /**
     * Default behaviour is to use DialogUtils to indicate progress.  Other classes
     * can override this to show progress in a less obtrusive manner.  Will be invoked
     * on the AWT thread.
     *
     * @param value the progress value between 0.0 and 1.0 (-1.0 to indicate indefinite progress)
     */
    public void showProgress(double value) {
        DialogUtils.showProgress(progressMessage, value);
    }
}