Java tutorial
/* 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.services.biogeomancer; import static edu.ku.brc.ui.UIRegistry.getResourceString; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.util.List; import java.util.Vector; import javax.swing.JFrame; import javax.swing.JOptionPane; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import edu.ku.brc.af.core.UsageTracker; import edu.ku.brc.helpers.SwingWorker; import edu.ku.brc.ui.JStatusBar; import edu.ku.brc.ui.ProgressDialog; import edu.ku.brc.ui.UIHelper; import edu.ku.brc.ui.UIRegistry; /** * @author rod * * @code_status Alpha * * Jan 14, 2008 * */ public class GeoCoordBGMProvider implements GeoCoordServiceProviderIFace { private static final Logger log = Logger.getLogger(GeoCoordBGMProvider.class); protected GeoCoordProviderListenerIFace listener = null; protected String helpContext = null; /** * */ public GeoCoordBGMProvider() { //This empty block is properly documented. } /* (non-Javadoc) * @see edu.ku.brc.services.biogeomancer.GeoCoordServiceProviderIFace#processGeoRefData(java.util.List, edu.ku.brc.services.biogeomancer.GeoCoordProviderListenerIFace, java.lang.String) */ public void processGeoRefData(final List<GeoCoordDataIFace> items, final GeoCoordProviderListenerIFace listenerArg, final String helpContextArg) { this.listener = listenerArg; this.helpContext = helpContextArg; UsageTracker.incrUsageCount("Tools.BioGeomancerData"); //$NON-NLS-1$ log.info("Performing BioGeomancer lookup of selected records"); //$NON-NLS-1$ // create a progress bar dialog to show the network progress final ProgressDialog progressDialog = new ProgressDialog( UIRegistry.getResourceString("GeoCoordBGMProvider.BIOGEOMANCER_PROGRESS"), false, true); // I18N //$NON-NLS-1$ progressDialog.getCloseBtn().setText(getResourceString("CANCEL")); //$NON-NLS-1$ progressDialog.setModal(true); progressDialog.setProcess(0, items.size()); // XXX Java 6 //progressDialog.setIconImage( IconManager.getImage("AppIcon").getImage()); // use a SwingWorker thread to do all of the work, and update the GUI when done final SwingWorker bgTask = new SwingWorker() { final JStatusBar statusBar = UIRegistry.getStatusBar(); protected boolean cancelled = false; @Override public void interrupt() { super.interrupt(); cancelled = true; } @SuppressWarnings("synthetic-access") //$NON-NLS-1$ @Override public Object construct() { // perform the BG web service call ON all rows, storing results in the rows int progress = 0; for (GeoCoordDataIFace item : items) { if (cancelled) { break; } // get the locality data String localityNameStr = item.getLocalityString(); // get the geography data String country = item.getCountry(); String state = item.getState(); String county = item.getCounty(); log.info("Making call to BioGeomancer service: " + localityNameStr); //$NON-NLS-1$ String bgResults; BioGeomancerQuerySummaryStruct bgQuerySummary; try { bgResults = BioGeomancer.getBioGeomancerResponse(item.getGeoCoordId().toString(), country, state, county, localityNameStr); bgQuerySummary = BioGeomancer.parseBioGeomancerResponse(bgResults); } catch (IOException ex1) { String warning = getResourceString("GeoCoordBGMProvider.WB_BIOGEOMANCER_UNAVAILABLE"); //$NON-NLS-1$ statusBar.setWarningMessage(warning, ex1); log.error("A network error occurred while contacting the BioGeomancer service", ex1); //$NON-NLS-1$ // update the progress bar UI and move on progressDialog.setProcess(++progress); continue; } catch (Exception ex2) { UsageTracker.incrHandledUsageCount(); edu.ku.brc.exceptions.ExceptionTracker.getInstance().capture(GeoCoordBGMProvider.class, ex2); // right now we'll simply blame this on BG // in the future we might get more specific about this error String warning = getResourceString("GeoCoordBGMProvider.WB_BIOGEOMANCER_UNAVAILABLE"); //$NON-NLS-1$ statusBar.setWarningMessage(warning, ex2); log.warn("Failed to get result count from BioGeomancer respsonse", ex2); //$NON-NLS-1$ // update the progress bar UI and move on progressDialog.setProcess(++progress); continue; } // if there was at least one result, pre-cache a map for that result int resCount = bgQuerySummary.results.length; if (resCount > 0) { final int rowNumber = item.getGeoCoordId(); final BioGeomancerQuerySummaryStruct summaryStruct = bgQuerySummary; // create a thread to go grab the map so it will be cached for later use Thread t = new Thread(new Runnable() { public void run() { try { log.info("Requesting map of BioGeomancer results for workbench row " //$NON-NLS-1$ + rowNumber); BioGeomancer.getMapOfQuerySummary(summaryStruct, null); } catch (Exception e) { UsageTracker.incrHandledUsageCount(); edu.ku.brc.exceptions.ExceptionTracker.getInstance() .capture(GeoCoordBGMProvider.class, e); log.warn("Failed to pre-cache BioGeomancer results map", e); //$NON-NLS-1$ } } }); t.setName("Map Pre-Caching Thread: row " + item.getGeoCoordId()); // I18N //$NON-NLS-1$ log.debug("Starting map pre-caching thread"); //$NON-NLS-1$ t.start(); } // if we got at least one result... if (resCount > 0) { item.setXML(bgResults); } // update the progress bar UI and move on progressDialog.setProcess(++progress); } return null; } @Override public void finished() { statusBar.setText(getResourceString("GeoCoordBGMProvider.BIOGEOMANCER_COMPLETED")); //$NON-NLS-1$ if (!cancelled) { // hide the progress dialog progressDialog.setVisible(false); // find out how many records actually had results List<GeoCoordDataIFace> rowsWithResults = new Vector<GeoCoordDataIFace>(); for (GeoCoordDataIFace row : items) { if (row.getXML() != null) { rowsWithResults.add(row); } } // if no records had possible results... int numRecordsWithResults = rowsWithResults.size(); if (numRecordsWithResults == 0) { statusBar.setText(getResourceString("GeoCoordBGMProvider.NO_BG_RESULTS")); //$NON-NLS-1$ JOptionPane.showMessageDialog(UIRegistry.getTopWindow(), getResourceString("GeoCoordBGMProvider.NO_BG_RESULTS"), getResourceString("NO_RESULTS"), JOptionPane.INFORMATION_MESSAGE); return; } if (listener != null) { listener.aboutToDisplayResults(); } // ask the user if they want to review the results String message = String.format( getResourceString("GeoCoordBGMProvider.BGM_VIEW_RESULTS_CONFIRM"), //$NON-NLS-1$ String.valueOf(numRecordsWithResults)); int userChoice = JOptionPane.showConfirmDialog(UIRegistry.getTopWindow(), message, getResourceString("GeoCoordBGMProvider.CONTINUE"), JOptionPane.YES_NO_OPTION);//$NON-NLS-1$ if (userChoice != JOptionPane.YES_OPTION) { statusBar.setText(getResourceString("GeoCoordBGMProvider.BIOGEOMANCER_TERMINATED")); //$NON-NLS-1$ return; } displayBioGeomancerResults(rowsWithResults); } } }; // if the user hits close, stop the worker thread progressDialog.getCloseBtn().addActionListener(new ActionListener() { @SuppressWarnings("synthetic-access") //$NON-NLS-1$ public void actionPerformed(ActionEvent ae) { log.debug("Stopping the BioGeomancer service worker thread"); //$NON-NLS-1$ bgTask.interrupt(); } }); log.debug("Starting the BioGeomancer service worker thread"); //$NON-NLS-1$ bgTask.start(); UIHelper.centerAndShow(progressDialog); } /** * Create a dialog to display the set of rows that had at least one result option * returned by BioGeomancer. The dialog allows the user to iterate through the * records supplied, choosing a result (or not) for each one. * * @param items the set of records containing valid BioGeomancer responses with at least one result */ protected void displayBioGeomancerResults(final List<GeoCoordDataIFace> items) { // create the UI for displaying the BG results JFrame topFrame = (JFrame) UIRegistry.getTopWindow(); BioGeomancerResultsChooser bgResChooser = new BioGeomancerResultsChooser(topFrame, getResourceString("GeoCoordBGMProvider.BIOGEOMANCER_CHOOSER"), //$NON-NLS-1$ items, helpContext); // I18N int itemsUpdated = 0; List<BioGeomancerResultStruct> results = bgResChooser.getResultsChosen(); for (int i = 0; i < items.size(); ++i) { GeoCoordDataIFace item = items.get(i); BioGeomancerResultStruct userChoice = results.get(i); if (userChoice != null) { //System.out.println(userChoice.coordinates); String[] coords = StringUtils.split(userChoice.coordinates); item.set(coords[1], coords[0]); itemsUpdated++; } } if (listener != null) { listener.complete(items, itemsUpdated); listener = null; } } }