From: <al...@us...> - 2008-02-07 03:15:06
|
Revision: 2185 http://archive-access.svn.sourceforge.net/archive-access/?rev=2185&view=rev Author: alexoz Date: 2008-02-06 19:15:11 -0800 (Wed, 06 Feb 2008) Log Message: ----------- Initial commit of wayback access-control library and oracle. Basic rule management and querying functionality is in place but it will require much more extensive testing. Added Paths: ----------- trunk/archive-access/projects/access-control/.classpath trunk/archive-access/projects/access-control/.project trunk/archive-access/projects/access-control/.settings/ trunk/archive-access/projects/access-control/.settings/org.eclipse.jdt.core.prefs trunk/archive-access/projects/access-control/access-control/ trunk/archive-access/projects/access-control/access-control/pom.xml trunk/archive-access/projects/access-control/access-control/src/ trunk/archive-access/projects/access-control/access-control/src/main/ trunk/archive-access/projects/access-control/access-control/src/main/java/ trunk/archive-access/projects/access-control/access-control/src/main/java/org/ trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/ trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/ trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/AccessControlClient.java trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/ trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/HibernateRuleDao.java trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/HttpRuleDao.java trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/Rule.java trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/RuleChange.java trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/RuleDao.java trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/RuleSet.java trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/surt/ trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/surt/SURTTokenizer2.java trunk/archive-access/projects/access-control/access-control/src/main/resources/ trunk/archive-access/projects/access-control/access-control/src/main/resources/Rule.hbm.xml trunk/archive-access/projects/access-control/access-control/src/main/resources/RuleChange.hbm.xml trunk/archive-access/projects/access-control/access-control/src/main/resources/hibernate.cfg.xml trunk/archive-access/projects/access-control/access-control/src/test/ trunk/archive-access/projects/access-control/access-control/src/test/java/ trunk/archive-access/projects/access-control/access-control/src/test/java/org/ trunk/archive-access/projects/access-control/access-control/src/test/java/org/archive/ trunk/archive-access/projects/access-control/access-control/src/test/java/org/archive/accesscontrol/ trunk/archive-access/projects/access-control/access-control/src/test/java/org/archive/accesscontrol/AccessControlClientTest.java trunk/archive-access/projects/access-control/access-control/src/test/java/org/archive/accesscontrol/model/ trunk/archive-access/projects/access-control/access-control/src/test/java/org/archive/accesscontrol/model/DaoTestCase.java trunk/archive-access/projects/access-control/access-control/src/test/java/org/archive/accesscontrol/model/HibernateRuleDaoTest.java trunk/archive-access/projects/access-control/access-control/src/test/java/org/archive/accesscontrol/model/RuleSetTest.java trunk/archive-access/projects/access-control/access-control/src/test/java/org/archive/accesscontrol/model/RuleTest.java trunk/archive-access/projects/access-control/access-control/src/test/java/org/archive/surt/ trunk/archive-access/projects/access-control/access-control/src/test/java/org/archive/surt/SURTTokenizer2Test.java trunk/archive-access/projects/access-control/access-control/src/test/resources/ trunk/archive-access/projects/access-control/access-control/src/test/resources/applicationContext.xml trunk/archive-access/projects/access-control/oracle/ trunk/archive-access/projects/access-control/oracle/pom.xml trunk/archive-access/projects/access-control/oracle/src/ trunk/archive-access/projects/access-control/oracle/src/main/ trunk/archive-access/projects/access-control/oracle/src/main/java/ trunk/archive-access/projects/access-control/oracle/src/main/java/org/ trunk/archive-access/projects/access-control/oracle/src/main/java/org/archive/ trunk/archive-access/projects/access-control/oracle/src/main/java/org/archive/accesscontrol/ trunk/archive-access/projects/access-control/oracle/src/main/java/org/archive/accesscontrol/oracle/ trunk/archive-access/projects/access-control/oracle/src/main/java/org/archive/accesscontrol/oracle/AutoFormatView.java trunk/archive-access/projects/access-control/oracle/src/main/java/org/archive/accesscontrol/oracle/CreatedView.java trunk/archive-access/projects/access-control/oracle/src/main/java/org/archive/accesscontrol/oracle/RulesController.java trunk/archive-access/projects/access-control/oracle/src/main/java/org/archive/accesscontrol/oracle/SimpleError.java trunk/archive-access/projects/access-control/oracle/src/main/java/org/archive/accesscontrol/oracle/XStreamView.java trunk/archive-access/projects/access-control/oracle/src/main/webapp/ trunk/archive-access/projects/access-control/oracle/src/main/webapp/WEB-INF/ trunk/archive-access/projects/access-control/oracle/src/main/webapp/WEB-INF/applicationContext.xml trunk/archive-access/projects/access-control/oracle/src/main/webapp/WEB-INF/exclusions-oracle-servlet.xml trunk/archive-access/projects/access-control/oracle/src/main/webapp/WEB-INF/urlrewrite.xml trunk/archive-access/projects/access-control/oracle/src/main/webapp/WEB-INF/web.xml trunk/archive-access/projects/access-control/oracle/src/main/webapp/index.html trunk/archive-access/projects/access-control/oracle/src/test/ trunk/archive-access/projects/access-control/oracle/src/test/java/ trunk/archive-access/projects/access-control/oracle/src/test/java/org/ trunk/archive-access/projects/access-control/oracle/src/test/java/org/archive/ trunk/archive-access/projects/access-control/oracle/src/test/java/org/archive/accesscontrol/ Added: trunk/archive-access/projects/access-control/.classpath =================================================================== --- trunk/archive-access/projects/access-control/.classpath (rev 0) +++ trunk/archive-access/projects/access-control/.classpath 2008-02-07 03:15:11 UTC (rev 2185) @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="access-control/src/main/java"/> + <classpathentry kind="src" path="access-control/src/test/java"/> + <classpathentry excluding="**" kind="src" output="access-control/src/main/resources" path="access-control/src/main/resources"/> + <classpathentry excluding="**" kind="src" output="access-control/src/test/resources" path="access-control/src/test/resources"/> + <classpathentry kind="src" path="oracle/src/main/java"/> + <classpathentry kind="src" path="oracle/src/test/java"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER/modules"/> + <classpathentry kind="output" path="target/classes"/> +</classpath> Added: trunk/archive-access/projects/access-control/.project =================================================================== --- trunk/archive-access/projects/access-control/.project (rev 0) +++ trunk/archive-access/projects/access-control/.project 2008-02-07 03:15:11 UTC (rev 2185) @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>access-control</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.maven.ide.eclipse.maven2Builder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.maven.ide.eclipse.maven2Nature</nature> + </natures> +</projectDescription> Added: trunk/archive-access/projects/access-control/.settings/org.eclipse.jdt.core.prefs =================================================================== --- trunk/archive-access/projects/access-control/.settings/org.eclipse.jdt.core.prefs (rev 0) +++ trunk/archive-access/projects/access-control/.settings/org.eclipse.jdt.core.prefs 2008-02-07 03:15:11 UTC (rev 2185) @@ -0,0 +1,7 @@ +#Fri Feb 01 11:37:16 PST 2008 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 Added: trunk/archive-access/projects/access-control/access-control/pom.xml =================================================================== --- trunk/archive-access/projects/access-control/access-control/pom.xml (rev 0) +++ trunk/archive-access/projects/access-control/access-control/pom.xml 2008-02-07 03:15:11 UTC (rev 2185) @@ -0,0 +1,131 @@ +<?xml version="1.0" encoding="UTF-8"?><project> + <modelVersion>4.0.0</modelVersion> + <groupId>org.archive.access-control</groupId> + <artifactId>access-control</artifactId> + <packaging>jar</packaging> + <version>0.0.1-SNAPSHOT</version> + <description></description> + + <parent> + <groupId>org.archive</groupId> + <artifactId>access-control</artifactId> + <version>0.0.1-SNAPSHOT</version> + </parent> + + <build> + <extensions> + <extension> + <groupId>hsqldb</groupId> + <artifactId>hsqldb</artifactId> + <version>1.8.0.7</version> + </extension> + </extensions> + <plugins> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.5</source> + <target>1.5</target> + </configuration> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>hibernate3-maven-plugin</artifactId> + <version>2.0-alpha-2</version> + <configuration> + <components> + <component> + <name>hbm2ddl</name> + <implementation>jdbcconfiguration</implementation> + </component> + <component> + <name>hbm2hbmxml</name> + <outputDirectory>src/main/resources</outputDirectory> + </component> + </components> + <componentProperties> + <drop>true</drop> + <configurationfile>/src/main/resources/hibernate.cfg.xml</configurationfile> + </componentProperties> + </configuration> + </plugin> + </plugins> + </build> + <repositories> + <repository> + <releases /> + <snapshots> + <enabled>false</enabled> + </snapshots> + <id>archive</id> + <url>http://builds.archive.org:8080/maven2</url> + </repository> + </repositories> + <dependencies> + <dependency> + <groupId>hsqldb</groupId> + <artifactId>hsqldb</artifactId> + <version>1.8.0.7</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-webmvc</artifactId> + <version>2.5.1</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-orm</artifactId> + <version>2.5.1</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-jdbc</artifactId> + <version>2.5.1</version> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.4</version> + </dependency> + <dependency> + <groupId>org.tuckey</groupId> + <artifactId>urlrewritefilter</artifactId> + <version>3.0.4</version> + </dependency> + <dependency> + <groupId>postgresql</groupId> + <artifactId>postgresql</artifactId> + <version>8.2-504.jdbc3</version> + </dependency> + <dependency> + <groupId>com.thoughtworks.xstream</groupId> + <artifactId>xstream</artifactId> + <version>1.2.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.jettison</groupId> + <artifactId>jettison</artifactId> + <version>1.0-beta-1</version> + </dependency> + <dependency> + <groupId>org.archive.heritrix</groupId> + <artifactId>commons</artifactId> + <version>2.0.0-RC1</version> + </dependency> + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate</artifactId> + <version>3.2.5.ga</version> + </dependency> + <dependency> + <groupId>commons-pool</groupId> + <artifactId>commons-pool</artifactId> + <version>1.3</version> + </dependency> + <dependency> + <groupId>commons-dbcp</groupId> + <artifactId>commons-dbcp</artifactId> + <version>1.2.2</version> + </dependency> + </dependencies> +</project> Added: trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/AccessControlClient.java =================================================================== --- trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/AccessControlClient.java (rev 0) +++ trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/AccessControlClient.java 2008-02-07 03:15:11 UTC (rev 2185) @@ -0,0 +1,106 @@ +package org.archive.accesscontrol; + +import java.util.Date; + +import org.archive.accesscontrol.model.HttpRuleDao; +import org.archive.accesscontrol.model.Rule; +import org.archive.accesscontrol.model.RuleDao; +import org.archive.accesscontrol.model.RuleSet; +import org.archive.net.PublicSuffixes; +import org.archive.util.SURT; + +/** + * The Exclusions Client provides a facade for accessing a remote or local + * exclusions oracle. + * + * In future it will perform heavy caching to prevent queries about related and + * recently-accessed pages from needing to hit the oracle. + * + * @author aosborne + */ +public class AccessControlClient { + protected RuleDao ruleDao; + + public AccessControlClient(RuleDao ruleDao) { + super(); + this.ruleDao = ruleDao; + } + + /** + * Create a new client to query a remote oracle. + * + * @param oracleUrl + * Base url of the oracle webapp. eg. + * "http://localhost:8080/exclusions-oracle/" + */ + public AccessControlClient(String oracleUrl) { + this(new HttpRuleDao(oracleUrl)); + } + + /** + * Return the best-matching policy for the requested document. + * + * @param url + * URL of the requested document. + * @param captureDate + * Date the document was archived. + * @param retrievalDate + * Date of retrieval (usually now). + * @param who + * Group name of the user accessing the document. + * @return Access-control policy that should be enforced. eg "robots", + * "block" or "allow". + */ + public String getPolicy(String url, Date captureDate, Date retrievalDate, + String who) { + Rule matchingRule = getRule(url, captureDate, retrievalDate, who); + return matchingRule.getPolicy(); + } + + /** + * Return the most specific matching rule for the requested document. + * + * @param url + * URL of the requested document. + * @param captureDate + * Date the document was archived. + * @param retrievalDate + * Date of retrieval (usually now). + * @param who + * Group name of the user accessing the document. + * @return + */ + public Rule getRule(String url, Date captureDate, Date retrievalDate, + String who) { + String surt = SURT.fromURI(url); + String publicSuffix = PublicSuffixes + .reduceSurtToTopmostAssigned(getSurtAuthority(surt)); + + surt = stripScheme(surt); + + RuleSet rules = ruleDao.getRuleTree("(" + publicSuffix); + Rule matchingRule = rules.getMatchingRule(surt, captureDate, + retrievalDate, who); + return matchingRule; + } + + protected String getSurtAuthority(String surt) { + int indexOfOpen = surt.indexOf("://("); + int indexOfClose = surt.indexOf(")"); + if (indexOfOpen == -1 || indexOfClose == -1 + || ((indexOfOpen + 4) >= indexOfClose)) { + return surt; + } + return surt.substring(indexOfOpen + 4, indexOfClose); + } + + protected static String stripScheme(String surt) { + int i = surt.indexOf("://"); + int j = surt.indexOf(":"); + if (i >= 0 && i == j) { + return surt.substring(i + 3); + } else { + return surt; + } + } +} Added: trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/HibernateRuleDao.java =================================================================== --- trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/HibernateRuleDao.java (rev 0) +++ trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/HibernateRuleDao.java 2008-02-07 03:15:11 UTC (rev 2185) @@ -0,0 +1,107 @@ + package org.archive.accesscontrol.model; + +import java.util.List; + +import org.apache.commons.httpclient.URIException; +import org.archive.surt.SURTTokenizer2; +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.springframework.orm.hibernate3.support.HibernateDaoSupport; + +/** + * The rule data access object provides convenience methods for using Hibernate + * to access stored rules. The database connection is expected to be configured + * using the SpringFramework ORM layer. + * + * @author aosborne + */ +@SuppressWarnings("unchecked") +public class HibernateRuleDao extends HibernateDaoSupport implements RuleDao { + public Rule getRule(Long id) { + return (Rule) getHibernateTemplate().get(Rule.class, id); + } + + public List<Rule> getAllRules() { + return getHibernateTemplate().find("from Rule"); + } + + public List<Rule> getRulesWithSurtPrefix(String prefix) { + // escape wildcard characters % and _ using ! as the escape character. + prefix = prefix.replace("!", "!!").replace("%", "!%") + .replace("_", "!_"); + return getHibernateTemplate().find( + "from Rule rule where rule.surt like ? escape '!'", + prefix + "%"); + } + + public List<Rule> getRulesWithExactSurt(String surt) { + return getHibernateTemplate().find( + "from Rule rule where rule.surt = ?", surt); + } + + /** + * Returns the "rule tree" for a given SURT. This is a sorted set of all + * rules equal or lower in specificity than the given SURT plus all rules on + * the path from this SURT to the root SURT "(". + * + * The intention is to call this function with a domain or public suffix, + * then queries within that domain can be made very fast by searching the + * resulting list. + * + * @param surt + * @return + */ + public RuleSet getRuleTree(String surt) { + RuleSet rules = new RuleSet(); + + // add the root SURT + rules.addAll(getRulesWithExactSurt("(")); + + // now pull out all of the requested branch and a path to the root + SURTTokenizer2 tok = SURTTokenizer2.newFromSURT(surt); + while (true) { + String search = tok.nextSearch(); + if (search == null) break; + + if (!search.endsWith(SURTTokenizer2.EXACT_SUFFIX)) { + rules.addAll(getRulesWithExactSurt(search)); + } else { + rules.addAll(getRulesWithSurtPrefix(search.substring(0, search.length() - 1))); + tok.nextSearch(); // skip the duplicate exact-match + } + } + + return rules; + } + + public void saveRule(Rule rule) { + getHibernateTemplate().saveOrUpdate(rule); + } + + /** + * Save a rule and a change log entry in one go. (Uses a transaction). + * @param rule + * @param change + */ + public void saveRule(Rule rule, RuleChange change) { + Session session1 = getHibernateTemplate().getSessionFactory().openSession(); + Transaction tx = session1.beginTransaction(); + session1.saveOrUpdate(rule); + session1.save(change); + tx.commit(); + session1.close(); + } + + public void saveChange(RuleChange change) { + getHibernateTemplate().saveOrUpdate(change); + } + + public void deleteRule(Long id) { + Object record = getHibernateTemplate().load(Rule.class, id); + getHibernateTemplate().delete(record); + } + + public void deleteAllRules() { + getHibernateTemplate().bulkUpdate("delete from Rule"); + } +} Added: trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/HttpRuleDao.java =================================================================== --- trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/HttpRuleDao.java (rev 0) +++ trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/HttpRuleDao.java 2008-02-07 03:15:11 UTC (rev 2185) @@ -0,0 +1,66 @@ +package org.archive.accesscontrol.model; + +import java.io.IOException; + +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpMethod; +import org.apache.commons.httpclient.methods.GetMethod; + +import com.thoughtworks.xstream.XStream; + +/** + * The HTTP Rule Data Access Object enables a rule database to be queried via + * the REST interface\xCAan oracle. + * + * For details of the protocol, see: + * http://webteam.archive.org/confluence/display/wayback/Exclusions+API + * + * @author aosborne + * + */ +public class HttpRuleDao implements RuleDao { + protected HttpClient http = new HttpClient(); + protected XStream xstream = new XStream(); + private String oracleUrl; + + public HttpRuleDao(String oracleUrl) { + this.oracleUrl = oracleUrl; + xstream.alias("rule", Rule.class); + xstream.alias("ruleSet", RuleSet.class); + } + + /** + * @see RuleDao#getRuleTree(String) + */ + public RuleSet getRuleTree(String surt) { + HttpMethod method = new GetMethod(oracleUrl + "/rules/tree/" + surt); + RuleSet rules; + + try { + http.executeMethod(method); + String response = method.getResponseBodyAsString(); + System.out.println(response); + rules = (RuleSet) xstream.fromXML(method.getResponseBodyAsStream()); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + method.releaseConnection(); + return rules; + } + + /** + * @return the oracleUrl + */ + public String getOracleUrl() { + return oracleUrl; + } + + /** + * @param oracleUrl the oracleUrl to set + */ + public void setOracleUrl(String oracleUrl) { + this.oracleUrl = oracleUrl; + } + +} Added: trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/Rule.java =================================================================== --- trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/Rule.java (rev 0) +++ trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/Rule.java 2008-02-07 03:15:11 UTC (rev 2185) @@ -0,0 +1,332 @@ +package org.archive.accesscontrol.model; + +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.SortedSet; + +import org.apache.commons.lang.ArrayUtils; + +/** + * An access control rules. Rules are organized into a tree based on SURT + * components. The leafmost (most specific) matching rule takes precedence. In + * the case that there are multiple matching rules for a particular node, allow + * takes precedence over deny which takes precedence over robots. + * + * @author aosborne + * + */ +public class Rule implements Comparable<Rule> { + + // in decreasing order of precedence + public static final String[] POLICIES = { "allow", "block", "robots" }; + + private Long id; + private String policy; + private String surt; + private Date captureStart; + private Date captureEnd; + private Date retrievalStart; + private Date retrievalEnd; + private Integer secondsSinceCapture; + private String who; + private String privateComment; + private String publicComment; + private Boolean enabled; + + public Rule() { + + } + + public Rule(String policy, String surt) { + super(); + this.policy = policy; + this.surt = surt; + } + + public Rule(String policy, String surt, Integer secondsSinceCapture) { + super(); + this.policy = policy; + this.surt = surt; + this.secondsSinceCapture = secondsSinceCapture; + } + + public Rule(String policy, String surt, String who) { + this(policy, surt); + this.who = who; + } + + + /** + * @return the enabled + */ + public Boolean getEnabled() { + return enabled; + } + + /** + * @param enabled the enabled to set + */ + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + /** + * Populate the rule data fields by copying them from a given rule. + */ + public void copyFrom(Rule rule) { + setPolicy(rule.getPolicy()); + setCaptureStart(rule.getCaptureStart()); + setCaptureEnd(rule.getCaptureEnd()); + setPrivateComment(rule.getPrivateComment()); + setPublicComment(rule.getPublicComment()); + setRetrievalStart(rule.getRetrievalStart()); + setRetrievalEnd(rule.getRetrievalEnd()); + setSecondsSinceCapture(rule.getSecondsSinceCapture()); + setSurt(rule.getSurt()); + setWho(rule.getWho()); + setEnabled(rule.getEnabled()); + } + + /** + * @return the id + */ + public Long getId() { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Long id) { + this.id = id; + } + + /** + * @return the policy + */ + public String getPolicy() { + return policy; + } + + /** + * @param policy + * the policy to set + */ + public void setPolicy(String policy) { + this.policy = policy; + } + + /** + * @return the surt + */ + public String getSurt() { + return surt; + } + + /** + * @param surt + * the surt to set + */ + public void setSurt(String surt) { + this.surt = surt; + } + + /** + * @return the captureStart + */ + public Date getCaptureStart() { + return captureStart; + } + + /** + * @param captureStart + * the captureStart to set + */ + public void setCaptureStart(Date captureStart) { + this.captureStart = captureStart; + } + + /** + * @return the captureEnd + */ + public Date getCaptureEnd() { + return captureEnd; + } + + /** + * @param captureEnd + * the captureEnd to set + */ + public void setCaptureEnd(Date captureEnd) { + this.captureEnd = captureEnd; + } + + /** + * @return the retrievalStart + */ + public Date getRetrievalStart() { + return retrievalStart; + } + + /** + * @param retrievalStart + * the retrievalStart to set + */ + public void setRetrievalStart(Date retrievalStart) { + this.retrievalStart = retrievalStart; + } + + /** + * @return the retrievalEnd + */ + public Date getRetrievalEnd() { + return retrievalEnd; + } + + /** + * @param retrievalEnd + * the retrievalEnd to set + */ + public void setRetrievalEnd(Date retrievalEnd) { + this.retrievalEnd = retrievalEnd; + } + + /** + * @return the secondsSinceCapture + */ + public Integer getSecondsSinceCapture() { + return secondsSinceCapture; + } + + /** + * @param secondsSinceCapture + * the secondsSinceCapture to set + */ + public void setSecondsSinceCapture(Integer secondsSinceCapture) { + this.secondsSinceCapture = secondsSinceCapture; + } + + /** + * @return the who + */ + public String getWho() { + return who; + } + + /** + * @param who + * the who to set + */ + public void setWho(String who) { + this.who = who; + } + + /** + * @return the privateComment + */ + public String getPrivateComment() { + return privateComment; + } + + /** + * @param privateComment + * the privateComment to set + */ + public void setPrivateComment(String privateComment) { + this.privateComment = privateComment; + } + + /** + * @return the publicComment + */ + public String getPublicComment() { + return publicComment; + } + + /** + * @param publicComment + * the publicComment to set + */ + public void setPublicComment(String publicComment) { + this.publicComment = publicComment; + } + + public Integer getPolicyId() { + return ArrayUtils.indexOf(POLICIES, getPolicy()); + } + + /* + * Rules are sorted in descending order of "specificity". + * So we order first by SURT, then group, then policy. + */ + public int compareTo(Rule o) { + int i = getSurt().compareTo(o.getSurt()); + if (i == 0) { + if (getWho() != null && o.getWho() == null) { + i = -1; + } else if (getWho() == null && o.getWho() != null) { + i = 1; + } else { + i = getPolicyId().compareTo(o.getPolicyId()); + } + } + return i; + } + + /** + * @see #matches(String, Date, Date, String) + */ + public boolean matches(String surt) { + return surt.startsWith(getSurt()); + } + + /** + * @see #matches(String, Date, Date, String) + */ + public boolean matches(String surt, Date captureDate) { + if (captureDate == null) { + return matches(surt); + } + return matches(surt) + && (getCaptureStart() == null || captureDate.after(getCaptureStart())) + && (getCaptureEnd() == null || captureDate.before(getCaptureEnd())); + } + + /** + * @see #matches(String, Date, Date, String) + */ + public boolean matches(String surt, Date captureDate, Date retrievalDate) { + if (retrievalDate == null) { + return matches(surt, captureDate); + } + + // embargo period + if (getSecondsSinceCapture() != null) { + GregorianCalendar periodEnd = new GregorianCalendar(); + periodEnd.setTime(captureDate); + periodEnd.add(Calendar.SECOND, getSecondsSinceCapture()); + + if (retrievalDate.before(periodEnd.getTime())) { + return false; + } + } + return matches(surt, captureDate) + && (getRetrievalStart() == null || retrievalDate.after(getRetrievalStart())) + && (getRetrievalEnd() == null || retrievalDate.before(getRetrievalEnd())); + } + + /** + * Return true if the given request matches against this rule. + * + * @param surt SURT of requested document + * @param captureDate Capture date of document + * @param retrievalDate + * @param who2 Group name of requesting user + * @return + */ + public boolean matches(String surt, Date captureDate, Date retrievalDate, String who2) { + return (who == null || who == who2) && matches(surt, captureDate, retrievalDate); + } +} Added: trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/RuleChange.java =================================================================== --- trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/RuleChange.java (rev 0) +++ trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/RuleChange.java 2008-02-07 03:15:11 UTC (rev 2185) @@ -0,0 +1,125 @@ +package org.archive.accesscontrol.model; + +import java.util.Date; + +/** + * The oracle keeps track of the history of rules by recording each change. This + * class describes a single change (create, update or delete). + * + * @author aosborne + * + */ +public class RuleChange extends Rule { + public static final String CREATED = "created"; + public static final String UPDATED = "updated"; + public static final String DELETED = "deleted"; + + private Date changeDate; + private String changeUser; + private String changeComment; + private String changeType; + private Long ruleId; + + public RuleChange() { + super(); + } + + public RuleChange(Rule rule, String changeType, Date changeDate, + String changeUser, String changeComment) { + super(); + setRule(rule); + setChangeType(changeType); + setChangeDate(changeDate); + setChangeUser(changeUser); + setChangeComment(changeComment); + copyFrom(rule); + } + + /** + * @return the date the rule was replaced. + */ + public Date getChangeDate() { + return changeDate; + } + + /** + * @param changeDate + * the changeDate to set + */ + public void setChangeDate(Date changeDate) { + this.changeDate = changeDate; + } + + /** + * @return the user who changed the rule + */ + public String getChangeUser() { + return changeUser; + } + + /** + * @param changeUser + * the user who changed the rule + */ + public void setChangeUser(String changeUser) { + this.changeUser = changeUser; + } + + /** + * @return a comment describing the change + */ + public String getChangeComment() { + return changeComment; + } + + /** + * @param changeComment + * a comment describing the change + */ + public void setChangeComment(String changeComment) { + this.changeComment = changeComment; + } + + /** + * @param rule + * the rule to set + */ + public void setRule(Rule rule) { + if (rule == null) { + setRuleId(null); + } else { + setRuleId(rule.getId()); + } + } + + /** + * @return the changeType + */ + public String getChangeType() { + return changeType; + } + + /** + * @param changeType + * the changeType to set + */ + public void setChangeType(String changeType) { + this.changeType = changeType; + } + + /** + * @return the ruleId + */ + public Long getRuleId() { + return ruleId; + } + + /** + * @param ruleId + * the ruleId to set + */ + public void setRuleId(Long ruleId) { + this.ruleId = ruleId; + } + +} Added: trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/RuleDao.java =================================================================== --- trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/RuleDao.java (rev 0) +++ trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/RuleDao.java 2008-02-07 03:15:11 UTC (rev 2185) @@ -0,0 +1,29 @@ +package org.archive.accesscontrol.model; + +import org.apache.commons.httpclient.URIException; + +/** + * A RuleDao provides methods for retrieving rule information from a local database or + * remote oracle. + * + * @author aosborne + * + */ +public interface RuleDao { + + /** + * Returns the "rule tree" for a given SURT. This is a sorted set of all + * rules equal or lower in specificity than the given SURT plus all rules on + * the path from this SURT to the root SURT "(". + * + * The intention is to call this function with a domain or public suffix, + * then queries within that domain can be made very fast by searching the + * resulting list. + * + * @param surt + * @return + * @throws URIException + */ + public RuleSet getRuleTree(String surt); + +} Added: trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/RuleSet.java =================================================================== --- trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/RuleSet.java (rev 0) +++ trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/accesscontrol/model/RuleSet.java 2008-02-07 03:15:11 UTC (rev 2185) @@ -0,0 +1,112 @@ +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.SURTTokenizer2; + +import sun.reflect.generics.reflectiveObjects.NotImplementedException; + +/** + * 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 = mapIterator.next().iterator(); + } + + public boolean hasNext() { + while (true) { + if (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 NotImplementedException(); + } + } + + 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) { + + SURTTokenizer2 tok = SURTTokenizer2.newFromSURT(surt); + boolean done = false; + + while (!done) { + String key = tok.nextSearch(); + if (key == null) { + key = "("; + done = true; + } + + Iterable<Rule> rules = rulemap.get(key); + if (rules != null) { + for (Rule rule : rules) { + if (rule.matches(surt, captureDate, retrievalDate, who)) { + return rule; + } + } + } + } + return null; + } + + 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(); + } + +} Added: trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/surt/SURTTokenizer2.java =================================================================== --- trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/surt/SURTTokenizer2.java (rev 0) +++ trunk/archive-access/projects/access-control/access-control/src/main/java/org/archive/surt/SURTTokenizer2.java 2008-02-07 03:15:11 UTC (rev 2185) @@ -0,0 +1,201 @@ +/* SURTTokenizer + * + * $Id: SURTTokenizer.java 4795 2006-12-12 23:42:09Z paul_jack $ + * + * Created on 3:21:49 PM May 11, 2006. + * + * Copyright (C) 2006 Internet Archive. + * + * This file is part of wayback. + * + * wayback is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * any later version. + * + * wayback is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser Public License for more details. + * + * You should have received a copy of the GNU Lesser Public License + * along with wayback; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package org.archive.surt; + +import java.util.Iterator; + +import org.apache.commons.httpclient.URIException; +import org.archive.net.UURI; +import org.archive.net.UURIFactory; +import org.archive.util.ArchiveUtils; +import org.archive.util.SURT; + +import sun.reflect.generics.reflectiveObjects.NotImplementedException; + +/** + * provides iterative Url reduction for prefix matching to find ever coarser + * grained URL-specific configuration. Assumes that a prefix binary search is + * being attempted for each returned value. First value is the entire SURT + * url String, with TAB appended. Second removes CGI ARGs. Then each subsequent + * path segment ('/' separated) is removed. Then the login:password, if present + * is removed. Then the port, if not :80 or omitted on the initial URL. Then + * each subsequent authority segment(. separated) is removed. + * + * the nextSearch() method will return null, finally, when no broader searches + * can be attempted on the URL. + * + * @author brad + * @version $Date: 2006-12-12 15:42:09 -0800 (Tue, 12 Dec 2006) $, $Revision: 4795 $ + */ +public class SURTTokenizer2 { + + public final static String EXACT_SUFFIX = "\t"; + private String remainder; + private boolean triedExact; + private boolean triedFull; + private boolean choppedArgs; + private boolean choppedPath; + private boolean choppedLogin; + private boolean choppedPort; + + public SURTTokenizer2() { + } + + public void setSURT(String surt) { + remainder = getKeyFromSURT(surt, false); + } + + /** + * constructor + * + * @param url String URL + * @throws URIException + */ + public SURTTokenizer2(final String url) throws URIException { + remainder = getKey(url,false); + } + /** + * update internal state and return the next smaller search string + * for the url + * + * @return string to lookup for prefix match for relevant information. + */ + public String nextSearch() { + if(!triedExact) { + triedExact = true; + //remainder = remainder.substring(0,remainder.length()-1); + return remainder + EXACT_SUFFIX; + } + if(!triedFull) { + triedFull = true; + return remainder; + } + if(!choppedArgs) { + choppedArgs = true; + int argStart = remainder.indexOf('?'); + if(argStart != -1) { + remainder = remainder.substring(0,argStart); + return remainder; + } + } + if(!choppedPath) { + int lastSlash = remainder.lastIndexOf('/'); + if(lastSlash != -1) { + remainder = remainder.substring(0,lastSlash); + if(remainder.endsWith(")")) { + remainder = remainder.substring(0,remainder.length()-1); + } + return remainder; + } + choppedPath = true; + } + if(!choppedLogin) { + choppedLogin = true; + int lastAt = remainder.lastIndexOf('@'); + if(lastAt != -1) { + remainder = remainder.substring(0,lastAt); + if(remainder.endsWith(",")) { + remainder = remainder.substring(0,remainder.length()-1); + } + return remainder; + } + } + if(!choppedPort) { + choppedPort = true; + int lastColon = remainder.lastIndexOf(':'); + if(lastColon != -1) { + remainder = remainder.substring(0,lastColon); + if(remainder.endsWith(",")) { + remainder = remainder.substring(0,remainder.length()-1); + } + return remainder; + } + } + // now just remove ','s + int lastComma = remainder.lastIndexOf(','); + if(lastComma == -1) { + return null; + } + remainder = remainder.substring(0,lastComma); + return remainder; + } + + /** + * @param url + * @return String SURT which will match exactly argument url + * @throws URIException + */ + public static String exactKey(String url) throws URIException { + return getKey(url,false); + } + + /** + * @param url + * @return String SURT which will match urls prefixed with the argument url + * @throws URIException + */ + public static String prefixKey(String url) throws URIException { + return getKey(url,true); + } + + private static String getKey(String url, boolean prefix) + throws URIException { + + String key = ArchiveUtils.addImpliedHttpIfNecessary(url); + UURI uuri = UURIFactory.getInstance(key); + key = uuri.getScheme() + "://" + uuri.getAuthority() + + uuri.getEscapedPathQuery(); + + key = SURT.fromURI(key); + key = getKeyFromSURT(key, prefix); + return key; + } + + private static String getKeyFromSURT(String surtKey, boolean prefix) { + int hashPos = surtKey.indexOf('#'); + if(hashPos != -1) { + surtKey = surtKey.substring(0,hashPos); + } + + if(surtKey.startsWith("http://")) { + surtKey = surtKey.substring(7); + } + if(prefix) { + if(surtKey.endsWith(")/")) { + surtKey = surtKey.substring(0,surtKey.length()-2); + } + } + return surtKey; + } + + /** + * Create new SURTTokenizer from a SURT rather than a URL. + */ + public static SURTTokenizer2 newFromSURT(String surt) { + SURTTokenizer2 tok = new SURTTokenizer2(); + tok.setSURT(surt); + return tok; + } +} Added: trunk/archive-access/projects/access-control/access-control/src/main/resources/Rule.hbm.xml =================================================================== --- trunk/archive-access/projects/access-control/access-control/src/main/resources/Rule.hbm.xml (rev 0) +++ trunk/archive-access/projects/access-control/access-control/src/main/resources/Rule.hbm.xml 2008-02-07 03:15:11 UTC (rev 2185) @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" > +<hibernate-mapping> + <class name="org.archive.accesscontrol.model.Rule" table="rules" polymorphism="explicit"> + <id name="id" column="id" type="java.lang.Long"> + <generator class="sequence"> + <param name="sequence">rule_id_seq</param> + </generator> + + </id> + + <property name="policy" column="policy" type="java.lang.String" /> + <property name="surt" column="surt" type="text" /> + <property name="captureStart" column="capture_start" + type="java.util.Date" /> + <property name="captureEnd" column="capture_end" + type="java.util.Date" /> + <property name="retrievalStart" column="retrieval_start" + type="java.util.Date" /> + <property name="retrievalEnd" column="retrieval_end" + type="java.util.Date" /> + <property name="secondsSinceCapture" + column="seconds_since_capture" type="java.lang.Integer" /> + <property name="who" column="who" type="java.lang.String" /> + <property name="privateComment" column="private_comment" type="text" /> + <property name="publicComment" column="public_comment" type="text" /> + <property name="enabled" column="enabled" type="java.lang.Boolean" /> + + </class> +</hibernate-mapping> \ No newline at end of file Added: trunk/archive-access/projects/access-control/access-control/src/main/resources/RuleChange.hbm.xml =================================================================== --- trunk/archive-access/projects/access-control/access-control/src/main/resources/RuleChange.hbm.xml (rev 0) +++ trunk/archive-access/projects/access-control/access-control/src/main/resources/RuleChange.hbm.xml 2008-02-07 03:15:11 UTC (rev 2185) @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" > +<hibernate-mapping> + <class name="org.archive.accesscontrol.model.RuleChange" table="rule_changes" polymorphism="explicit"> + <id name="id" column="id" type="java.lang.Long"> + <generator class="sequence"> + <param name="sequence">rule_change_id_seq</param> + </generator> + </id> + + <property name="ruleId" column="rule_id" type="java.lang.Long" /> + + <property name="changeDate" column="change_date" + type="java.util.Date" /> + <property name="changeUser" column="change_user" + type="java.lang.String" /> + <property name="changeComment" column="change_comment" + type="text" /> + <property name="changeType" column="change_type" + type="java.lang.String" /> + + <property name="policy" column="policy" type="java.lang.String" /> + <property name="surt" column="surt" type="text" /> + <property name="captureStart" column="capture_start" + type="java.util.Date" /> + <property name="captureEnd" column="capture_end" + type="java.util.Date" /> + <property name="retrievalStart" column="retrieval_start" + type="java.util.Date" /> + <property name="retrievalEnd" column="retrieval_end" + type="java.util.Date" /> + <property name="secondsSinceCapture" + column="seconds_since_capture" type="java.lang.Long" /> + <property name="who" column="who" type="java.lang.String" /> + <property name="privateComment" column="private_comment" type="text" /> + <property name="publicComment" column="public_comment" type="text" /> + <property name="enabled" column="enabled" type="java.lang.Boolean" /> + </class> +</hibernate-mapping> \ No newline at end of file Added: trunk/archive-access/projects/access-control/access-control/src/main/resources/hibernate.cfg.xml =================================================================== --- trunk/archive-access/projects/access-control/access-control/src/main/resources/hibernate.cfg.xml (rev 0) +++ trunk/archive-access/projects/access-control/access-control/src/main/resources/hibernate.cfg.xml 2008-02-07 03:15:11 UTC (rev 2185) @@ -0,0 +1,26 @@ +<?xml version='1.0' encoding='utf-8'?> +<!DOCTYPE hibernate-configuration PUBLIC +"-//Hibernate/Hibernate Configuration DTD 2.0//EN" +"http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd"> +<hibernate-configuration> + <session-factory> + <property name="connection.driver_class"> + org.hsqldb.jdbcDriver + </property> + <property name="connection.url"> + jdbc:hsqldb:data/userejb + </property> + <property name="connection.username">sa</property> + <property name="connection.password"></property> + <property name="show_sql">true</property> + <property name="dialect"> + org.hibernate.dialect.HSQLDialect + </property> + <property name="transaction.factory_class"> + org.hibernate.transaction.JDBCTransactionFactory + </property> + <mapping resource="Rule.hbm.xml" /> + <mapping resource="RuleChange.hbm.xml" /> + + </session-factory> +</hibernate-configuration> Added: trunk/archive-access/projects/access-control/access-control/src/test/java/org/archive/accesscontrol/AccessControlClientTest.java =================================================================== --- trunk/archive-access/projects/access-control/access-control/src/test/java/org/archive/accesscontrol/AccessControlClientTest.java (rev 0) +++ trunk/archive-access/projects/access-control/access-control/src/test/java/org/archive/accesscontrol/AccessControlClientTest.java 2008-02-07 03:15:11 UTC (rev 2185) @@ -0,0 +1,28 @@ +package org.archive.accesscontrol; + +import java.util.Date; + +import org.archive.accesscontrol.AccessControlClient; +import org.archive.accesscontrol.model.HttpRuleDao; + +import junit.framework.TestCase; + +public class AccessControlClientTest extends TestCase { + public static final String ORACLE_URL = "http://localhost:8080/exclusions-oracle-0.0.1-SNAPSHOT/"; + private AccessControlClient client; + + protected void setUp() throws Exception { + super.setUp(); + client = new AccessControlClient(new HttpRuleDao(ORACLE_URL)); + } + + protected void tearDown() throws Exception { + super.tearDown(); + client = null; + } + + public void testBasicOkToShow() throws Exception { + //System.out.println(client.getPolicy("http://www.archive.org/secret/page.html", new Date(), new Date())); + } + +} Added: trunk/archive-access/projects/access-control/access-control/src/test/java/org/archive/accesscontrol/model/DaoTestCase.java =================================================================== --- trunk/archive-access/projects/access-control/access-control/src/test/java/org/archive/accesscontrol/model/DaoTestCase.java (rev 0) +++ trunk/archive-access/projects/access-control/access-control/src/test/java/org/archive/accesscontrol/model/DaoTestCase.java 2008-02-07 03:15:11 UTC (rev 2185) @@ -0,0 +1,16 @@ +package org.archive.accesscontrol.model; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import junit.framework.TestCase; + +public abstract class DaoTestCase extends TestCase { + protected ApplicationContext ctx = null; + + public DaoTestCase() { + // Should put in a parent class that extends TestCase + String[] paths = { "applicationContext.xml" }; + ctx = new ClassPathXmlApplicationContext(paths); + } +} Added: trunk/archive-access/projects/access-control/access-control/src/test/java/org/archive/accesscontrol/model/HibernateRuleDaoTest.java =================================================================== --- trunk/archive-access/projects/access-control/access-control/src/test/java/org/archive/accesscontrol/model/HibernateRuleDaoTest.java (rev 0) +++ trunk/archive-access/projects/access-control/access-control/src/test/java/org/archive/accesscontrol/model/HibernateRuleDaoTest.java 2008-02-07 03:15:11 UTC (rev 2185) @@ -0,0 +1,144 @@ +package org.archive.accesscontrol.model; + +import java.util.Iterator; +import java.util.List; +import java.util.SortedSet; + +import org.archive.accesscontrol.model.HibernateRuleDao; +import org.archive.accesscontrol.model.Rule; +import org.archive.accesscontrol.model.RuleChange; + +import junit.framework.Assert; + +public class HibernateRuleDaoTest extends DaoTestCase { + private Rule rule = null; + private HibernateRuleDao dao = null; + + + protected void setUp() throws Exception { + super.setUp(); + dao = (HibernateRuleDao) ctx.getBean("ruleDao"); + + // clear database of rules + for (Rule rule: dao.getAllRules()) { + try { + dao.deleteRule(rule.getId()); + } catch (Exception e) {} + } + } + + protected void tearDown() throws Exception { + super.tearDown(); + dao = null; + } + + public void testSaveRecord() throws Exception { + rule = new Rule(); + rule.setSurt("org,archive"); + rule.setWho("admins"); + dao.saveRule(rule); + Assert.assertNotNull("primary key assigned", rule.getId()); + } + + public void testChange() throws Exception { + RuleChange change = new RuleChange(); + change.setSurt("org,archive"); + change.setWho("admins"); + dao.saveChange(change); + Assert.assertNotNull("primary key assigned", change.getId()); + } + + public void testSurtPrefixQuery() throws Exception { + rule = new Rule(); + rule.setSurt("http://(org,archive,unique)/%%__/fish"); + dao.saveRule(rule); + + Rule rule2 = new Rule(); + rule2.setSurt("http://(org,archive,unique)/blasted/fish"); + dao.saveRule(rule2); + + List<Rule> rules = dao.getRulesWithSurtPrefix("http://(org,archive,unique)/%%__"); + + Boolean foundRule1 = false; + Boolean foundRule2 = false; + for (Rule r: rules) { + if (rule.getId().e... [truncated message content] |