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