]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.charts/src/org/simantics/charts/TrendSupport.java
Navigate to substructure
[simantics/platform.git] / bundles / org.simantics.charts / src / org / simantics / charts / TrendSupport.java
1 /*******************************************************************************
2  * Copyright (c) 2012 Association for Decentralized Information Management in
3  * Industry THTH ry.
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
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.charts;
13
14 import java.io.File;
15 import java.io.FileNotFoundException;
16 import java.io.IOException;
17
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;
37
38 /**
39  * This class contains utilities for initializing history collection and makes
40  * trending of subscribed dynamic experiment data possible.
41  * 
42  * @author Tuukka Lehtonen
43  */
44 public class TrendSupport {
45
46     // Input
47     private IDynamicExperiment experiment;
48     private String workspaceDataDirectoryName;
49
50     // Internals
51     private ModelHistoryCollector historyCollector;
52     private ChartData chartData;
53
54     public TrendSupport(IDynamicExperiment experiment, String workspaceDataDirectoryName) {
55         this.experiment = experiment;
56         this.workspaceDataDirectoryName = workspaceDataDirectoryName;
57     }
58
59     public void initializeHistoryCollection(ReadGraph graph) throws DatabaseException {
60         final IProject project = Simantics.peekProject();
61         if (project == null)
62             return;
63
64         try {
65             File workarea = getExperimentDirectory(graph, experiment.getResource(), true, "result-" + experiment.getIdentifier());
66             final HistoryManager history = History.openFileHistory(workarea);
67
68             historyCollector = ModelHistoryCollector.createCollector(
69                     experiment,
70                     history,
71                     Activator.getDefault().getLog(),
72                     () ->  {
73                         CollectSubscriptions cs = new CollectSubscriptions(TrendSupport.this.experiment, 0.1);
74                         return cs;
75                     }, 
76                     () -> {
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);
81                     });
82
83             historyCollector.initialize(graph, 0, true);
84
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);
97         }
98     }
99
100     public void dispose() {
101         if (historyCollector != null) {
102             historyCollector.dispose();
103             historyCollector = null;
104         }
105         if (chartData != null) {
106             final IProject project = Simantics.peekProject();
107             if (project != null)
108                 Charts.resetChartEditorData(project, experiment.getModel(), null);
109             chartData = null;
110         }
111     }
112
113     /**
114      * @param g
115      * @param experiment
116      * @param ensureExistence
117      * @param subdirs
118      * @return
119      * @throws DatabaseException
120      * @throws IOException
121      */
122     protected File getExperimentDirectory(ReadGraph g, Resource experiment, boolean ensureExistence, String... subdirs) throws DatabaseException, IOException {
123         Resource model = g.syncRequest(new PossibleModel(experiment));
124         if (model == null)
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?");
128
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);
134
135         File experimentPath = getWorkspacePath(false, dirs);
136         if (ensureExistence)
137             ensureDirectoryExistence(experimentPath);
138
139         return experimentPath;
140     }
141
142     /**
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
146      */
147     protected static File ensureDirectoryExistence(File dir) throws IOException {
148         if (dir.exists() && !dir.isDirectory())
149             FileUtils.deleteAll(dir);
150
151         dir.mkdirs();
152         if (!dir.exists() || !dir.isDirectory())
153             throw new FileNotFoundException("Could not create directory '" + dir + "'. Out of disk space?");
154
155         return dir;
156     }
157
158     /**
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
162      *        path
163      * @return the designated path within the workspace
164      */
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]);
169
170         return finalPath.toFile();
171     }
172
173 }