Defer change set disposal in State.commitWriteTransaction
[simantics/platform.git] / bundles / org.simantics.db.procore / src / fi / vtt / simantics / procore / internal / ReservedIds.java
1 package fi.vtt.simantics.procore.internal;
2
3 import java.io.File;
4 import java.io.FileInputStream;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.io.OutputStream;
9 import java.nio.ByteBuffer;
10
11 import org.simantics.db.common.utils.Logger;
12 import org.simantics.db.exception.DatabaseException;
13 import org.simantics.db.exception.RuntimeDatabaseException;
14
15
16 public class ReservedIds {
17     private File file = null;
18     private boolean loaded = false;
19     private Data data = new Data();
20     public static class Data {
21         int idCount = 0;
22         long nextId = 0;
23     }
24     ReservedIds(File workDir, String id) {
25         if (!workDir.isDirectory()) {
26             if (!workDir.mkdir())
27                 throw new RuntimeDatabaseException("Work directory not correct: " + workDir.getPath());
28         }
29         String name = workDir.getPath() + File.separator + "reservedIds." + id;
30         file = new File(name);
31     }
32     public boolean loaded() {
33         return loaded;  
34     }
35     public Data load() {
36         try {
37                 if(file == null || !file.exists())
38                     return data;
39             loadInternal();
40             loaded = true;
41         } catch (IOException e) {
42             e.printStackTrace();
43             Logger.defaultLogError("Failed to load reserved ids.", e);
44             return null;
45         }
46         return data;
47     }
48     public void create(int idCount, long nextId) {
49         data.idCount = idCount;
50         data.nextId = nextId;
51         saveNoThrow(idCount, nextId);
52         loaded = true;
53     }
54     public void saveNoThrow(int idCount, long nextId) {
55         try {
56             save(idCount, nextId);
57         } catch (IOException e) {
58             e.printStackTrace();
59             Logger.defaultLogError("Failed to load reserved ids.", e);
60         }
61     }
62     public void save(int idCount, long nextId)
63     throws IOException {
64         data.idCount = idCount;
65         data.nextId = nextId;
66         OutputStream stream = new FileOutputStream(file);
67         try  {
68             byte[] bytes = new byte[12];
69             ByteBuffer bb = ByteBuffer.wrap(bytes);
70             bb.putInt(idCount);
71             bb.putLong(nextId);
72             stream.write(bb.array());
73             stream.close();
74         } finally {
75             stream.close();
76         }
77         loaded = true;
78     }
79     public void mergeToFile(File toFile)
80     throws DatabaseException {
81         if (!loaded)
82             load();
83         long next = data.nextId + data.idCount;
84         if (toFile.isDirectory()) {
85             toFile = new File(toFile, file.getName());
86         }else if (toFile.exists()) {
87             try {
88                 InputStream is = null;
89                 try {
90                     is = new FileInputStream(toFile);
91                     byte[] bytes = new byte[8];
92                     int n = is.read(bytes);
93                     if (n == 8) {
94                         ByteBuffer bb = ByteBuffer.wrap(bytes);
95                         long oldNext = bb.getLong();
96                         if (oldNext > next)
97                             next = oldNext;
98                     }
99                 } finally {
100                     is.close();
101                 }
102             } catch (IOException e) {
103                 String msg = "Could not open file " + toFile.getAbsolutePath() + ".";
104                 Logger.defaultLogError(msg, e);
105                 throw new DatabaseException(msg, e);
106             }
107         }
108         try{
109             OutputStream stream = new FileOutputStream(toFile);
110             try  {
111                 byte[] bytes = new byte[8];
112                 ByteBuffer bb = ByteBuffer.wrap(bytes);
113                 bb.putLong(next);
114                 stream.write(bb.array());
115                 stream.close();
116             } finally {
117                 stream.close();
118             }
119         } catch (IOException e) {
120             String msg = "Could not save file " + toFile.getAbsolutePath() + ".";
121             Logger.defaultLogError(msg, e);
122             throw new DatabaseException(msg, e);
123         }
124     }
125     private void loadInternal()
126     throws IOException {
127         InputStream is = new FileInputStream(file);
128         try {
129             byte[] bytes = new byte[12];
130             int n = is.read(bytes);
131             if (n != 12)
132                 return;
133             ByteBuffer bb = ByteBuffer.wrap(bytes);
134             data.idCount = bb.getInt();
135             data.nextId = bb.getLong();
136         } finally {
137             is.close();
138         }
139     }
140 }