69 lines
2.0 KiB
Java
69 lines
2.0 KiB
Java
import java.io.IOException;
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Path;
|
|
import java.nio.file.StandardCopyOption;
|
|
import java.time.Instant;
|
|
import java.util.Arrays;
|
|
import java.util.UUID;
|
|
|
|
final class FileMessageBoard {
|
|
static final Path ROOT = Path.of(
|
|
System.getProperty("messageBoard.root", "messageBoard")
|
|
).toAbsolutePath().normalize();
|
|
|
|
private FileMessageBoard() {}
|
|
|
|
static String serialize(Message message) {
|
|
var text = message.type() + "\n" + message.value();
|
|
|
|
if (message.timestamp() != null)
|
|
text += "\nTIMESTAMP: " + message.timestamp();
|
|
|
|
return text;
|
|
}
|
|
|
|
static Message read(Path file) throws IOException {
|
|
var lines = Files.readString(file).split("\\R", -1);
|
|
|
|
if (lines.length < 2)
|
|
throw new IOException("A message needs a type and a value: " + file);
|
|
|
|
var endOfValue = lines.length;
|
|
Instant timestamp = null;
|
|
var lastLine = lines[lines.length - 1];
|
|
|
|
if (lastLine.startsWith("TIMESTAMP: ")) {
|
|
timestamp = Instant.parse(lastLine.substring("TIMESTAMP: ".length()));
|
|
endOfValue--;
|
|
}
|
|
|
|
var value = String.join(
|
|
"\n",
|
|
Arrays.copyOfRange(lines, 1, endOfValue)
|
|
);
|
|
|
|
return new Message(lines[0], value, timestamp);
|
|
}
|
|
|
|
static void publish(String mailbox, Message message) throws IOException {
|
|
var directory = directory(mailbox);
|
|
Files.createDirectories(directory);
|
|
|
|
var id = UUID.randomUUID().toString();
|
|
var temporary = directory.resolve(id + ".tmp");
|
|
var published = directory.resolve(id + ".msg");
|
|
|
|
Files.writeString(temporary, serialize(message));
|
|
Files.move(temporary, published, StandardCopyOption.ATOMIC_MOVE);
|
|
}
|
|
|
|
static Path directory(String name) {
|
|
var directory = ROOT.resolve(name).normalize();
|
|
|
|
if (!directory.startsWith(ROOT))
|
|
throw new IllegalArgumentException("Mailbox escapes the message board");
|
|
|
|
return directory;
|
|
}
|
|
}
|