package com.onionnetworks.io;
import com.onionnetworks.util.*;
import java.io.*;
import java.util.*;
public class JournalingRAF extends FilterRAF {
Journal journal;
public JournalingRAF(RAF raf, Journal journal) throws IOException {
super(raf);
if (raf.getMode().equals("r")) {
throw new IllegalStateException("Can't create a journal for a "+
"read-only file.");
}
this.journal = journal;
// Track the initial file path.
journal.setTargetFile(raf.getFile());
}
public synchronized void seekAndWrite(long pos, byte[] b, int off,
int len) throws IOException {
super.seekAndWrite(pos,b,off,len);
//FIX flush problem, what if it crashes before data is persisted?
if (journal != null) {
// can be null from deleteJournal
// Update the journal..
journal.addByteRange(new Range(pos,pos+len-1));
}
}
public synchronized void renameTo(File newFile) throws IOException {
super.renameTo(newFile);
// Update the file location.
// Can be null from deleteJournal()
if (journal != null) {
// Use _raf.getFile() because renameTo() may have failed and was
// forced to fall back.
journal.setTargetFile(_raf.getFile());
// flush here because it is important that the journal stay in
// sync on this operation.
journal.flush();
}
}
public synchronized void setReadOnly() throws IOException {
super.setReadOnly();
// done writing, delete the journal
deleteJournal();
}
public synchronized void close() throws IOException {
super.close();
// Can be null from deleteJournal
if (journal != null) {
journal.close();
}
}
public synchronized void deleteOnClose() {
super.deleteOnClose();
deleteJournal();
}
private void deleteJournal() {
File file = journal.getFile();
try {
journal.close();
} catch (IOException e) {e.printStackTrace();}
//FIX maybe throw exception on failed delete?
file.delete();
journal = null;
}
}