]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.acorn/src/org/simantics/acorn/HeadState1.java
Merge branch 'feature/funcwrite'
[simantics/platform.git] / bundles / org.simantics.acorn / src / org / simantics / acorn / HeadState1.java
1 package org.simantics.acorn;
2
3 import java.io.ByteArrayInputStream;
4 import java.io.IOException;
5 import java.io.OutputStream;
6 import java.nio.file.Files;
7 import java.nio.file.Path;
8 import java.security.MessageDigest;
9 import java.security.NoSuchAlgorithmException;
10 import java.util.ArrayList;
11 import java.util.Arrays;
12
13 import org.simantics.acorn.exception.InvalidHeadStateException;
14 import org.simantics.databoard.Bindings;
15 import org.simantics.databoard.binding.mutable.MutableVariant;
16 import org.simantics.databoard.serialization.Serializer;
17 import org.simantics.databoard.util.binary.BinaryMemory;
18
19 public class HeadState1 {
20
21     public static final String HEAD_STATE = "head.state";
22     public static final String SHA_1 = "SHA-1";
23     
24     public int headChangeSetId = 0;
25     public long transactionId = 1;
26     public long reservedIds = 3;
27
28     public ArrayList<String> clusters = new ArrayList<>();
29     public ArrayList<String> files = new ArrayList<>();
30     public ArrayList<String> stream = new ArrayList<>();
31     public ArrayList<String> cs = new ArrayList<>();
32     
33     public HeadState migrate() {
34         HeadState state = new HeadState();
35         state.headChangeSetId = headChangeSetId;
36         state.transactionId = transactionId;
37         state.reservedIds = reservedIds;
38         state.clusters = clusters;
39         state.files = files;
40         state.stream = stream;
41         state.cs = cs;
42         return state;
43     }
44
45     public static HeadState1 load(Path directory) throws InvalidHeadStateException {
46         Path f = directory.resolve(HEAD_STATE);
47         
48         try {
49             byte[] bytes = Files.readAllBytes(f);
50             MessageDigest sha1 = MessageDigest.getInstance(SHA_1);
51             int digestLength = sha1.getDigestLength();
52             
53             sha1.update(bytes, digestLength, bytes.length - digestLength);
54             byte[] newChecksum = sha1.digest();
55             if (!Arrays.equals(newChecksum, Arrays.copyOfRange(bytes, 0, digestLength))) {
56                 throw new InvalidHeadStateException(
57                         "Checksum " + Arrays.toString(newChecksum) + " does not match excpected "
58                                 + Arrays.toString(Arrays.copyOfRange(bytes, 0, digestLength)) + " for " + f.toAbsolutePath());
59             }
60             try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes, digestLength, bytes.length - digestLength)) {
61                 HeadState1 object = (HeadState1) org.simantics.databoard.Files.readFile(bais, Bindings.getBindingUnchecked(HeadState1.class));
62                 return object;
63             }
64         } catch (IOException i) {
65             return new HeadState1();
66         } catch (NoSuchAlgorithmException e) {
67             throw new Error("SHA-1 Algorithm not found", e);
68         } catch (Throwable t) {
69             throw new InvalidHeadStateException(t);
70         }
71     }
72     
73     public void save(Path directory) throws IOException {
74         Path f = directory.resolve(HEAD_STATE);
75         try {
76             BinaryMemory rf = new BinaryMemory(4096);
77             try {
78                 MutableVariant v = new MutableVariant(Bindings.getBindingUnchecked(HeadState1.class), this);
79                 Serializer s = Bindings.getSerializerUnchecked( Bindings.VARIANT );
80                 s.serialize(rf, v);
81             } finally {
82                 rf.close();
83             }
84             
85             byte[] bytes = rf.toByteBuffer().array();
86             
87             MessageDigest sha1 = MessageDigest.getInstance(SHA_1);
88             sha1.update(bytes);
89             byte[] checksum = sha1.digest();
90             
91             try (OutputStream out = Files.newOutputStream(f)) {
92                 out.write(checksum);
93                 out.write(bytes);
94             }
95             FileIO.syncPath(f);
96         } catch (NoSuchAlgorithmException e) {
97             throw new Error("SHA-1 digest not found, should not happen", e);
98         }
99     }
100
101     public static void validateHeadStateIntegrity(Path headState) throws InvalidHeadStateException, IOException {
102         try {
103             byte[] bytes = Files.readAllBytes(headState);
104             MessageDigest sha1 = MessageDigest.getInstance(SHA_1);
105             int digestLength = sha1.getDigestLength();
106             sha1.update(bytes, digestLength, bytes.length - digestLength);
107             byte[] newChecksum = sha1.digest();
108             if (!Arrays.equals(newChecksum, Arrays.copyOfRange(bytes, 0, digestLength))) {
109                 throw new InvalidHeadStateException(
110                         "Checksum " + Arrays.toString(newChecksum) + " does not match excpected "
111                                 + Arrays.toString(Arrays.copyOfRange(bytes, 0, digestLength)) + " for " + headState.toAbsolutePath());
112             }
113         } catch (NoSuchAlgorithmException e) {
114             throw new Error("SHA-1 digest not found, should not happen", e);
115         }
116     }
117 }