/* GanttProject is an opensource project management tool. Copyright (C) 2011-2012 GanttProject Team 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 3 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 net.sourceforge.ganttproject.export; import java.io.File; import java.util.ArrayList; import java.util.Arrays; 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.core.runtime.jobs.IJobManager; import org.eclipse.core.runtime.jobs.Job; import org.osgi.service.prefs.Preferences; import org.w3c.util.DateParser; import org.w3c.util.InvalidDateException; import biz.ganttproject.core.option.DefaultDateOption; import biz.ganttproject.core.option.GPOption; import biz.ganttproject.core.option.GPOptionGroup; import net.sourceforge.ganttproject.GPLogger; import net.sourceforge.ganttproject.GanttExportSettings; import net.sourceforge.ganttproject.IGanttProject; import net.sourceforge.ganttproject.chart.Chart; import net.sourceforge.ganttproject.gui.UIFacade; import net.sourceforge.ganttproject.gui.zoom.ZoomManager.ZoomState; import net.sourceforge.ganttproject.language.GanttLanguage; public abstract class ExporterBase implements Exporter { private IGanttProject myProject; private Chart myGanttChart; private Chart myResourceChart; private UIFacade myUIFacade; private Preferences myRootPreferences; private DefaultDateOption myExportRangeStart; private DefaultDateOption myExportRangeEnd; protected static final GanttLanguage language = GanttLanguage.getInstance(); static protected Object EXPORT_JOB_FAMILY = new String("Export job family"); @Override public void setContext(IGanttProject project, UIFacade uiFacade, Preferences prefs) { myGanttChart = uiFacade.getGanttChart(); myResourceChart = uiFacade.getResourceChart(); myProject = project; myUIFacade = uiFacade; myRootPreferences = prefs; myExportRangeStart = new DefaultDateOption("export.range.start", myGanttChart.getStartDate()); myExportRangeEnd = new DefaultDateOption("export.range.end", myGanttChart.getEndDate()); } protected DefaultDateOption getExportRangeStartOption() { return myExportRangeStart; } protected DefaultDateOption getExportRangeEndOption() { return myExportRangeEnd; } protected GPOptionGroup createExportRangeOptionGroup() { return new GPOptionGroup("export.range", new GPOption[] { getExportRangeStartOption(), getExportRangeEndOption() }); } public UIFacade getUIFacade() { return myUIFacade; } public IGanttProject getProject() { return myProject; } protected Preferences getPreferences() { return myRootPreferences; } protected Chart getGanttChart() { return myGanttChart; } protected Chart getResourceChart() { return myResourceChart; } @Override public String[] getCommandLineKeys() { // By default use the same return getFileExtensions(); } public GanttExportSettings createExportSettings() { GanttExportSettings result = new GanttExportSettings(); if (myRootPreferences != null) { int zoomLevel = myRootPreferences.getInt("zoom", -1); ZoomState zoomState = zoomLevel < 0 ? myUIFacade.getZoomManager().getZoomState() : myUIFacade.getZoomManager().getZoomState(zoomLevel); result.setZoomLevel(zoomState); String exportRange = myRootPreferences.get("exportRange", null); if (exportRange == null) { result.setStartDate(myExportRangeStart.getValue()); result.setEndDate(myExportRangeEnd.getValue()); } else { String[] rangeBounds = exportRange.split(" "); try { result.setStartDate(DateParser.parse(rangeBounds[0])); result.setEndDate(DateParser.parse(rangeBounds[1])); } catch (InvalidDateException e) { GPLogger.log(e); } result.setWidth(-1); } result.setCommandLineMode(myRootPreferences.getBoolean("commandLine", false)); if (myRootPreferences.getBoolean("expandResources", false)) { result.setExpandedResources(""); } } return result; } @Override public void run(final File outputFile, final ExportFinalizationJob finalizationJob) throws Exception { final IJobManager jobManager = Job.getJobManager(); final List<File> resultFiles = new ArrayList<File>(); final List<ExporterJob> jobs = new ArrayList<ExporterJob>(Arrays.asList(createJobs(outputFile, resultFiles))); jobs.add(new ExporterJob("Finalizing") { @Override protected IStatus run() { finalizationJob.run(resultFiles.toArray(new File[0])); return Status.OK_STATUS; } }); final IProgressMonitor monitor = jobManager.createProgressGroup(); Job driverJob = new Job("Running export") { @Override protected IStatus run(IProgressMonitor monitor) { monitor.beginTask("Running export", jobs.size()); for (ExporterJob job : jobs) { if (monitor.isCanceled()) { jobManager.cancel(EXPORT_JOB_FAMILY); return Status.CANCEL_STATUS; } monitor.subTask(job.getName()); final IStatus state; try { state = job.run(); } catch (Throwable e) { GPLogger.log(new RuntimeException("Export failure. Failed subtask: " + job.getName(), e)); monitor.setCanceled(true); continue; } if (state.isOK() == false) { GPLogger.log(new RuntimeException("Export failure. Failed subtask: " + job.getName(), state.getException())); monitor.setCanceled(true); continue; } // Sub task for export is finished without problems // So, updated the total amount of work with the current // work performed monitor.worked(1); // and remove the sub task description // (convenient for debugging to know the sub task is // finished properly) monitor.subTask(null); } monitor.done(); return Status.OK_STATUS; } }; driverJob.setProgressGroup(monitor, 0); driverJob.schedule(); } /** @return a list with {@link ExporterJob}s required to actually export the current format */ protected abstract ExporterJob[] createJobs(File outputFile, List<File> resultFiles); public abstract static class ExporterJob { private final String myName; protected ExporterJob(String name) { myName = name; } String getName() { return myName; } protected abstract IStatus run(); } }