package org.prevayler.implementation.journal;
import org.prevayler.implementation.TransactionGuide;
import org.prevayler.implementation.TransactionTimestamp;
import org.prevayler.implementation.publishing.TransactionSubscriber;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class TransientJournal implements Journal {
private final List journal=new ArrayList();
private long _initialTransaction;
private boolean _initialTransactionInitialized=false;
public void append( TransactionGuide guide){
if (!_initialTransactionInitialized) throw new IllegalStateException("Journal.update() has to be called at least once before Journal.journal().");
guide.startTurn();
try {
guide.checkSystemVersion(_initialTransaction + journal.size());
journal.add(guide.timestamp().cleanCopy());
}
finally {
guide.endTurn();
}
}
public synchronized void update( TransactionSubscriber subscriber, long initialTransaction) throws IOException {
if (!_initialTransactionInitialized) {
_initialTransactionInitialized=true;
_initialTransaction=initialTransaction;
return;
}
if (initialTransaction < _initialTransaction) throw new IOException("Unable to recover transaction " + initialTransaction + ". The oldest recoverable transaction is "+ _initialTransaction+ ".");
int i=(int)(initialTransaction - _initialTransaction);
if (i > journal.size()) throw new IOException("The transaction journal has not yet reached transaction " + initialTransaction + ". The last logged transaction was "+ (_initialTransaction + journal.size() - 1)+ ".");
while (i != journal.size()) {
TransactionTimestamp entry=(TransactionTimestamp)journal.get(i);
long recoveringTransaction=_initialTransaction + i;
if (entry.systemVersion() != recoveringTransaction) {
throw new IOException("Expected " + recoveringTransaction + " but was "+ entry.systemVersion());
}
subscriber.receive(entry);
i++;
}
}
public void close(){
}
public synchronized long nextTransaction(){
if (!_initialTransactionInitialized) throw new IllegalStateException("update() must be called at least once");
return _initialTransaction + journal.size();
}
}