updates for label management

This commit is contained in:
hudajkhan 2013-10-01 11:24:15 -04:00
parent cba46c4f72
commit 9fae5d7c3e
10 changed files with 453 additions and 82 deletions

View file

@ -76,6 +76,7 @@ public class SimplePermission extends Permission {
NAMESPACE + "UseAdvancedDataToolsPages");
public static final SimplePermission USE_SPARQL_QUERY_PAGE = new SimplePermission(
NAMESPACE + "UseSparqlQueryPage");
// ----------------------------------------------------------------------
// These instances are "catch all" permissions to cover poorly defined

View file

@ -0,0 +1,246 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.vocabulary.RDFS;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ExceptionResponseValues;
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.jena.QueryUtils;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
import edu.cornell.mannlib.vitro.webapp.i18n.selection.SelectedLocale;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.DataPropertyStatementTemplateModel;
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
/*Servlet to view all labels in various languages for individual*/
public class ViewLabelsServlet extends FreemarkerHttpServlet{
private static final Log log = LogFactory.getLog(ViewLabelsServlet.class.getName());
@Override
protected ResponseValues processRequest(VitroRequest vreq) {
Map<String, Object> body = new HashMap<String, Object>();
String subjectUri = vreq.getParameter("subjectUri");
body.put("subjectUri", subjectUri);
try {
//Get all language codes/labels in the system, and this list is sorted by language name
List<HashMap<String, String>> locales = this.getLocales(vreq);
//Get code to label hashmap - we use this to get the language name for the language code returned in the rdf literal
HashMap<String, String> localeCodeToNameMap = this.getFullCodeToLanguageNameMap(locales);
//the labels already added by the user
ArrayList<Literal> existingLabels = this.getExistingLabels(subjectUri, vreq);
//existing labels keyed by language name and each of the list of labels is sorted by language name
HashMap<String, List<LabelInformation>> existingLabelsByLanguageName = this.getLabelsSortedByLanguageName(existingLabels, localeCodeToNameMap, vreq, subjectUri);
//Get available locales for the drop down for adding a new label, also sorted by language name
HashSet<String> existingLanguageNames = new HashSet<String>(existingLabelsByLanguageName.keySet());
body.put("labelsSortedByLanguageName", existingLabelsByLanguageName);
Individual subject = vreq.getWebappDaoFactory().getIndividualDao().getIndividualByURI(subjectUri);
if( subject != null && subject.getName() != null ){
body.put("subjectName", subject.getName());
}else{
body.put("subjectName", null);
}
} catch (Throwable e) {
log.error(e, e);
return new ExceptionResponseValues(e);
}
String template = "viewLabelsForIndividual.ftl";
return new TemplateResponseValues(template, body);
}
//Languages sorted by language name
private HashMap<String, List<LabelInformation>> getLabelsSortedByLanguageName(List<Literal> labels, Map<String, String> localeCodeToNameMap,
VitroRequest vreq, String subjectUri) {
//Iterate through the labels and create a hashmap
HashMap<String, List<LabelInformation>> labelsHash= new HashMap<String, List<LabelInformation>>();
for(Literal l: labels) {
String languageTag = l.getLanguage();
String languageName = "";
if(languageTag == "") {
languageName = "untyped";
}
else if(localeCodeToNameMap.containsKey(languageTag)) {
languageName = localeCodeToNameMap.get(languageTag);
} else {
log.warn("This language tag " + languageTag + " does not have corresponding name in the system and was not processed");
}
if(languageName != "") {
if(!labelsHash.containsKey(languageName)) {
labelsHash.put(languageName, new ArrayList<LabelInformation>());
}
ArrayList<LabelInformation> labelsList = (ArrayList<LabelInformation>)labelsHash.get(languageName);
//This should put the label in the list
//Create label information instance with the required information
//To generate link
labelsList.add(new LabelInformation(
l, languageTag, languageName));
}
}
//Sort each label list
LabelInformationComparator lic = new LabelInformationComparator();
for(String languageName: labelsHash.keySet()) {
List<LabelInformation> labelInfo = labelsHash.get(languageName);
Collections.sort(labelInfo, lic);
}
return labelsHash;
}
public static class LabelInformationComparator implements Comparator<LabelInformation> {
public int compare(LabelInformation l1, LabelInformation l2) {
return l1.getLabelStringValue().compareTo(l2.getLabelStringValue());
}
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
//get locales
public List<HashMap<String, String>> getLocales(VitroRequest vreq) {
List<Locale> selectables = SelectedLocale.getSelectableLocales(vreq);
if (selectables.isEmpty()) {
return Collections.emptyList();
}
List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
Locale currentLocale = SelectedLocale.getCurrentLocale(vreq);
for (Locale locale : selectables) {
try {
list.add(buildLocaleMap(locale, currentLocale));
} catch (FileNotFoundException e) {
log.warn("Can't show the Locale selector for '" + locale
+ "': " + e);
}
}
return list;
}
//copied from locale selection data getter but don't need all this information
private HashMap<String, String> buildLocaleMap(Locale locale,
Locale currentLocale) throws FileNotFoundException {
HashMap<String, String> map = new HashMap<String, String>();
//Replacing the underscore with a hyphen because that is what is represented in the actual literals
map.put("code", locale.toString().replace("_", "-"));
map.put("label", locale.getDisplayName(currentLocale));
return map;
}
public HashMap<String, String> getFullCodeToLanguageNameMap(List<HashMap<String, String>> localesList) {
HashMap<String, String> codeToLanguageMap = new HashMap<String, String>();
for(Map<String, String> locale: localesList) {
String code = (String) locale.get("code");
String label = (String) locale.get("label");
if(!codeToLanguageMap.containsKey(code)) {
codeToLanguageMap.put(code, label);
}
else {
log.warn("Language code " + code + " for " + label + " was not associated in map becayse label already exists");
}
}
return codeToLanguageMap;
}
private ArrayList<Literal> getExistingLabels(String subjectUri, VitroRequest vreq) {
String queryStr = QueryUtils.subUriForQueryVar(LABEL_QUERY, "subject", subjectUri);
log.debug("queryStr = " + queryStr);
ArrayList<Literal> labels = new ArrayList<Literal>();
try {
//We want to get the labels for all the languages, not just the display language
ResultSet results = QueryUtils.getLanguageNeutralQueryResults(queryStr, vreq);
while (results.hasNext()) {
QuerySolution soln = results.nextSolution();
Literal nodeLiteral = soln.get("label").asLiteral();
labels.add(nodeLiteral);
}
} catch (Exception e) {
log.error(e, e);
}
return labels;
}
//Class used to store the information needed for the template, such as the labels, their languages, their edit links
public class LabelInformation {
private Literal labelLiteral = null;
private String languageCode; //languageCode
private String languageName;
public LabelInformation(Literal inputLiteral, String inputLanguageCode, String inputLanguageName) {
this.labelLiteral = inputLiteral;
this.languageCode = inputLanguageCode;
this.languageName = inputLanguageName;
}
public Literal getLabelLiteral() {
return this.labelLiteral;
}
public String getLabelStringValue() {
return this.labelLiteral.getString();
}
public String getLanguageCode() {
return this.languageCode;
}
public String getLanguageName() {
return this.languageName;
}
}
private static String LABEL_QUERY = ""
+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n"
+ "SELECT DISTINCT ?label WHERE { \n"
+ " ?subject rdfs:label ?label \n"
+ "} ORDER BY ?label";
}

View file

@ -4,63 +4,118 @@ package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocess
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.QuerySolutionMap;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.Syntax;
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.Property;
import com.hp.hpl.jena.rdf.model.ResIterator;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.shared.Lock;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
public class FoafNameToRdfsLabelPreprocessor implements ModelChangePreprocessor {
private static final String FOAF = "http://xmlns.com/foaf/0.1/";
private Log log = LogFactory.getLog(FoafNameToRdfsLabelPreprocessor.class);
@Override
public void preprocess(Model retractionsModel, Model additionsModel,
HttpServletRequest request) {
Property firstNameP = additionsModel.getProperty(FOAF+"firstName");
Property lastNameP = additionsModel.getProperty(FOAF+"lastName");
//middle name is optional
Property middleNameP = additionsModel.getProperty(FOAF+"middleName");
updateModelWithLabel(additionsModel);
}
private String getSparqlQuery() {
String queryStr = "SELECT ?subject ?firstName ?middleName ?lastName where {" +
"?subject <http://purl.obolibrary.org/obo/ARG_2000028> ?individualVcard ." +
"?individualVcard <http://www.w3.org/2006/vcard/ns#hasName> ?fullName ." +
"?fullName <http://www.w3.org/2006/vcard/ns#givenName> ?firstName ." +
"?fullName <http://www.w3.org/2006/vcard/ns#familyName> ?lastName ." +
"OPTIONAL {?fullName <http://www.w3.org/2006/vcard/ns#middleName> ?middleName .}" +
"}";
return queryStr;
}
private void updateModelWithLabel(Model additionsModel) {
Model changesModel = ModelFactory.createDefaultModel();
String queryStr = getSparqlQuery();
Property rdfsLabelP = additionsModel.getProperty(VitroVocabulary.LABEL);
ResIterator subs =
additionsModel.listSubjectsWithProperty(firstNameP);
while( subs.hasNext() ){
Resource sub = subs.nextResource();
Statement fname = sub.getProperty( firstNameP );
Statement lname = sub.getProperty( lastNameP );
Statement mname = sub.getProperty(middleNameP);
if( fname != null && lname != null && fname.getString() != null && lname.getString() != null ){
//Check if there are languages associated with first name and last name and add the language
//attribute to the label
//This preprocessor is used in multiple places, including for managing labels
Literal firstNameLiteral = fname.getLiteral();
Literal lastNameLiteral = lname.getLiteral();
String firstNameLanguage = firstNameLiteral.getLanguage();
String lastNameLanguage = lastNameLiteral.getLanguage();
//Start creating string for new label
String newLabel = lname.getString() + ", " + fname.getString();
//Middle name handling
if(mname != null && mname.getString() != null) {
newLabel += " " + mname.getString();
}
if(firstNameLanguage != null && lastNameLanguage != null && firstNameLanguage.equals(lastNameLanguage)) {
//create a literal with the appropriate value and the language
Literal labelWithLanguage = additionsModel.createLiteral(newLabel, firstNameLanguage);
additionsModel.add(sub, rdfsLabelP, labelWithLanguage);
} else {
additionsModel.add(sub, rdfsLabelP, newLabel );
}
}
}
Query query = null;
QueryExecution qe = null;
additionsModel.getLock().enterCriticalSection(Lock.READ);
try {
query = QueryFactory.create(queryStr);
qe = QueryExecutionFactory.create(
query, additionsModel);
ResultSet res = qe.execSelect();
while( res.hasNext() ){
String newLabel = "";
Resource subject = null;
QuerySolution qs = res.nextSolution();
subject = qs.getResource("subject");
//Get first and last names, and middle names if they exist
if(qs.getLiteral("firstName") != null && qs.getLiteral("lastName") != null) {
Literal firstNameLiteral = qs.getLiteral("firstName");
Literal lastNameLiteral = qs.getLiteral("lastName");
String firstNameLanguage = firstNameLiteral.getLanguage();
String lastNameLanguage = lastNameLiteral.getLanguage();
newLabel = lastNameLiteral.getString() + ", " + firstNameLiteral.getString();
if(qs.getLiteral("middleName") != null) {
Literal middleNameLiteral = qs.getLiteral("middleName");
newLabel += " " + middleNameLiteral.getString();
}
if(subject != null &&
firstNameLanguage != null && lastNameLanguage != null
&& firstNameLanguage.equals(lastNameLanguage)) {
//create a literal with the appropriate value and the language
Literal labelWithLanguage = changesModel.createLiteral(newLabel, firstNameLanguage);
changesModel.add(subject, rdfsLabelP, labelWithLanguage);
} else {
changesModel.add(subject, rdfsLabelP, newLabel );
}
}
}
} catch(Throwable th){
log.error("An error occurred in executing query:" + queryStr);
} finally {
if (qe != null) {
qe.close();
}
additionsModel.getLock().leaveCriticalSection();
}
//Write changes model to additions model
additionsModel.getLock().enterCriticalSection(Lock.WRITE);
try {
additionsModel.add(changesModel);
}catch(Throwable th){
log.error("An error occurred in writing model", th);
} finally {
additionsModel.getLock().leaveCriticalSection();
}
}
}