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