/******************************************************************************* * Copyright (c) 2012-2015 INRIA. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Generoso Pagano - initial API and implementation ******************************************************************************/ package fr.inria.soctrace.framesoc.core.tools.management; import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.swt.widgets.Display; import fr.inria.soctrace.framesoc.core.bus.FramesocBus; import fr.inria.soctrace.framesoc.core.bus.FramesocBusTopic; import fr.inria.soctrace.framesoc.core.tools.importers.TraceChecker; import fr.inria.soctrace.framesoc.core.tools.model.IPluginToolJobBody; import fr.inria.soctrace.lib.model.utils.SoCTraceException; import fr.inria.soctrace.lib.storage.SystemDBObject; import fr.inria.soctrace.lib.storage.TraceDBObject; /** * Subclass of {@link PluginToolJob} for Plugin Importer Tools. * * <p> * In the {@link PluginToolJob#postExecute(IStatus)} method implementation, a message is sent on the * {@link FramesocBus} for the topic {@link FramesocBusTopic#TOPIC_UI_SYNCH_TRACES_NEEDED}. The * associated data is true or false, depending on whether the Job returned status is * {@link Status#OK_STATUS} or {@link Status#CANCEL_STATUS} respectively. * * @author "Generoso Pagano <generoso.pagano@inria.fr>" */ public class PluginImporterJob extends PluginToolJob { private TraceChecker checker; public PluginImporterJob(String name, IPluginToolJobBody body) { super(name, body); } @Override public void preExecute(IProgressMonitor monitor) { checker = new TraceChecker(); } @Override public void postExecute(IProgressMonitor monitor, IStatus status) { try { monitor.beginTask("Post-processing imported traces", IProgressMonitor.UNKNOWN); // check trace metadata checker.checkTraces(monitor); // we want to provide UI feedback, so we post the event using // Display sync exec final IStatus jobStatus = status; Display.getDefault().syncExec(new Runnable() { @Override public void run() { if (!jobStatus.equals(Status.OK_STATUS)) { FramesocBus.getInstance().send( FramesocBusTopic.TOPIC_UI_SYNCH_TRACES_NEEDED, false); } else { FramesocBus.getInstance().send( FramesocBusTopic.TOPIC_UI_SYNCH_TRACES_NEEDED, true); } } }); } finally { monitor.done(); } } /** * Static utility methods to print user message if import fails. * * It should be used to generate the exception message for exceptions launched in * {@link IPluginToolJobBody#run(IProgressMonitor)}. The alternative is to call * {@link #catchImporterException(Exception, SystemDBObject, TraceDBObject)}, which manages the * exception and calls this method internally. * * @param e * Exception * @param sysDbRollback * true if the System DB modifications have been rollbacked, false otherwise * @param traceDbDrop * true if the Trace DB has been deleted, false otherwise * @return the complete user message */ public static String getExceptionMessage(Exception e, boolean sysDbRollback, boolean traceDbDrop) { String base = ""; if (e != null) { if (e.getMessage() != null) { base = e.getMessage(); int i = base.indexOf(":"); if (i != -1) { base = base.substring(base.indexOf(":") + 2); } } } StringBuilder sb = new StringBuilder("Import failed.\n\n"); sb.append(base); sb.append("\n\n"); sb.append("System DB rollback " + ((sysDbRollback) ? "done." : "not done.")); sb.append("\n"); sb.append("Trace DB " + ((traceDbDrop) ? "" : "not ") + "deleted."); return sb.toString(); } /** * Method to manage an exception that occurs in importers. * * The method should be called in the catch clause of the * {@link IPluginToolJobBody#run(IProgressMonitor)}. The method tries to rollback the * modifications on the System DB and to drop the Trace DB. At the end an exception is thrown to * the user code. * * @param e * exception thrown in the importer * @param sysDB * system DB * @param traceDB * trace DB * @throws SoCTraceException * Exception always thrown to the user. The message is generated with * {@link #getExceptionMessage(String, boolean, boolean)} */ public static void catchImporterException(Exception e, SystemDBObject sysDB, TraceDBObject traceDB) throws SoCTraceException { System.err.println("Import failure. Trying to rollback modifications in DB."); boolean rollback = rollbackSystemDB(sysDB); boolean drop = dropTraceDB(traceDB); throw new SoCTraceException(getExceptionMessage(e, rollback, drop)); } /** * Method to manage an exception that occurs in importers. * * The method should be called in the catch clause of the * {@link IPluginToolJobBody#run(IProgressMonitor)}. The method tries to rollback the * modifications on the System DB and to drop the Trace DB. At the end an exception is thrown to * the user code. * * @param e * exception thrown in the importer * @param sysDB * system DB * @param tdbs * list of trace DBs * @throws SoCTraceException * Exception always thrown to the user. The message is generated with * {@link #getExceptionMessage(String, boolean, boolean)} */ public static void catchImporterException(Exception e, SystemDBObject sysDB, List<TraceDBObject> tdbs) throws SoCTraceException { System.err.println("Import failure. Trying to rollback modifications in DB."); boolean rollback = rollbackSystemDB(sysDB); boolean drop = true; for (TraceDBObject traceDB : tdbs) { drop = drop && dropTraceDB(traceDB); } throw new SoCTraceException(getExceptionMessage(e, rollback, drop)); } private static boolean rollbackSystemDB(SystemDBObject sysDB) { boolean rollback = false; if (sysDB != null) { try { sysDB.rollback(); rollback = true; } catch (SoCTraceException ex) { System.err.println("Exception trying to rollback System DB."); System.err.println(ex.getMessage()); } } else { rollback = true; } return rollback; } private static boolean dropTraceDB(TraceDBObject traceDB) { boolean drop = false; if (traceDB != null) { try { traceDB.dropDatabase(); drop = true; } catch (SoCTraceException ex) { System.err.println("Exception trying to drop Trace DB."); System.err.println(ex.getMessage()); } } else { drop = true; } return drop; } }