NIHVIVO-2343 First stab at a ProxyRelationshipSelector and tests.
This commit is contained in:
parent
b3edf5cb3d
commit
b06467e893
9 changed files with 1251 additions and 0 deletions
|
@ -0,0 +1,77 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An immutable collection of fields that will be displayed in a
|
||||||
|
* ProxyRelationship.
|
||||||
|
*/
|
||||||
|
public class ProxyItemInfo {
|
||||||
|
private final String uri;
|
||||||
|
private final String label;
|
||||||
|
private final String classLabel;
|
||||||
|
private final String imageUrl;
|
||||||
|
|
||||||
|
public ProxyItemInfo(String uri, String label, String classLabel,
|
||||||
|
String imageUrl) {
|
||||||
|
this.uri = uri;
|
||||||
|
this.label = label;
|
||||||
|
this.classLabel = classLabel;
|
||||||
|
this.imageUrl = imageUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUri() {
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClassLabel() {
|
||||||
|
return classLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getImageUrl() {
|
||||||
|
return imageUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!o.getClass().equals(this.getClass())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ProxyItemInfo that = (ProxyItemInfo) o;
|
||||||
|
return equivalent(this.uri, that.uri)
|
||||||
|
&& equivalent(this.label, that.label)
|
||||||
|
&& equivalent(this.classLabel, that.classLabel)
|
||||||
|
&& equivalent(this.imageUrl, that.imageUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean equivalent(Object o1, Object o2) {
|
||||||
|
return (o1 == null) ? (o2 == null) : o1.equals(o2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return hash(this.uri) ^ hash(this.label) ^ hash(this.classLabel)
|
||||||
|
^ hash(this.imageUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int hash(Object o) {
|
||||||
|
return (o == null) ? 0 : o.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ProxyItemInfo[uri=" + uri + ", label=" + label
|
||||||
|
+ ", classLabel=" + classLabel + ", imageUrl=" + imageUrl + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An immutable relationship between Proxies and Profiles.
|
||||||
|
*
|
||||||
|
* In most cases, this will either be between one Proxy and many Profiles (view
|
||||||
|
* by Proxy), or between on Profile and many Proxies (view by Profile). However,
|
||||||
|
* we can imagine it being a many-to-many relationship.
|
||||||
|
*/
|
||||||
|
public class ProxyRelationship {
|
||||||
|
private final List<ProxyItemInfo> proxyInfos;
|
||||||
|
private final List<ProxyItemInfo> profileInfos;
|
||||||
|
|
||||||
|
public ProxyRelationship(List<ProxyItemInfo> proxyInfos,
|
||||||
|
List<ProxyItemInfo> profileInfos) {
|
||||||
|
this.proxyInfos = Collections
|
||||||
|
.unmodifiableList(new ArrayList<ProxyItemInfo>(proxyInfos));
|
||||||
|
this.profileInfos = Collections
|
||||||
|
.unmodifiableList(new ArrayList<ProxyItemInfo>(profileInfos));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ProxyItemInfo> getProxyInfos() {
|
||||||
|
return proxyInfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ProxyItemInfo> getProfileInfos() {
|
||||||
|
return profileInfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ProxyRelationship[proxyInfos=" + proxyInfos + ", profileInfos="
|
||||||
|
+ profileInfos + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An immutable group of relationships (might be empty), with the criteria that
|
||||||
|
* were used to select them.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ProxyRelationshipSelection {
|
||||||
|
private final ProxyRelationshipSelectionCriteria criteria;
|
||||||
|
private final List<ProxyRelationship> proxyRelationships;
|
||||||
|
private final int totalResultCount;
|
||||||
|
|
||||||
|
public ProxyRelationshipSelection(
|
||||||
|
ProxyRelationshipSelectionCriteria criteria,
|
||||||
|
List<ProxyRelationship> proxyRelationships, int totalResultCount) {
|
||||||
|
this.criteria = criteria;
|
||||||
|
this.proxyRelationships = Collections
|
||||||
|
.unmodifiableList(new ArrayList<ProxyRelationship>(
|
||||||
|
proxyRelationships));
|
||||||
|
this.totalResultCount = totalResultCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProxyRelationshipSelectionCriteria getCriteria() {
|
||||||
|
return criteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ProxyRelationship> getProxyRelationships() {
|
||||||
|
return proxyRelationships;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTotalResultCount() {
|
||||||
|
return totalResultCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ProxyRelationshipSelection[count=" + totalResultCount
|
||||||
|
+ ", relationships=" + proxyRelationships + ", criteria="
|
||||||
|
+ criteria + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A mutable version of ProxyRelationshipSelection, that can be assembled
|
||||||
|
* piecemeal as the info becomes available and then translated to an immutable
|
||||||
|
* ProxyRelationshipSelection.
|
||||||
|
*
|
||||||
|
* Uses mutable subclasses Relationship and ItemInfo.
|
||||||
|
*
|
||||||
|
* ItemInfo contains a field for externalAuthId only because it is useful when
|
||||||
|
* gathering the classLabel and imageUrl.
|
||||||
|
*/
|
||||||
|
public class ProxyRelationshipSelectionBuilder {
|
||||||
|
final ProxyRelationshipSelectionCriteria criteria;
|
||||||
|
|
||||||
|
final List<Relationship> relationships = new ArrayList<Relationship>();
|
||||||
|
int count;
|
||||||
|
|
||||||
|
public ProxyRelationshipSelectionBuilder(
|
||||||
|
ProxyRelationshipSelectionCriteria criteria) {
|
||||||
|
this.criteria = criteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProxyRelationshipSelection build() {
|
||||||
|
List<ProxyRelationship> proxyRelationships = new ArrayList<ProxyRelationship>();
|
||||||
|
for (Relationship r : relationships) {
|
||||||
|
proxyRelationships.add(buildProxyRelationship(r));
|
||||||
|
}
|
||||||
|
return new ProxyRelationshipSelection(criteria, proxyRelationships,
|
||||||
|
count);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ProxyRelationship buildProxyRelationship(Relationship r) {
|
||||||
|
List<ProxyItemInfo> proxyInfos = buildInfos(r.proxyInfos);
|
||||||
|
List<ProxyItemInfo> profileInfos = buildInfos(r.profileInfos);
|
||||||
|
return new ProxyRelationship(proxyInfos, profileInfos);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ProxyItemInfo> buildInfos(List<ItemInfo> infos) {
|
||||||
|
List<ProxyItemInfo> result = new ArrayList<ProxyItemInfo>();
|
||||||
|
for (ItemInfo info : infos) {
|
||||||
|
result.add(new ProxyItemInfo(info.uri, info.label, info.classLabel,
|
||||||
|
info.imageUrl));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Relationship {
|
||||||
|
final List<ItemInfo> proxyInfos = new ArrayList<ItemInfo>();
|
||||||
|
final List<ItemInfo> profileInfos = new ArrayList<ItemInfo>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ItemInfo {
|
||||||
|
String uri = "";
|
||||||
|
String label = "";
|
||||||
|
String externalAuthId = "";
|
||||||
|
String classLabel = "";
|
||||||
|
String imageUrl = "";
|
||||||
|
|
||||||
|
public ItemInfo() {
|
||||||
|
// leave fields at default values.
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemInfo(String uri, String label, String externalAuthId,
|
||||||
|
String classLabel, String imageUrl) {
|
||||||
|
this.uri = uri;
|
||||||
|
this.label = label;
|
||||||
|
this.externalAuthId = externalAuthId;
|
||||||
|
this.classLabel = classLabel;
|
||||||
|
this.imageUrl = imageUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On what basis are we selecting proxy relationships?
|
||||||
|
*
|
||||||
|
* Are we viewing by Proxy or by Profile? What is the search term, if any? How
|
||||||
|
* many results per page, and what page are we on?
|
||||||
|
*
|
||||||
|
* Search terms are matched against last name combined with first name, of
|
||||||
|
* either UserAccount(Proxy) or Individual(Profile), depending on how we are
|
||||||
|
* listing. Searches are case-insensitive.
|
||||||
|
*/
|
||||||
|
public class ProxyRelationshipSelectionCriteria {
|
||||||
|
public static final int DEFAULT_RELATIONSHIPS_PER_PAGE = 20;
|
||||||
|
|
||||||
|
public static final ProxyRelationshipSelectionCriteria DEFAULT_CRITERIA = new ProxyRelationshipSelectionCriteria(
|
||||||
|
DEFAULT_RELATIONSHIPS_PER_PAGE, 1, ProxyRelationshipView.BY_PROXY,
|
||||||
|
"");
|
||||||
|
|
||||||
|
public enum ProxyRelationshipView {
|
||||||
|
BY_PROXY, BY_PROFILE;
|
||||||
|
|
||||||
|
public static ProxyRelationshipView DEFAULT_VIEW = BY_PROXY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** How many relationships should we bring back, at most? */
|
||||||
|
private final int relationshipsPerPage;
|
||||||
|
|
||||||
|
/** What page are we on? (1-origin) */
|
||||||
|
private final int pageIndex;
|
||||||
|
|
||||||
|
/** What view are we using? */
|
||||||
|
private final ProxyRelationshipView viewBy;
|
||||||
|
|
||||||
|
/** What term are we searching on, if any? */
|
||||||
|
private final String searchTerm;
|
||||||
|
|
||||||
|
public ProxyRelationshipSelectionCriteria(int relationshipsPerPage,
|
||||||
|
int pageIndex, ProxyRelationshipView viewBy, String searchTerm) {
|
||||||
|
if (relationshipsPerPage <= 0) {
|
||||||
|
throw new IllegalArgumentException("relationshipsPerPage "
|
||||||
|
+ "must be a positive integer, not " + relationshipsPerPage);
|
||||||
|
}
|
||||||
|
this.relationshipsPerPage = relationshipsPerPage;
|
||||||
|
|
||||||
|
if (pageIndex <= 0) {
|
||||||
|
throw new IllegalArgumentException("pageIndex must be a "
|
||||||
|
+ "non-negative integer, not " + pageIndex);
|
||||||
|
}
|
||||||
|
this.pageIndex = pageIndex;
|
||||||
|
|
||||||
|
this.viewBy = nonNull(viewBy, ProxyRelationshipView.DEFAULT_VIEW);
|
||||||
|
this.searchTerm = nonNull(searchTerm, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRelationshipsPerPage() {
|
||||||
|
return relationshipsPerPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPageIndex() {
|
||||||
|
return pageIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProxyRelationshipView getViewBy() {
|
||||||
|
return viewBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSearchTerm() {
|
||||||
|
return searchTerm;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> T nonNull(T t, T nullValue) {
|
||||||
|
return (t == null) ? nullValue : t;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ProxyRelationshipSelectionCriteria[relationshipsPerPage="
|
||||||
|
+ relationshipsPerPage + ", pageIndex=" + pageIndex
|
||||||
|
+ ", viewBy=" + viewBy + "', searchTerm='" + searchTerm + "']";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,402 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import com.hp.hpl.jena.ontology.OntModel;
|
||||||
|
import com.hp.hpl.jena.query.QuerySolution;
|
||||||
|
import com.hp.hpl.jena.query.ResultSet;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies.ProxyRelationshipSelectionBuilder.ItemInfo;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies.ProxyRelationshipSelectionBuilder.Relationship;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies.ProxyRelationshipSelectionCriteria.ProxyRelationshipView;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner.QueryParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class which will accept a ProxyRelationshipSelectionCriteria and produce a
|
||||||
|
* ProxyRelationshipSelection.
|
||||||
|
*/
|
||||||
|
public class ProxyRelationshipSelector {
|
||||||
|
private static final Log log = LogFactory
|
||||||
|
.getLog(ProxyRelationshipSelector.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience method.
|
||||||
|
*/
|
||||||
|
public static ProxyRelationshipSelection select(Context context,
|
||||||
|
ProxyRelationshipSelectionCriteria criteria) {
|
||||||
|
return new ProxyRelationshipSelector(context, criteria).select();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String PREFIX_LINES = ""
|
||||||
|
+ "PREFIX fn: <http://www.w3.org/2005/xpath-functions#> \n"
|
||||||
|
+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n"
|
||||||
|
+ "PREFIX auth: <http://vitro.mannlib.cornell.edu/ns/vitro/authorization#> \n"
|
||||||
|
+ "PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> \n"
|
||||||
|
+ "PREFIX vpublic: <http://vitro.mannlib.cornell.edu/ns/vitro/public#> \n";
|
||||||
|
|
||||||
|
private final Context context;
|
||||||
|
private final ProxyRelationshipSelectionCriteria criteria;
|
||||||
|
private final ProxyRelationshipSelectionBuilder builder;
|
||||||
|
|
||||||
|
public ProxyRelationshipSelector(Context context,
|
||||||
|
ProxyRelationshipSelectionCriteria criteria) {
|
||||||
|
if (context == null) {
|
||||||
|
throw new NullPointerException("context may not be null.");
|
||||||
|
}
|
||||||
|
this.context = context;
|
||||||
|
|
||||||
|
if (criteria == null) {
|
||||||
|
throw new NullPointerException("criteria may not be null.");
|
||||||
|
}
|
||||||
|
this.criteria = criteria;
|
||||||
|
|
||||||
|
this.builder = new ProxyRelationshipSelectionBuilder(criteria);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProxyRelationshipSelection select() {
|
||||||
|
if (criteria.getViewBy() == ProxyRelationshipView.BY_PROXY) {
|
||||||
|
figureTotalResultCount();
|
||||||
|
getProxyBasics();
|
||||||
|
expandProxies();
|
||||||
|
getRelationships();
|
||||||
|
expandProfiles();
|
||||||
|
} else {
|
||||||
|
// This implementation is brain-dead if you ask for BY_PROFILE.
|
||||||
|
// Maybe someday soon.
|
||||||
|
log.error("Trying to select ProxyRelationships by profile!");
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String COUNT_QUERY_TEMPLATE = "" //
|
||||||
|
+ "%prefixes% \n" //
|
||||||
|
+ "SELECT count(DISTINCT ?uri) \n" //
|
||||||
|
+ "WHERE {\n" //
|
||||||
|
+ " ?uri a auth:UserAccount ; \n" //
|
||||||
|
+ " auth:firstName ?firstName ; \n" //
|
||||||
|
+ " auth:lastName ?lastName ; \n" //
|
||||||
|
+ " auth:proxyEditorFor ?profile . \n" //
|
||||||
|
+ "} \n"; //
|
||||||
|
|
||||||
|
private void figureTotalResultCount() {
|
||||||
|
String qString = COUNT_QUERY_TEMPLATE.replace("%prefixes%",
|
||||||
|
PREFIX_LINES);
|
||||||
|
|
||||||
|
int count = new SparqlQueryRunner<Integer>(context.userAccountsModel,
|
||||||
|
new CountQueryParser()).executeQuery(qString);
|
||||||
|
|
||||||
|
log.debug("result count: " + count);
|
||||||
|
builder.count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String QUERY_PROXY_BASICS = "" //
|
||||||
|
+ "%prefixes% \n" //
|
||||||
|
+ "SELECT DISTINCT ?uri ?label ?externalAuthId \n" //
|
||||||
|
+ "WHERE { \n" //
|
||||||
|
+ " ?uri a auth:UserAccount ; \n" //
|
||||||
|
+ " auth:firstName ?firstName ; \n" //
|
||||||
|
+ " auth:lastName ?lastName ; \n" //
|
||||||
|
+ " auth:proxyEditorFor ?profile . \n" //
|
||||||
|
+ " LET ( ?label := fn:concat(?lastName, ', ', ?firstName) )" //
|
||||||
|
+ " OPTIONAL { ?uri auth:externalAuthId ?externalAuthId } \n" //
|
||||||
|
+ "} \n" //
|
||||||
|
+ "ORDER BY ASC(?lastName) ASC(?firstName) \n" //
|
||||||
|
+ "LIMIT %perPage% \n" //
|
||||||
|
+ "OFFSET %offset%\n";
|
||||||
|
|
||||||
|
private void getProxyBasics() {
|
||||||
|
String qString = QUERY_PROXY_BASICS
|
||||||
|
.replace("%prefixes%", PREFIX_LINES)
|
||||||
|
.replace("%perPage%",
|
||||||
|
String.valueOf(criteria.getRelationshipsPerPage()))
|
||||||
|
.replace("%offset%", offset());
|
||||||
|
|
||||||
|
List<Relationship> relationships = new SparqlQueryRunner<List<Relationship>>(
|
||||||
|
context.userAccountsModel, new ProxyBasicsParser())
|
||||||
|
.executeQuery(qString);
|
||||||
|
log.debug("getProxyBasics returns: " + relationships);
|
||||||
|
builder.relationships.addAll(relationships);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String QUERY_EXPAND_PROXY = "" //
|
||||||
|
+ "%prefixes% \n" //
|
||||||
|
+ "SELECT ?classLabel ?imageUrl \n" //
|
||||||
|
+ "WHERE { \n" //
|
||||||
|
+ " ?uri <%matchingProperty%> '%externalAuthId%'. \n" //
|
||||||
|
+ " OPTIONAL { \n"
|
||||||
|
+ " ?uri vitro:mostSpecificType ?type. \n" //
|
||||||
|
+ " ?type rdfs:label ?classLabel \n" //
|
||||||
|
+ " } \n" //
|
||||||
|
+ " OPTIONAL { \n" //
|
||||||
|
+ " ?uri vpublic:mainImage ?imageUri. \n" //
|
||||||
|
+ " ?imageUri vpublic:thumbnailImage ?thumbUri. \n" //
|
||||||
|
+ " ?thumbUri vpublic:downloadLocation ?thumbstreamUri. \n" //
|
||||||
|
+ " ?thumbstreamUri vpublic:directDownloadUrl ?imageUrl. \n" //
|
||||||
|
+ " } \n" //
|
||||||
|
+ "} \n" //
|
||||||
|
+ "LIMIT 1 \n"; //
|
||||||
|
|
||||||
|
private void expandProxies() {
|
||||||
|
if (context.matchingProperty.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Relationship r : builder.relationships) {
|
||||||
|
for (ItemInfo proxy : r.proxyInfos) {
|
||||||
|
if (proxy.externalAuthId.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String qString = QUERY_EXPAND_PROXY
|
||||||
|
.replace("%prefixes%", PREFIX_LINES)
|
||||||
|
.replace("%matchingProperty%", context.matchingProperty)
|
||||||
|
.replace("%externalAuthId%", proxy.externalAuthId);
|
||||||
|
|
||||||
|
ItemInfo expansion = new SparqlQueryRunner<ItemInfo>(
|
||||||
|
context.unionModel, new ExpandProxyParser())
|
||||||
|
.executeQuery(qString);
|
||||||
|
proxy.classLabel = expansion.classLabel;
|
||||||
|
proxy.imageUrl = expansion.imageUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String QUERY_RELATIONSHIPS = "" //
|
||||||
|
+ "%prefixes% \n" //
|
||||||
|
+ "SELECT DISTINCT ?profileUri \n" //
|
||||||
|
+ "WHERE { \n" //
|
||||||
|
+ " <%proxyUri%> a auth:UserAccount ; \n" //
|
||||||
|
+ " auth:proxyEditorFor ?profileUri . \n" //
|
||||||
|
+ "} \n"; //
|
||||||
|
|
||||||
|
private void getRelationships() {
|
||||||
|
for (Relationship r : builder.relationships) {
|
||||||
|
for (ItemInfo proxy : r.proxyInfos) {
|
||||||
|
String qString = QUERY_RELATIONSHIPS.replace("%prefixes%",
|
||||||
|
PREFIX_LINES).replace("%proxyUri%", proxy.uri);
|
||||||
|
|
||||||
|
List<String> profileUris = new SparqlQueryRunner<List<String>>(
|
||||||
|
context.userAccountsModel, new RelationshipsParser())
|
||||||
|
.executeQuery(qString);
|
||||||
|
|
||||||
|
for (String profileUri : profileUris) {
|
||||||
|
r.profileInfos
|
||||||
|
.add(new ItemInfo(profileUri, "", "", "", ""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String QUERY_EXPAND_PROFILE = "" //
|
||||||
|
+ "%prefixes% \n" //
|
||||||
|
+ "SELECT ?label ?classLabel ?imageUrl \n" //
|
||||||
|
+ "WHERE { \n" //
|
||||||
|
+ " <%profileUri%> rdfs:label ?label . \n" //
|
||||||
|
+ " OPTIONAL { \n"
|
||||||
|
+ " <%profileUri%> vitro:mostSpecificType ?type. \n" //
|
||||||
|
+ " ?type rdfs:label ?classLabel \n" //
|
||||||
|
+ " } \n" //
|
||||||
|
+ " OPTIONAL { \n" //
|
||||||
|
+ " <%profileUri%> vpublic:mainImage ?imageUri. \n" //
|
||||||
|
+ " ?imageUri vpublic:thumbnailImage ?thumbUri. \n" //
|
||||||
|
+ " ?thumbUri vpublic:downloadLocation ?thumbstreamUri. \n" //
|
||||||
|
+ " ?thumbstreamUri vpublic:directDownloadUrl ?imageUrl. \n" //
|
||||||
|
+ " } \n" //
|
||||||
|
+ "} \n" //
|
||||||
|
+ "LIMIT 1 \n"; //
|
||||||
|
|
||||||
|
private void expandProfiles() {
|
||||||
|
for (Relationship r : builder.relationships) {
|
||||||
|
for (ItemInfo profile : r.profileInfos) {
|
||||||
|
String qString = QUERY_EXPAND_PROFILE.replace("%prefixes%",
|
||||||
|
PREFIX_LINES).replace("%profileUri%", profile.uri);
|
||||||
|
|
||||||
|
ItemInfo expansion = new SparqlQueryRunner<ItemInfo>(
|
||||||
|
context.unionModel, new ExpandProfileParser())
|
||||||
|
.executeQuery(qString);
|
||||||
|
profile.label = expansion.label;
|
||||||
|
profile.classLabel = expansion.classLabel;
|
||||||
|
profile.imageUrl = expansion.imageUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String offset() {
|
||||||
|
int offset = criteria.getRelationshipsPerPage()
|
||||||
|
* (criteria.getPageIndex() - 1);
|
||||||
|
return String.valueOf(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* What do we need to make this work? 2 models and an optional property.
|
||||||
|
*/
|
||||||
|
public static class Context {
|
||||||
|
private final OntModel userAccountsModel;
|
||||||
|
private final OntModel unionModel;
|
||||||
|
private final String matchingProperty;
|
||||||
|
|
||||||
|
public Context(OntModel userAccountsModel, OntModel unionModel,
|
||||||
|
String matchingProperty) {
|
||||||
|
if (userAccountsModel == null) {
|
||||||
|
throw new NullPointerException(
|
||||||
|
"userAccountsModel may not be null.");
|
||||||
|
}
|
||||||
|
this.userAccountsModel = userAccountsModel;
|
||||||
|
|
||||||
|
if (unionModel == null) {
|
||||||
|
throw new NullPointerException("unionModel may not be null.");
|
||||||
|
}
|
||||||
|
this.unionModel = unionModel;
|
||||||
|
|
||||||
|
if (matchingProperty == null) {
|
||||||
|
this.matchingProperty = "";
|
||||||
|
} else {
|
||||||
|
this.matchingProperty = matchingProperty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Parser classes
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
private static class ProxyBasicsParser extends
|
||||||
|
QueryParser<List<Relationship>> {
|
||||||
|
@Override
|
||||||
|
protected List<Relationship> defaultValue() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<Relationship> parseResults(String queryStr,
|
||||||
|
ResultSet results) {
|
||||||
|
List<Relationship> relationships = new ArrayList<Relationship>();
|
||||||
|
while (results.hasNext()) {
|
||||||
|
try {
|
||||||
|
relationships.add(parseSolution(results.next()));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("Failed to parse the query result: " + queryStr, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return relationships;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Relationship parseSolution(QuerySolution solution) {
|
||||||
|
ItemInfo info = new ItemInfo();
|
||||||
|
info.uri = solution.getResource("uri").getURI();
|
||||||
|
info.label = solution.getLiteral("label").getString();
|
||||||
|
info.externalAuthId = ifLiteralPresent(solution, "externalAuthId",
|
||||||
|
"");
|
||||||
|
|
||||||
|
Relationship r = new Relationship();
|
||||||
|
r.proxyInfos.add(info);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class CountQueryParser extends QueryParser<Integer> {
|
||||||
|
@Override
|
||||||
|
protected Integer defaultValue() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Integer parseResults(String queryStr, ResultSet results) {
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
if (!results.hasNext()) {
|
||||||
|
log.warn("count query returned no results.");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
QuerySolution solution = results.next();
|
||||||
|
count = ifIntPresent(solution, ".1", 0);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("Failed to parse the query result" + queryStr, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ExpandProxyParser extends QueryParser<ItemInfo> {
|
||||||
|
@Override
|
||||||
|
protected ItemInfo defaultValue() {
|
||||||
|
return new ItemInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ItemInfo parseResults(String queryStr, ResultSet results) {
|
||||||
|
ItemInfo item = new ItemInfo();
|
||||||
|
|
||||||
|
if (results.hasNext()) {
|
||||||
|
try {
|
||||||
|
QuerySolution solution = results.next();
|
||||||
|
item.classLabel = ifLiteralPresent(solution, "classLabel",
|
||||||
|
"");
|
||||||
|
item.imageUrl = ifLiteralPresent(solution, "imageUrl", "");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("Failed to parse the query result" + queryStr, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class RelationshipsParser extends QueryParser<List<String>> {
|
||||||
|
@Override
|
||||||
|
protected List<String> defaultValue() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<String> parseResults(String queryStr, ResultSet results) {
|
||||||
|
List<String> proxyUris = new ArrayList<String>();
|
||||||
|
while (results.hasNext()) {
|
||||||
|
try {
|
||||||
|
QuerySolution solution = results.next();
|
||||||
|
proxyUris.add(solution.getResource("profileUri").getURI());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("Failed to parse the query result: " + queryStr, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return proxyUris;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ExpandProfileParser extends QueryParser<ItemInfo> {
|
||||||
|
@Override
|
||||||
|
protected ItemInfo defaultValue() {
|
||||||
|
return new ItemInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ItemInfo parseResults(String queryStr, ResultSet results) {
|
||||||
|
ItemInfo item = new ItemInfo();
|
||||||
|
|
||||||
|
if (results.hasNext()) {
|
||||||
|
try {
|
||||||
|
QuerySolution solution = results.next();
|
||||||
|
item.label = ifLiteralPresent(solution, "label", "");
|
||||||
|
item.classLabel = ifLiteralPresent(solution, "classLabel",
|
||||||
|
"");
|
||||||
|
item.imageUrl = ifLiteralPresent(solution, "imageUrl", "");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("Failed to parse the query result" + queryStr, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,281 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies;
|
||||||
|
|
||||||
|
import static edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies.ProxyRelationshipSelectionCriteria.ProxyRelationshipView.DEFAULT_VIEW;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.log4j.Level;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
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.controller.accounts.manageproxies.ProxyRelationshipSelectionCriteria.ProxyRelationshipView;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies.ProxyRelationshipSelector.Context;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
public class ProxyRelationshipSelectorTest extends AbstractTestClass {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final String URL_PROFILE_IMAGE = "http://mydomain.edu/profileImage.jpg";
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final String URL_SELF_IMAGE = "http://mydomain.edu/selfImage.jpg";
|
||||||
|
private static final String USER_ACCOUNT_DATA_FILENAME = "ProxyRelationshipSelectorTest_UserAccountsModel.n3";
|
||||||
|
private static final String UNION_DATA_FILENAME = "ProxyRelationshipSelectorTest_UnionModel.n3";
|
||||||
|
|
||||||
|
private static final String NS_MINE = "http://vivo.mydomain.edu/individual/";
|
||||||
|
private static final String MATCHING_PROPERTY = NS_MINE + "matching";
|
||||||
|
|
||||||
|
private static OntModel userAccountsModel;
|
||||||
|
private static OntModel unionModel;
|
||||||
|
private static Context context;
|
||||||
|
|
||||||
|
private ProxyRelationshipSelection selection;
|
||||||
|
private ProxyRelationshipSelectionCriteria criteria;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setupModel() throws IOException {
|
||||||
|
userAccountsModel = prepareModel(USER_ACCOUNT_DATA_FILENAME);
|
||||||
|
unionModel = prepareModel(UNION_DATA_FILENAME);
|
||||||
|
context = new Context(userAccountsModel, unionModel, MATCHING_PROPERTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static OntModel prepareModel(String filename) throws IOException {
|
||||||
|
InputStream stream = ProxyRelationshipSelectorTest.class
|
||||||
|
.getResourceAsStream(filename);
|
||||||
|
Model model = ModelFactory.createDefaultModel();
|
||||||
|
model.read(stream, null, "N3");
|
||||||
|
stream.close();
|
||||||
|
|
||||||
|
OntModel ontModel = ModelFactory.createOntologyModel(
|
||||||
|
OntModelSpec.OWL_DL_MEM, model);
|
||||||
|
ontModel.prepare();
|
||||||
|
return ontModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// exceptions tests
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@Test(expected = NullPointerException.class)
|
||||||
|
public void contextIsNull() {
|
||||||
|
ProxyRelationshipSelector.select(null,
|
||||||
|
criteria(10, 1, DEFAULT_VIEW, ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NullPointerException.class)
|
||||||
|
public void userAccountsModelIsNull_select_nullPointerException() {
|
||||||
|
Context brokenContext = new Context(null, unionModel, MATCHING_PROPERTY);
|
||||||
|
ProxyRelationshipSelector.select(brokenContext,
|
||||||
|
criteria(10, 1, DEFAULT_VIEW, ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NullPointerException.class)
|
||||||
|
public void unionModelIsNull_select_nullPointerException() {
|
||||||
|
Context brokenContext = new Context(userAccountsModel, null,
|
||||||
|
MATCHING_PROPERTY);
|
||||||
|
ProxyRelationshipSelector.select(brokenContext,
|
||||||
|
criteria(10, 1, DEFAULT_VIEW, ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NullPointerException.class)
|
||||||
|
public void criteriaIsNull() {
|
||||||
|
ProxyRelationshipSelector.select(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// fields tests
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void checkAllFieldsOnFirstRelationship() {
|
||||||
|
setLoggerLevel(SparqlQueryRunner.class, Level.DEBUG);
|
||||||
|
selectOnCriteria(1, 1, DEFAULT_VIEW, "");
|
||||||
|
System.out.println("SELECTION: " + selection);
|
||||||
|
assertExpectedCounts(7, counts(1, 1));
|
||||||
|
|
||||||
|
ProxyRelationship pr = selection.getProxyRelationships().get(0);
|
||||||
|
assertEquals(
|
||||||
|
"proxy",
|
||||||
|
item(NS_MINE + "userFirstProxy", "AAAA, FirstProxy", "Self",
|
||||||
|
URL_SELF_IMAGE), pr.getProxyInfos().get(0));
|
||||||
|
assertEquals(
|
||||||
|
"profile",
|
||||||
|
item(NS_MINE + "firstProfile", "AAAA, FirstProfile", "Profile",
|
||||||
|
URL_PROFILE_IMAGE), pr.getProfileInfos().get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test plan:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* pagination tests: (repeat both views?)
|
||||||
|
* page 1 of several
|
||||||
|
* page 1 of 1
|
||||||
|
* page 2 of several
|
||||||
|
* page out of range (zero results)
|
||||||
|
* last page divides evenly
|
||||||
|
* last page divides unevenly
|
||||||
|
*
|
||||||
|
* search tests: (repeat both views)
|
||||||
|
* some results
|
||||||
|
* no results
|
||||||
|
* special REGEX characters
|
||||||
|
*
|
||||||
|
* profile w/no proxies
|
||||||
|
* profile w/proxies
|
||||||
|
* no associated profile
|
||||||
|
* profile w/no classLabel
|
||||||
|
* profile w/no imageUrl
|
||||||
|
* profile w/neither
|
||||||
|
* profile w/both
|
||||||
|
*
|
||||||
|
* proxy w/no profiles
|
||||||
|
* proxy w profiles:
|
||||||
|
* no classLabel
|
||||||
|
* no imageUrl
|
||||||
|
* neither
|
||||||
|
* both
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// pagination tests
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// @Test
|
||||||
|
// public void showFirstPageOfFifteen() {
|
||||||
|
// selectOnCriteria(15, 1, DEFAULT_ORDERING, "", "");
|
||||||
|
// assertSelectedUris(10, "user01", "user02", "user03", "user04",
|
||||||
|
// "user05", "user06", "user07", "user08", "user09", "user10");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// public void showFirstPageOfOne() {
|
||||||
|
// selectOnCriteria(1, 1, DEFAULT_ORDERING, "", "");
|
||||||
|
// assertSelectedUris(10, "user01");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// public void showFirstPageOfFive() {
|
||||||
|
// selectOnCriteria(5, 1, DEFAULT_ORDERING, "", "");
|
||||||
|
// assertSelectedUris(10, "user01", "user02", "user03", "user04", "user05");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// public void showSecondPageOfSeven() {
|
||||||
|
// selectOnCriteria(7, 2, DEFAULT_ORDERING, "", "");
|
||||||
|
// assertSelectedUris(10, "user08", "user09", "user10");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// public void showTenthPageOfThree() {
|
||||||
|
// selectOnCriteria(3, 10, DEFAULT_ORDERING, "", "");
|
||||||
|
// assertSelectedUris(10);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// search tests
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// public void searchTermFoundInAllThreeFields() {
|
||||||
|
// selectOnCriteria(20, 1, DEFAULT_ORDERING, "", "bob");
|
||||||
|
// assertSelectedUris(3, "user02", "user05", "user10");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// public void searchTermNotFound() {
|
||||||
|
// selectOnCriteria(20, 1, DEFAULT_ORDERING, "", "bogus");
|
||||||
|
// assertSelectedUris(0);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * If the special characters were allowed into the Regex, this would have
|
||||||
|
// 3
|
||||||
|
// * matches. If they are escaped properly, it will have none.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void searchTermContainsSpecialRegexCharacters() {
|
||||||
|
// selectOnCriteria(20, 1, DEFAULT_ORDERING, "", "b.b");
|
||||||
|
// assertSelectedUris(0);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // ----------------------------------------------------------------------
|
||||||
|
// // combination tests
|
||||||
|
// // ----------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// public void searchWithFilter() {
|
||||||
|
// selectOnCriteria(20, 1, DEFAULT_ORDERING, NS_MINE + "role1", "bob");
|
||||||
|
// assertSelectedUris(2, "user02", "user05");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// public void searchWithFilterPaginatedWithFunkySortOrder() {
|
||||||
|
// selectOnCriteria(1, 2, new UserAccountsOrdering(Field.STATUS,
|
||||||
|
// Direction.ASCENDING), NS_MINE + "role1", "bob");
|
||||||
|
// assertSelectedUris(2, "user02");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// helper methods
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Create a new criteria object */
|
||||||
|
private ProxyRelationshipSelectionCriteria criteria(int accountsPerPage,
|
||||||
|
int pageIndex, ProxyRelationshipView view, String searchTerm) {
|
||||||
|
return new ProxyRelationshipSelectionCriteria(accountsPerPage,
|
||||||
|
pageIndex, view, searchTerm);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Create a criteria object and select against it. */
|
||||||
|
private void selectOnCriteria(int relationshipsPerPage, int pageIndex,
|
||||||
|
ProxyRelationshipView viewBy, String searchTerm) {
|
||||||
|
criteria = new ProxyRelationshipSelectionCriteria(relationshipsPerPage,
|
||||||
|
pageIndex, viewBy, searchTerm);
|
||||||
|
selection = ProxyRelationshipSelector.select(context, criteria);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] counts(int proxyCount, int profileCount) {
|
||||||
|
return new int[] { proxyCount, profileCount };
|
||||||
|
}
|
||||||
|
|
||||||
|
private ProxyItemInfo item(String uri, String label, String classLabel,
|
||||||
|
String imageUrl) {
|
||||||
|
return new ProxyItemInfo(uri, label, classLabel, imageUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertExpectedCounts(int total, int[]... counts) {
|
||||||
|
assertEquals("total result count", total,
|
||||||
|
selection.getTotalResultCount());
|
||||||
|
|
||||||
|
List<ProxyRelationship> relationships = selection
|
||||||
|
.getProxyRelationships();
|
||||||
|
assertEquals("number of returns", counts.length, relationships.size());
|
||||||
|
|
||||||
|
for (int i = 0; i < counts.length; i++) {
|
||||||
|
ProxyRelationship r = relationships.get(i);
|
||||||
|
assertEquals("number of proxies in result " + i, counts[i][0], r
|
||||||
|
.getProxyInfos().size());
|
||||||
|
assertEquals("number of profiles in result " + i, counts[i][1], r
|
||||||
|
.getProfileInfos().size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
# $This file is distributed under the terms of the license in /doc/license.txt$
|
||||||
|
|
||||||
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
|
@prefix vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> .
|
||||||
|
@prefix public: <http://vitro.mannlib.cornell.edu/ns/vitro/public#> .
|
||||||
|
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
||||||
|
@prefix auth: <http://vitro.mannlib.cornell.edu/ns/vitro/authorization#> .
|
||||||
|
@prefix mydomain: <http://vivo.mydomain.edu/individual/> .
|
||||||
|
|
||||||
|
### This file provides a UserAccounts model for ProxyRelationshipSelectorTest.java
|
||||||
|
|
||||||
|
#
|
||||||
|
# The first relationship to be returned, regardless of view, is this profile to its proxy,
|
||||||
|
# and here is the self for that proxy also.
|
||||||
|
#
|
||||||
|
mydomain:firstProfile
|
||||||
|
a foaf:Person ;
|
||||||
|
rdfs:label "AAAA, FirstProfile" ;
|
||||||
|
vitro:mostSpecificType mydomain:profileType ;
|
||||||
|
public:mainImage mydomain:profileImage ;
|
||||||
|
.
|
||||||
|
mydomain:firstSelf
|
||||||
|
a foaf:Person ;
|
||||||
|
vitro:mostSpecificType mydomain:selfType ;
|
||||||
|
public:mainImage mydomain:selfImage ;
|
||||||
|
mydomain:matching "firstSelf" ;
|
||||||
|
.
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# An individual with no proxy
|
||||||
|
#
|
||||||
|
mydomain:bozo
|
||||||
|
a foaf:Person ;
|
||||||
|
rdfs:label "Bozo, Not Just Any" ;
|
||||||
|
vitro:mostSpecificType mydomain:profileType;
|
||||||
|
.
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# This Individual can be edited by a bunch of proxies.
|
||||||
|
#
|
||||||
|
mydomain:popularProfile
|
||||||
|
a foaf:Person ;
|
||||||
|
rdfs:label "Profile, Popular" ;
|
||||||
|
vitro:mostSpecificType mydomain:profileType;
|
||||||
|
public:mainImage mydomain:profileImage;
|
||||||
|
.
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# These Individuals can all be edited by one popular proxy.
|
||||||
|
# Each profile has different combinations of attributes.
|
||||||
|
#
|
||||||
|
mydomain:profileWithNoClassLabel
|
||||||
|
a foaf:Person ;
|
||||||
|
rdfs:label "NoClassLabel, Profile with" ;
|
||||||
|
public:mainImage mydomain:profileImage;
|
||||||
|
.
|
||||||
|
|
||||||
|
mydomain:profileWithNoImageUrl
|
||||||
|
a foaf:Person ;
|
||||||
|
rdfs:label "NoImageUrl, Profile with" ;
|
||||||
|
vitro:mostSpecificType mydomain:profileType;
|
||||||
|
.
|
||||||
|
|
||||||
|
mydomain:profileWithNeither
|
||||||
|
a foaf:Person ;
|
||||||
|
rdfs:label "Neither, Profile with" ;
|
||||||
|
.
|
||||||
|
|
||||||
|
mydomain:profileWithBoth
|
||||||
|
a foaf:Person ;
|
||||||
|
rdfs:label "Both, Profile with" ;
|
||||||
|
vitro:mostSpecificType mydomain:profileType;
|
||||||
|
public:mainImage mydomain:profileImage;
|
||||||
|
.
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# These Individiauls are each the "self" for a different proxy.
|
||||||
|
# Each profile has a different combination of attributes.
|
||||||
|
#
|
||||||
|
mydomain:individualWithNoClassLabel
|
||||||
|
a foaf:Person ;
|
||||||
|
rdfs:label "Person, Bozo" ;
|
||||||
|
public:mainImage mydomain:selfImage;
|
||||||
|
mydomain:matching "individualWithNoClassLabel" ;
|
||||||
|
.
|
||||||
|
|
||||||
|
mydomain:individualWithNoImageUrl
|
||||||
|
a foaf:Person ;
|
||||||
|
rdfs:label "Person, Bozo" ;
|
||||||
|
vitro:mostSpecificType mydomain:selfType;
|
||||||
|
mydomain:matching "individualWithNoImageUrl" ;
|
||||||
|
.
|
||||||
|
|
||||||
|
mydomain:individualWithNeither
|
||||||
|
a foaf:Person ;
|
||||||
|
rdfs:label "Person, Bozo" ;
|
||||||
|
mydomain:matching "individualWithNeither" ;
|
||||||
|
.
|
||||||
|
|
||||||
|
mydomain:individualWithBoth
|
||||||
|
a foaf:Person ;
|
||||||
|
rdfs:label "Person, Bozo" ;
|
||||||
|
vitro:mostSpecificType mydomain:selfType;
|
||||||
|
public:mainImage mydomain:selfImage;
|
||||||
|
mydomain:matching "individualWithBoth" ;
|
||||||
|
.
|
||||||
|
|
||||||
|
#
|
||||||
|
# Use this as a "most specific type" for Profiles.
|
||||||
|
#
|
||||||
|
mydomain:profileType
|
||||||
|
rdfs:label "Profile";
|
||||||
|
.
|
||||||
|
|
||||||
|
#
|
||||||
|
# Use this as a "most specific type" for "selves".
|
||||||
|
#
|
||||||
|
mydomain:selfType
|
||||||
|
rdfs:label "Self";
|
||||||
|
.
|
||||||
|
|
||||||
|
#
|
||||||
|
# Image hierarchy for those profiles that need one.
|
||||||
|
#
|
||||||
|
mydomain:profileImage
|
||||||
|
public:thumbnailImage mydomain:profileThumbnail;
|
||||||
|
.
|
||||||
|
mydomain:profileThumbnail
|
||||||
|
public:downloadLocation mydomain:profileThumbStream;
|
||||||
|
.
|
||||||
|
mydomain:profileThumbStream
|
||||||
|
public:directDownloadUrl "http://mydomain.edu/profileImage.jpg"
|
||||||
|
.
|
||||||
|
|
||||||
|
#
|
||||||
|
# Image hierarchy for those "selves" that need one.
|
||||||
|
#
|
||||||
|
mydomain:selfImage
|
||||||
|
public:thumbnailImage mydomain:selfThumbnail;
|
||||||
|
.
|
||||||
|
mydomain:selfThumbnail
|
||||||
|
public:downloadLocation mydomain:selfThumbStream;
|
||||||
|
.
|
||||||
|
mydomain:selfThumbStream
|
||||||
|
public:directDownloadUrl "http://mydomain.edu/selfImage.jpg"
|
||||||
|
.
|
|
@ -0,0 +1,88 @@
|
||||||
|
# $This file is distributed under the terms of the license in /doc/license.txt$
|
||||||
|
|
||||||
|
@prefix auth: <http://vitro.mannlib.cornell.edu/ns/vitro/authorization#> .
|
||||||
|
@prefix mydomain: <http://vivo.mydomain.edu/individual/> .
|
||||||
|
|
||||||
|
### This file provides a UserAccounts model for ProxyRelationshipSelectorTest.java
|
||||||
|
|
||||||
|
#
|
||||||
|
# The first relationship to be returned, regardless of view, is this proxy to its profile.
|
||||||
|
#
|
||||||
|
mydomain:userFirstProxy
|
||||||
|
a auth:UserAccount ;
|
||||||
|
auth:emailAddress "firstProxy@some.edu" ;
|
||||||
|
auth:firstName "FirstProxy" ;
|
||||||
|
auth:lastName "AAAA" ;
|
||||||
|
auth:externalAuthId "firstSelf" ;
|
||||||
|
auth:proxyEditorFor mydomain:firstProfile ;
|
||||||
|
.
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# A user account with no proxy relationship and no profile.
|
||||||
|
#
|
||||||
|
mydomain:userProxyForNone
|
||||||
|
a auth:UserAccount ;
|
||||||
|
auth:emailAddress "proxyForNone@some.edu" ;
|
||||||
|
auth:firstName "Proxy4" ;
|
||||||
|
auth:lastName "None" ;
|
||||||
|
.
|
||||||
|
|
||||||
|
#
|
||||||
|
# This user account is proxy for a bunch of profiles.
|
||||||
|
# This user account has no self
|
||||||
|
#
|
||||||
|
mydomain:userPopularProxy
|
||||||
|
a auth:UserAccount ;
|
||||||
|
auth:emailAddress "popularProxy@some.edu" ;
|
||||||
|
auth:firstName "Popular" ;
|
||||||
|
auth:lastName "Proxy" ;
|
||||||
|
auth:proxyEditorFor mydomain:profileWithNoClassLabel ;
|
||||||
|
auth:proxyEditorFor mydomain:profileWithNoImageUrl ;
|
||||||
|
auth:proxyEditorFor mydomain:profileWithNeither ;
|
||||||
|
auth:proxyEditorFor mydomain:profileWithBoth ;
|
||||||
|
.
|
||||||
|
|
||||||
|
#
|
||||||
|
# These user accounts are each proxy for a popular profile.
|
||||||
|
# All but one has a self, but each self has different combinations of attributes.
|
||||||
|
#
|
||||||
|
mydomain:userProxyWithNoSelf
|
||||||
|
a auth:UserAccount ;
|
||||||
|
auth:emailAddress "proxyWithNoSelf@some.edu" ;
|
||||||
|
auth:firstName "ProxyWith" ;
|
||||||
|
auth:lastName "NoSelf" ;
|
||||||
|
auth:proxyEditorFor mydomain:popularProfile ;
|
||||||
|
.
|
||||||
|
mydomain:userProxyWithSelfWithNoClassLabel
|
||||||
|
a auth:UserAccount ;
|
||||||
|
auth:emailAddress "proxyWithSelfWithNoClassLabel@some.edu" ;
|
||||||
|
auth:firstName "ProxyWithSelfWith" ;
|
||||||
|
auth:lastName "NoClassLabel" ;
|
||||||
|
auth:externalAuthId "individualWithNoClassLabel" ;
|
||||||
|
auth:proxyEditorFor mydomain:popularProfile ;
|
||||||
|
.
|
||||||
|
mydomain:userProxyWithSelfWithNoImageUrl
|
||||||
|
a auth:UserAccount ;
|
||||||
|
auth:emailAddress "proxyWithSelfWithNoImageUrl@some.edu" ;
|
||||||
|
auth:firstName "ProxyWithSelfWith" ;
|
||||||
|
auth:lastName "NoImageUrl" ;
|
||||||
|
auth:externalAuthId "individualWithNoImageUrl" ;
|
||||||
|
auth:proxyEditorFor mydomain:popularProfile ;
|
||||||
|
.
|
||||||
|
mydomain:userProxyWithSelfWithNeither
|
||||||
|
a auth:UserAccount ;
|
||||||
|
auth:emailAddress "proxyWithSelfWithNeither@some.edu" ;
|
||||||
|
auth:firstName "ProxyWithSelfWith" ;
|
||||||
|
auth:lastName "Neither" ;
|
||||||
|
auth:externalAuthId "individualWithNeither" ;
|
||||||
|
auth:proxyEditorFor mydomain:popularProfile ;
|
||||||
|
.
|
||||||
|
mydomain:userProxyWithSelfWithBoth
|
||||||
|
a auth:UserAccount ;
|
||||||
|
auth:emailAddress "proxyWithSelfWithBoth@some.edu" ;
|
||||||
|
auth:firstName "ProxyWithSelfWith" ;
|
||||||
|
auth:lastName "Both" ;
|
||||||
|
auth:externalAuthId "individualWithBoth" ;
|
||||||
|
auth:proxyEditorFor mydomain:popularProfile ;
|
||||||
|
.
|
Loading…
Add table
Reference in a new issue