1 /*******************************************************************************
2 * Copyright (c) 2012 Association for Decentralized Information Management in
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.charts;
15 import java.io.FileNotFoundException;
16 import java.io.IOException;
18 import org.eclipse.core.runtime.IPath;
19 import org.eclipse.core.runtime.Platform;
20 import org.simantics.Simantics;
21 import org.simantics.charts.editor.ChartData;
22 import org.simantics.databoard.util.URIUtil;
23 import org.simantics.db.ReadGraph;
24 import org.simantics.db.Resource;
25 import org.simantics.db.common.utils.NameUtils;
26 import org.simantics.db.exception.DatabaseException;
27 import org.simantics.db.exception.ValidationException;
28 import org.simantics.db.layer0.request.PossibleModel;
29 import org.simantics.history.History;
30 import org.simantics.history.HistoryException;
31 import org.simantics.history.HistoryManager;
32 import org.simantics.modeling.subscription.CollectSubscriptions;
33 import org.simantics.modeling.subscription.ModelHistoryCollector;
34 import org.simantics.project.IProject;
35 import org.simantics.simulation.experiment.IDynamicExperiment;
36 import org.simantics.utils.FileUtils;
39 * This class contains utilities for initializing history collection and makes
40 * trending of subscribed dynamic experiment data possible.
42 * @author Tuukka Lehtonen
44 public class TrendSupport {
47 private IDynamicExperiment experiment;
48 private String workspaceDataDirectoryName;
51 private ModelHistoryCollector historyCollector;
52 private ChartData chartData;
54 public TrendSupport(IDynamicExperiment experiment, String workspaceDataDirectoryName) {
55 this.experiment = experiment;
56 this.workspaceDataDirectoryName = workspaceDataDirectoryName;
59 public void initializeHistoryCollection(ReadGraph graph) throws DatabaseException {
60 final IProject project = Simantics.peekProject();
65 File workarea = getExperimentDirectory(graph, experiment.getResource(), true, "result-" + experiment.getIdentifier());
66 final HistoryManager history = History.openFileHistory(workarea);
68 historyCollector = ModelHistoryCollector.createCollector(
71 Activator.getDefault().getLog(),
73 CollectSubscriptions cs = new CollectSubscriptions(TrendSupport.this.experiment, 0.1);
77 // Reset chart data every time subscriptions change
78 // to make sure that trend editor react.
79 if (chartData != null)
80 Charts.resetChartEditorData(project, experiment.getModel(), chartData);
83 historyCollector.initialize(graph, 0, true);
85 // Initialize chart source to support trend viewing
86 HistoryManager historyManager = History.openFileHistory(historyCollector.getWorkarea());
87 chartData = new ChartData(experiment.getModel(), null,
88 experiment, experiment.getDatasource(), historyManager,
89 historyCollector.getCollector());
90 Charts.resetChartEditorData(project, experiment.getModel(), chartData);
91 } catch (IOException e) {
92 throw new DatabaseException(e);
93 } catch (HistoryException e) {
94 throw new DatabaseException(e);
95 } catch (InterruptedException e) {
96 throw new DatabaseException(e);
100 public void dispose() {
101 if (historyCollector != null) {
102 historyCollector.dispose();
103 historyCollector = null;
105 if (chartData != null) {
106 final IProject project = Simantics.peekProject();
108 Charts.resetChartEditorData(project, experiment.getModel(), null);
116 * @param ensureExistence
119 * @throws DatabaseException
120 * @throws IOException
122 protected File getExperimentDirectory(ReadGraph g, Resource experiment, boolean ensureExistence, String... subdirs) throws DatabaseException, IOException {
123 Resource model = g.syncRequest(new PossibleModel(experiment));
125 throw new ValidationException(
126 "Experiment '" + NameUtils.getSafeName(g, experiment)
127 + "' is not part of any model. Has the experiment been removed already? Database may also be corrupted?");
129 String[] dirs = new String[3 + subdirs.length];
130 dirs[0] = workspaceDataDirectoryName;
131 dirs[1] = "model-" + model.getResourceId();
132 dirs[2] = "experiment-" + experiment.getResourceId();
133 System.arraycopy(subdirs, 0, dirs, 3, subdirs.length);
135 File experimentPath = getWorkspacePath(false, dirs);
137 ensureDirectoryExistence(experimentPath);
139 return experimentPath;
143 * @param dir the directory that needs to be created if it does not exist
144 * @return the requested directory if created or deemed existing
145 * @throws IOException if the requested directory cannot be created
147 protected static File ensureDirectoryExistence(File dir) throws IOException {
148 if (dir.exists() && !dir.isDirectory())
149 FileUtils.deleteAll(dir);
152 if (!dir.exists() || !dir.isDirectory())
153 throw new FileNotFoundException("Could not create directory '" + dir + "'. Out of disk space?");
159 * @param escapeNames <code>true</code> to run each path segment through
160 * {@link URIUtil#encodeFilename(String)}
161 * @param relativeSegments path segments to append to the workspace root
163 * @return the designated path within the workspace
165 protected static File getWorkspacePath(boolean escapeNames, String... relativeSegments) {
166 IPath finalPath = Platform.getLocation();
167 for (int i = 0; i < relativeSegments.length; ++i)
168 finalPath = finalPath.append(escapeNames ? URIUtil.encodeFilename(relativeSegments[i]) : relativeSegments[i]);
170 return finalPath.toFile();