X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.charts%2Fsrc%2Forg%2Fsimantics%2Fcharts%2Fexport%2FExportChartPDF.java;h=e176f118dbb6ab94c67eb5023f6099c62ebfa7c2;hp=645fb50ea62884a5af8bdb535f42e72acc5065bb;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hpb=969bd23cab98a79ca9101af33334000879fb60c5 diff --git a/bundles/org.simantics.charts/src/org/simantics/charts/export/ExportChartPDF.java b/bundles/org.simantics.charts/src/org/simantics/charts/export/ExportChartPDF.java index 645fb50ea..e176f118d 100644 --- a/bundles/org.simantics.charts/src/org/simantics/charts/export/ExportChartPDF.java +++ b/bundles/org.simantics.charts/src/org/simantics/charts/export/ExportChartPDF.java @@ -1,301 +1,301 @@ -package org.simantics.charts.export; - -import java.awt.Graphics2D; -import java.awt.geom.Rectangle2D; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.UUID; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.preferences.DefaultScope; -import org.eclipse.core.runtime.preferences.InstanceScope; -import org.osgi.service.prefs.Preferences; -import org.simantics.Simantics; -import org.simantics.charts.preference.ChartPreferences; -import org.simantics.charts.query.MilestoneSpecQuery; -import org.simantics.charts.query.TrendSpecQuery; -import org.simantics.databoard.Accessors; -import org.simantics.databoard.accessor.RecordAccessor; -import org.simantics.databoard.accessor.error.AccessorConstructionException; -import org.simantics.databoard.accessor.reference.ChildReference; -import org.simantics.databoard.binding.mutable.Variant; -import org.simantics.databoard.type.RecordType; -import org.simantics.databoard.type.UnionType; -import org.simantics.db.Resource; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.layer0.request.PossibleModel; -import org.simantics.export.core.ExportContext; -import org.simantics.export.core.error.ExportException; -import org.simantics.export.core.manager.Content; -import org.simantics.export.core.pdf.ExportPdfWriter; -import org.simantics.export.core.pdf.ExportPdfWriter.Page; -import org.simantics.export.core.util.ExportQueries; -import org.simantics.export.core.util.ExporterUtils; -import org.simantics.g2d.canvas.impl.CanvasContext; -import org.simantics.history.History; -import org.simantics.history.HistoryException; -import org.simantics.history.HistoryManager; -import org.simantics.simulation.experiment.IExperiment; -import org.simantics.simulation.experiment.IHistoryExperiment; -import org.simantics.simulation.export.ExperimentExportClass; -import org.simantics.simulation.project.ExperimentManager; -import org.simantics.simulation.project.IExperimentManager; -import org.simantics.trend.TrendInitializer; -import org.simantics.trend.configuration.ItemPlacement; -import org.simantics.trend.configuration.TimeFormat; -import org.simantics.trend.configuration.TrendSpec; -import org.simantics.trend.impl.MilestoneSpec; -import org.simantics.trend.impl.TrendNode; -import org.simantics.utils.datastructures.MapList; -import org.simantics.utils.format.ValueFormat; -import org.simantics.utils.threads.ThreadUtils; -import org.simantics.utils.threads.WorkerThread; - -public class ExportChartPDF extends ExperimentExportClass { - - public static final RecordType chartOptions; - - public static String S_CHART = "Chart"; - public static ChildReference P_ITEMPLACEMENT = ChildReference.parsePath(S_CHART+"/Item Placement"); - public static ChildReference P_TIMEFORMAT = ChildReference.parsePath(S_CHART+"/Time Format"); - public static ChildReference P_VALUEFORMAT = ChildReference.parsePath(S_CHART+"/Value Format"); - - static { - chartOptions = new RecordType(); - chartOptions.addComponent("Item Placement", UnionType.newEnum("Stacked", "Overlapping")); - chartOptions.addComponent("Time Format", UnionType.newEnum("Decimal", "Time")); - chartOptions.addComponent("Value Format", UnionType.newEnum("Currency", "Scientific", "Engineering", "Default")); - } - - @Override - public void export(List contents, - Object handle, - ExportContext ctx, - Variant options, - IProgressMonitor monitor, - MapList attachmentMap - ) throws ExportException { - - // Flush all experiments, just in case. - IExperimentManager em = Simantics.getProject().getHint( ExperimentManager.KEY_EXPERIMENT_MANAGER ); - if ( em != null ) { - for (IExperiment exp : em.getExperiments()) { - if ( exp instanceof IHistoryExperiment ) { - IHistoryExperiment he = (IHistoryExperiment) exp; - try { - he.flushHistory(); - } catch (HistoryException e) { - } - } - } - } - - final ExportPdfWriter writer = (ExportPdfWriter) handle; - final WorkerThread workerThread = new WorkerThread("Chart PDF Painter"); - workerThread.start(); - try { - - final RecordAccessor ra = Accessors.getAccessor( options ); - - // Get a list of the history managers the user has selected. - List modelRefs = ExperimentExportClass.getResult(ctx, options, true); - List charts = new ArrayList(); - - for ( Content content : contents ) { - if (monitor.isCanceled()) - throw new OperationCanceledException(); - - Resource chartRes = ctx.session.syncRequest( ExportQueries.toResource(content.url) ); - Resource model = ctx.session.syncRequest( new PossibleModel( chartRes ) ); - for (ModelRef modelRef : modelRefs) { - if ( !modelRef.resource.equals(model) ) continue; - for (ExperimentRef experimentRef : modelRef.experiments) { - for (RunRef runRef : experimentRef.runs) { - if ( runRef.historyFolder == null || !runRef.historyFolder.exists() ) continue; - HistoryManager history = History.openFileHistory( runRef.historyFolder ); - - ChartSettings cs = new ChartSettings(); - cs.history = history; - cs.modelRef = modelRef; - cs.experimentRef = experimentRef; - cs.runRef = runRef; - cs.chartRes = chartRes; - charts.add( cs ); - } - } - } - } - - - for ( final ChartSettings cs : charts ) { - UUID id = UUID.randomUUID(); - final TrendSpec trendSpec = ctx.session.syncRequest( new TrendSpecQuery( id, cs.chartRes ) ); - if ( cs.modelRef.enabledRunCount() > 1 ) { - // Add run ref to the label - trendSpec.name += " / " + cs.runRef.label; - } - - - final MilestoneSpec milestones = ctx.session.syncRequest( new MilestoneSpecQuery( cs.experimentRef.resource ) ); - //final CanvasContext cctx = new CanvasContext( workerThread ); - final ExportException[] error = new ExportException[1]; - - ThreadUtils.syncExec(workerThread, new Runnable() { - @Override - public void run() { - CanvasContext cctx = TrendInitializer.createDefaultCanvas(workerThread, cs.history, null, null, trendSpec); - Page pdfPage = null; - try { - TrendNode trend = TrendInitializer.getTrendNode( cctx ); - trend.printing = true; - - String s = ExporterUtils.getUnionValue(ra, P_ITEMPLACEMENT); - if ( s!=null ) trend.itemPlacement = ItemPlacement.valueOf(s); - s = ExporterUtils.getUnionValue(ra, P_TIMEFORMAT); - if ( s!=null ) trend.timeFormat = TimeFormat.valueOf(s); - s = ExporterUtils.getUnionValue(ra, P_VALUEFORMAT); - if ( s!=null ) trend.valueFormat = ValueFormat.valueOf(s); - - if (milestones!=null) trend.setMilestones(milestones); - - pdfPage = writer.createPage( null ); - Graphics2D g2d = pdfPage.createGraphics( true ); - try { - Rectangle2D clip = new Rectangle2D.Double(0, 0, pdfPage.getWidth(), pdfPage.getHeight()); - g2d.setClip( clip ); - g2d.scale(0.25, 0.25); - trend.autoscale(true, true); - trend.zoomOut(); - trend.layout(); - trend.render( g2d ); - } finally { - trend.cleanup(); - g2d.dispose(); - cs.history.close(); - } - } catch (ExportException e) { - error[0] = e; - } finally { - cctx.dispose(); - if ( pdfPage != null ) - try { - pdfPage.close(); - } catch (ExportException e) { - if ( error[0]==null ) error[0] = e; - } - } - } - }); - if ( error[0] != null ) throw error[0]; - - } - } catch (DatabaseException e) { - throw new ExportException( e ); - } catch (AccessorConstructionException e) { - throw new ExportException( e ); - } finally { - workerThread.stopDispatchingEvents(true); - } - - } - - - @Override - public RecordType options(ExportContext context, Collection content) throws ExportException { - RecordType options = super.options(context, content); - options.addComponent(S_CHART, chartOptions); - return options; - } - - @Override - public void fillDefaultPrefs(ExportContext ctx, Variant options) throws ExportException { - super.fillDefaultPrefs(ctx, options); - // Read from eclipse preferences - try { - RecordAccessor ra = Accessors.getAccessor(options); - Preferences instPrefs = InstanceScope.INSTANCE.getNode( ChartPreferences.P_NODE ); - Preferences defaultPrefs = DefaultScope.INSTANCE.getNode( ChartPreferences.P_NODE ); - - String s; - s = ExporterUtils.getPrefString(instPrefs, defaultPrefs, ChartPreferences.P_ITEMPLACEMENT); - ExporterUtils.setUnionValue(ra, P_ITEMPLACEMENT, s); - - s = ExporterUtils.getPrefString(instPrefs, defaultPrefs, ChartPreferences.P_TIMEFORMAT); - ExporterUtils.setUnionValue(ra, P_TIMEFORMAT, s); - - s = ExporterUtils.getPrefString(instPrefs, defaultPrefs, ChartPreferences.P_VALUEFORMAT); - ExporterUtils.setUnionValue(ra, P_VALUEFORMAT, s); - - } catch (AccessorConstructionException e) { - throw new ExportException(e); - } - } - - @Override - public void savePref(Variant options, Preferences contentScopeNode, Preferences workbenchScopeNode) throws ExportException { - super.savePref(options, contentScopeNode, workbenchScopeNode); - try { - RecordAccessor ra = Accessors.getAccessor(options); - String s; - - s = ExporterUtils.getUnionValue(ra, P_ITEMPLACEMENT); - ExporterUtils.setPrefString(contentScopeNode, ChartPreferences.P_ITEMPLACEMENT, s); - ExporterUtils.setPrefString(workbenchScopeNode, ChartPreferences.P_ITEMPLACEMENT, s); - - s = ExporterUtils.getUnionValue(ra, P_TIMEFORMAT); - ExporterUtils.setPrefString(contentScopeNode, ChartPreferences.P_TIMEFORMAT, s); - ExporterUtils.setPrefString(workbenchScopeNode, ChartPreferences.P_TIMEFORMAT, s); - - s = ExporterUtils.getUnionValue(ra, P_VALUEFORMAT); - ExporterUtils.setPrefString(contentScopeNode, ChartPreferences.P_VALUEFORMAT, s); - ExporterUtils.setPrefString(workbenchScopeNode, ChartPreferences.P_VALUEFORMAT, s); - - } catch (AccessorConstructionException e) { - throw new ExportException(e); - } - - } - - @Override - public void loadPref(Variant options, Preferences contentScopeNode, Preferences workbenchScopeNode) throws ExportException { - super.loadPref(options, contentScopeNode, workbenchScopeNode); - try { - RecordAccessor ra = Accessors.getAccessor(options); - - String s; - s = ExporterUtils.getPrefString(contentScopeNode, ChartPreferences.P_ITEMPLACEMENT); - if ( s==null ) s = ExporterUtils.getPrefString(workbenchScopeNode, ChartPreferences.P_ITEMPLACEMENT); - ExporterUtils.setUnionValue(ra, P_ITEMPLACEMENT, s); - - s = ExporterUtils.getPrefString(contentScopeNode, ChartPreferences.P_TIMEFORMAT); - if ( s==null ) s = ExporterUtils.getPrefString(workbenchScopeNode, ChartPreferences.P_TIMEFORMAT); - ExporterUtils.setUnionValue(ra, P_TIMEFORMAT, s); - - s = ExporterUtils.getPrefString(contentScopeNode, ChartPreferences.P_VALUEFORMAT); - if ( s==null ) s = ExporterUtils.getPrefString(workbenchScopeNode, ChartPreferences.P_VALUEFORMAT); - ExporterUtils.setUnionValue(ra, P_VALUEFORMAT, s); - - } catch (AccessorConstructionException e) { - throw new ExportException(e); - } - } - - @Override - public List validate(String contentUri, ExportContext context, Variant options) { - return Collections.emptyList(); - } - - static class ChartSettings { - - Resource chartRes; - ModelRef modelRef; - ExperimentRef experimentRef; - RunRef runRef; - HistoryManager history; - - } - -} +package org.simantics.charts.export; + +import java.awt.Graphics2D; +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.preferences.DefaultScope; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.osgi.service.prefs.Preferences; +import org.simantics.Simantics; +import org.simantics.charts.preference.ChartPreferences; +import org.simantics.charts.query.MilestoneSpecQuery; +import org.simantics.charts.query.TrendSpecQuery; +import org.simantics.databoard.Accessors; +import org.simantics.databoard.accessor.RecordAccessor; +import org.simantics.databoard.accessor.error.AccessorConstructionException; +import org.simantics.databoard.accessor.reference.ChildReference; +import org.simantics.databoard.binding.mutable.Variant; +import org.simantics.databoard.type.RecordType; +import org.simantics.databoard.type.UnionType; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.request.PossibleModel; +import org.simantics.export.core.ExportContext; +import org.simantics.export.core.error.ExportException; +import org.simantics.export.core.manager.Content; +import org.simantics.export.core.pdf.ExportPdfWriter; +import org.simantics.export.core.pdf.ExportPdfWriter.Page; +import org.simantics.export.core.util.ExportQueries; +import org.simantics.export.core.util.ExporterUtils; +import org.simantics.g2d.canvas.impl.CanvasContext; +import org.simantics.history.History; +import org.simantics.history.HistoryException; +import org.simantics.history.HistoryManager; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.experiment.IHistoryExperiment; +import org.simantics.simulation.export.ExperimentExportClass; +import org.simantics.simulation.project.ExperimentManager; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.trend.TrendInitializer; +import org.simantics.trend.configuration.ItemPlacement; +import org.simantics.trend.configuration.TimeFormat; +import org.simantics.trend.configuration.TrendSpec; +import org.simantics.trend.impl.MilestoneSpec; +import org.simantics.trend.impl.TrendNode; +import org.simantics.utils.datastructures.MapList; +import org.simantics.utils.format.ValueFormat; +import org.simantics.utils.threads.ThreadUtils; +import org.simantics.utils.threads.WorkerThread; + +public class ExportChartPDF extends ExperimentExportClass { + + public static final RecordType chartOptions; + + public static String S_CHART = "Chart"; + public static ChildReference P_ITEMPLACEMENT = ChildReference.parsePath(S_CHART+"/Item Placement"); + public static ChildReference P_TIMEFORMAT = ChildReference.parsePath(S_CHART+"/Time Format"); + public static ChildReference P_VALUEFORMAT = ChildReference.parsePath(S_CHART+"/Value Format"); + + static { + chartOptions = new RecordType(); + chartOptions.addComponent("Item Placement", UnionType.newEnum("Stacked", "Overlapping")); + chartOptions.addComponent("Time Format", UnionType.newEnum("Decimal", "Time")); + chartOptions.addComponent("Value Format", UnionType.newEnum("Currency", "Scientific", "Engineering", "Default")); + } + + @Override + public void export(List contents, + Object handle, + ExportContext ctx, + Variant options, + IProgressMonitor monitor, + MapList attachmentMap + ) throws ExportException { + + // Flush all experiments, just in case. + IExperimentManager em = Simantics.getProject().getHint( ExperimentManager.KEY_EXPERIMENT_MANAGER ); + if ( em != null ) { + for (IExperiment exp : em.getExperiments()) { + if ( exp instanceof IHistoryExperiment ) { + IHistoryExperiment he = (IHistoryExperiment) exp; + try { + he.flushHistory(); + } catch (HistoryException e) { + } + } + } + } + + final ExportPdfWriter writer = (ExportPdfWriter) handle; + final WorkerThread workerThread = new WorkerThread("Chart PDF Painter"); + workerThread.start(); + try { + + final RecordAccessor ra = Accessors.getAccessor( options ); + + // Get a list of the history managers the user has selected. + List modelRefs = ExperimentExportClass.getResult(ctx, options, true); + List charts = new ArrayList(); + + for ( Content content : contents ) { + if (monitor.isCanceled()) + throw new OperationCanceledException(); + + Resource chartRes = ctx.session.syncRequest( ExportQueries.toResource(content.url) ); + Resource model = ctx.session.syncRequest( new PossibleModel( chartRes ) ); + for (ModelRef modelRef : modelRefs) { + if ( !modelRef.resource.equals(model) ) continue; + for (ExperimentRef experimentRef : modelRef.experiments) { + for (RunRef runRef : experimentRef.runs) { + if ( runRef.historyFolder == null || !runRef.historyFolder.exists() ) continue; + HistoryManager history = History.openFileHistory( runRef.historyFolder ); + + ChartSettings cs = new ChartSettings(); + cs.history = history; + cs.modelRef = modelRef; + cs.experimentRef = experimentRef; + cs.runRef = runRef; + cs.chartRes = chartRes; + charts.add( cs ); + } + } + } + } + + + for ( final ChartSettings cs : charts ) { + UUID id = UUID.randomUUID(); + final TrendSpec trendSpec = ctx.session.syncRequest( new TrendSpecQuery( id, cs.chartRes ) ); + if ( cs.modelRef.enabledRunCount() > 1 ) { + // Add run ref to the label + trendSpec.name += " / " + cs.runRef.label; + } + + + final MilestoneSpec milestones = ctx.session.syncRequest( new MilestoneSpecQuery( cs.experimentRef.resource ) ); + //final CanvasContext cctx = new CanvasContext( workerThread ); + final ExportException[] error = new ExportException[1]; + + ThreadUtils.syncExec(workerThread, new Runnable() { + @Override + public void run() { + CanvasContext cctx = TrendInitializer.createDefaultCanvas(workerThread, cs.history, null, null, trendSpec); + Page pdfPage = null; + try { + TrendNode trend = TrendInitializer.getTrendNode( cctx ); + trend.printing = true; + + String s = ExporterUtils.getUnionValue(ra, P_ITEMPLACEMENT); + if ( s!=null ) trend.itemPlacement = ItemPlacement.valueOf(s); + s = ExporterUtils.getUnionValue(ra, P_TIMEFORMAT); + if ( s!=null ) trend.timeFormat = TimeFormat.valueOf(s); + s = ExporterUtils.getUnionValue(ra, P_VALUEFORMAT); + if ( s!=null ) trend.valueFormat = ValueFormat.valueOf(s); + + if (milestones!=null) trend.setMilestones(milestones); + + pdfPage = writer.createPage( null ); + Graphics2D g2d = pdfPage.createGraphics( true ); + try { + Rectangle2D clip = new Rectangle2D.Double(0, 0, pdfPage.getWidth(), pdfPage.getHeight()); + g2d.setClip( clip ); + g2d.scale(0.25, 0.25); + trend.autoscale(true, true); + trend.zoomOut(); + trend.layout(); + trend.render( g2d ); + } finally { + trend.cleanup(); + g2d.dispose(); + cs.history.close(); + } + } catch (ExportException e) { + error[0] = e; + } finally { + cctx.dispose(); + if ( pdfPage != null ) + try { + pdfPage.close(); + } catch (ExportException e) { + if ( error[0]==null ) error[0] = e; + } + } + } + }); + if ( error[0] != null ) throw error[0]; + + } + } catch (DatabaseException e) { + throw new ExportException( e ); + } catch (AccessorConstructionException e) { + throw new ExportException( e ); + } finally { + workerThread.stopDispatchingEvents(true); + } + + } + + + @Override + public RecordType options(ExportContext context, Collection content) throws ExportException { + RecordType options = super.options(context, content); + options.addComponent(S_CHART, chartOptions); + return options; + } + + @Override + public void fillDefaultPrefs(ExportContext ctx, Variant options) throws ExportException { + super.fillDefaultPrefs(ctx, options); + // Read from eclipse preferences + try { + RecordAccessor ra = Accessors.getAccessor(options); + Preferences instPrefs = InstanceScope.INSTANCE.getNode( ChartPreferences.P_NODE ); + Preferences defaultPrefs = DefaultScope.INSTANCE.getNode( ChartPreferences.P_NODE ); + + String s; + s = ExporterUtils.getPrefString(instPrefs, defaultPrefs, ChartPreferences.P_ITEMPLACEMENT); + ExporterUtils.setUnionValue(ra, P_ITEMPLACEMENT, s); + + s = ExporterUtils.getPrefString(instPrefs, defaultPrefs, ChartPreferences.P_TIMEFORMAT); + ExporterUtils.setUnionValue(ra, P_TIMEFORMAT, s); + + s = ExporterUtils.getPrefString(instPrefs, defaultPrefs, ChartPreferences.P_VALUEFORMAT); + ExporterUtils.setUnionValue(ra, P_VALUEFORMAT, s); + + } catch (AccessorConstructionException e) { + throw new ExportException(e); + } + } + + @Override + public void savePref(Variant options, Preferences contentScopeNode, Preferences workbenchScopeNode) throws ExportException { + super.savePref(options, contentScopeNode, workbenchScopeNode); + try { + RecordAccessor ra = Accessors.getAccessor(options); + String s; + + s = ExporterUtils.getUnionValue(ra, P_ITEMPLACEMENT); + ExporterUtils.setPrefString(contentScopeNode, ChartPreferences.P_ITEMPLACEMENT, s); + ExporterUtils.setPrefString(workbenchScopeNode, ChartPreferences.P_ITEMPLACEMENT, s); + + s = ExporterUtils.getUnionValue(ra, P_TIMEFORMAT); + ExporterUtils.setPrefString(contentScopeNode, ChartPreferences.P_TIMEFORMAT, s); + ExporterUtils.setPrefString(workbenchScopeNode, ChartPreferences.P_TIMEFORMAT, s); + + s = ExporterUtils.getUnionValue(ra, P_VALUEFORMAT); + ExporterUtils.setPrefString(contentScopeNode, ChartPreferences.P_VALUEFORMAT, s); + ExporterUtils.setPrefString(workbenchScopeNode, ChartPreferences.P_VALUEFORMAT, s); + + } catch (AccessorConstructionException e) { + throw new ExportException(e); + } + + } + + @Override + public void loadPref(Variant options, Preferences contentScopeNode, Preferences workbenchScopeNode) throws ExportException { + super.loadPref(options, contentScopeNode, workbenchScopeNode); + try { + RecordAccessor ra = Accessors.getAccessor(options); + + String s; + s = ExporterUtils.getPrefString(contentScopeNode, ChartPreferences.P_ITEMPLACEMENT); + if ( s==null ) s = ExporterUtils.getPrefString(workbenchScopeNode, ChartPreferences.P_ITEMPLACEMENT); + ExporterUtils.setUnionValue(ra, P_ITEMPLACEMENT, s); + + s = ExporterUtils.getPrefString(contentScopeNode, ChartPreferences.P_TIMEFORMAT); + if ( s==null ) s = ExporterUtils.getPrefString(workbenchScopeNode, ChartPreferences.P_TIMEFORMAT); + ExporterUtils.setUnionValue(ra, P_TIMEFORMAT, s); + + s = ExporterUtils.getPrefString(contentScopeNode, ChartPreferences.P_VALUEFORMAT); + if ( s==null ) s = ExporterUtils.getPrefString(workbenchScopeNode, ChartPreferences.P_VALUEFORMAT); + ExporterUtils.setUnionValue(ra, P_VALUEFORMAT, s); + + } catch (AccessorConstructionException e) { + throw new ExportException(e); + } + } + + @Override + public List validate(String contentUri, ExportContext context, Variant options) { + return Collections.emptyList(); + } + + static class ChartSettings { + + Resource chartRes; + ModelRef modelRef; + ExperimentRef experimentRef; + RunRef runRef; + HistoryManager history; + + } + +}