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