From 3ad03c07677056e2d5cb7194a03256bfccd68de6 Mon Sep 17 00:00:00 2001 From: j2blake Date: Fri, 6 May 2011 21:09:30 +0000 Subject: [PATCH] NIHVIVO-2279 Start to create a real DAO, with tests, etc. --- .../auth/permissions/PermissionSet.java | 40 ----- .../vitro/webapp/beans/PermissionSet.java | 51 ++++++ .../vitro/webapp/beans/UserAccount.java | 101 +++++++++-- .../accounts/BogusPermissionSetDao.java | 81 --------- .../accounts/UserAccountsListController.java | 23 +-- .../accounts/UserAccountsSelector.java | 4 +- .../vitro/webapp/dao/PermissionSetDao.java | 16 -- .../vitro/webapp/dao/UserAccountDao.java | 36 ---- .../vitro/webapp/dao/UserAccountsDao.java | 37 +++++ .../vitro/webapp/dao/WebappDaoFactory.java | 3 + .../filtering/UserAccountsDaoFiltering.java | 44 +++++ .../filtering/WebappDaoFactoryFiltering.java | 12 +- .../dao/filtering/filters/VitroFilters.java | 2 +- .../vitro/webapp/dao/jena/JenaBaseDao.java | 48 +++++- .../webapp/dao/jena/UserAccountsDaoJena.java | 123 ++++++++++++++ .../webapp/dao/jena/WebappDaoFactoryJena.java | 12 +- .../accounts/UserAccountsSelectorTest.java | 4 +- .../dao/jena/UserAccountsDaoJenaTest.java | 157 ++++++++++++++++++ .../jena/resources/UserAccountsDaoJenaTest.n3 | 38 +++++ .../webapp/dao/WebappDaoFactoryStub.java | 8 + 20 files changed, 624 insertions(+), 216 deletions(-) delete mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionSet.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/beans/PermissionSet.java delete mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/BogusPermissionSetDao.java delete mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/dao/PermissionSetDao.java delete mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/dao/UserAccountDao.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/dao/UserAccountsDao.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/UserAccountsDaoFiltering.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/UserAccountsDaoJena.java create mode 100644 webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/UserAccountsDaoJenaTest.java create mode 100644 webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/resources/UserAccountsDaoJenaTest.n3 diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionSet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionSet.java deleted file mode 100644 index 75047ba4d..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionSet.java +++ /dev/null @@ -1,40 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.permissions; - -import java.util.Set; - -/** - * Reflects a collection of Permissions that can be made available to a user. - * Similar to the concept of a Role. - */ -public class PermissionSet { - private String uri; - private String label; - private Set permissions; - - public String getUri() { - return uri; - } - - public void setUri(String uri) { - this.uri = uri; - } - - public String getLabel() { - return label; - } - - public void setLabel(String label) { - this.label = label; - } - - public Set getPermissions() { - return permissions; - } - - public void setPermissions(Set permissions) { - this.permissions = permissions; - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/PermissionSet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/PermissionSet.java new file mode 100644 index 000000000..160fb7c62 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/PermissionSet.java @@ -0,0 +1,51 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.beans; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** + * Reflects a collection of Permissions that can be made available to a user. + * Similar to the concept of a Role. + */ +public class PermissionSet { + /** This may be empty, but it should never be null. */ + private String uri = ""; + + /** This may be empty, but it should never be null. */ + private String label = ""; + + /** This may be empty, but it should never be null. */ + private Set permissionUris = Collections.emptySet(); + + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = (uri == null) ? "" : uri; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = (label == null) ? "" : label; + } + + public Set getPermissionUris() { + return permissionUris; + } + + public void setPermissionUris(Collection permissionUris) { + if (permissionUris == null) { + throw new NullPointerException("permissionUris may not be null."); + } + this.permissionUris = new HashSet(permissionUris); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/UserAccount.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/UserAccount.java index df428a959..79a7542e7 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/UserAccount.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/UserAccount.java @@ -12,20 +12,56 @@ import java.util.Set; */ public class UserAccount { public enum Status { - ACTIVE, INACTIVE + ACTIVE, INACTIVE; + + public static Status fromString(String s) { + if (s == null) { + return null; + } + + for (Status status : Status.values()) { + if (status.toString().equals(s)) { + return status; + } + } + + return null; + } + } + /** Should never be null. */ private String uri = ""; + + /** Should never be null. */ private String emailAddress = ""; + + /** Should never be null. */ private String firstName = ""; + + /** Should never be null. */ private String lastName = ""; - private String md5password = ""; - private long passwordChangeExpires = 0L; + + /** Should never be null. */ + private String md5Password = ""; + + /** Should never be null. */ + private String oldPassword = ""; + + /** Should never be negative. */ + private long passwordLinkExpires = 0L; + + private boolean passwordChangeRequired = false; + + /** Should never be negative. */ private int loginCount = 0; + + /** Might be null. */ private Status status = Status.INACTIVE; + /** This may be empty, but should never be null. */ private Set permissionSetUris = Collections.emptySet(); public String getUri() { @@ -33,6 +69,9 @@ public class UserAccount { } public void setUri(String uri) { + if (uri == null) { + throw new NullPointerException("uri may not be null."); + } this.uri = uri; } @@ -41,7 +80,7 @@ public class UserAccount { } public void setEmailAddress(String emailAddress) { - this.emailAddress = emailAddress; + this.emailAddress = nonNull(emailAddress, ""); } public String getFirstName() { @@ -49,7 +88,7 @@ public class UserAccount { } public void setFirstName(String firstName) { - this.firstName = firstName; + this.firstName = nonNull(firstName, ""); } public String getLastName() { @@ -57,23 +96,39 @@ public class UserAccount { } public void setLastName(String lastName) { - this.lastName = lastName; + this.lastName = nonNull(lastName, ""); } - public String getMd5password() { - return md5password; + public String getMd5Password() { + return md5Password; } - public void setMd5password(String md5password) { - this.md5password = md5password; + public void setMd5Password(String md5Password) { + this.md5Password = nonNull(md5Password, ""); } - public long getPasswordChangeExpires() { - return passwordChangeExpires; + public String getOldPassword() { + return oldPassword; } - public void setPasswordChangeExpires(long passwordChangeExpires) { - this.passwordChangeExpires = passwordChangeExpires; + public void setOldPassword(String oldPassword) { + this.oldPassword = nonNull(oldPassword, ""); + } + + public long getPasswordLinkExpires() { + return passwordLinkExpires; + } + + public void setPasswordLinkExpires(long passwordLinkExpires) { + this.passwordLinkExpires = Math.max(0, passwordLinkExpires); + } + + public boolean isPasswordChangeRequired() { + return passwordChangeRequired; + } + + public void setPasswordChangeRequired(Boolean passwordChangeRequired) { + this.passwordChangeRequired = nonNull(passwordChangeRequired, Boolean.FALSE); } public int getLoginCount() { @@ -81,7 +136,7 @@ public class UserAccount { } public void setLoginCount(int loginCount) { - this.loginCount = loginCount; + this.loginCount = Math.max(0, loginCount); } public Status getStatus() { @@ -92,21 +147,33 @@ public class UserAccount { this.status = status; } + public void setStatusFromString(String statusString) { + this.status = Status.fromString(statusString); + } + public Set getPermissionSetUris() { return new HashSet(permissionSetUris); } public void setPermissionSetUris(Collection permissionSetUris) { + if (permissionSetUris == null) { + throw new NullPointerException("permissionSetUris may not be null."); + } this.permissionSetUris = new HashSet(permissionSetUris); } + + private T nonNull(T value, T defaultValue) { + return (value == null) ? defaultValue : value; + } @Override public String toString() { return "UserAccount[uri=" + uri + ", emailAddress=" + emailAddress + ", firstName=" + firstName + ", lastName=" + lastName - + ", md5password=" + md5password + ", passwordChangeExpires=" - + passwordChangeExpires + ", loginCount=" + loginCount + + ", md5password=" + md5Password + ", passwordChangeExpires=" + + passwordLinkExpires + ", loginCount=" + loginCount + ", status=" + status + ", permissionSetUris=" + permissionSetUris + "]"; } + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/BogusPermissionSetDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/BogusPermissionSetDao.java deleted file mode 100644 index 23617dc82..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/BogusPermissionSetDao.java +++ /dev/null @@ -1,81 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.controller.accounts; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionSet; -import edu.cornell.mannlib.vitro.webapp.dao.PermissionSetDao; - -/** - * TODO Destroy this as soon as PermissionSetDaoJena is in place. - */ -public class BogusPermissionSetDao implements PermissionSetDao { - private static final Log log = LogFactory - .getLog(BogusPermissionSetDao.class); - - private final Map map; - - public BogusPermissionSetDao() { - Map psMap = new HashMap(); - putPermissionSet(psMap, createDbaPermissionSet()); - putPermissionSet(psMap, createCuratorPermissionSet()); - putPermissionSet(psMap, createEditorPermissionSet()); - putPermissionSet(psMap, createSelfEditorPermissionSet()); - this.map = Collections.unmodifiableMap(psMap); - } - - private void putPermissionSet(Map psMap, - PermissionSet ps) { - psMap.put(ps.getUri(), ps); - } - - private PermissionSet createDbaPermissionSet() { - PermissionSet ps = new PermissionSet(); - ps.setUri("http://vivo.mydomain.edu/individual/role1"); - ps.setLabel("DBA"); - return ps; - } - - private PermissionSet createCuratorPermissionSet() { - PermissionSet ps = new PermissionSet(); - ps.setUri("http://vivo.mydomain.edu/individual/role2"); - ps.setLabel("Curator"); - return ps; - } - - private PermissionSet createEditorPermissionSet() { - PermissionSet ps = new PermissionSet(); - ps.setUri("http://vivo.mydomain.edu/individual/role3"); - ps.setLabel("Editor"); - return ps; - } - - private PermissionSet createSelfEditorPermissionSet() { - PermissionSet ps = new PermissionSet(); - ps.setUri("http://vivo.mydomain.edu/individual/role4"); - ps.setLabel("Self-Editor"); - return ps; - } - - @Override - public PermissionSet getPermissionSetByUri(String uri) { - PermissionSet permissionSet = map.get(uri); - if (permissionSet == null) { - log.warn("Can't find a PermissionSet for uri '" + uri + "'"); - } - return permissionSet; - } - - @Override - public Collection getAllPermissionSets() { - return new ArrayList(map.values()); - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsListController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsListController.java index 3fb910b93..40c36689a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsListController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsListController.java @@ -18,9 +18,9 @@ import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.ontology.OntModel; -import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionSet; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageUserAccounts; +import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; @@ -30,8 +30,8 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; -import edu.cornell.mannlib.vitro.webapp.dao.PermissionSetDao; -import edu.cornell.mannlib.vitro.webapp.dao.UserAccountDao; +import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; /** @@ -55,18 +55,19 @@ public class UserAccountsListController extends FreemarkerHttpServlet { private static final String TEMPLATE_NAME = "userAccounts-list.ftl"; private OntModel userAccountsModel; - private PermissionSetDao permissionSetDao; - private UserAccountDao userAccountDao; + private UserAccountsDao userAccountsDao; @Override public void init() throws ServletException { super.init(); + OntModelSelector oms = (OntModelSelector) getServletContext() .getAttribute("baseOntModelSelector"); userAccountsModel = oms.getUserAccountsModel(); - // TODO Fix this when we have a real framework for PermissionSetDao - permissionSetDao = new BogusPermissionSetDao(); + WebappDaoFactory wdf = (WebappDaoFactory) getServletContext() + .getAttribute("webappDaoFactory"); + userAccountsDao = wdf.getUserAccountsDao(); } @Override @@ -83,7 +84,7 @@ public class UserAccountsListController extends FreemarkerHttpServlet { if (log.isDebugEnabled()) { dumpRequestParameters(vreq); } - + Map body = new HashMap(); UserAccountsSelectionCriteria criteria = buildCriteria(vreq); @@ -181,7 +182,7 @@ public class UserAccountsListController extends FreemarkerHttpServlet { private List buildRolesList() { List list = new ArrayList(); - list.addAll(permissionSetDao.getAllPermissionSets()); + list.addAll(userAccountsDao.getAllPermissionSets()); Collections.sort(list, new Comparator() { @Override public int compare(PermissionSet ps1, PermissionSet ps2) { @@ -223,7 +224,7 @@ public class UserAccountsListController extends FreemarkerHttpServlet { return null; } - return userAccountDao.getUserAccountByUri(uri); + return userAccountsDao.getUserAccountByUri(uri); } private boolean isFlagOnRequest(VitroRequest vreq, String key) { @@ -248,7 +249,7 @@ public class UserAccountsListController extends FreemarkerHttpServlet { private List findPermissionSetLabels(UserAccount account) { List labels = new ArrayList(); for (String uri : account.getPermissionSetUris()) { - PermissionSet pSet = permissionSetDao.getPermissionSetByUri(uri); + PermissionSet pSet = userAccountsDao.getPermissionSetByUri(uri); if (pSet != null) { labels.add(pSet.getLabel()); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsSelector.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsSelector.java index b1ca4cbfa..8ebd07685 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsSelector.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsSelector.java @@ -269,8 +269,8 @@ public class UserAccountsSelector { user.setEmailAddress(solution.getLiteral("email").getString()); user.setFirstName(ifLiteralPresent(solution, "firstName", "")); user.setLastName(ifLiteralPresent(solution, "lastName", "")); - user.setMd5password(ifLiteralPresent(solution, "pwd", "")); - user.setPasswordChangeExpires(ifLongPresent(solution, "expire", 0L)); + user.setMd5Password(ifLiteralPresent(solution, "pwd", "")); + user.setPasswordLinkExpires(ifLongPresent(solution, "expire", 0L)); user.setLoginCount(ifIntPresent(solution, "count", 0)); user.setStatus(parseStatus(solution, "status", null)); return user; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/PermissionSetDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/PermissionSetDao.java deleted file mode 100644 index 66f2c6e5e..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/PermissionSetDao.java +++ /dev/null @@ -1,16 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.dao; - -import java.util.Collection; - -import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionSet; - -/** - * Methods for manipulating PermissionSets. - */ -public interface PermissionSetDao { - public PermissionSet getPermissionSetByUri(String uri); - - public Collection getAllPermissionSets(); -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/UserAccountDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/UserAccountDao.java deleted file mode 100644 index 3b07c9a30..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/UserAccountDao.java +++ /dev/null @@ -1,36 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.dao; - -import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; - - -/** - * TODO - */ -public interface UserAccountDao { - - public UserAccount getUserAccountByUri(String uri); - - /** - *
-	 * public User getUserByUsername(String username);
-	 * 
-	 * public User getUserByURI(String URI);
-	 * 
-	 * public List<User> getAllUsers();
-	 * 
-	 * public void updateUser(User user);
-	 * 
-	 * public String insertUser(User user);
-	 * 
-	 * public void deleteUser(User user);
-	 * 
-	 * public List<String> getIndividualsUserMayEditAs(String userURI);
-	 * 
-	 * public List<String> getUserAccountEmails();
-	 * 
-	 * public String getUserEmailAddress(String userURI);
-	 * 
- */ -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/UserAccountsDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/UserAccountsDao.java new file mode 100644 index 000000000..b787bc15c --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/UserAccountsDao.java @@ -0,0 +1,37 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao; + +import java.util.Collection; + +import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet; +import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; + +/** + * Methods for dealing with UserAccount and PermissionSet objects in the User + * Accounts model. + */ +public interface UserAccountsDao { + + /** + * Get the UserAccount for this URI. + * + * @return null if the URI is null, or if there is no such UserAccount + */ + UserAccount getUserAccountByUri(String uri); + + /** + * Get the PermissionSet for this URI. + * + * @return null if the URI is null, or if there is no such PermissionSet. + */ + PermissionSet getPermissionSetByUri(String uri); + + /** + * Get all of the PermissionSets in the model. + * + * @return a collection which might be empty, but is never null. + */ + Collection getAllPermissionSets(); + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactory.java index a835e8783..3c1f5d8a7 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactory.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactory.java @@ -124,7 +124,10 @@ public interface WebappDaoFactory { public FlagDao getFlagDao(); + // TODO This goes away when the UserAccounts stuff is fully implemented - jblake. public UserDao getUserDao(); + + public UserAccountsDao getUserAccountsDao(); public VClassGroupDao getVClassGroupDao(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/UserAccountsDaoFiltering.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/UserAccountsDaoFiltering.java new file mode 100644 index 000000000..4253b5093 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/UserAccountsDaoFiltering.java @@ -0,0 +1,44 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.filtering; + +import java.util.Collection; + +import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet; +import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; +import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; +import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilters; + +/** + * This doesn't actually do any filtering. It's just a placeholder in case we + * decide to filter either UserAccounts or PermissionSets. + */ +public class UserAccountsDaoFiltering extends BaseFiltering implements + UserAccountsDao { + + private final UserAccountsDao innerDao; + + @SuppressWarnings("unused") + private final VitroFilters filters; + + public UserAccountsDaoFiltering(UserAccountsDao userDao, + VitroFilters filters) { + this.innerDao = userDao; + this.filters = filters; + } + + @Override + public UserAccount getUserAccountByUri(String uri) { + return innerDao.getUserAccountByUri(uri); + } + + @Override + public PermissionSet getPermissionSetByUri(String uri) { + return innerDao.getPermissionSetByUri(uri); + } + + @Override + public Collection getAllPermissionSets() { + return innerDao.getAllPermissionSets(); + } +} \ No newline at end of file diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/WebappDaoFactoryFiltering.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/WebappDaoFactoryFiltering.java index 014335297..020cd89be 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/WebappDaoFactoryFiltering.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/WebappDaoFactoryFiltering.java @@ -29,6 +29,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.PropertyInstanceDao; import edu.cornell.mannlib.vitro.webapp.dao.TabDao; import edu.cornell.mannlib.vitro.webapp.dao.TabIndividualRelationDao; import edu.cornell.mannlib.vitro.webapp.dao.TabVClassRelationDao; +import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; import edu.cornell.mannlib.vitro.webapp.dao.UserDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupDao; @@ -72,7 +73,8 @@ public class WebappDaoFactoryFiltering implements WebappDaoFactory { transient private VClassDao filteringVClassDao=null; transient private TabDao filteringTabDao=null; - transient private UserDao filteringUserDao=null; + transient private UserDao filteringUserDao=null; // TODO This goes away when the UserAccounts stuff is fully implemented - jblake. + transient private UserAccountsDao filteringUserAccountsDao=null; transient private VClassGroupDao filteringVClassGroupDao=null; transient private PropertyGroupDao filteringPropertyGroupDao=null; transient private PropertyInstanceDao filteringPropertyInstanceDao=null; @@ -137,6 +139,7 @@ public class WebappDaoFactoryFiltering implements WebappDaoFactory { return filteringTabDao; } + // TODO This goes away when the UserAccounts stuff is fully implemented - jblake. public UserDao getUserDao() { if( filteringUserDao == null) filteringUserDao = @@ -144,6 +147,13 @@ public class WebappDaoFactoryFiltering implements WebappDaoFactory { return filteringUserDao; } + public UserAccountsDao getUserAccountsDao() { + if( filteringUserAccountsDao == null) + filteringUserAccountsDao = + new UserAccountsDaoFiltering(innerWebappDaoFactory.getUserAccountsDao(),filters); + return filteringUserAccountsDao; + } + public VClassGroupDao getVClassGroupDao() { if( filteringVClassGroupDao == null) filteringVClassGroupDao = diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/filters/VitroFilters.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/filters/VitroFilters.java index 017114196..ef42e7cc2 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/filters/VitroFilters.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/filters/VitroFilters.java @@ -42,7 +42,7 @@ public interface VitroFilters { public UnaryFunctor getVClassGroupFilter(); - + // TODO This goes away when the UserAccounts stuff is fully implemented -- jb public UnaryFunctor getUserFilter(); public UnaryFunctor getPropertyGroupFilter(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java index 0ba35b96b..079f04aa6 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java @@ -5,8 +5,8 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Collection; import java.util.Date; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -31,8 +31,6 @@ import com.hp.hpl.jena.query.Query; import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QueryExecutionFactory; import com.hp.hpl.jena.query.QueryFactory; -import com.hp.hpl.jena.query.QuerySolution; -import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.query.Syntax; import com.hp.hpl.jena.rdf.model.AnonId; import com.hp.hpl.jena.rdf.model.Literal; @@ -119,10 +117,10 @@ public class JenaBaseDao extends JenaBaseDaoCon { protected String getPropertyStringValue(OntResource res, Property dataprop) { if (dataprop != null) { try { - ClosableIterator stateIt = res.getModel().listStatements(res,dataprop,(Literal)null); + ClosableIterator stateIt = res.getModel().listStatements(res,dataprop,(Literal)null); try { if (stateIt.hasNext()) - return ((Literal)((Statement)stateIt.next()).getObject()).getString(); + return ((Literal)stateIt.next().getObject()).getString(); else return null; } finally { @@ -320,6 +318,21 @@ public class JenaBaseDao extends JenaBaseDaoCon { } + /** + * convenience method + */ + protected long getPropertyLongValue(OntResource res, Property dataprop) { + if (dataprop != null) { + try { + return ((Literal)res.getPropertyValue(dataprop)).getLong(); + } catch (Exception e) { + return -1L; + } + } else { + return -1L; + } + } + /** * convenience method */ @@ -441,9 +454,6 @@ public class JenaBaseDao extends JenaBaseDaoCon { /** * convenience method - * @param ind - * @param dataprop - * @param value */ protected synchronized void addPropertyDateTimeValue(Resource res, Property dataprop, Date value, Model model) { if (dataprop != null && value != null) { @@ -479,6 +489,28 @@ public class JenaBaseDao extends JenaBaseDaoCon { } } + /** + * convenience method for use with functional object properties + */ + protected Collection getPropertyResourceURIValues(Resource res, ObjectProperty prop) { + List list = new ArrayList(); + if (prop != null) { + try { + ClosableIterator stateIt = res.getModel().listStatements(res,prop,(Literal)null); + try { + while(stateIt.hasNext()) { + list.add(stateIt.next().getObject().asResource().getURI()); + } + } finally { + stateIt.close(); + } + } catch (Exception e) { + log.debug("can't get object property URI values: ", e); + } + } + return list; + } + /** * convenience method for use with functional object properties */ diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/UserAccountsDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/UserAccountsDaoJena.java new file mode 100644 index 000000000..63548e7a5 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/UserAccountsDaoJena.java @@ -0,0 +1,123 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.ontology.OntResource; +import com.hp.hpl.jena.rdf.model.Statement; +import com.hp.hpl.jena.shared.Lock; +import com.hp.hpl.jena.util.iterator.ClosableIterator; +import com.hp.hpl.jena.vocabulary.RDF; +import com.hp.hpl.jena.vocabulary.RDFS; + +import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet; +import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; +import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; + +/** + * Implement UserAccountsDao for Jena models. + */ +public class UserAccountsDaoJena extends JenaBaseDao implements UserAccountsDao { + public UserAccountsDaoJena(WebappDaoFactoryJena wadf) { + super(wadf); + } + + @Override + protected OntModel getOntModel() { + return getOntModelSelector().getUserAccountsModel(); + } + + @Override + public UserAccount getUserAccountByUri(String uri) { + if (uri == null) { + return null; + } + + getOntModel().enterCriticalSection(Lock.READ); + try { + OntResource r = getOntModel().getOntResource(uri); + if (r == null) { + return null; + } + + UserAccount u = new UserAccount(); + u.setUri(r.getURI()); + u.setEmailAddress(getPropertyStringValue(r, + USERACCOUNT_EMAIL_ADDRESS)); + u.setFirstName(getPropertyStringValue(r, USERACCOUNT_FIRST_NAME)); + u.setLastName(getPropertyStringValue(r, USERACCOUNT_LAST_NAME)); + u.setMd5Password(getPropertyStringValue(r, USERACCOUNT_MD5_PASSWORD)); + u.setOldPassword(getPropertyStringValue(r, USERACCOUNT_OLD_PASSWORD)); + u.setPasswordLinkExpires(getPropertyLongValue(r, + USERACCOUNT_PASSWORD_LINK_EXPIRES)); + u.setPasswordChangeRequired(getPropertyBooleanValue(r, + USERACCOUNT_PASSWORD_CHANGE_REQUIRED)); + u.setLoginCount(getPropertyIntValue(r, USERACCOUNT_LOGIN_COUNT)); + u.setStatusFromString(getPropertyStringValue(r, USERACCOUNT_STATUS)); + u.setPermissionSetUris(getPropertyResourceURIValues(r, + USERACCOUNT_HAS_PERMISSION_SET)); + return u; + } finally { + getOntModel().leaveCriticalSection(); + } + } + + @Override + public PermissionSet getPermissionSetByUri(String uri) { + if (uri == null) { + return null; + } + + getOntModel().enterCriticalSection(Lock.READ); + try { + OntResource r = getOntModel().getOntResource(uri); + if (r == null) { + return null; + } + + PermissionSet ps = new PermissionSet(); + ps.setUri(uri); + ps.setLabel(getPropertyStringValue(r, RDFS.label)); + ps.setPermissionUris(getPropertyResourceURIValues(r, + PERMISSIONSET_HAS_PERMISSION)); + return ps; + } finally { + getOntModel().leaveCriticalSection(); + } + } + + @Override + public Collection getAllPermissionSets() { + List list = new ArrayList(); + + getOntModel().enterCriticalSection(Lock.READ); + try { + ClosableIterator stmtIt = getOntModel().listStatements( + null, RDF.type, PERMISSIONSET); + try { + while (stmtIt.hasNext()) { + Statement stmt = stmtIt.next(); + OntResource r = stmt.getSubject().as(OntResource.class); + + PermissionSet ps = new PermissionSet(); + ps.setUri(r.getURI()); + ps.setLabel(getPropertyStringValue(r, RDFS.label)); + ps.setPermissionUris(getPropertyResourceURIValues(r, + PERMISSIONSET_HAS_PERMISSION)); + list.add(ps); + } + } finally { + stmtIt.close(); + } + } finally { + getOntModel().leaveCriticalSection(); + } + + return list; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java index d81cf1c9a..6c8d61f46 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java @@ -56,6 +56,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.PropertyInstanceDao; import edu.cornell.mannlib.vitro.webapp.dao.TabDao; import edu.cornell.mannlib.vitro.webapp.dao.TabIndividualRelationDao; import edu.cornell.mannlib.vitro.webapp.dao.TabVClassRelationDao; +import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; import edu.cornell.mannlib.vitro.webapp.dao.UserDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupDao; @@ -77,7 +78,8 @@ public class WebappDaoFactoryJena implements WebappDaoFactory { protected TabIndividualRelationDao tabs2EntsDao; protected TabVClassRelationDao tabs2TypesDao; - protected UserDao userDao; + protected UserDao userDao; // TODO This goes away when the UserAccounts stuff is fully implemented -- jb + protected UserAccountsDao userAccountsDao; protected VClassGroupDao vClassGroupDao; protected PropertyGroupDao propertyGroupDao; @@ -528,6 +530,7 @@ public class WebappDaoFactoryJena implements WebappDaoFactory { return propertyGroupDao = new PropertyGroupDaoJena(this); } + // TODO This goes away when the UserAccounts stuff is fully implemented -- jb public UserDao getUserDao() { if (userDao != null) return userDao; @@ -535,6 +538,13 @@ public class WebappDaoFactoryJena implements WebappDaoFactory { return userDao = new UserDaoJena(this); } + public UserAccountsDao getUserAccountsDao() { + if (userAccountsDao != null) + return userAccountsDao; + else + return userAccountsDao = new UserAccountsDaoJena(this); + } + Classes2ClassesDao classes2ClassesDao = null; public Classes2ClassesDao getClasses2ClassesDao() { if(classes2ClassesDao == null ) diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsSelectorTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsSelectorTest.java index 1c39c08a3..773f3d888 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsSelectorTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsSelectorTest.java @@ -93,8 +93,8 @@ public class UserAccountsSelectorTest extends AbstractTestClass { assertEquals("email", "email@jones.edu", acct.getEmailAddress()); assertEquals("firstName", "Brian", acct.getFirstName()); assertEquals("lastName", "Caruso", acct.getLastName()); - assertEquals("password", "garbage", acct.getMd5password()); - assertEquals("expires", 1100234965897L, acct.getPasswordChangeExpires()); + assertEquals("password", "garbage", acct.getMd5Password()); + assertEquals("expires", 1100234965897L, acct.getPasswordLinkExpires()); assertEquals("loginCount", 50, acct.getLoginCount()); assertEquals("status", UserAccount.Status.ACTIVE, acct.getStatus()); assertEqualSets( diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/UserAccountsDaoJenaTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/UserAccountsDaoJenaTest.java new file mode 100644 index 000000000..3a6cff241 --- /dev/null +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/UserAccountsDaoJenaTest.java @@ -0,0 +1,157 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.log4j.Level; +import org.junit.Before; +import org.junit.Test; + +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.ontology.OntModelSpec; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; + +import edu.cornell.mannlib.vitro.testing.AbstractTestClass; +import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet; +import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; +import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status; + +/** + * TODO + */ +public class UserAccountsDaoJenaTest extends AbstractTestClass { + /** + * Where the model statements are stored for this test. + */ + private static final String N3_DATA_FILENAME = "resources/UserAccountsDaoJenaTest.n3"; + + private static final String NS_AUTH = "http://vitro.mannlib.cornell.edu/ns/vitro/authorization#"; + private static final String NS_MINE = "http://vivo.mydomain.edu/individual/"; + + private OntModel ontModel; + private WebappDaoFactoryJena wadf; + private UserAccountsDaoJena dao; + + @Before + public void setup() throws IOException { + InputStream stream = UserAccountsDaoJenaTest.class + .getResourceAsStream(N3_DATA_FILENAME); + Model model = ModelFactory.createDefaultModel(); + model.read(stream, null, "N3"); + stream.close(); + + ontModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM, + model); + ontModel.prepare(); + + wadf = new WebappDaoFactoryJena(ontModel); + dao = new UserAccountsDaoJena(wadf); + } + + @Test + public void getUserAccountByUriSuccess() { + UserAccount u = dao.getUserAccountByUri(NS_MINE + "user01"); + assertEquals("uri", NS_MINE + "user01", u.getUri()); + assertEquals("email", "email@able.edu", u.getEmailAddress()); + assertEquals("firstName", "Zack", u.getFirstName()); + assertEquals("lastName", "Roberts", u.getLastName()); + assertEquals("md5Password", "garbage", u.getMd5Password()); + assertEquals("oldPassword", "", u.getOldPassword()); + assertEquals("changeExpires", 0L, u.getPasswordLinkExpires()); + assertEquals("changeRequired", false, u.isPasswordChangeRequired()); + assertEquals("loginCount", 5, u.getLoginCount()); + assertEquals("status", Status.ACTIVE, u.getStatus()); + assertEquals("permissionSetUris", + Collections.singleton(NS_MINE + "role1"), + u.getPermissionSetUris()); + } + + @Test + public void getUserAccountByUriNull() { + UserAccount u = dao.getUserAccountByUri(null); + assertNull("null result", u); + } + + @Test + public void getUserAccountByUriNotFound() { + UserAccount u = dao.getUserAccountByUri("bogusUri"); + assertNull("null result", u); + } + + @Test + public void getPermissionSetByUriSuccess() { + PermissionSet ps = dao.getPermissionSetByUri(NS_MINE + "role1"); + assertEquals("uri", NS_MINE + "role1", ps.getUri()); + assertEquals("label", "Role 1", ps.getLabel()); + assertEquals("permissionUris", + Collections.singleton(NS_MINE + "permissionA"), + ps.getPermissionUris()); + } + + @Test + public void getPermissionSetByUriNull() { + PermissionSet ps = dao.getPermissionSetByUri(null); + assertNull("null result", ps); + } + + @Test + public void getPermissionSetByUriNotFound() { + PermissionSet ps = dao.getPermissionSetByUri("bogusUri"); + assertNull("null result", ps); + } + + @Test + public void getAllPermissionSets() { + setLoggerLevel(JenaBaseDao.class, Level.DEBUG); + + Set expected = new HashSet(); + + PermissionSet ps1 = new PermissionSet(); + ps1.setUri(NS_MINE + "role1"); + ps1.setLabel("Role 1"); + ps1.setPermissionUris(Collections.singleton(NS_MINE + "permissionA")); + expected.add(ps1); + + PermissionSet ps2 = new PermissionSet(); + ps2.setUri(NS_MINE + "role2"); + ps2.setLabel("Role 2"); + expected.add(ps2); + + assertCorrectPermissionSets(expected, dao.getAllPermissionSets()); + } + + private void assertCorrectPermissionSets(Set expected, + Collection actual) { + Set> expectedMaps = new HashSet>(); + for (PermissionSet ps : expected) { + Map map = new HashMap(); + map.put("uri", ps.getUri()); + map.put("label", ps.getLabel()); + map.put("permissions", ps.getPermissionUris()); + expectedMaps.add(map); + } + + Set> actualMaps = new HashSet>(); + for (PermissionSet ps : actual) { + Map map = new HashMap(); + map.put("uri", ps.getUri()); + map.put("label", ps.getLabel()); + map.put("permissions", ps.getPermissionUris()); + actualMaps.add(map); + } + + assertEquals("all permission sets", expectedMaps, actualMaps); + } +} diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/resources/UserAccountsDaoJenaTest.n3 b/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/resources/UserAccountsDaoJenaTest.n3 new file mode 100644 index 000000000..23ccced76 --- /dev/null +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/resources/UserAccountsDaoJenaTest.n3 @@ -0,0 +1,38 @@ +# $This file is distributed under the terms of the license in /doc/license.txt$ + +@prefix rdf: . +@prefix rdfs: . +@prefix owl: . +@prefix auth: . +@prefix mydomain: . + +### This file is for the test UserAccountsSelectorTest.java. + +mydomain:user01 + a auth:UserAccount ; + auth:emailAddress "email@able.edu" ; + auth:firstName "Zack" ; + auth:lastName "Roberts" ; + auth:md5password "garbage" ; + auth:passwordChangeExpires 0 ; + auth:loginCount 5 ; + auth:status "ACTIVE" ; + auth:hasPermissionSet mydomain:role1 ; + . + +mydomain:role1 + a auth:PermissionSet ; + rdfs:label "Role 1" ; + auth:hasPermission mydomain:permissionA ; + . + +mydomain:role2 + a auth:PermissionSet ; + rdfs:label "Role 2" ; + . + +mydomain:permissionA + a auth:Permission ; + rdfs:label "Permission A" ; + . + \ No newline at end of file diff --git a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactoryStub.java b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactoryStub.java index 0c0082444..159949814 100644 --- a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactoryStub.java +++ b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactoryStub.java @@ -29,6 +29,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.PropertyInstanceDao; import edu.cornell.mannlib.vitro.webapp.dao.TabDao; import edu.cornell.mannlib.vitro.webapp.dao.TabIndividualRelationDao; import edu.cornell.mannlib.vitro.webapp.dao.TabVClassRelationDao; +import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; import edu.cornell.mannlib.vitro.webapp.dao.UserDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupDao; @@ -240,12 +241,19 @@ public class WebappDaoFactoryStub implements WebappDaoFactory { "WebappDaoFactory.getFlagDao() not implemented."); } + // TODO This goes away when the UserAccounts stuff is fully implemented -- jb @Override public UserDao getUserDao() { throw new RuntimeException( "WebappDaoFactory.getUserDao() not implemented."); } + @Override + public UserAccountsDao getUserAccountsDao() { + throw new RuntimeException( + "WebappDaoFactory.getUserAccountsDao() not implemented."); + } + @Override public VClassGroupDao getVClassGroupDao() { throw new RuntimeException(