]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.common/src/org/simantics/db/common/utils/LiteralFileUtil.java
ListUtils.create(g,elements) creates a list without element inverses
[simantics/platform.git] / bundles / org.simantics.db.common / src / org / simantics / db / common / utils / LiteralFileUtil.java
1 package org.simantics.db.common.utils;
2
3 import java.io.File;
4 import java.io.FileInputStream;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.io.OutputStream;
9 import java.nio.ByteBuffer;
10 import java.nio.channels.FileChannel;
11 import java.util.Arrays;
12
13 import org.simantics.databoard.Bindings;
14 import org.simantics.databoard.Files;
15 import org.simantics.databoard.binding.Binding;
16 import org.simantics.databoard.serialization.Serializer;
17 import org.simantics.databoard.type.Datatype;
18 import org.simantics.databoard.util.binary.RandomAccessBinary;
19 import org.simantics.db.ReadGraph;
20 import org.simantics.db.Resource;
21 import org.simantics.db.WriteGraph;
22 import org.simantics.db.exception.DatabaseException;
23 import org.simantics.layer0.Layer0;
24
25 /**
26  * Converts byte[] literals to files and back. These utilities are not usable
27  * for literals of any other type than byte[].
28  */
29 public class LiteralFileUtil {
30
31     public static void copyByteArrayToFile(ReadGraph g, Resource source, File target) throws DatabaseException, IOException {
32         byte[] data = g.getValue(source, Bindings.BYTE_ARRAY);
33         OutputStream stream = new FileOutputStream(target);
34         try {
35             // TODO: For some peculiar reason a direct stream.write(data) OOMs with approx. 70MB array
36             for(int pos = 0;pos < data.length;) {
37                 int len = Math.min(65536, data.length-pos);
38                 stream.write(data,pos,len);
39                 pos += len;
40             }
41         } finally {
42             stream.close();
43         }
44     }
45     
46     public static void copyByteArrayToFile(ReadGraph g, Resource subject, Resource predicate, File target) throws DatabaseException, IOException {
47         Resource source = g.getSingleObject(subject, predicate);
48         copyByteArrayToFile(g, source, target);
49     }
50
51     public static void copyRandomAccessBinaryToFile(ReadGraph g, Resource source, File target) throws DatabaseException, IOException {
52         OutputStream stream = new FileOutputStream(target);
53         try {
54             RandomAccessBinary rab = g.getRandomAccessBinary(source);
55             // Skip byte array length data according to databoard byte[] serialization rules.
56             rab.position(4);
57             ByteBuffer bb =  ByteBuffer.wrap(new byte[65536]);
58             byte[] bbArray = bb.array();
59             while (rab.position() < rab.length()) {
60                 rab.readFully(bb, (int) Math.min(bbArray.length, rab.length() - rab.position()));
61                 stream.write(bbArray, 0, bb.position());
62                 bb.position(0);
63             }
64         } finally {
65             stream.close();
66         }
67     }
68
69     public static void copyRandomAccessBinaryFromFile(File source, RandomAccessBinary rab) throws IOException {
70         ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[65536]);
71
72         FileInputStream stream = new FileInputStream(source);
73         FileChannel channel = stream.getChannel();
74
75         try {
76             rab.position(0);
77             rab.writeInt((int)source.length());
78             while(channel.read(byteBuffer) != -1) {
79                 byteBuffer.limit(byteBuffer.position());
80                 byteBuffer.position(0);
81                 rab.writeFully(byteBuffer);
82                 byteBuffer.position(0);
83             }
84         } finally {
85             stream.close();
86         }
87
88         // Make sure the RAB file will not be longer than the
89         // source file due to possible previously existing data.
90         rab.setLength(rab.position());
91         rab.flush();
92     }
93
94
95     public static void copyRandomAccessBinaryToFile(ReadGraph g, Resource subject, Resource predicate, File target) throws DatabaseException, IOException {
96         Resource source = g.getSingleObject(subject, predicate);
97         copyRandomAccessBinaryToFile(g, source, target);
98     }
99
100     public static void copyToFileWithBinding(ReadGraph g, Resource source, File target, Binding binding) throws DatabaseException, IOException {
101         // Datatyyppi tieto on jo resurssissa, eik�? 
102         // Sidonnan saisi Bindings.getBinding( type )
103         Object value = g.getValue(source, binding);
104         Serializer s = Bindings.getSerializerUnchecked(binding);
105         s.serialize(value, target);
106     }
107
108     public static void copyToFileWithBinding(ReadGraph g, Resource subject, Resource predicate, File target, Binding binding) throws DatabaseException, IOException {
109         Resource source = g.getSingleObject(subject, predicate);
110         copyToFileWithBinding(g, source, target, binding);
111     }
112
113     public static void copyToFileAsVariant(ReadGraph g, Resource source, File target, Binding binding) throws DatabaseException, IOException {
114         Object value = g.getValue(source, binding);
115         Files.createFile(target, binding, value);
116     }
117
118     public static void copyToFileAsVariant(ReadGraph g, Resource source, File target) throws DatabaseException, IOException {
119         Datatype type = g.getDataType(source);
120         Binding binding = Bindings.getBinding(type);
121         copyToFileAsVariant(g, source, target, binding);
122     }
123
124     public static void copyToFileAsVariant(ReadGraph g, Resource subject, Resource predicate, File target) throws DatabaseException, IOException {
125         Resource source = g.getSingleObject(subject, predicate);
126         copyToFileAsVariant(g, source, target);
127     }
128
129     public static void copyByteArrayFromFile(WriteGraph g, File source, Resource target) throws DatabaseException, IOException {
130         InputStream stream = new FileInputStream(source);
131         byte[] data = new byte[(int)source.length()];
132         stream.read(data);
133         stream.close();
134         g.claimValue(target, data, Bindings.BYTE_ARRAY);
135     }
136
137     public static void copyByteArrayFromFile(WriteGraph g, File source, Resource subject, Resource predicate) throws DatabaseException, IOException {
138         InputStream stream = new FileInputStream(source);
139         byte[] data = new byte[(int)source.length()];
140         stream.read(data);
141         stream.close();
142         g.claimLiteral(subject, predicate, data, Bindings.BYTE_ARRAY);
143     }
144
145     /**
146      * @param g
147      * @param source
148      * @param subject
149      * @param predicate
150      * @throws DatabaseException
151      * @throws IOException
152      */
153     public static void streamingCopyByteArrayFromFile(WriteGraph g, File source, Resource subject, Resource predicate) throws DatabaseException, IOException {
154         Resource target = g.getPossibleObject(subject, predicate);
155         if (target == null) {
156             Layer0 L0 = Layer0.getInstance(g);
157             target = g.newResource();
158             g.claim(target, L0.InstanceOf, null, L0.ByteArray);
159             g.claim(subject, predicate, target);
160         }
161         InputStream stream = new FileInputStream(source);
162         try {
163             copyStreamToRandomAccessBinary(g, stream, target);
164         } finally {
165             stream.close();
166         }
167     }
168
169     public static void copyByteArrayFromStream(WriteGraph g, InputStream source, Resource target) throws IOException, DatabaseException {
170         byte[] buffer = new byte[0x10000];
171         int pos = 0;
172         while(true) {
173             int count = source.read(buffer, pos, buffer.length - pos);
174             if(count <= 0)
175                 break;
176             pos += count;
177             if(pos == buffer.length)
178                 buffer = Arrays.copyOf(buffer, (pos * 3) / 2);
179         }
180         buffer = Arrays.copyOf(buffer, pos);
181         g.claimValue(target, buffer, Bindings.BYTE_ARRAY);
182     }
183
184     public static void copyStreamToRandomAccessBinary(WriteGraph g, InputStream source, Resource target) throws IOException, DatabaseException {
185         RandomAccessBinary rab = g.getRandomAccessBinary(target);
186         byte[] buffer = new byte[0x10000];
187         if (rab.length() < 4)
188             rab.setLength(4);
189         rab.position(4);
190         int length = 0;
191         while (true) {
192             int count = source.read(buffer, 0, buffer.length);
193             if (count <= 0)
194                 break;
195             rab.write(buffer, 0, count);
196             length += count;
197         }
198         rab.position(0);
199         rab.writeInt(length);
200         rab.flush();
201     }
202
203 }