package org.prevayler.implementation.publishing.censorship;
import org.prevayler.foundation.serialization.Serializer;
import org.prevayler.implementation.PrevalentSystemGuard;
import org.prevayler.implementation.TransactionTimestamp;
import org.prevayler.implementation.snapshot.GenericSnapshotManager;
public class StrictTransactionCensor implements TransactionCensor {
private final PrevalentSystemGuard _king;
private PrevalentSystemGuard _royalFoodTaster;
private final Serializer _snapshotSerializer;
public StrictTransactionCensor( GenericSnapshotManager snapshotManager){
_king=snapshotManager.recoveredPrevalentSystem();
_snapshotSerializer=snapshotManager.primarySerializer();
}
public void approve( TransactionTimestamp transactionTimestamp) throws RuntimeException, Error {
try {
TransactionTimestamp timestampCopy=transactionTimestamp.cleanCopy();
PrevalentSystemGuard royalFoodTaster=royalFoodTaster(transactionTimestamp.systemVersion() - 1);
royalFoodTaster.receive(timestampCopy);
}
catch ( RuntimeException rx) {
letTheFoodTasterDie();
throw rx;
}
catch ( Error error) {
letTheFoodTasterDie();
throw error;
}
}
private void letTheFoodTasterDie(){
_royalFoodTaster=null;
}
private PrevalentSystemGuard royalFoodTaster( long systemVersion){
if (_royalFoodTaster == null) produceNewFoodTaster(systemVersion);
return _royalFoodTaster;
}
private void produceNewFoodTaster( long systemVersion){
try {
_royalFoodTaster=_king.deepCopy(systemVersion,_snapshotSerializer);
}
catch ( Exception ex) {
ex.printStackTrace();
throw new RuntimeException("Unable to produce a copy of the prevalent system for trying out transactions before applying them to the real system.");
}
}
}