1 package org.simantics.acorn;
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;
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;
19 public class HeadState1 {
21 public static final String HEAD_STATE = "head.state";
22 public static final String SHA_1 = "SHA-1";
24 public int headChangeSetId = 0;
25 public long transactionId = 1;
26 public long reservedIds = 3;
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<>();
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;
40 state.stream = stream;
45 public static HeadState1 load(Path directory) throws InvalidHeadStateException {
46 Path f = directory.resolve(HEAD_STATE);
49 byte[] bytes = Files.readAllBytes(f);
50 MessageDigest sha1 = MessageDigest.getInstance(SHA_1);
51 int digestLength = sha1.getDigestLength();
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());
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));
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);
73 public void save(Path directory) throws IOException {
74 Path f = directory.resolve(HEAD_STATE);
76 BinaryMemory rf = new BinaryMemory(4096);
78 MutableVariant v = new MutableVariant(Bindings.getBindingUnchecked(HeadState1.class), this);
79 Serializer s = Bindings.getSerializerUnchecked( Bindings.VARIANT );
85 byte[] bytes = rf.toByteBuffer().array();
87 MessageDigest sha1 = MessageDigest.getInstance(SHA_1);
89 byte[] checksum = sha1.digest();
91 try (OutputStream out = Files.newOutputStream(f)) {
96 } catch (NoSuchAlgorithmException e) {
97 throw new Error("SHA-1 digest not found, should not happen", e);
101 public static void validateHeadStateIntegrity(Path headState) throws InvalidHeadStateException, IOException {
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());
113 } catch (NoSuchAlgorithmException e) {
114 throw new Error("SHA-1 digest not found, should not happen", e);