edu.ku.brc.specify.tasks.subpane.LabelsPane.java Source code

Java tutorial

Introduction

Here is the source code for edu.ku.brc.specify.tasks.subpane.LabelsPane.java

Source

/* Copyright (C) 2015, University of Kansas Center for Research
 * 
 * Specify Software Project, specify@ku.edu, Biodiversity Institute,
 * 1345 Jayhawk Boulevard, Lawrence, Kansas, 66045, USA
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
package edu.ku.brc.specify.tasks.subpane;

import static edu.ku.brc.ui.UIHelper.centerAndShow;
import static edu.ku.brc.ui.UIHelper.createIconBtn;
import static edu.ku.brc.ui.UIHelper.createLabel;
import static edu.ku.brc.ui.UIHelper.createScrollPane;
import static edu.ku.brc.ui.UIHelper.createTextArea;
import static edu.ku.brc.ui.UIRegistry.forceTopFrameRepaint;
import static edu.ku.brc.ui.UIRegistry.getMostRecentWindow;
import static edu.ku.brc.ui.UIRegistry.getResourceString;
import static edu.ku.brc.ui.UIRegistry.getTopWindow;

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.fill.AsynchronousFillHandle;
import net.sf.jasperreports.engine.fill.AsynchronousFilllListener;
import net.sf.jasperreports.engine.fill.JRFileVirtualizer;
import net.sf.jasperreports.engine.query.JRHibernateQueryExecuterFactory;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.view.JRViewer;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.hibernate.Session;

import com.jgoodies.forms.builder.PanelBuilder;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

import edu.ku.brc.af.core.AppContextMgr;
import edu.ku.brc.af.core.AppResourceIFace;
import edu.ku.brc.af.core.Taskable;
import edu.ku.brc.af.core.db.DBTableIdMgr;
import edu.ku.brc.af.tasks.subpane.BaseSubPane;
import edu.ku.brc.dbsupport.DBConnection;
import edu.ku.brc.dbsupport.HibernateUtil;
import edu.ku.brc.dbsupport.RecordSetIFace;
import edu.ku.brc.specify.tasks.subpane.qb.QBDataSource;
import edu.ku.brc.specify.tasks.subpane.qb.QBDataSourceBase;
import edu.ku.brc.specify.tasks.subpane.qb.QBDataSourceListenerIFace;
import edu.ku.brc.specify.tasks.subpane.qb.ReportParametersPanel;
import edu.ku.brc.ui.CustomDialog;
import edu.ku.brc.ui.IconManager;
import edu.ku.brc.util.Pair;

/**
 * This class will display Label previews and may eventually hold a labels editor
 *
 * @code_status Complete
 *
 * @author rods
 *
 *
 */
@SuppressWarnings("serial")
public class LabelsPane extends BaseSubPane
        implements AsynchronousFilllListener, JasperCompileListener, QBDataSourceListenerIFace {
    // Static Data Members
    protected static final Logger log = Logger.getLogger(LabelsPane.class);

    protected static int virtualizerThresholdSize = 666;

    // Data Members
    protected AsynchronousFillHandle asyncFillHandler = null;
    protected JLabel label = null;
    protected JasperCompilerRunnable compiler = null;
    protected AtomicBoolean compiling = new AtomicBoolean(false);
    protected AtomicBoolean filling = new AtomicBoolean(false);
    protected AtomicBoolean loading = new AtomicBoolean(false);
    protected RecordSetIFace recordSet = null;
    protected JRDataSource dataSource = null;
    protected File cachePath = null;

    protected Properties params = null;
    protected boolean requiresHibernate = false;
    protected Session session = null;
    protected ImageIcon icon = null;

    protected java.lang.Throwable errThrowable = null;

    /**
     * Constructor.
     * @param name name of subpanel
     * @param task the owning task
     * @param params parameters for the report
     */
    public LabelsPane(final String name, final Taskable task, final Properties params) {
        super(name, task, true, true);

        this.params = params;

        cachePath = JasperReportsCache.checkAndCreateReportsCache();

        progressCancelBtn.addActionListener(new ActionListener() {

            /* (non-Javadoc)
             * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
             */
            @Override
            public void actionPerformed(ActionEvent arg0) {
                if (compiler != null && compiling.get()) {
                    compiler.stop();
                } else if (asyncFillHandler != null && filling.get()) {
                    try {
                        asyncFillHandler.cancellFill();
                        if (dataSource != null && (dataSource instanceof QBDataSource) && loading.get()) {
                            ((QBDataSource) dataSource).cancelLoad();
                        }
                    } catch (JRException ex) {
                        log.error(ex);
                    }
                }
            }

        });
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.af.tasks.subpane.BaseSubPane#getIcon()
     */
    @Override
    public Icon getIcon() {
        return icon != null ? icon : super.getIcon();
    }

    /**
     * @param icon the icon to set
     */
    public void setIcon(ImageIcon icon) {
        this.icon = icon;
    }

    /**
     * Set the text to the label (create the label if it doesn't exist)
     * @param msg the message to be displayed
     */
    public void setLabelText(final String msg) {
        if (label == null) {
            removeAll();

            CellConstraints cc = new CellConstraints();
            PanelBuilder pb = new PanelBuilder(new FormLayout("f:p:g,p,2px,p,f:p:g", "f:p:g, p, f:p:g"), this);//$NON-NLS-1$ //$NON-NLS-2$

            JButton moreBtn = createIconBtn("InfoIcon", IconManager.IconSize.Std16, null, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    showErrorMsgs();
                }
            });
            label = createLabel("", SwingConstants.CENTER);
            pb.add(label, cc.xy(2, 2));
            pb.add(moreBtn, cc.xy(4, 2));

            moreBtn.setEnabled(true);
        }

        if (progressBarPanel != null) {
            remove(progressBarPanel);
        }

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                label.setText(msg);
                invalidate();
                doLayout();
                repaint();
            }
        });
    }

    private void showErrorMsgs() {
        CellConstraints cc = new CellConstraints();
        PanelBuilder pb = new PanelBuilder(new FormLayout("f:p:g", "f:p:g"));
        JTextArea ta = createTextArea(40, 80);
        pb.add(createScrollPane(ta, true), cc.xy(1, 1));
        pb.setDefaultDialogBorder();

        ta.setText(errThrowable != null ? getStackTrace(errThrowable) : "");
        ta.setEditable(false);

        CustomDialog dlg = new CustomDialog((Frame) getMostRecentWindow(), getResourceString("Error"), true,
                CustomDialog.OK_BTN, pb.getPanel());
        dlg.setOkLabel(getResourceString("CLOSE"));
        centerAndShow(dlg);
    }

    /**
     * @param throwable
     * @return
     */
    protected String getStackTrace(Throwable throwable) {
        String sep = System.getProperty("line.separator");
        StringBuilder result = new StringBuilder();
        result.append(throwable.toString());
        result.append(sep);

        for (StackTraceElement element : throwable.getStackTrace()) {
            result.append(element);
            result.append(sep);
        }
        return result.toString();
    }

    /**
     * Returns whether the LabelsPane contains a "label".
     * @return  whether the LabelsPane contains a "label".
     */
    public boolean isEmpty() {
        return label != null;
    }

    /**
     * Starts the report creation process
     * @param fileName the XML file name of the report definition
     * @param recrdSet the recordset to use to fill the labels
     * @param paramsArg parameters for the report
    */
    public void createReport(final String mainReportName, final Object data, final Properties paramsArg) {
        if (progressBarPanel != null) {
            if (label != null) {
                remove(label);
            }
            add(progressBarPanel, BorderLayout.CENTER);
        }

        if (data instanceof RecordSetIFace) {
            this.recordSet = (RecordSetIFace) data;
            this.dataSource = null;

        } else if (data instanceof JRDataSource) {
            this.recordSet = null;
            this.dataSource = (JRDataSource) data;
        } else {
            this.recordSet = null;
            this.dataSource = null;
        }
        this.params = paramsArg;

        AppResourceIFace appRes = AppContextMgr.getInstance().getResource(mainReportName);
        String resName = params.getProperty("name");
        if (appRes == null) {
            if (resName != null) {
                appRes = AppContextMgr.getInstance().getResource(resName);
            }
        }
        if (appRes != null) {
            String hqlStr = appRes.getMetaData("hql");
            if (StringUtils.isNotEmpty(hqlStr)) {
                requiresHibernate = Boolean.parseBoolean(hqlStr.toLowerCase());
            }
        } else {
            log.error("could not find report resource for " + mainReportName);
        }

        File compiledFile = (File) params.get("compiled-file");
        if (compiledFile != null) {
            compileComplete(compiledFile, null);
        } else {
            progressLabel.setText(getResourceString("JasperReportCompiling"));
            compiler = new JasperCompilerRunnable(this, mainReportName, resName);
            compiling.set(true);
            compiler.start();
        }
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.specify.tasks.subpane.JasperCompileListener#compileComplete(java.io.File)
     */
    public void compileComplete(final File compiledFile, final Throwable throwable) {
        compiling.set(false);
        if (compiledFile != null) {
            try {
                JasperReport jasperReport = (JasperReport) JRLoader.loadObject(compiledFile.getAbsoluteFile());
                if (jasperReport != null) {
                    int size = -1;
                    if (recordSet != null) {
                        size = recordSet.getNumItems();

                    } else if (dataSource != null) {
                        if (dataSource instanceof QBDataSourceBase) {
                            //if source has not finished retrieving results, size = -1
                            size = ((QBDataSourceBase) dataSource).size();
                        }
                    }

                    boolean go = true;
                    ReportParametersPanel rpp = null;
                    String skipParams = params.getProperty("skip-parameter-prompt");
                    if (StringUtils.isBlank(skipParams) || skipParams.equalsIgnoreCase("false")) {
                        rpp = new ReportParametersPanel(jasperReport, true);
                        if (rpp.getParamCount() > 0) {
                            CustomDialog cd = new CustomDialog((Frame) getTopWindow(),
                                    getResourceString("LabelsPane.REPORT_PARAMS"), true, rpp);
                            centerAndShow(cd);
                            go = !cd.isCancelled(); // XXX what about x box?
                            cd.dispose();
                        }
                    }

                    if (go) {
                        Map<String, Object> parameters = new HashMap<String, Object>();

                        if (rpp != null) {
                            for (int p = 0; p < rpp.getParamCount(); p++) {
                                Pair<String, String> param = rpp.getParam(p);
                                if (StringUtils.isNotBlank(param.getSecond())) {
                                    parameters.put(param.getFirst(), param.getSecond());
                                }
                            }
                        }

                        parameters.put("RPT_IMAGE_DIR", JasperReportsCache.getImagePath().getAbsolutePath());
                        parameters.put("SUBREPORT_DIR", cachePath.getAbsoluteFile() + File.separator);
                        parameters.put("DATASOURCE", dataSource);

                        if (size > virtualizerThresholdSize) {
                            JRFileVirtualizer fileVirtualizer = new JRFileVirtualizer(10,
                                    JasperReportsCache.getCachePath().getAbsolutePath());
                            parameters.put(JRParameter.REPORT_VIRTUALIZER, fileVirtualizer);
                        }
                        // Add external parameters
                        if (params != null) {
                            for (Object key : params.keySet()) {
                                // System.out.println("key["+key+"] Val["+params.get(key)+"]");
                                if (parameters.get(key) == null) {
                                    parameters.put(key.toString(), params.get(key));
                                }
                            }
                        }
                        if (recordSet != null) {
                            parameters.put("itemnum", DBTableIdMgr.getInstance().getInClause(recordSet));
                        }

                        // XXX What about losing a connection here?
                        if (requiresHibernate) {
                            session = HibernateUtil.getNewSession();
                            parameters.put(JRHibernateQueryExecuterFactory.PARAMETER_HIBERNATE_SESSION, session);
                        }

                        if (dataSource instanceof QBDataSourceBase) {
                            ((QBDataSourceBase) dataSource).addListener(this);
                            progressLabel.setText(getResourceString("LabelsPane.LoadingReportData"));
                        } else {
                            progressLabel.setText(getResourceString("JasperReportFilling"));
                        }

                        //This needs to be done for newer jasperreports.jar. see bugzilla #7940 for details.
                        jasperReport.setProperty("net.sf.jasperreports.awt.ignore.missing.font", "true");

                        if (recordSet != null || (recordSet == null && dataSource == null)) {
                            asyncFillHandler = AsynchronousFillHandle.createHandle(jasperReport, parameters,
                                    DBConnection.getInstance().getConnection());
                        } else {
                            asyncFillHandler = AsynchronousFillHandle.createHandle(jasperReport, parameters,
                                    dataSource);
                        }
                        asyncFillHandler.addListener(this);
                        filling.set(true);
                        asyncFillHandler.startFill();
                    } else {
                        removeAll();
                        setLabelText(getResourceString("LabelsPane.ReportCancelled"));
                    }
                } else {
                    log.error("jasperReport came back null [" + compiledFile.getAbsolutePath() + "]");
                    progressBar.setIndeterminate(false);
                    setLabelText(getResourceString("JasperReportReadingCachedReport"));
                }

            } catch (JRException ex) {
                edu.ku.brc.af.core.UsageTracker.incrHandledUsageCount();
                edu.ku.brc.exceptions.ExceptionTracker.getInstance().capture(LabelsPane.class, ex);
                setLabelText(getResourceString("JasperReportCreatingViewer"));
                log.error(ex);
                ex.printStackTrace();
            }
        } else {
            errThrowable = throwable;
            setLabelText(getResourceString("JasperReportCompileError"));
        }
        compiler = null;
    }

    //------------------------------------------------------------
    // AsynchronousFilllListener
    //------------------------------------------------------------

    /* (non-Javadoc)
     * @see net.sf.jasperreports.engine.fill.AsynchronousFilllListener#reportCancelled()
     */
    public void reportCancelled() {
        removeAll();
        setLabelText(getResourceString("JasperReportCancelled"));
        asyncFillHandler = null;
        closeSession();
    }

    protected void closeSession() {
        if (session != null) {
            try {
                session.close();

            } catch (Exception ex) {
                log.error(ex);
                edu.ku.brc.af.core.UsageTracker.incrHandledUsageCount();
                edu.ku.brc.exceptions.ExceptionTracker.getInstance().capture(LabelsPane.class, ex);
            }
        }
    }

    /* (non-Javadoc)
     * @see net.sf.jasperreports.engine.fill.AsynchronousFilllListener#reportFillError(java.lang.Throwable)
     */
    public void reportFillError(java.lang.Throwable t) {
        errThrowable = t;
        removeAll();
        setLabelText(getResourceString("JasperReportFillError"));
        log.error(t);
        t.printStackTrace();
        asyncFillHandler = null;
        closeSession();
    }

    /**
     * @author timo
     *
     *cheap hack for SPNCH demo. keeping it around for debugging.
     */
    protected class JRViewerPrintHackForSPNHCBDayQueryLinuxOnly extends JRViewer {
        protected final JasperPrint jp;

        JRViewerPrintHackForSPNHCBDayQueryLinuxOnly(final JasperPrint print) {
            super(print);
            jp = print;
            ActionListener[] lists = btnPrint.getActionListeners();
            for (int l = 0; l < lists.length; l++) {
                btnPrint.removeActionListener(lists[l]);
            }
            this.btnPrint.addActionListener(new ActionListener() {

                /* (non-Javadoc)
                 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
                 */
                public void actionPerformed(ActionEvent e) {
                    try {
                        JasperExportManager.exportReportToPdfFile(jp, "/home/timo/hbd.pdf");
                        Runtime.getRuntime().exec("lp -P1 /home/timo/hbd.pdf");
                    } catch (Exception ex) {
                        errThrowable = ex;
                        edu.ku.brc.af.core.UsageTracker.incrHandledUsageCount();
                        edu.ku.brc.exceptions.ExceptionTracker.getInstance().capture(LabelsPane.class, ex);
                        setLabelText(getResourceString("JasperReportCreatingViewer"));
                        //log.error(ex);
                        ex.printStackTrace();
                    }
                }

            });
        }
    }

    /* (non-Javadoc)
     * @see net.sf.jasperreports.engine.fill.AsynchronousFilllListener#reportFinished(net.sf.jasperreports.engine.JasperPrint)
     */
    public void reportFinished(JasperPrint print) {
        filling.set(false);
        try {
            removeAll();
            label = null;

            JRViewer jasperViewer = new JRViewer(print);

            //this vile hack for SPNHC demo may be useful for debugging...
            //            JRViewer jasperViewer = new JRViewerPrintHackForSPNHCBDayQueryLinuxOnly(print);            
            //... end vile hack

            add(jasperViewer, BorderLayout.CENTER);

            forceTopFrameRepaint();

            closeSession();

        } catch (Exception ex) {
            errThrowable = ex;
            log.error(ex);
            edu.ku.brc.af.core.UsageTracker.incrHandledUsageCount();
            edu.ku.brc.exceptions.ExceptionTracker.getInstance().capture(LabelsPane.class, ex);
            setLabelText(getResourceString("JasperReportCreatingViewer"));
            ex.printStackTrace();
        }
        asyncFillHandler = null;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.specify.tasks.subpane.qb.QBDataSourceListenerIFace#currentRow(int)
     */
    @Override
    public void currentRow(final long currentRow) {
        SwingUtilities.invokeLater(new Runnable() {

            /* (non-Javadoc)
             * @see java.lang.Runnable#run()
             */
            @Override
            public void run() {
                if (progressBar.isIndeterminate() && dataSource instanceof QBDataSource) {
                    progressBar.setMinimum(0);
                    progressBar.setMaximum(((QBDataSource) dataSource).size());
                    progressBar.setIndeterminate(false);
                }
                progressBar.setValue((int) currentRow);
            }

        });
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.specify.tasks.subpane.qb.QBDataSourceListenerIFace#done(int)
     */
    @Override
    public void done(long rows) {
        // TODO Auto-generated method stub

    }

    /* (non-Javadoc)
     * @see edu.ku.brc.specify.tasks.subpane.qb.QBDataSourceListenerIFace#filling()
     */
    @Override
    public void filling() {
        SwingUtilities.invokeLater(new Runnable() {

            /* (non-Javadoc)
             * @see java.lang.Runnable#run()
             */
            @Override
            public void run() {
                progressBar.setValue(0);
                progressLabel.setText(getResourceString("JasperReportFilling"));
            }

        });
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.specify.tasks.subpane.qb.QBDataSourceListenerIFace#loaded()
     */
    @Override
    public void loaded() {
        loading.set(false);
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.specify.tasks.subpane.qb.QBDataSourceListenerIFace#loading()
     */
    @Override
    public void loading() {
        loading.set(true);
        SwingUtilities.invokeLater(new Runnable() {

            /* (non-Javadoc)
             * @see java.lang.Runnable#run()
             */
            @Override
            public void run() {
                progressLabel.setText(getResourceString("LabelsPane.LoadingReportData"));
            }

        });
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.specify.tasks.subpane.qb.QBDataSourceListenerIFace#rowCount(int)
     */
    @Override
    public void rowCount(final long rowCount) {
        if (rowCount > 0) {
            SwingUtilities.invokeLater(new Runnable() {

                /*
                 * (non-Javadoc)
                 * 
                 * @see java.lang.Runnable#run()
                 */
                @Override
                public void run() {
                    progressBar.setMinimum(0);
                    progressBar.setMaximum((int) rowCount);
                    progressBar.setValue(0);
                    progressBar.setIndeterminate(false);
                }

            });
        }
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.specify.tasks.subpane.qb.QBDataSourceListenerIFace#isListeningClosely()
     */
    @Override
    public boolean isListeningClosely() {
        return true;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.specify.tasks.subpane.qb.QBDataSourceListenerIFace#doTellAll()
     */
    @Override
    public boolean doTellAll() {
        return false;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.specify.tasks.subpane.qb.QBDataSourceListenerIFace#deletedRecs(java.util.List)
     */
    @Override
    public void deletedRecs(List<Integer> keysDeleted) {
        //nuthin
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.specify.tasks.subpane.qb.QBDataSourceListenerIFace#updatedRec(java.lang.Integer)
     */
    @Override
    public void updatedRec(Integer key) {
        //nuthin
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.specify.tasks.subpane.qb.QBDataSourceListenerIFace#addedRec(java.lang.Integer)
     */
    @Override
    public void addedRec(Integer key) {
        //whatever
    }

}