1 package org.simantics.acorn;
3 import java.io.ByteArrayInputStream;
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;
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;
19 public class HeadState {
21 public int headChangeSetId = 0;
22 public long transactionId = 1;
23 public long reservedIds = 3;
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>();
31 public static HeadState load(Path directory) throws InvalidHeadStateException {
32 Path f = directory.resolve("head.state");
35 byte[] bytes = Files.readAllBytes(f);
36 MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
37 int digestLength = sha1.getDigestLength();
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());
47 HeadState object = (HeadState) org.simantics.databoard.Files.readFile(new ByteArrayInputStream(bytes, digestLength, bytes.length - digestLength), Bindings.getBindingUnchecked(HeadState.class));
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);
60 public void save(Path directory) throws IOException {
61 Path f = directory.resolve("head.state");
63 BinaryMemory rf = new BinaryMemory(4096);
65 MutableVariant v = new MutableVariant(Bindings.getBindingUnchecked(HeadState.class), this);
66 Serializer s = Bindings.getSerializerUnchecked( Bindings.VARIANT );
72 byte[] bytes = rf.toByteBuffer().array();
74 MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
76 byte[] checksum = sha1.digest();
78 try (OutputStream out = Files.newOutputStream(f)) {
83 } catch (NoSuchAlgorithmException e) {
84 throw new Error("SHA-1 digest not found, should not happen", e);
88 public static void validateHeadStateIntegrity(Path headState) throws InvalidHeadStateException, IOException {
90 byte[] bytes = Files.readAllBytes(headState);
91 MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
92 int digestLength = sha1.getDigestLength();
93 sha1.update(bytes, digestLength, bytes.length - digestLength);
94 byte[] newChecksum = sha1.digest();
95 if (!Arrays.equals(newChecksum, Arrays.copyOfRange(bytes, 0, digestLength))) {
96 throw new InvalidHeadStateException(
97 "Checksum " + Arrays.toString(newChecksum) + " does not match excpected "
98 + Arrays.toString(Arrays.copyOfRange(bytes, 0, digestLength)) + " for " + headState.toAbsolutePath());
100 } catch (NoSuchAlgorithmException e) {
101 throw new Error("SHA-1 digest not found, should not happen", e);