]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.acorn/src/org/simantics/acorn/HeadState.java
Merge commit '3b5069d' into develop
[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.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 HeadState {
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 //    public ArrayList<String> ccs = new ArrayList<String>();
33
34     public static HeadState load(Path directory) throws InvalidHeadStateException {
35         Path f = directory.resolve(HEAD_STATE);
36         
37         try {
38             byte[] bytes = Files.readAllBytes(f);
39             MessageDigest sha1 = MessageDigest.getInstance(SHA_1);
40             int digestLength = sha1.getDigestLength();
41             
42             sha1.update(bytes, digestLength, bytes.length - digestLength);
43             byte[] newChecksum = sha1.digest();
44             if (!Arrays.equals(newChecksum, Arrays.copyOfRange(bytes, 0, digestLength))) {
45                 throw new InvalidHeadStateException(
46                         "Checksum " + Arrays.toString(newChecksum) + " does not match excpected "
47                                 + Arrays.toString(Arrays.copyOfRange(bytes, 0, digestLength)) + " for " + f.toAbsolutePath());
48             }
49             try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes, digestLength, bytes.length - digestLength)) {
50                 HeadState object = (HeadState) org.simantics.databoard.Files.readFile(bais, Bindings.getBindingUnchecked(HeadState.class));
51                 return object;
52             }
53         } catch (IOException i) {
54             return new HeadState();
55 //            throw new InvalidHeadStateException(i);
56         } catch (NoSuchAlgorithmException e) {
57             throw new Error("SHA-1 Algorithm not found", e);
58         } catch (Throwable t) {
59             throw new InvalidHeadStateException(t);
60         }
61     }
62     
63     public void save(Path directory) throws IOException {
64         Path f = directory.resolve(HEAD_STATE);
65         try {
66             BinaryMemory rf = new BinaryMemory(4096);
67             try {
68                 MutableVariant v = new MutableVariant(Bindings.getBindingUnchecked(HeadState.class), this);
69                 Serializer s = Bindings.getSerializerUnchecked( Bindings.VARIANT );
70                 s.serialize(rf, v);
71             } finally {
72                 rf.close();
73             }
74             
75             byte[] bytes = rf.toByteBuffer().array();
76             
77             MessageDigest sha1 = MessageDigest.getInstance(SHA_1);
78             sha1.update(bytes);
79             byte[] checksum = sha1.digest();
80             
81             try (OutputStream out = Files.newOutputStream(f)) {
82                 out.write(checksum);
83                 out.write(bytes);
84             }
85             FileIO.syncPath(f);
86         } catch (NoSuchAlgorithmException e) {
87             throw new Error("SHA-1 digest not found, should not happen", e);
88         }
89     }
90
91     public static void validateHeadStateIntegrity(Path headState) throws InvalidHeadStateException, IOException {
92         try {
93             byte[] bytes = Files.readAllBytes(headState);
94             MessageDigest sha1 = MessageDigest.getInstance(SHA_1);
95             int digestLength = sha1.getDigestLength();
96             sha1.update(bytes, digestLength, bytes.length - digestLength);
97             byte[] newChecksum = sha1.digest();
98             if (!Arrays.equals(newChecksum, Arrays.copyOfRange(bytes, 0, digestLength))) {
99                 throw new InvalidHeadStateException(
100                         "Checksum " + Arrays.toString(newChecksum) + " does not match excpected "
101                                 + Arrays.toString(Arrays.copyOfRange(bytes, 0, digestLength)) + " for " + headState.toAbsolutePath());
102             }
103         } catch (NoSuchAlgorithmException e) {
104             throw new Error("SHA-1 digest not found, should not happen", e);
105         }
106     }
107 }