]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/Files.java
Added addFirst/After/Before + remove SCL functions for Ordered Sets
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / Files.java
1 /*******************************************************************************
2  * Copyright (c) 2010- 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.databoard;
13
14 import java.io.DataInput;
15 import java.io.DataOutput;
16 import java.io.File;
17 import java.io.FileInputStream;
18 import java.io.FileOutputStream;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.io.OutputStream;
22 import java.io.OutputStreamWriter;
23 import java.nio.ByteBuffer;
24
25 import org.simantics.databoard.accessor.error.AccessorException;
26 import org.simantics.databoard.adapter.AdaptException;
27 import org.simantics.databoard.adapter.Adapter;
28 import org.simantics.databoard.adapter.AdapterConstructionException;
29 import org.simantics.databoard.binding.Binding;
30 import org.simantics.databoard.binding.RecordBinding;
31 import org.simantics.databoard.binding.error.BindingException;
32 import org.simantics.databoard.binding.mutable.MutableVariant;
33 import org.simantics.databoard.parser.repository.DataTypeSyntaxError;
34 import org.simantics.databoard.parser.repository.DataValueRepository;
35 import org.simantics.databoard.serialization.RuntimeSerializerConstructionException;
36 import org.simantics.databoard.serialization.Serializer;
37 import org.simantics.databoard.serialization.SerializerConstructionException;
38 import org.simantics.databoard.type.Datatype;
39 import org.simantics.databoard.util.StreamUtil;
40 import org.simantics.databoard.util.binary.BinaryFile;
41 import org.simantics.databoard.util.binary.BinaryReadable;
42 import org.simantics.databoard.util.binary.ByteBufferReadable;
43 import org.simantics.databoard.util.binary.ByteBufferWriteable;
44 import org.simantics.databoard.util.binary.InputStreamReadable;
45 import org.simantics.databoard.util.binary.OutputStreamWriteable;
46 import org.simantics.databoard.util.binary.UTF8;
47
48 public class Files {
49         
50         /**
51          * Create a text file (.dbv) with a value. The file is UTF-8 encoded.  
52          * If old file exists, it is deleted.
53          * 
54          * @param file
55          * @param binding
56          * @param value
57          * @throws IOException 
58          */
59         public static void createTextFile(File file, Binding binding, Object value) 
60         throws IOException
61         {
62                 try {
63                         if (file.exists()) file.delete();
64                         file.createNewFile();
65                         
66                         String txt = binding.printValueDefinition(value, false);
67                         FileOutputStream fos = new FileOutputStream(file, false);
68                         try {
69                                 OutputStreamWriter os = new OutputStreamWriter(fos, UTF8.CHARSET);
70                                 os.append(txt);
71                                 os.flush();
72                                 os.close();
73                         } finally {
74                                 fos.close();
75                         }
76                 } catch(BindingException e) {
77                         throw new IOException(e);
78                 }
79         }
80         
81         /**
82          * Create a binary file (.dbb) with a initial value. Binary file is a variant, 
83          * there is a filetype in the header of the file.
84          * If old file exists, it is deleted.
85          * 
86          * @param file
87          * @param binding
88          * @param value
89          * @throws IOException 
90          */
91         public static void createFile(File file, Binding binding, Object value) 
92         throws IOException 
93         {
94                 if (file.exists()) file.delete();
95                 file.createNewFile();
96                 MutableVariant v = new MutableVariant(binding, value);
97                 Serializer s = Bindings.getSerializerUnchecked( Bindings.MUTABLE_VARIANT );
98                 s.serialize(v, file);
99         }
100
101         /**
102          * Create a new binary file (.dbb) with an empty value. Binary file is a variant, 
103          * there is a filetype in the header of the file.
104          * If old file exists, it is deleted.
105          * 
106          * @since 0.5
107          * @param file
108          * @throws IOException 
109          * @throws RuntimeSerializerConstructionException
110          */
111         public static void createFile(File file) throws IOException, RuntimeSerializerConstructionException  
112         {
113                 if (file.exists()) file.delete();
114                 file.createNewFile();
115                 BinaryFile bf = new BinaryFile(file);
116                 try {
117                         Binding binding = Bindings.MUTABLE_VARIANT;
118                         Object value = new MutableVariant(); 
119                         Serializer s = Bindings.getSerializerUnchecked( binding );
120                         s.serialize(bf, value);
121                 } finally {
122                         bf.close();
123                 }
124         }       
125
126         /**
127          * Create a binary file (.dbb) with empty value of given type. Binary file is a variant, 
128          * there is a filetype in the header of the file.
129          * If old file exists, it is deleted.
130          * 
131          * @param file
132          * @param type
133          * @throws IOException 
134          * @throws RuntimeSerializerConstructionException 
135          */
136         public static void createFile(File file, Datatype type) throws IOException, RuntimeSerializerConstructionException 
137         {
138                 if (file.exists()) file.delete();
139                 file.createNewFile();
140                 BinaryFile bf = new BinaryFile(file);
141                 try {
142                         Binding binding = Bindings.MUTABLE_VARIANT;
143                         Object value = binding.createDefault();
144                         Serializer s = Bindings.getSerializer( binding );
145                         s.serialize(bf, value);
146                 } catch (BindingException e) {
147                         throw new IOException(e);
148                 } catch (SerializerConstructionException e) {
149                         throw new IOException(e);
150                 } finally {
151                         bf.close();
152                 }
153         }
154         
155         
156         /**
157          * Read a text file (.dbv).   
158          * 
159          * @param file
160          * @param binding
161          * @return value
162          * @throws IOException 
163          * @throws BindingException 
164          * @throws DataTypeSyntaxError 
165          */
166         public static Object readTextFile(File file, Binding binding) 
167         throws IOException, DataTypeSyntaxError, BindingException 
168         {
169                 FileInputStream fis = new FileInputStream(file);
170                 try {
171                         byte[] data = StreamUtil.readFully(fis);
172                         String txt = new String(data, UTF8.CHARSET);
173                         DataValueRepository repo = new DataValueRepository();
174                         repo.setTypeRepository( Datatypes.datatypeRepository );
175                         return binding.parseValue(txt, repo);
176                 } finally {
177                         fis.close();
178                 }
179         }
180         
181         /**
182          * Read file type of a binary file. 
183          * 
184          * @param file
185          * @return datatype
186          * @throws IOException 
187          */
188         public static Datatype readFileType(File file) throws IOException {
189                 BinaryFile rf = new BinaryFile( file, "r" );
190                 try {
191                         Binding datatype_binding = Bindings.getBindingUnchecked( Datatype.class );
192                         return (Datatype) Bindings.getSerializerUnchecked( datatype_binding ).deserialize( rf );
193                 } finally {
194                         rf.close();
195                 }               
196         }
197         
198         /**
199          * Read a binary file into a java instance. Binary file is a variant, 
200          * there is a filetype in the header of the file. 
201          * If requested binding is not the exact binding of the file, an adapter is tried.
202          * 
203          * @param file file
204          * @param binding content binding
205          * @return instance
206          * @throws IOException 
207          */
208         public static Object readFile(File file, Binding binding) throws IOException {
209                 BinaryFile rf = new BinaryFile( file, "r" );
210                 try {
211                         Binding datatype_binding = Bindings.getBindingUnchecked( Datatype.class );
212                         Datatype type = (Datatype) Bindings.getSerializerUnchecked( datatype_binding ).deserialize( rf );
213                         
214                         if (type.equals(binding.type())) {
215                                 return Bindings.getSerializerUnchecked( binding ).deserialize(rf);
216                         } else {
217                                 try {
218                                         Binding fileContentBinding = Bindings.getMutableBinding(type);
219                                         Adapter adapter = Bindings.getAdapter(fileContentBinding, binding);
220                                         Object value = Bindings.getSerializerUnchecked( fileContentBinding ).deserialize(rf);
221                                         return adapter.adapt( value );
222                                 } catch (AdapterConstructionException e) {
223                                         throw new IOException(e);
224                                 } catch (AdaptException e) {
225                                         throw new IOException(e);
226                                 }
227                         }
228                 } finally {
229                         rf.close();
230                 }
231         }
232
233         /**
234          * Read a file to an object.
235          * 
236          * @param file
237          * @param binding
238          * @param dst
239          * @throws IOException 
240          */
241         public static void readFile(File file, RecordBinding binding, Object dst) throws IOException {
242                 BinaryFile rf = new BinaryFile( file, "r" );
243                 try {
244                         Binding datatype_binding = Bindings.getBindingUnchecked( Datatype.class );
245                         Datatype type = (Datatype) Bindings.getSerializerUnchecked( datatype_binding ).deserialize( rf );
246                         
247                         if (type.equals(binding.type())) {
248                                 Serializer s = Bindings.getSerializerUnchecked( binding ); 
249                                 s.deserializeTo(rf, dst);
250                         } else {
251                                 try {
252                                         Binding fileContentBinding = Bindings.getMutableBinding(type);
253                                         Serializer s = Bindings.getSerializerUnchecked( fileContentBinding );
254                                         Object tmpObj = s.deserialize( rf );                                    
255                                         binding.readFrom(fileContentBinding, tmpObj, dst);
256                                 } catch (BindingException e) {
257                                         throw new IOException(e);
258                                 }
259                         }
260                 } finally {
261                         rf.close();
262                 }
263         }
264         
265         /**
266          * Read input stream into a java instance. Binary file is a variant, 
267          * there is a filetype in the header of the file. If requested binding is not the 
268          * exact binding of the file, an adapter is tried.<p>
269          * 
270          * The implementation reads the inputstream fully into memory.<p>
271          * 
272          * @param is input stream
273          * @param binding content binding
274          * @return instance
275          * @throws IOException 
276          */
277         public static Object readFile(InputStream is, Binding binding) throws IOException {
278                 BinaryReadable readable = InputStreamReadable.readFully( is );
279                 Binding datatype_binding = Bindings.getBindingUnchecked( Datatype.class );
280                 Datatype type = (Datatype) Bindings.getSerializerUnchecked( datatype_binding ).deserialize( readable );
281                         
282                 if (!type.equals(binding.type())) {
283                         try {
284                                 Binding fileContentBinding = Bindings.getMutableBinding(type);
285                                 Adapter adapter = Bindings.getAdapter(fileContentBinding, binding);
286                                 Object value = Bindings.getSerializerUnchecked( fileContentBinding ).deserialize( readable );
287                                 return adapter.adapt( value );
288                         } catch (AdapterConstructionException e) {
289                                 throw new IOException(e);
290                         } catch (AdaptException e) {
291                                 throw new IOException(e);
292                         }
293                 }
294                         
295                 return Bindings.getSerializerUnchecked( binding ).deserialize( readable );
296         }
297         
298         /**
299          * Read input stream into a java instance. If requested binding is not the 
300          * exact binding of the file, an adapter is tried.
301          * 
302          * @param is input stream
303          * @param streamLength
304          * @param binding content binding
305          * @return instance
306          * @throws IOException 
307          * @throws AccessorException 
308          */
309         public static Object readFile(InputStream is, long streamLength, Binding binding) throws IOException {
310                 BinaryReadable readable = new InputStreamReadable( is, streamLength );
311                 Binding datatype_binding = Bindings.getBindingUnchecked( Datatype.class );
312                 Datatype type = (Datatype) Bindings.getSerializerUnchecked( datatype_binding ).deserialize( readable );
313                         
314                 if (!type.equals(binding.type())) {
315                         try {
316                                 Binding fileContentBinding = Bindings.getMutableBinding(type);
317                                 Adapter adapter = Bindings.getAdapter(fileContentBinding, binding);
318                                 Object value = Bindings.getSerializerUnchecked( fileContentBinding ).deserialize( readable );
319                                 return adapter.adapt( value );
320                         } catch (AdapterConstructionException e) {
321                                 throw new IOException(e);
322                         } catch (AdaptException e) {
323                                 throw new IOException(e);
324                         }
325                 }
326                         
327                 return Bindings.getSerializerUnchecked( binding ).deserialize( readable );
328         }
329
330         /**
331          * Write value as binary file (.dbb).
332          * 
333          * @param file file
334          * @param binding content binding
335          * @param value value
336          * @throws IOException 
337          */
338         public static void writeFile(File file, Binding binding, Object value) throws IOException {
339                 BinaryFile rf = new BinaryFile( file );
340                 try {
341                         MutableVariant v = new MutableVariant(binding, value);
342                         Serializer s = Bindings.getSerializerUnchecked( Bindings.MUTABLE_VARIANT );
343                         s.serialize(rf, v);
344                 } finally {
345                         rf.close();
346                 }
347         }       
348
349         public static DataInput openInput( InputStream is )
350         {
351                 return new InputStreamReadable(is, Long.MAX_VALUE);
352         }
353         
354         public static DataInput openInput( File file ) throws IOException
355         {
356                 return new BinaryFile(file, "r");
357         }
358         
359         public static DataInput openInput( byte[] data ) 
360         {
361                 ByteBuffer buffer = ByteBuffer.wrap( data );
362                 return new ByteBufferReadable( buffer );
363         }
364         
365         public static DataOutput openOutput( OutputStream os )
366         {
367                 return new OutputStreamWriteable( os );
368         }
369         
370         public static DataOutput openOutput( File file ) throws IOException
371         {
372                 return new BinaryFile( file );
373         }
374         
375         public static DataOutput openOutput( byte[] data ) throws IOException
376         {
377                 ByteBuffer buffer = ByteBuffer.wrap( data );
378                 return new ByteBufferWriteable( buffer );
379         }       
380
381 }
382