package org.archive.accesscontrol.model;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.TreeSet;
import org.archive.surt.NewSurtTokenizer;
/**
* A set of acess control rules which can be queried to find the governing rule
* for a particular request.
*
* @author aosborne
*
*/
public class RuleSet implements Iterable<Rule> {
protected HashMap<String, TreeSet<Rule>> rulemap = new HashMap<String, TreeSet<Rule>>();
class RuleSetIterator implements Iterator<Rule> {
private Iterator<TreeSet<Rule>> mapIterator;
private Iterator<Rule> setIterator;
public RuleSetIterator() {
mapIterator = rulemap.values().iterator();
setIterator = null;
hasNext();
}
public boolean hasNext() {
while (true) {
if (setIterator != null && setIterator.hasNext())
return true;
if (!mapIterator.hasNext())
return false;
setIterator = mapIterator.next().iterator();
}
}
public Rule next() {
if (hasNext()) {
return setIterator.next();
}
return null;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
public RuleSet() {
super();
}
/**
* Return the most specific matching rule for the given request.
*
* @param surt
* @param captureDate
* @param retrievalDate
* @param who
* group
* @return
*/
public Rule getMatchingRule(String surt, Date captureDate,
Date retrievalDate, String who) {
NewSurtTokenizer tok = new NewSurtTokenizer(surt);
// Best general rule (when accessGroup is blank)
Rule ruleGeneral = null;
for (String key: tok.getSearchList()) {
Iterable<Rule> rules = rulemap.get(key);
if (rules != null) {
for (Rule rule : rules) {
if (rule.matches(surt, captureDate, retrievalDate, who)) {
// Return this if accessGroup (who) matches exactly
if ((who != null) && who.equals(rule.getWho())) {
return rule;
// otherwise, store the first/best one
} else if (ruleGeneral == null) {
ruleGeneral = rule;
}
}
}
}
}
return ruleGeneral;
}
public void addAll(Iterable<Rule> rules) {
for (Rule rule : rules) {
add(rule);
}
}
public void add(Rule rule) {
String surt = rule.getSurt();
TreeSet<Rule> set = rulemap.get(surt);
if (set == null) {
set = new TreeSet<Rule>();
rulemap.put(surt, set);
}
set.add(rule);
}
public Iterator<Rule> iterator() {
return new RuleSetIterator();
}
}