]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.history/src/org/simantics/history/util/HistoryExportUtil.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.history / src / org / simantics / history / util / HistoryExportUtil.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.history.util;\r
13 \r
14 import java.io.IOException;\r
15 import java.io.InputStream;\r
16 import java.io.OutputStream;\r
17 import java.math.BigDecimal;\r
18 import java.math.MathContext;\r
19 import java.util.ArrayList;\r
20 import java.util.List;\r
21 \r
22 import org.simantics.databoard.Bindings;\r
23 import org.simantics.databoard.accessor.StreamAccessor;\r
24 import org.simantics.databoard.accessor.error.AccessorException;\r
25 import org.simantics.databoard.binding.Binding;\r
26 import org.simantics.databoard.binding.RecordBinding;\r
27 import org.simantics.databoard.binding.error.BindingException;\r
28 import org.simantics.databoard.binding.mutable.Variant;\r
29 import org.simantics.databoard.serialization.Serializer;\r
30 import org.simantics.databoard.serialization.SerializerConstructionException;\r
31 import org.simantics.databoard.type.Datatype;\r
32 import org.simantics.databoard.util.Bean;\r
33 import org.simantics.databoard.util.binary.BinaryReadable;\r
34 import org.simantics.databoard.util.binary.InputStreamReadable;\r
35 import org.simantics.history.HistoryAndCollectorItem;\r
36 import org.simantics.history.HistoryException;\r
37 import org.simantics.history.HistoryManager;\r
38 \r
39 /**\r
40  * Util for import/export.\r
41  * \r
42  * @author toni.kalajainen\r
43  */\r
44 public class HistoryExportUtil {\r
45 \r
46         Binding beanArrayBinding = Bindings.getBindingUnchecked(Bean[].class);\r
47         Serializer beanArraySerializer = Bindings.getSerializerUnchecked( beanArrayBinding );\r
48         \r
49         Serializer intSerializer = Bindings.getSerializerUnchecked( Bindings.INTEGER );\r
50         \r
51         /**\r
52          * Export history to an output stream.\r
53          * \r
54          * @param history\r
55          * @param timeBinding\r
56          * @param from\r
57          * @param end\r
58          * @param out\r
59          * @throws IOException\r
60          * @throws HistoryException\r
61          */\r
62         public void exportHistory( HistoryManager history, Binding timeBinding, Object from, Object end, OutputStream out )\r
63         throws IOException, HistoryException\r
64         {\r
65                 try {\r
66                         Bean[] items = history.getItems();\r
67                         // Serialize items as Variants\r
68                         beanArraySerializer.serialize(out, items);\r
69                         for (Bean item : items) {\r
70                                 Datatype format = (Datatype) item.getField("format");\r
71                                 String id = (String) item.getField("id");\r
72                                 RecordBinding sampleBinding = Bindings.getBinding( format );\r
73                                 Serializer sampleSerializer = Bindings.getSerializer(sampleBinding);\r
74                                 Object sample = sampleBinding.createDefault();\r
75                                 StreamAccessor sa = history.openStream(id, "r");\r
76                                 Stream stream = new Stream(sa, sampleBinding);\r
77                                 try {\r
78                                         // Start index\r
79                                         int startIndex = stream.binarySearch(Bindings.DOUBLE, from);                                            \r
80                                         if ( startIndex < -stream.count() ) {\r
81                                                 intSerializer.serialize(0, out);\r
82                                                 continue;\r
83                                         }\r
84                                         if ( startIndex<0 ) startIndex = -2-startIndex;\r
85                                         if ( startIndex == -1 ) startIndex = 0;\r
86                                                 \r
87                                         // End index\r
88                                         int endIndex = stream.binarySearch(Bindings.DOUBLE, end);\r
89                                         if ( endIndex == -1 ) {\r
90                                                 intSerializer.serialize(0, out);\r
91                                                 continue;\r
92                                         }\r
93                                         if ( endIndex<0 ) endIndex = -1-endIndex;\r
94                                         if ( endIndex == sa.size() ) endIndex = sa.size()-1;\r
95                                         if ( endIndex<startIndex ) {\r
96                                                 intSerializer.serialize(0, out);\r
97                                                 continue;\r
98                                         }\r
99                                                 \r
100                                         // Write sample count\r
101                                         int count = endIndex - startIndex + 1;\r
102                                         intSerializer.serialize(count, out);\r
103                                                 \r
104                                         for (int i=0; i<count; i++) {\r
105                                                 // Read sample\r
106                                                 sa.get(i, sampleBinding, sample);\r
107                                                 sampleSerializer.serialize(sample, out);\r
108                                         }                                               \r
109                                 } finally {\r
110                                         sa.close();\r
111                                 } \r
112                         }\r
113                 } catch (AccessorException ae) {\r
114                         throw new HistoryException( ae );\r
115                 } catch (BindingException e) {\r
116                         throw new HistoryException( e );\r
117                 } catch (SerializerConstructionException e) {\r
118                         throw new HistoryException( e );\r
119                 }\r
120         }\r
121         \r
122         /**\r
123          * Import history from input stream \r
124          * \r
125          * @param history\r
126          * @param is\r
127          * @throws IOException\r
128          * @throws HistoryException\r
129          */\r
130         public void importHistory( HistoryManager history, InputStream is )\r
131         throws IOException, HistoryException\r
132         {               \r
133                 try {\r
134                         List<Object> ids = new ArrayList<Object>();\r
135                         BinaryReadable in = new InputStreamReadable( is, Long.MAX_VALUE );\r
136                         Bean[] items = (Bean[]) beanArraySerializer.deserialize( in );\r
137                         for (Bean item : items) {\r
138                                 StreamAccessor sa = null;\r
139                                 try {\r
140                                         Datatype format = (Datatype) item.getField("format");\r
141                                         String id = (String) item.getField("id");\r
142                                         history.create(item);\r
143                                         RecordBinding sampleBinding = Bindings.getBinding( format );\r
144                                         Serializer sampleSerializer = Bindings.getSerializer(sampleBinding);\r
145                                         Object sample = sampleBinding.createDefault();\r
146                                         sa = history.openStream(id, "rw");\r
147                                         int count = (Integer) intSerializer.deserialize(in);\r
148                                         ids.clear();\r
149                                         for (int i=0; i<count; i++) {\r
150                                                 sample = sampleSerializer.deserializeToTry(in, ids, sample);\r
151                                                 sa.add(sampleBinding, sample);\r
152                                         }\r
153                                 }\r
154                                 finally {\r
155                                         try {\r
156                                                 if (sa != null)\r
157                                                         sa.close();\r
158                                         } catch (AccessorException e) {\r
159                                         }\r
160                                 }\r
161                         }\r
162                 } catch (AccessorException ae) {\r
163                         throw new HistoryException( ae );\r
164                 } catch (BindingException e) {\r
165                         throw new HistoryException( e );\r
166                 } catch (SerializerConstructionException e) {\r
167                         throw new HistoryException( e );\r
168                 }\r
169         }\r
170         \r
171         /**\r
172          * An export of the history \r
173          */\r
174         static public class HistoryExport {\r
175                 public HistoryAndCollectorItem[] subscriptionItems;\r
176                 public Variant[] items;\r
177                 /* Variant = {\r
178                                 int count;\r
179                                 Sample[] samples;\r
180                        }\r
181                  */\r
182         }\r
183         \r
184         private static MathContext mc = new MathContext(15); \r
185 \r
186         /**\r
187          * Performs a linear interpolation with the specified times and values.\r
188          * @param t1\r
189          * @param v1\r
190          * @param t2\r
191          * @param v2\r
192          * @param ts\r
193          * @return\r
194          */\r
195         public static double biglerp(double t1, double v1, double t2, double v2, double ts) {\r
196                 assert (t1 < ts) && (ts < t2);\r
197 \r
198                 // #11585: Safety for Inf/NaN numbers.\r
199                 // BigDecimal throws NumberFormatException for non-finite values.\r
200                 if (!Double.isFinite(v1) || !Double.isFinite(v2)) {\r
201                         double d1 = ts-t1;\r
202                         double d2 = t2-ts;\r
203                         return (d1 > d2) ? v1 : v2;\r
204                 }\r
205 \r
206                 BigDecimal T1 = new BigDecimal(-t1, mc);\r
207                 BigDecimal T2 = new BigDecimal(t2, mc);\r
208                 BigDecimal TS = new BigDecimal(ts, mc);\r
209                 BigDecimal T = (TS.add(T1, mc)).divide(T2.add(T1, mc), mc);\r
210 \r
211                 BigDecimal V1 = new BigDecimal(v1, mc);\r
212                 BigDecimal V2 = new BigDecimal(v2, mc);\r
213                 BigDecimal VS = V1.add(V2.subtract(V1, mc).multiply(T, mc), mc);\r
214 \r
215                 return VS.doubleValue();\r
216         }\r
217         \r
218     public static boolean contains(StreamIterator iter, double time) {\r
219         double start = iter.getStartTime();\r
220         double end = iter.getEndTime();\r
221         // A special case, where start == end => accept\r
222         if(time == start) return true;\r
223         else if(time < start) return false;\r
224         else if(time >= end) return false;\r
225         else return true;\r
226     }\r
227 \r
228 }\r