[VIVO-1249] Add capability maps for research areas (#35)

* Initial capability map implementation

* Add autocomplete

* Make headers update the info panel

* Ajax retrieval of person details - reduce memory requirements and startup time

* Remove old referer info

* Handle missing labels.

* Fix refresh button; add menu entry for new installations
This commit is contained in:
grahamtriggs 2016-06-20 17:01:51 +01:00 committed by GitHub
parent 1443ff6685
commit ee7b974ac5
21 changed files with 3126 additions and 36 deletions

View file

@ -0,0 +1,284 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.visualization.capabilitymap;
import com.google.gson.Gson;
import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
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.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
import edu.cornell.mannlib.vitro.webapp.rdfservice.ResultSetConsumer;
import edu.cornell.mannlib.vitro.webapp.visualization.constants.QueryConstants;
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
import edu.cornell.mannlib.vitro.webapp.visualization.model.ConceptLabelMap;
import edu.cornell.mannlib.vitro.webapp.visualization.model.ConceptPeopleMap;
import edu.cornell.mannlib.vitro.webapp.visualization.model.OrganizationPeopleMap;
import edu.cornell.mannlib.vitro.webapp.visualization.utilities.VisualizationCaches;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.VisualizationRequestHandler;
import org.apache.axis.utils.StringUtils;
import org.apache.commons.logging.Log;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class CapabilityMapRequestHandler implements VisualizationRequestHandler {
@Override
public AuthorizationRequest getRequiredPrivileges() {
return null;
}
@Override
public ResponseValues generateStandardVisualization(VitroRequest vitroRequest, Log log, Dataset dataSource) throws MalformedQueryParametersException {
return null;
}
@Override
public ResponseValues generateVisualizationForShortURLRequests(Map<String, String> parameters, VitroRequest vitroRequest, Log log, Dataset dataSource) throws MalformedQueryParametersException {
return prepareMarkup(vitroRequest);
}
@Override
public Object generateAjaxVisualization(VitroRequest vitroRequest, Log log, Dataset dataSource) throws MalformedQueryParametersException {
ConceptLabelMap conceptLabelMap = VisualizationCaches.conceptToLabel.get(vitroRequest.getRDFService());
ConceptPeopleMap conceptPeopleMap = VisualizationCaches.conceptToPeopleMap.get(vitroRequest.getRDFService());
OrganizationPeopleMap organizationPeopleMap = VisualizationCaches.organisationToPeopleMap.get(vitroRequest.getRDFService());
Map<String, String> organizationLabels = VisualizationCaches.organizationLabels.get(vitroRequest.getRDFService());
String data = vitroRequest.getParameter("data");
if (!StringUtils.isEmpty(data)) {
if ("concepts".equalsIgnoreCase(data)) {
Set<String> concepts = new HashSet<String>();
for (String conceptKey : conceptPeopleMap.conceptToPeople.keySet()) {
String label = conceptLabelMap.conceptToLabel.get(conceptKey);
if (!StringUtils.isEmpty(label)) {
concepts.add(conceptLabelMap.conceptToLabel.get(conceptKey));
}
}
Gson gson = new Gson();
return gson.toJson(concepts);
}
return "";
}
String personParam = vitroRequest.getParameter("person");
if (!StringUtils.isEmpty(personParam)) {
CapabilityMapResponse response = new CapabilityMapResponse();
CapabilityMapResult result = new CapabilityMapResult();
fillPersonDetails(vitroRequest.getRDFService(), personParam, result);
if (StringUtils.isEmpty(result.firstName) && StringUtils.isEmpty(result.lastName)) {
result.lastName = "Missing Name";
}
Set<String> concepts = conceptPeopleMap.personToConcepts.get(personParam);
if (concepts != null) {
result.subjectArea = concepts.toArray(new String[concepts.size()]);
}
Set<String> organizations = organizationPeopleMap.organizationToPeople.get(personParam);
if (organizations != null) {
for (String org : organizations) {
result.department = organizationLabels.get(org);
if (!StringUtils.isEmpty(result.department)) {
break;
}
}
}
response.results.add(result);
Gson gson = new Gson();
String callback = vitroRequest.getParameter("callback");
if (!StringUtils.isEmpty(callback)) {
return callback + "(" + gson.toJson(response) + ");";
}
return gson.toJson(response);
}
String query = vitroRequest.getParameter("query");
if (!StringUtils.isEmpty(query)) {
CapabilityMapResponse response = new CapabilityMapResponse();
Set<String> matchedConcepts = conceptLabelMap.lowerLabelToConcepts.get(query.toLowerCase());
Set<String> people = new HashSet<String>();
if (matchedConcepts != null) {
for (String uri : matchedConcepts) {
Set<String> peopleSet = conceptPeopleMap.conceptToPeople.get(uri);
if (peopleSet != null) {
people.addAll(peopleSet);
}
}
}
Set<String> clusterConcepts = new HashSet<String>();
for (String person : people) {
if (conceptPeopleMap.personToConcepts.containsKey(person)) {
clusterConcepts.addAll(conceptPeopleMap.personToConcepts.get(person));
}
}
if (matchedConcepts != null) {
clusterConcepts.removeAll(matchedConcepts);
}
Set<String> clusterLabels = new HashSet<String>();
for (String clusterConcept : clusterConcepts) {
String label = conceptLabelMap.conceptToLabel.get(clusterConcept);
if (!StringUtils.isEmpty(label)) {
clusterLabels.add(label);
}
}
String[] clusters = clusterLabels.toArray(new String[clusterLabels.size()]);
for (String person : people) {
CapabilityMapResult result = new CapabilityMapResult();
result.profileId = person;
result.query = query;
result.clusters = clusters;
response.results.add(result);
}
Gson gson = new Gson();
String callback = vitroRequest.getParameter("callback");
if (!StringUtils.isEmpty(callback)) {
return callback + "(" + gson.toJson(response) + ");";
}
return gson.toJson(response);
}
return "";
}
@Override
public Map<String, String> generateDataVisualization(VitroRequest vitroRequest, Log log, Dataset dataset) throws MalformedQueryParametersException {
return null;
}
private ResponseValues prepareMarkup(VitroRequest vreq) {
String standaloneTemplate = "capabilityMap.ftl";
Map<String, Object> body = new HashMap<String, Object>();
body.put("title", "Capability Map");
body.put("vivoDefaultNamespace", vreq.getWebappDaoFactory().getDefaultNamespace());
return new TemplateResponseValues(standaloneTemplate, body);
}
private void fillPersonDetails(final RDFService rdfService, final String personUri, final CapabilityMapResult result) {
try {
String construct = QueryConstants.getSparqlPrefixQuery() +
"CONSTRUCT {\n" +
" <" + personUri + "> a foaf:Person .\n" +
" <" + personUri + "> foaf:lastName ?lastName .\n" +
" <" + personUri + "> foaf:firstName ?firstName .\n" +
" <" + personUri + "> obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasName ?contactName .\n" +
" ?contactName vcard:familyName ?familyName .\n" +
" ?contactName vcard:givenName ?givenName .\n" +
" ?contactInfo vcard:hasTitle ?contactTitle .\n" +
" ?contactTitle vcard:title ?contactTitleLabel .\n" +
" <" + personUri + "> public:thumbnailImage ?directDownloadUrl .\n" +
"} WHERE {\n" +
" { \n" +
" <" + personUri + "> foaf:lastName ?lastName .\n" +
" } UNION { \n" +
" <" + personUri + "> foaf:firstName ?firstName .\n" +
" } UNION { \n" +
" <" + personUri + "> obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasName ?contactName .\n" +
" ?contactName vcard:familyName ?familyName .\n" +
" } UNION { \n" +
" <" + personUri + "> obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasName ?contactName .\n" +
" ?contactName vcard:givenName ?givenName .\n" +
" } UNION { \n" +
" <" + personUri + "> obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasTitle ?contactTitle .\n" +
" ?contactTitle vcard:title ?contactTitleLabel .\n" +
" } UNION { \n" +
" <" + personUri + "> public:mainImage ?mainImage .\n" +
" ?mainImage public:thumbnailImage ?thumbnailImage .\n" +
" ?thumbnailImage public:downloadLocation ?downloadLocation .\n" +
" ?downloadLocation public:directDownloadUrl ?directDownloadUrl .\n" +
" } \n" +
"}\n";
Model constructedModel = ModelFactory.createDefaultModel();
rdfService.sparqlConstructQuery(construct, constructedModel);
String nameQuery = QueryConstants.getSparqlPrefixQuery() +
"SELECT ?familyName ?givenName ?lastName ?firstName ?title ?thumbnailUrl\n" +
"WHERE\n" +
"{\n" +
" <" + personUri + "> a foaf:Person .\n" + // ?person
" OPTIONAL {\n" +
" <" + personUri + "> obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasName ?contactName .\n" +
" OPTIONAL { ?contactName vcard:familyName ?familyName . }\n" +
" OPTIONAL { ?contactName vcard:givenName ?givenName . }\n" +
" }\n" +
" OPTIONAL {\n" +
" <" + personUri + "> obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasTitle ?contactTitle .\n" +
" ?contactTitle vcard:title ?title .\n" +
" }\n" +
" OPTIONAL { <" + personUri + "> foaf:lastName ?lastName . }\n" +
" OPTIONAL { <" + personUri + "> foaf:firstName ?firstName . }\n" +
" OPTIONAL { <" + personUri + "> public:thumbnailImage ?thumbnailUrl . }\n" +
"}\n";
QueryExecution qe = QueryExecutionFactory.create(nameQuery, constructedModel);
try {
new ResultSetConsumer() {
@Override
protected void processQuerySolution(QuerySolution qs) {
result.profileId = personUri;
result.firstName = null;
result.lastName = null;
result.thumbNail = null;
result.preferredTitle = null;
Literal familyNameNode = qs.getLiteral("familyName");
if (familyNameNode != null) {
result.lastName = familyNameNode.getString();
} else {
Literal lastNameNode = qs.getLiteral("lastName");
result.lastName = lastNameNode == null ? null : lastNameNode.getString();
}
Literal givenNameNode = qs.getLiteral("givenName");
if (givenNameNode != null) {
result.firstName = givenNameNode.getString();
} else {
Literal firstNameNode = qs.getLiteral("firstName");
result.firstName = firstNameNode == null ? null : firstNameNode.getString();
}
Literal thumbnailUrlNode = qs.getLiteral("thumbnailUrl");
result.thumbNail = thumbnailUrlNode == null ? null : thumbnailUrlNode.getString();
Literal titleNode = qs.getLiteral("title");
result.preferredTitle = titleNode == null ? null : titleNode.getString();
}
}.processResultSet(qe.execSelect());
} finally {
qe.close();
}
} catch (RDFServiceException e) {
}
}
}

View file

@ -0,0 +1,10 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.visualization.capabilitymap;
import java.util.ArrayList;
import java.util.List;
class CapabilityMapResponse {
List<CapabilityMapResult> results = new ArrayList<CapabilityMapResult>();
}

View file

@ -0,0 +1,68 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.visualization.capabilitymap;
import com.google.gson.annotations.SerializedName;
class CapabilityMapResult {
String[] clusters;
@SerializedName("md_1")
String profileId;
@SerializedName("md_2")
String description;
@SerializedName("md_3")
String thumbNail;
@SerializedName("md_4")
String department;
@SerializedName("md_5")
String overview;
@SerializedName("md_6")
String geographicFocus;
@SerializedName("md_7")
String geographicLocation;
@SerializedName("md_8")
String[] grants;
@SerializedName("md_A")
String firstName;
@SerializedName("md_B")
String lastName;
@SerializedName("md_F")
String fax;
@SerializedName("md_G")
String email;
@SerializedName("md_H")
String availableForSupervision;
@SerializedName("md_I")
String homepage;
@SerializedName("md_L")
String phoneNumber;
@SerializedName("md_U")
String[] publications;
@SerializedName("md_X")
String[] researchOverview;
@SerializedName("md_Y")
String[] subjectArea;
@SerializedName("md_Z")
String preferredTitle;
String query;
}

View file

@ -39,11 +39,12 @@ public class QueryConstants {
put("wos", "http://vivo.mannlib.cornell.edu/ns/ThomsonWOS/0.1#");
put("core", "http://vivoweb.org/ontology/core#");
put("vivo", "http://vivo.library.cornell.edu/ns/0.1#");
put("j.1", "http://aims.fao.org/aos/geopolitical.owl#");
put("j.2", "http://vitro.mannlib.cornell.edu/ns/vitro/public#");
put("geo", "http://aims.fao.org/aos/geopolitical.owl#");
put("public", "http://vitro.mannlib.cornell.edu/ns/vitro/public#");
put("afn", "http://jena.hpl.hp.com/ARQ/function#");
put("vivosocnet", "http://vivo.cns.iu.edu/ns/#");
put("obo", "http://purl.obolibrary.org/obo/");
put("vcard", "http://www.w3.org/2006/vcard/ns#");
} };
public static String getSparqlPrefixQuery() {

View file

@ -15,6 +15,7 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
import edu.cornell.mannlib.vitro.webapp.rdfservice.ResultSetConsumer;
import edu.cornell.mannlib.vitro.webapp.visualization.constants.QueryConstants;
import edu.cornell.mannlib.vitro.webapp.visualization.model.OrganizationPeopleMap;
import edu.cornell.mannlib.vitro.webapp.visualization.utilities.OrgUtils;
import edu.cornell.mannlib.vitro.webapp.visualization.utilities.VisualizationCaches;
import mapping.ScienceMapping;
@ -252,7 +253,7 @@ public class MapOfScienceVisualizationRequestHandler implements VisualizationReq
}
Map<String, Set<String>> subOrgMap = VisualizationCaches.organizationSubOrgs.get(rdfService);
Map<String, Set<String>> organisationToPeopleMap = VisualizationCaches.organisationToPeopleMap.get(rdfService);
OrganizationPeopleMap organisationToPeopleMap = VisualizationCaches.organisationToPeopleMap.get(rdfService);
Map<String, Set<String>> personToPublicationMap = VisualizationCaches.personToPublication.get(rdfService).personToPublication;
Map<String, String> publicationToJournalMap = VisualizationCaches.publicationToJournal.get(rdfService);
@ -267,7 +268,7 @@ public class MapOfScienceVisualizationRequestHandler implements VisualizationReq
orgPublicationsPeople,
subOrgPublicationsMap,
subOrgMap,
organisationToPeopleMap,
organisationToPeopleMap.organizationToPeople,
personToPublicationMap
);

View file

@ -0,0 +1,12 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.visualization.model;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class ConceptLabelMap {
public final Map<String, String> conceptToLabel = new HashMap<String, String>();
public final Map<String, Set<String>> lowerLabelToConcepts = new HashMap<String, Set<String>>();
}

View file

@ -0,0 +1,12 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.visualization.model;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class ConceptPeopleMap {
public final Map<String, Set<String>> conceptToPeople = new HashMap<String, Set<String>>();
public final Map<String, Set<String>> personToConcepts = new HashMap<String, Set<String>>();
}

View file

@ -0,0 +1,12 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.visualization.model;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class OrganizationPeopleMap {
public final Map<String, Set<String>> organizationToPeople = new HashMap<String, Set<String>>();
public final Map<String, Set<String>> personToOrganizations = new HashMap<String, Set<String>>();
}

View file

@ -0,0 +1,11 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.visualization.model;
public class Person {
public String uri;
public String preferredTitle;
public String firstName;
public String lastName;
public String thumbnailUrl;
}

View file

@ -11,6 +11,7 @@ import java.util.Map;
import java.util.Set;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.visualization.model.OrganizationPeopleMap;
import edu.cornell.mannlib.vitro.webapp.visualization.utilities.CounterUtils;
import edu.cornell.mannlib.vitro.webapp.visualization.utilities.OrgUtils;
import edu.cornell.mannlib.vitro.webapp.visualization.utilities.VisualizationCaches;
@ -152,7 +153,7 @@ public class TemporalGrantVisualizationRequestHandler implements
}
Map<String, Set<String>> subOrgMap = VisualizationCaches.organizationSubOrgs.get(rdfService);
Map<String, Set<String>> organisationToPeopleMap = VisualizationCaches.organisationToPeopleMap.get(rdfService);
OrganizationPeopleMap organisationToPeopleMap = VisualizationCaches.organisationToPeopleMap.get(rdfService);
Map<String, String> orgMostSpecificLabelMap = VisualizationCaches.organizationToMostSpecificLabel.get(rdfService);
Map<String, String> personMostSpecificLabelMap = VisualizationCaches.personToMostSpecificLabel.get(rdfService);
Map<String, Set<String>> personToGrantMap = VisualizationCaches.personToGrant.get(rdfService);
@ -169,7 +170,7 @@ public class TemporalGrantVisualizationRequestHandler implements
orgGrantsPeople,
subOrgGrantsMap,
subOrgMap,
organisationToPeopleMap,
organisationToPeopleMap.organizationToPeople,
personToGrantMap
);

View file

@ -11,6 +11,7 @@ import java.util.Map;
import java.util.Set;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.visualization.model.OrganizationPeopleMap;
import edu.cornell.mannlib.vitro.webapp.visualization.utilities.CounterUtils;
import edu.cornell.mannlib.vitro.webapp.visualization.utilities.OrgUtils;
import edu.cornell.mannlib.vitro.webapp.visualization.utilities.VisualizationCaches;
@ -91,7 +92,7 @@ public class TemporalPublicationVisualizationRequestHandler implements
Map<String, Set<String>> subOrgMap = VisualizationCaches.organizationSubOrgs.get(rdfService);
Map<String, String> orgMostSpecificLabelMap = VisualizationCaches.organizationToMostSpecificLabel.get(rdfService);
Map<String, String> personMostSpecificLabelMap = VisualizationCaches.personToMostSpecificLabel.get(rdfService);
Map<String, Set<String>> organisationToPeopleMap = VisualizationCaches.organisationToPeopleMap.get(rdfService);
OrganizationPeopleMap organisationToPeopleMap = VisualizationCaches.organisationToPeopleMap.get(rdfService);
Map<String, Set<String>> personToPublicationMap = VisualizationCaches.personToPublication.get(rdfService).personToPublication;
Map<String, String> publicationToYearMap = VisualizationCaches.publicationToYear.get(rdfService);
@ -106,7 +107,7 @@ public class TemporalPublicationVisualizationRequestHandler implements
orgPublicationsPeople,
subOrgPublicationsMap,
subOrgMap,
organisationToPeopleMap,
organisationToPeopleMap.organizationToPeople,
personToPublicationMap
);

View file

@ -2,11 +2,21 @@
package edu.cornell.mannlib.vitro.webapp.visualization.utilities;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.ResultSetConsumer;
import edu.cornell.mannlib.vitro.webapp.visualization.constants.QueryConstants;
import edu.cornell.mannlib.vitro.webapp.visualization.model.ConceptLabelMap;
import edu.cornell.mannlib.vitro.webapp.visualization.model.ConceptPeopleMap;
import edu.cornell.mannlib.vitro.webapp.visualization.model.OrganizationPeopleMap;
import edu.cornell.mannlib.vitro.webapp.visualization.model.Person;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UtilityFunctions;
import org.joda.time.DateTime;
@ -17,6 +27,11 @@ import java.util.Set;
/**
* Holder for the caches we are using in the visualizations
*
* String.intern() was a problem pre-Java 7, but has greater utility now.
* Please see the following guide for information on the implementation of String.intern()
*
* http://java-performance.info/string-intern-in-java-6-7-8/
*/
final public class VisualizationCaches {
// Affinity object to ensure that only one background thread can be running at once when updating the caches
@ -32,6 +47,8 @@ final public class VisualizationCaches {
* @param rdfService if not null, use this service in foreground, otherwise may use the background thread
*/
public static void rebuildAll(RDFService rdfService) {
conceptToLabel.build(rdfService);
conceptToPeopleMap.build(rdfService);
organizationLabels.build(rdfService);
organizationSubOrgs.build(rdfService);
organizationToMostSpecificLabel.build(rdfService);
@ -43,9 +60,12 @@ final public class VisualizationCaches {
publicationToYear.build(rdfService);
personToGrant.build(rdfService);
grantToYear.build(rdfService);
// people.build(rdfService);
}
public static void buildMissing() {
if (!conceptToLabel.isCached()) { conceptToLabel.build(null); }
if (!conceptToPeopleMap.isCached()) { conceptToPeopleMap.build(null); }
if (!organizationLabels.isCached()) { organizationLabels.build(null); }
if (!organizationSubOrgs.isCached()) { organizationSubOrgs.build(null); }
if (!organizationToMostSpecificLabel.isCached()) { organizationToMostSpecificLabel.build(null); }
@ -57,6 +77,7 @@ final public class VisualizationCaches {
if (!publicationToYear.isCached()) { publicationToYear.build(null); }
if (!personToGrant.isCached()) { personToGrant.build(null); }
if (!grantToYear.isCached()) { grantToYear.build(null); }
// if (!people.isCached()) { people.build(null); }
}
/**
@ -71,6 +92,139 @@ final public class VisualizationCaches {
}
}
/**
* Cache of people
*/
public static final CachingRDFServiceExecutor<Map<String, Person>> people =
new CachingRDFServiceExecutor<>(
new CachingRDFServiceExecutor.RDFServiceCallable<Map<String, Person>>(visualizationAffinity) {
@Override
protected Map<String, Person> callWithService(RDFService rdfService) throws Exception {
final Map<String, Person> map = new HashMap<String, Person>();
String construct = QueryConstants.getSparqlPrefixQuery() +
"CONSTRUCT {\n" +
" ?person a foaf:Person .\n" +
" ?person foaf:lastName ?lastName .\n" +
" ?person foaf:firstName ?firstName .\n" +
" ?person obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasName ?contactName .\n" +
" ?contactName vcard:familyName ?familyName .\n" +
" ?contactName vcard:givenName ?givenName .\n" +
" ?contactInfo vcard:hasTitle ?contactTitle .\n" +
" ?contactTitle vcard:title ?contactTitleLabel .\n" +
" ?person public:thumbnailImage ?directDownloadUrl .\n" +
"} WHERE {\n" +
" { \n" +
" ?person a foaf:Person .\n" +
" } UNION { \n" +
" ?person a foaf:Person .\n" +
" ?person foaf:lastName ?lastName .\n" +
" } UNION { \n" +
" ?person a foaf:Person .\n" +
" ?person foaf:firstName ?firstName .\n" +
" } UNION { \n" +
" ?person a foaf:Person .\n" +
" ?person obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasName ?contactName .\n" +
" ?contactName vcard:familyName ?familyName .\n" +
" } UNION { \n" +
" ?person a foaf:Person .\n" +
" ?person obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasName ?contactName .\n" +
" ?contactName vcard:givenName ?givenName .\n" +
" } UNION { \n" +
" ?person a foaf:Person .\n" +
" ?person obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasTitle ?contactTitle .\n" +
" ?contactTitle vcard:title ?contactTitleLabel .\n" +
" } UNION { \n" +
" ?person a foaf:Person .\n" +
" ?person public:mainImage ?mainImage .\n" +
" ?mainImage public:thumbnailImage ?thumbnailImage .\n" +
" ?thumbnailImage public:downloadLocation ?downloadLocation .\n" +
" ?downloadLocation public:directDownloadUrl ?directDownloadUrl .\n" +
" } \n" +
"}\n";
Model constructedModel = ModelFactory.createDefaultModel();
rdfService.sparqlConstructQuery(construct, constructedModel);
String nameQuery = QueryConstants.getSparqlPrefixQuery() +
"SELECT ?person ?familyName ?givenName ?lastName ?firstName ?title ?thumbnailUrl\n" +
"WHERE\n" +
"{\n" +
" ?person a foaf:Person .\n" +
" OPTIONAL {\n" +
" ?person obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasName ?contactName .\n" +
" OPTIONAL { ?contactName vcard:familyName ?familyName . }\n" +
" OPTIONAL { ?contactName vcard:givenName ?givenName . }\n" +
" }\n" +
" OPTIONAL {\n" +
" ?person obo:ARG_2000028 ?contactInfo .\n" +
" ?contactInfo vcard:hasTitle ?contactTitle .\n" +
" ?contactTitle vcard:title ?title .\n" +
" }\n" +
" OPTIONAL { ?person foaf:lastName ?lastName . }\n" +
" OPTIONAL { ?person foaf:firstName ?firstName . }\n" +
" OPTIONAL { ?person public:thumbnailImage ?thumbnailUrl . }\n" +
"}\n";
QueryExecution qe = QueryExecutionFactory.create(nameQuery, constructedModel);
try {
new ResultSetConsumer() {
@Override
protected void processQuerySolution(QuerySolution qs) {
String personUri = qs.getResource("person").getURI();
String familyName = null;
String givenName = null;
String thumbnailUrl = null;
String title = null;
Literal familyNameNode = qs.getLiteral("familyName");
if (familyNameNode != null) {
familyName = familyNameNode.getString();
} else {
Literal lastNameNode = qs.getLiteral("lastName");
familyName = lastNameNode == null ? null : lastNameNode.getString();
}
Literal givenNameNode = qs.getLiteral("givenName");
if (givenNameNode != null) {
givenName = givenNameNode.getString();
} else {
Literal firstNameNode = qs.getLiteral("firstName");
givenName = firstNameNode == null ? null : firstNameNode.getString();
}
Literal thumbnailUrlNode = qs.getLiteral("thumbnailUrl");
thumbnailUrl = thumbnailUrlNode == null ? null : thumbnailUrlNode.getString();
Literal titleNode = qs.getLiteral("title");
title = titleNode == null ? null : titleNode.getString();
Person person = map.get(personUri);
if (person == null) {
person = new Person();
map.put(personUri.intern(), person);
}
person.firstName = givenName == null ? null : givenName.intern();
person.lastName = familyName == null ? null : familyName.intern();
person.preferredTitle = title == null ? null : title.intern();
person.thumbnailUrl = thumbnailUrl;
}
}.processResultSet(qe.execSelect());
} finally {
qe.close();
}
return map;
}
}
);
/**
* Cache of organization labels (uri -> label)
*/
@ -95,7 +249,7 @@ final public class VisualizationCaches {
String org = qs.getResource("org").getURI();
String orgLabel = qs.getLiteral("orgLabel").getString();
map.put(org, orgLabel);
map.put(org.intern(), orgLabel.intern());
}
});
@ -131,10 +285,10 @@ final public class VisualizationCaches {
Set<String> subOrgs = map.get(org);
if (subOrgs == null) {
subOrgs = new HashSet<String>();
subOrgs.add(subOrg);
map.put(org, subOrgs);
subOrgs.add(subOrg.intern());
map.put(org.intern(), subOrgs);
} else {
subOrgs.add(subOrg);
subOrgs.add(subOrg.intern());
}
}
});
@ -168,7 +322,7 @@ final public class VisualizationCaches {
protected void processQuerySolution(QuerySolution qs) {
String org = qs.getResource("org").getURI();
String typeLabel = qs.getLiteral("typeLabel").getString();
map.put(org, String.valueOf(typeLabel));
map.put(org.intern(), typeLabel.intern());
}
});
@ -180,11 +334,11 @@ final public class VisualizationCaches {
/**
* Map of people within an organisation (org uri -> list of person uri)
*/
public static final CachingRDFServiceExecutor<Map<String, Set<String>>> organisationToPeopleMap =
new CachingRDFServiceExecutor<Map<String, Set<String>>>(
new CachingRDFServiceExecutor.RDFServiceCallable<Map<String, Set<String>>>(visualizationAffinity) {
public static final CachingRDFServiceExecutor<OrganizationPeopleMap> organisationToPeopleMap =
new CachingRDFServiceExecutor<OrganizationPeopleMap>(
new CachingRDFServiceExecutor.RDFServiceCallable<OrganizationPeopleMap>(visualizationAffinity) {
@Override
protected Map<String, Set<String>> callWithService(RDFService rdfService) throws Exception {
protected OrganizationPeopleMap callWithService(RDFService rdfService) throws Exception {
String query = QueryConstants.getSparqlPrefixQuery() +
"SELECT ?organisation ?person\n" +
"WHERE\n" +
@ -196,22 +350,31 @@ final public class VisualizationCaches {
" ?person a foaf:Person .\n" +
"}\n";
final Map<String, Set<String>> orgToPeopleMap = new HashMap<String, Set<String>>();
final OrganizationPeopleMap orgToPeopleMap = new OrganizationPeopleMap();
rdfService.sparqlSelectQuery(query, new ResultSetConsumer() {
@Override
protected void processQuerySolution(QuerySolution qs) {
String org = qs.getResource("organisation").getURI();
String person = qs.getResource("person").getURI();
String org = qs.getResource("organisation").getURI().intern();
String person = qs.getResource("person").getURI().intern();
Set<String> people = orgToPeopleMap.get(org);
Set<String> people = orgToPeopleMap.organizationToPeople.get(org);
if (people == null) {
people = new HashSet<String>();
people.add(person);
orgToPeopleMap.put(org, people);
orgToPeopleMap.organizationToPeople.put(org, people);
} else {
people.add(person);
}
Set<String> organizations = orgToPeopleMap.personToOrganizations.get(org);
if (organizations == null) {
organizations = new HashSet<String>();
organizations.add(org);
orgToPeopleMap.organizationToPeople.put(person, organizations);
} else {
organizations.add(org);
}
}
});
@ -220,6 +383,103 @@ final public class VisualizationCaches {
}
);
/**
* Concept to label
*/
public static final CachingRDFServiceExecutor<ConceptLabelMap> conceptToLabel =
new CachingRDFServiceExecutor<>(
new CachingRDFServiceExecutor.RDFServiceCallable<ConceptLabelMap>() {
@Override
protected ConceptLabelMap callWithService(RDFService rdfService) throws Exception {
String query = QueryConstants.getSparqlPrefixQuery() +
"SELECT ?concept ?label\n" +
"WHERE\n" +
"{\n" +
" ?person a foaf:Person .\n" +
" ?person core:hasResearchArea ?concept .\n" +
" ?concept a skos:Concept .\n" +
" ?concept rdfs:label ?label .\n" +
"}\n";
// final Map<String, String> map = new HashMap<>();
final ConceptLabelMap map = new ConceptLabelMap();
rdfService.sparqlSelectQuery(query, new ResultSetConsumer() {
@Override
protected void processQuerySolution(QuerySolution qs) {
String conceptURI = qs.getResource("concept").getURI().intern();
String label = qs.getLiteral("label").getString().intern();
String labelLower = label.toLowerCase().intern();
map.conceptToLabel.put(conceptURI, label);
Set<String> conceptSet = map.lowerLabelToConcepts.get(labelLower);
if (conceptSet == null) {
conceptSet = new HashSet<String>();
conceptSet.add(conceptURI);
map.lowerLabelToConcepts.put(labelLower, conceptSet);
} else {
conceptSet.add(conceptURI);
}
}
});
return map;
}
}
);
/**
* Map of people associated with a concept
*/
public static final CachingRDFServiceExecutor<ConceptPeopleMap> conceptToPeopleMap =
new CachingRDFServiceExecutor<ConceptPeopleMap>(
new CachingRDFServiceExecutor.RDFServiceCallable<ConceptPeopleMap>(visualizationAffinity) {
@Override
protected ConceptPeopleMap callWithService(RDFService rdfService) throws Exception {
String query = QueryConstants.getSparqlPrefixQuery() +
"SELECT ?person ?concept\n" +
"WHERE\n" +
"{\n" +
" ?person a foaf:Person .\n" +
" ?person core:hasResearchArea ?concept .\n" +
" ?concept a skos:Concept .\n" +
"}\n";
final ConceptPeopleMap conceptPeopleMap = new ConceptPeopleMap();
rdfService.sparqlSelectQuery(query, new ResultSetConsumer() {
@Override
protected void processQuerySolution(QuerySolution qs) {
String concept = qs.getResource("concept").getURI().intern();
String person = qs.getResource("person").getURI().intern();
Set<String> people = conceptPeopleMap.conceptToPeople.get(concept);
if (people == null) {
people = new HashSet<String>();
people.add(person);
conceptPeopleMap.conceptToPeople.put(concept, people);
} else {
people.add(person);
}
Set<String> concepts = conceptPeopleMap.personToConcepts.get(person);
if (concepts == null) {
concepts = new HashSet<String>();
concepts.add(concept);
conceptPeopleMap.personToConcepts.put(person, concepts);
} else {
concepts.add(concept);
}
}
});
return conceptPeopleMap;
}
}
);
/**
* Display labels for people (uri -> label)
*/
@ -244,7 +504,7 @@ final public class VisualizationCaches {
String person = qs.getResource("person").getURI();
String personLabel = qs.getLiteral("personLabel").getString();
map.put(person, personLabel);
map.put(person.intern(), personLabel.intern());
}
});
@ -277,7 +537,7 @@ final public class VisualizationCaches {
protected void processQuerySolution(QuerySolution qs) {
String person = qs.getResource("person").getURI();
String typeLabel = qs.getLiteral("typeLabel").getString();
map.put(person, String.valueOf(typeLabel));
map.put(person.intern(), String.valueOf(typeLabel).intern());
}
});
@ -317,7 +577,7 @@ final public class VisualizationCaches {
String personURI = person.getURI();
String documentURI = document.getURI();
map.put(personURI, documentURI);
map.put(personURI.intern(), documentURI.intern());
}
}
});
@ -352,7 +612,7 @@ final public class VisualizationCaches {
String document = qs.getResource("document").getURI();
String journalLabel = qs.getLiteral("journalLabel").getString();
map.put(document, journalLabel);
map.put(document.intern(), journalLabel.intern());
}
});
@ -390,7 +650,7 @@ final public class VisualizationCaches {
.getValidParsedDateTimeObject(pubDate);
if (validParsedDateTimeObject != null) {
map.put(document, String.valueOf(validParsedDateTimeObject.getYear()));
map.put(document.intern(), String.valueOf(validParsedDateTimeObject.getYear()).intern());
}
}
}
@ -434,10 +694,10 @@ final public class VisualizationCaches {
Set<String> documents = map.get(personURI);
if (documents == null) {
documents = new HashSet<String>();
documents.add(grant.getURI());
map.put(personURI, documents);
documents.add(grant.getURI().intern());
map.put(personURI.intern(), documents);
} else {
documents.add(grant.getURI());
documents.add(grant.getURI().intern());
}
}
}
@ -478,7 +738,7 @@ final public class VisualizationCaches {
.getValidParsedDateTimeObject(startDate);
if (validParsedDateTimeObject != null) {
map.put(grant, String.valueOf(validParsedDateTimeObject.getYear()));
map.put(grant.intern(), String.valueOf(validParsedDateTimeObject.getYear()).intern());
}
}
}
@ -520,7 +780,7 @@ final public class VisualizationCaches {
.getValidParsedDateTimeObject(startDate);
if (validParsedDateTimeObject != null) {
map.put(grant, String.valueOf(validParsedDateTimeObject.getYear()));
map.put(grant.intern(), String.valueOf(validParsedDateTimeObject.getYear()).intern());
}
}
}