home /
connvers /
src /
main /
java /
avividi /
connvers /
server /
Storage.java
Storage.java
package avividi.connvers.server;
import avividi.connvers.protocol.Message;
import avividi.connvers.protocol.MessageEncoder;
import avividi.connvers.protocol.ValidationException;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedDeque;
public class Storage implements Closeable {
private static final int MEM_MESSAGE_SIZE = 10;
private final MessageEncoder messageEncoder;
private final OutputStream outputStream;
private final Deque<Message> stack = new ConcurrentLinkedDeque<>();
public Storage(MessageEncoder messageEncoder, File file) throws IOException {
if (!file.exists()) {
file.createNewFile();
}
this.messageEncoder = messageEncoder;
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
while ((line = reader.readLine()) != null) {
try {
addToMem(messageEncoder.decode(line));
} catch (ValidationException e) {
throw new RuntimeException(e);
}
}
}
outputStream = new BufferedOutputStream(new FileOutputStream(file, true));
}
public List<Message> getMessages() {
return new ArrayList<>(stack);
}
private void addToMem(Message message) {
stack.addLast(message);
while (stack.size() > MEM_MESSAGE_SIZE) {
stack.pollFirst();
}
}
void push(Message message) {
addToMem(message);
persistMessage(message);
}
private synchronized void persistMessage(Message message) {
try {
outputStream.write(messageEncoder.encode(message).getBytes());
outputStream.write("\n".getBytes());
outputStream.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void close() throws IOException {
outputStream.close();
}
}