/* * Copyright 2010-2015 Institut Pasteur. * * This file is part of Icy. * * Icy 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 3 of the License, or * (at your option) any later version. * * Icy 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 Icy. If not, see <http://www.gnu.org/licenses/>. */ package icy.gui.plugin; import icy.gui.frame.error.ErrorReportFrame; import icy.gui.frame.progress.AnnounceFrame; import icy.gui.frame.progress.CancelableProgressFrame; import icy.gui.frame.progress.ProgressFrame; import icy.main.Icy; import icy.plugin.PluginDescriptor; import icy.plugin.PluginInstaller; import icy.plugin.PluginRepositoryLoader; import icy.plugin.PluginUpdater; import icy.system.IcyExceptionHandler; import icy.system.thread.ThreadUtil; import icy.util.StringUtil; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.Icon; import javax.swing.text.BadLocationException; /** * This class create a report from a plugin crash and ask the * user if he wants to send it to the dev team of the plugin. * * @author Fabrice de Chaumont & Stephane<br> */ public class PluginErrorReport { /** * Report an error thrown by the specified plugin. * * @param plugin * {@link PluginDescriptor} of the plugin which thrown the error. * @param devId * Plugin developer Id, used only if we do not have plugin descriptor information. * @param title * Error title if any * @param message * Error message to report */ public static void report(final PluginDescriptor plugin, final String devId, final String title, final String message) { // headless mode ? if (Icy.getMainInterface().isHeadLess()) { // do nothing // directly report // IcyExceptionHandler.report(plugin, devId, message); return; } // cannot be reported... // if ((plugin == null) && StringUtil.isEmpty(devId)) // return; if (ErrorReportFrame.hasErrorFrameOpened()) return; // always do that in background process ThreadUtil.bgRun(new Runnable() { @Override public void run() { if (plugin != null) { final CancelableProgressFrame info = new CancelableProgressFrame("Plugin '" + plugin.getName() + "' has crashed, searching for update..."); // wait for online basic info loaded PluginRepositoryLoader.waitLoaded(); PluginDescriptor onlinePlugin = null; try { // search for update if (!info.isCancelRequested()) onlinePlugin = PluginUpdater.getUpdate(plugin); } finally { info.close(); } // update found and not canceled if (!info.isCancelRequested() && (onlinePlugin != null)) { PluginInstaller.install(onlinePlugin, true); new AnnounceFrame( "The plugin crashed but a new version has been found, try it again when installation is done", 10); // don't need to report return; } // display report as no update were found ThreadUtil.invokeLater(new Runnable() { @Override public void run() { doReport(plugin, null, title, message); } }); } else { // directly display report frame ThreadUtil.invokeLater(new Runnable() { @Override public void run() { doReport(null, devId, title, message); } }); } } }); } /** * Report an error thrown by the specified plugin. * * @param plugin * {@link PluginDescriptor} of the plugin which thrown the error. * @param devId * Plugin developer Id, used only if we do not have plugin descriptor information. * @param message * Error message to report */ public static void report(final PluginDescriptor plugin, final String devId, final String message) { report(plugin, devId, null, message); } /** * Report an error thrown by the specified plugin. * * @param plugin * {@link PluginDescriptor} of the plugin which thrown the error. * @param message * Error message to report */ public static void report(PluginDescriptor plugin, String message) { report(plugin, null, null, message); } // internal use only static void doReport(final PluginDescriptor plugin, final String devId, String title, String message) { // headless mode if (Icy.getMainInterface().isHeadLess()) { // do not report // report directly // IcyExceptionHandler.report(plugin, devId, message); return; } String str; Icon icon; // build title if (plugin != null) { str = "<html><br>The plugin named <b>" + plugin.getName() + "</b> has encountered a problem"; icon = plugin.getIcon(); } else if (!StringUtil.isEmpty(devId)) { str = "<html><br>The plugin from the developer <b>" + devId + "</b> has encountered a problem"; icon = null; } else { str = "<html><br>The application has encountered a problem"; icon = null; } if (StringUtil.isEmpty(title)) str += ".<br><br>"; else str += " :<br><i>" + title + "</i><br><br>"; str += "Reporting this problem is anonymous and will help improving this plugin.<br><br></html>"; final ErrorReportFrame frame = new ErrorReportFrame(icon, str, message); // set specific report action here frame.setReportAction(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { final ProgressFrame progressFrame = new ProgressFrame("Sending report..."); try { IcyExceptionHandler.report(plugin, devId, frame.getReportMessage()); } catch (BadLocationException ex) { System.err.println("Error while reporting error :"); IcyExceptionHandler.showErrorMessage(ex, true); } finally { progressFrame.close(); } } }); } }