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%2Fui%2FCSVExporter.java;h=9798b57f2c63db2057656f233bca6ce9799924c4;hp=91c8b201fd4ca491e5443676ee7a66b0338125b9;hb=bf39e5c2544ec6e60d4e68996a6a7d4a84b30950;hpb=969bd23cab98a79ca9101af33334000879fb60c5 diff --git a/bundles/org.simantics.charts/src/org/simantics/charts/ui/CSVExporter.java b/bundles/org.simantics.charts/src/org/simantics/charts/ui/CSVExporter.java index 91c8b201f..9798b57f2 100644 --- a/bundles/org.simantics.charts/src/org/simantics/charts/ui/CSVExporter.java +++ b/bundles/org.simantics.charts/src/org/simantics/charts/ui/CSVExporter.java @@ -1,218 +1,200 @@ -/******************************************************************************* - * Copyright (c) 2012 Association for Decentralized Information Management in - * Industry THTH ry. - * 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: - * VTT Technical Research Centre of Finland - initial API and implementation - *******************************************************************************/ -package org.simantics.charts.ui; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.io.RandomAccessFile; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.core.runtime.preferences.IScopeContext; -import org.eclipse.core.runtime.preferences.InstanceScope; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.osgi.service.prefs.BackingStoreException; -import org.osgi.service.prefs.Preferences; -import org.simantics.Simantics; -import org.simantics.charts.Activator; -import org.simantics.charts.editor.ChartData; -import org.simantics.charts.editor.ChartKeys; -import org.simantics.databoard.binding.error.BindingException; -import org.simantics.databoard.serialization.SerializationException; -import org.simantics.db.ReadGraph; -import org.simantics.db.Resource; -import org.simantics.db.Session; -import org.simantics.db.common.NamedResource; -import org.simantics.db.common.request.UniqueRead; -import org.simantics.db.common.utils.Logger; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.layer0.request.PossibleModel; -import org.simantics.history.HistoryException; -import org.simantics.history.csv.CSVFormatter; -import org.simantics.modeling.preferences.CSVPreferences; -import org.simantics.utils.datastructures.hints.IHintContext.Key; -import org.simantics.utils.format.FormattingUtils; -import org.simantics.utils.ui.dialogs.ShowMessage; - -/** - * @author Antti Villberg - */ -public class CSVExporter implements IRunnableWithProgress { - - CSVExportPlan exportModel; - - public CSVExporter(CSVExportPlan exportModel) { - this.exportModel = exportModel; - } - - @Override - public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - SubMonitor progress = SubMonitor.convert(monitor, 50); - try { - exportModel(progress.newChild(50, SubMonitor.SUPPRESS_NONE)); - } catch (IOException e) { - throw new InvocationTargetException(e); - } catch (DatabaseException e) { - throw new InvocationTargetException(e); - } catch (BindingException e) { - throw new InvocationTargetException(e); - } finally { - monitor.done(); - } - } - - void exportModel(SubMonitor mon) throws IOException, DatabaseException, SerializationException, BindingException{ - - try { - doExport(mon, exportModel.exportLocation, exportModel); - } catch (ExecutionException e) { - e.printStackTrace(); - Logger.defaultLogError(e); - mon.setCanceled(true); - ShowMessage.showError("Export failed.", "Internal application error in export. See log for details."); - } finally { - mon.setWorkRemaining(0); - } - - } - - private static Set resolveContainingModels(final Collection res) throws DatabaseException { - return Simantics.getSession().syncRequest(new UniqueRead>() { - @Override - public Set perform(ReadGraph graph) throws DatabaseException { - Set models = new HashSet(); - for (NamedResource r : res) { - Resource m = graph.syncRequest(new PossibleModel(r.getResource())); - if (m != null) - models.add(m); - } - return models; - } - }); - } - - public static void doExport(IProgressMonitor monitor, final File f, final CSVExportPlan plan) throws ExecutionException, IOException { - - IScopeContext context = InstanceScope.INSTANCE; - Preferences node = context.getNode(CSVPreferences.P_NODE); - - node.putDouble(CSVPreferences.P_CSV_START_TIME, plan.startTime); - node.putDouble(CSVPreferences.P_CSV_TIME_STEP, plan.timeStep); - node.put(CSVPreferences.P_CSV_DECIMAL_SEPARATOR, plan.decimalSeparator.toPreference()); - node.put(CSVPreferences.P_CSV_COLUMN_SEPARATOR, plan.columnSeparator.toPreference()); - - node.putBoolean(CSVPreferences.P_CSV_RESAMPLE, plan.resample); - node.put(CSVPreferences.P_CSV_SAMPLING_MODE, plan.samplingMode.toPreference()); - - node.putInt(CSVPreferences.P_CSV_TIME_DIGITS, plan.timeDigits); - node.putInt(CSVPreferences.P_CSV_FLOAT_DIGITS, plan.floatDigits); - node.putInt(CSVPreferences.P_CSV_DOUBLE_DIGITS, plan.doubleDigits); - - try { - node.flush(); - } catch (BackingStoreException ex) { - Activator.getDefault().getLog().log( - new Status(IStatus.WARNING, Activator.PLUGIN_ID, "Could not store preferences for node " + node.absolutePath())); - } - - Set models; - try { - models = resolveContainingModels(plan.models); - } catch (DatabaseException e3) { - throw new ExecutionException("Containing model resolution failed.", e3); - } - if (models.isEmpty()) - throw new ExecutionException("Selected resources are not part of any model"); - if (models.size() > 1) - throw new ExecutionException("Selected resources are part of several models, only subscriptions from a single model can be selected"); - Resource model = models.iterator().next(); - Key chartDataKey = ChartKeys.chartSourceKey(model); - - final ChartData data = Simantics.getProject().getHint(chartDataKey); - if ( data == null ) { - throw new ExecutionException("There is no "+chartDataKey); - } - if ( data.history == null ) { - throw new ExecutionException("There is no history in "+chartDataKey); - } - - final CSVFormatter csv = new CSVFormatter(); - - csv.setStartTime( plan.startTime ); - csv.setTimeStep( plan.timeStep ); - csv.setDecimalSeparator( plan.decimalSeparator ); - csv.setColumnSeparator( plan.columnSeparator ); - csv.setResample( plan.resample ); - csv.setNumberInterpolation( plan.samplingMode ); - csv.setTimeFormat( FormattingUtils.significantDigitFormat( plan.timeDigits ) ); - csv.setFloatFormat( FormattingUtils.significantDigitFormat( plan.floatDigits ) ); - csv.setNumberFormat( FormattingUtils.significantDigitFormat( plan.doubleDigits ) ); - - try { - Session session = Simantics.getSession(); - List list = new ArrayList(); - for(NamedResource nr : plan.models) list.add(nr.getResource()); - session.sync( new CSVParamsQuery(data.history, csv, list) ); - csv.sort(); - } catch (DatabaseException e2) { - throw new ExecutionException(e2.getMessage(), e2); - } catch (HistoryException e) { - throw new ExecutionException(e.getMessage(), e); - } - - try { - // Ensure all views are built. - monitor.beginTask("Exporting Time Series as CSV...", IProgressMonitor.UNKNOWN); - try { - data.collector.flush(); - if ( !f.exists() ) { - f.createNewFile(); - } else { - RandomAccessFile raf = new RandomAccessFile(f, "rw"); - raf.setLength(0); - raf.close(); - } - - FileOutputStream fos = new FileOutputStream(f, true); - BufferedOutputStream bos = new BufferedOutputStream( fos ); - try { - PrintStream ps = new PrintStream( bos ); - csv.formulate2( new CSVProgressMonitor( monitor ), ps ); - bos.flush(); - } finally { - fos.close(); - } - } catch (HistoryException e) { - throw new ExecutionException(e.getMessage(), e); - } catch (IOException e1) { - throw new ExecutionException(e1.getMessage(), e1); - } - monitor.setTaskName("Done"); - } finally { - monitor.done(); - } - - } - -} +/******************************************************************************* + * Copyright (c) 2012,2017 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.charts.ui; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.io.RandomAccessFile; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.core.runtime.preferences.IScopeContext; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.osgi.service.prefs.BackingStoreException; +import org.osgi.service.prefs.Preferences; +import org.simantics.Simantics; +import org.simantics.charts.Activator; +import org.simantics.charts.editor.ChartData; +import org.simantics.charts.editor.ChartKeys; +import org.simantics.databoard.binding.error.BindingException; +import org.simantics.databoard.serialization.SerializationException; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.UniqueRead; +import org.simantics.db.common.utils.Logger; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.request.PossibleModel; +import org.simantics.history.HistoryException; +import org.simantics.history.csv.CSVFormatter; +import org.simantics.modeling.preferences.CSVPreferences; +import org.simantics.utils.datastructures.hints.IHintContext.Key; +import org.simantics.utils.format.FormattingUtils; +import org.simantics.utils.ui.dialogs.ShowMessage; + +/** + * @author Antti Villberg + */ +public class CSVExporter implements IRunnableWithProgress { + + CSVExportPlan exportModel; + + public CSVExporter(CSVExportPlan exportModel) { + this.exportModel = exportModel; + } + + @Override + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + SubMonitor progress = SubMonitor.convert(monitor, 50); + try { + exportModel(progress.newChild(50, SubMonitor.SUPPRESS_NONE)); + } catch (IOException e) { + throw new InvocationTargetException(e); + } catch (DatabaseException e) { + throw new InvocationTargetException(e); + } catch (BindingException e) { + throw new InvocationTargetException(e); + } finally { + monitor.done(); + } + } + + void exportModel(SubMonitor mon) throws IOException, DatabaseException, SerializationException, BindingException{ + try { + doExport(mon, exportModel.exportLocation, exportModel); + } catch (ExecutionException e) { + e.printStackTrace(); + Logger.defaultLogError(e); + mon.setCanceled(true); + ShowMessage.showError("Export failed.", "Internal application error in export. See log for details."); + } finally { + mon.setWorkRemaining(0); + } + } + + private static Set resolveContainingModels(Collection res) throws DatabaseException { + return Simantics.getSession().syncRequest(new UniqueRead>() { + @Override + public Set perform(ReadGraph graph) throws DatabaseException { + Set models = new HashSet<>(); + for (Resource r : res) { + Resource m = graph.syncRequest(new PossibleModel(r)); + if (m != null) + models.add(m); + } + return models; + } + }); + } + + public static void doExport(IProgressMonitor monitor, final File f, final CSVExportPlan plan) throws ExecutionException, IOException { + IScopeContext context = InstanceScope.INSTANCE; + Preferences node = context.getNode(CSVPreferences.P_NODE); + + node.putDouble(CSVPreferences.P_CSV_START_TIME, plan.startTime); + node.putDouble(CSVPreferences.P_CSV_TIME_STEP, plan.timeStep); + node.put(CSVPreferences.P_CSV_DECIMAL_SEPARATOR, plan.decimalSeparator.toPreference()); + node.put(CSVPreferences.P_CSV_COLUMN_SEPARATOR, plan.columnSeparator.toPreference()); + + node.putBoolean(CSVPreferences.P_CSV_RESAMPLE, plan.resample); + node.put(CSVPreferences.P_CSV_SAMPLING_MODE, plan.samplingMode.toPreference()); + + node.putInt(CSVPreferences.P_CSV_TIME_DIGITS, plan.timeDigits); + node.putInt(CSVPreferences.P_CSV_FLOAT_DIGITS, plan.floatDigits); + node.putInt(CSVPreferences.P_CSV_DOUBLE_DIGITS, plan.doubleDigits); + + try { + node.flush(); + } catch (BackingStoreException ex) { + Activator.getDefault().getLog().log( + new Status(IStatus.WARNING, Activator.PLUGIN_ID, "Could not store preferences for node " + node.absolutePath())); + } + + Set models; + try { + models = resolveContainingModels(plan.items); + } catch (DatabaseException e3) { + throw new ExecutionException("Containing model resolution failed.", e3); + } + if (models.isEmpty()) + throw new ExecutionException("Selected resources are not part of any model"); + if (models.size() > 1) + throw new ExecutionException("Selected resources are part of several models, only subscriptions from a single model can be selected"); + Resource model = models.iterator().next(); + Key chartDataKey = ChartKeys.chartSourceKey(model); + + final ChartData data = Simantics.getProject().getHint(chartDataKey); + if ( data == null ) { + throw new ExecutionException("There is no "+chartDataKey); + } + if ( data.history == null ) { + throw new ExecutionException("There is no history in "+chartDataKey); + } + + final CSVFormatter csv = new CSVFormatter(); + + csv.setStartTime( plan.startTime ); + csv.setTimeStep( plan.timeStep ); + csv.setDecimalSeparator( plan.decimalSeparator ); + csv.setColumnSeparator( plan.columnSeparator ); + csv.setResample( plan.resample ); + csv.setNumberInterpolation( plan.samplingMode ); + csv.setTimeFormat( FormattingUtils.significantDigitFormat( plan.timeDigits ) ); + csv.setFloatFormat( FormattingUtils.significantDigitFormat( plan.floatDigits ) ); + csv.setNumberFormat( FormattingUtils.significantDigitFormat( plan.doubleDigits ) ); + + try { + Simantics.getSession().syncRequest( + new CSVParamsQuery(data.history, csv, + new ArrayList<>(plan.items)) ); + csv.sort(); + + // Ensure all views are built. + monitor.beginTask("Exporting Time Series as CSV...", IProgressMonitor.UNKNOWN); + data.collector.flush(); + + // Truncate existing file it if happens to exist. + try (RandomAccessFile raf = new RandomAccessFile(f, "rw")) { + raf.setLength(0); + } + + // Write CSV + try (PrintStream ps = new PrintStream( + new BufferedOutputStream( + new FileOutputStream(f, true) ))) + { + csv.formulate2( new CSVProgressMonitor( monitor ), ps ); + ps.flush(); + } + + monitor.setTaskName("Done"); + } catch (DatabaseException e2) { + throw new ExecutionException(e2.getMessage(), e2); + } catch (HistoryException e) { + throw new ExecutionException(e.getMessage(), e); + } finally { + monitor.done(); + } + } + +}