package mireka.pop.store;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.concurrent.GuardedBy;
/**
* MaildropRepository represents a collection of maildrops within the same file
* system directory, it maintains a list of the currently used maildrops in
* order to make possible the synchronization of access to a maildrop.
*/
public class MaildropRepository {
/**
* The directory where the individual maildrop directories are residing.
*/
private String dir;
@GuardedBy("this")
private Map<String, MaildropSlot> openMaildrops =
new HashMap<String, MaildropSlot>();
public synchronized Maildrop borrowMaildrop(String maildropName) {
Maildrop maildrop = getOrCreateMaildrop(maildropName);
return maildrop;
}
private Maildrop getOrCreateMaildrop(String maildropName) {
MaildropSlot maildropSlot = openMaildrops.get(maildropName);
if (maildropSlot == null) {
maildropSlot = new MaildropSlot();
File maildropDir = new File(dir, maildropName);
maildropSlot.maildrop = new Maildrop(maildropName, maildropDir);
openMaildrops.put(maildropName, maildropSlot);
}
maildropSlot.borrowCount++;
return maildropSlot.maildrop;
}
public synchronized void releaseMaildrop(Maildrop maildrop) {
MaildropSlot maildropSlot = openMaildrops.get(maildrop.getName());
if (maildropSlot == null)
throw new IllegalStateException("Maildrop is already released");
maildropSlot.borrowCount--;
if (maildropSlot.borrowCount < 0)
throw new RuntimeException("Assertion failed");
else if (maildropSlot.borrowCount == 0) {
openMaildrops.remove(maildrop.getName());
maildrop.checkReleasedState();
}
}
/**
* @x.category GETSET
*/
public void setDir(String dir) {
this.dir = dir;
}
private static class MaildropSlot {
int borrowCount = 0;
Maildrop maildrop;
}
}