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