--- /dev/null
+package fi.vtt.simantics.procore.internal;\r
+\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.FileOutputStream;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.OutputStream;\r
+import java.nio.ByteBuffer;\r
+\r
+import org.simantics.db.common.utils.Logger;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.RuntimeDatabaseException;\r
+\r
+\r
+public class ReservedIds {\r
+ private File file = null;\r
+ private boolean loaded = false;\r
+ private Data data = new Data();\r
+ public static class Data {\r
+ int idCount = 0;\r
+ long nextId = 0;\r
+ }\r
+ ReservedIds(File workDir, String id) {\r
+ if (!workDir.isDirectory()) {\r
+ if (!workDir.mkdir())\r
+ throw new RuntimeDatabaseException("Work directory not correct: " + workDir.getPath());\r
+ }\r
+ String name = workDir.getPath() + File.separator + "reservedIds." + id;\r
+ file = new File(name);\r
+ }\r
+ public boolean loaded() {\r
+ return loaded; \r
+ }\r
+ public Data load() {\r
+ try {\r
+ if(file == null || !file.exists())\r
+ return data;\r
+ loadInternal();\r
+ loaded = true;\r
+ } catch (IOException e) {\r
+ e.printStackTrace();\r
+ Logger.defaultLogError("Failed to load reserved ids.", e);\r
+ return null;\r
+ }\r
+ return data;\r
+ }\r
+ public void create(int idCount, long nextId) {\r
+ data.idCount = idCount;\r
+ data.nextId = nextId;\r
+ saveNoThrow(idCount, nextId);\r
+ loaded = true;\r
+ }\r
+ public void saveNoThrow(int idCount, long nextId) {\r
+ try {\r
+ save(idCount, nextId);\r
+ } catch (IOException e) {\r
+ e.printStackTrace();\r
+ Logger.defaultLogError("Failed to load reserved ids.", e);\r
+ }\r
+ }\r
+ public void save(int idCount, long nextId)\r
+ throws IOException {\r
+ data.idCount = idCount;\r
+ data.nextId = nextId;\r
+ OutputStream stream = new FileOutputStream(file);\r
+ try {\r
+ byte[] bytes = new byte[12];\r
+ ByteBuffer bb = ByteBuffer.wrap(bytes);\r
+ bb.putInt(idCount);\r
+ bb.putLong(nextId);\r
+ stream.write(bb.array());\r
+ stream.close();\r
+ } finally {\r
+ stream.close();\r
+ }\r
+ loaded = true;\r
+ }\r
+ public void mergeToFile(File toFile)\r
+ throws DatabaseException {\r
+ if (!loaded)\r
+ load();\r
+ long next = data.nextId + data.idCount;\r
+ if (toFile.isDirectory()) {\r
+ toFile = new File(toFile, file.getName());\r
+ }else if (toFile.exists()) {\r
+ try {\r
+ InputStream is = null;\r
+ try {\r
+ is = new FileInputStream(toFile);\r
+ byte[] bytes = new byte[8];\r
+ int n = is.read(bytes);\r
+ if (n == 8) {\r
+ ByteBuffer bb = ByteBuffer.wrap(bytes);\r
+ long oldNext = bb.getLong();\r
+ if (oldNext > next)\r
+ next = oldNext;\r
+ }\r
+ } finally {\r
+ is.close();\r
+ }\r
+ } catch (IOException e) {\r
+ String msg = "Could not open file " + toFile.getAbsolutePath() + ".";\r
+ Logger.defaultLogError(msg, e);\r
+ throw new DatabaseException(msg, e);\r
+ }\r
+ }\r
+ try{\r
+ OutputStream stream = new FileOutputStream(toFile);\r
+ try {\r
+ byte[] bytes = new byte[8];\r
+ ByteBuffer bb = ByteBuffer.wrap(bytes);\r
+ bb.putLong(next);\r
+ stream.write(bb.array());\r
+ stream.close();\r
+ } finally {\r
+ stream.close();\r
+ }\r
+ } catch (IOException e) {\r
+ String msg = "Could not save file " + toFile.getAbsolutePath() + ".";\r
+ Logger.defaultLogError(msg, e);\r
+ throw new DatabaseException(msg, e);\r
+ }\r
+ }\r
+ private void loadInternal()\r
+ throws IOException {\r
+ InputStream is = new FileInputStream(file);\r
+ try {\r
+ byte[] bytes = new byte[12];\r
+ int n = is.read(bytes);\r
+ if (n != 12)\r
+ return;\r
+ ByteBuffer bb = ByteBuffer.wrap(bytes);\r
+ data.idCount = bb.getInt();\r
+ data.nextId = bb.getLong();\r
+ } finally {\r
+ is.close();\r
+ }\r
+ }\r
+}\r