updates for concepts and labels

This commit is contained in:
hudajkhan 2013-09-24 13:44:58 -04:00
parent 213f8ffd91
commit 91fd8a4c1b
11 changed files with 792 additions and 61 deletions

View file

@ -8,6 +8,12 @@
<label for="firstName">${i18n().first_name} ${requiredHint}</label> <label for="firstName">${i18n().first_name} ${requiredHint}</label>
<input size="30" type="text" id="firstName" name="firstName" value="${firstNameValue}" /> <input size="30" type="text" id="firstName" name="firstName" value="${firstNameValue}" />
</p> </p>
<#--TODO: With ISF changes, add middle name input-->
<!--p-->
<!--label for="middleName">${i18n().middle_name} ${requiredHint}</label>
<input size="30" type="text" id="middleName" name="middleName" value="${middleNameValue}" />
</p-->
<p> <p>
<label for="lastName">${i18n().last_name} ${requiredHint}</label> <label for="lastName">${i18n().last_name} ${requiredHint}</label>

View file

@ -5,6 +5,9 @@
<#--Get existing value for specific data literals and uris, in case the form is returned because of an error--> <#--Get existing value for specific data literals and uris, in case the form is returned because of an error-->
<#assign firstNameValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "firstName")/> <#assign firstNameValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "firstName")/>
<#assign lastNameValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "lastName")/> <#assign lastNameValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "lastName")/>
<#--With ISF changes, we also have a niddle name value, also add error field below-->
<#--assign middleNameValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "middleName") /-->
<#assign labelValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "label")/> <#assign labelValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "label")/>
<#assign newLabelLanguageValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "newLabelLanguage")/> <#assign newLabelLanguageValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "newLabelLanguage")/>

View file

@ -101,9 +101,8 @@
<form id="addConceptForm" class="customForm" action="${submitUrl}"> <form id="addConceptForm" class="customForm" action="${submitUrl}">
<#assign checkedSource = false /> <#assign checkedSource = false />
<h4 class="services">${i18n().external_vocabulary_services}</h4> <h4 class="services">${i18n().external_vocabulary_services}</h4>
<#list sources?keys?sort as sourceUri> <#list sources?values?sort_by("label") as thisSource>
<#assign thisSource = sources[sourceUri]/> <input type="radio" name="source" value="${thisSource.url}" role="radio" <#if checkedSource = false><#assign checkedSource = true/>checked="checked"</#if>>
<input type="radio" name="source" value="${sourceUri}" role="radio" <#if checkedSource = false><#assign checkedSource = true/>checked="checked"</#if>>
<label class="inline" for="${thisSource.label}"> <a href="${thisSource.url}">${thisSource.label}</a> &nbsp;(${thisSource.description})</label> <label class="inline" for="${thisSource.label}"> <a href="${thisSource.url}">${thisSource.label}</a> &nbsp;(${thisSource.description})</label>
<br /> <br />
</#list> </#list>
@ -180,6 +179,7 @@ ${stylesheets.add('<link rel="stylesheet" href="${urls.base}/templates/freemarke
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/templates/freemarker/edit/forms/css/addConcept.css" />')} ${stylesheets.add('<link rel="stylesheet" href="${urls.base}/templates/freemarker/edit/forms/css/addConcept.css" />')}
${scripts.add('<script type="text/javascript" src="${urls.base}/js/jquery-ui/js/jquery-ui-1.8.9.custom.min.js"></script>')} ${scripts.add('<script type="text/javascript" src="${urls.base}/js/jquery-ui/js/jquery-ui-1.8.9.custom.min.js"></script>')}
${scripts.add('<script type="text/javascript" src="${urls.base}/js/json2.js"></script>')}
${scripts.add('<script type="text/javascript" src="${urls.base}/js/customFormUtils.js"></script>')} ${scripts.add('<script type="text/javascript" src="${urls.base}/js/customFormUtils.js"></script>')}
${scripts.add('<script type="text/javascript" src="${urls.base}/js/browserUtils.js"></script>')} ${scripts.add('<script type="text/javascript" src="${urls.base}/js/browserUtils.js"></script>')}
${scripts.add('<script type="text/javascript" src="${urls.base}/templates/freemarker/edit/forms/js/addConcept.js"></script>')} ${scripts.add('<script type="text/javascript" src="${urls.base}/templates/freemarker/edit/forms/js/addConcept.js"></script>')}

View file

@ -321,8 +321,11 @@ var addConceptForm = {
this.externalConceptLabel.val(conceptLabels); this.externalConceptLabel.val(conceptLabels);
this.externalConceptSource.val(conceptSources); this.externalConceptSource.val(conceptSources);
this.externalConceptSemanticTypeLabel.val(conceptSemanticTypes); this.externalConceptSemanticTypeLabel.val(conceptSemanticTypes);
this.externalConceptBroaderUris.val(conceptBroaderUris); //Using JSON here because there may be multiple broader and narrower uris per concept
this.externalConceptNarrowerUris.val(conceptNarrowerUris); //and using a regular string representation does not differentiate between which set of uris
//would belong to which concept
this.externalConceptBroaderUris.val(JSON.stringify(conceptBroaderUris));
this.externalConceptNarrowerUris.val(JSON.stringify(conceptNarrowerUris));
return true; return true;
}, },

View file

@ -108,20 +108,23 @@ public class AgrovocService implements ExternalConceptService {
String lang = ""; String lang = "";
for (SKOSLiteral literal : skosConcept.getSKOSRelatedConstantByProperty(dataset, manager.getSKOSDataFactory().getSKOSPrefLabelProperty())) { for (SKOSLiteral literal : skosConcept.getSKOSRelatedConstantByProperty(dataset, manager.getSKOSDataFactory().getSKOSPrefLabelProperty())) {
if(literal != null) {
if (!literal.isTyped()) {
// if it has language
SKOSUntypedLiteral untypedLiteral = literal.getAsSKOSUntypedLiteral();
if (untypedLiteral.hasLang()) {
lang = untypedLiteral.getLang();
} else {
lang = "";
}
}
if (lang.equals("en")) {
//System.out.println("prefLabel: " + literal.getLiteral());
if (!literal.isTyped()) { concept.setLabel(literal.getLiteral());
// if it has language }
SKOSUntypedLiteral untypedLiteral = literal.getAsSKOSUntypedLiteral(); } else {
if (untypedLiteral.hasLang()) { logger.debug("Literal returned for preferred label was null and was ignored");
lang = untypedLiteral.getLang();
} else {
lang = "";
}
}
if (lang.equals("en")) {
//System.out.println("prefLabel: " + literal.getLiteral());
concept.setLabel(literal.getLiteral());
} }
} }
@ -130,21 +133,24 @@ public class AgrovocService implements ExternalConceptService {
for (SKOSLiteral literal : skosConcept for (SKOSLiteral literal : skosConcept
.getSKOSRelatedConstantByProperty(dataset, manager .getSKOSRelatedConstantByProperty(dataset, manager
.getSKOSDataFactory().getSKOSAltLabelProperty())) { .getSKOSDataFactory().getSKOSAltLabelProperty())) {
if(literal != null) {
if (!literal.isTyped()) { if (!literal.isTyped()) {
// if it has language // if it has language
SKOSUntypedLiteral untypedLiteral = literal SKOSUntypedLiteral untypedLiteral = literal
.getAsSKOSUntypedLiteral(); .getAsSKOSUntypedLiteral();
if (untypedLiteral.hasLang()) { if (untypedLiteral.hasLang()) {
lang = untypedLiteral.getLang(); lang = untypedLiteral.getLang();
} else { } else {
lang = ""; lang = "";
}
} }
} //System.out.println("literal: "+ literal.getLiteral());
//System.out.println("literal: "+ literal.getLiteral()); if (lang.equals("en")) {
if (lang.equals("en")) { //System.out.println("altLabel: " + literal.getLiteral());
//System.out.println("altLabel: " + literal.getLiteral()); altLabelList.add(literal.getLiteral());
altLabelList.add(literal.getLiteral()); }
} else {
logger.debug("Literal retrieved for altlabel was null and was ignored");
} }
} }
concept.setAltLabelList(altLabelList); concept.setAltLabelList(altLabelList);

View file

@ -269,20 +269,24 @@ public class LCSHService implements ExternalConceptService {
String lang = ""; String lang = "";
List<String> literalValues = new ArrayList<String>(); List<String> literalValues = new ArrayList<String>();
for (SKOSLiteral literal : skosLiterals) { for (SKOSLiteral literal : skosLiterals) {
if (!literal.isTyped()) { if(literal != null) {
// if it has language if (!literal.isTyped()) {
SKOSUntypedLiteral untypedLiteral = literal // if it has language
.getAsSKOSUntypedLiteral(); SKOSUntypedLiteral untypedLiteral = literal
if (untypedLiteral.hasLang()) { .getAsSKOSUntypedLiteral();
lang = untypedLiteral.getLang(); if (untypedLiteral.hasLang()) {
} else { lang = untypedLiteral.getLang();
lang = ""; } else {
lang = "";
}
} }
} // log.debug("literal: "+ literal.getLiteral());
// log.debug("literal: "+ literal.getLiteral()); if (lang.equals("en")) {
if (lang.equals("en")) { log.debug("literal value: " + literal.getLiteral());
log.debug("literal value: " + literal.getLiteral()); literalValues.add(literal.getLiteral());
literalValues.add(literal.getLiteral()); }
} else {
log.debug("Literal returned was null so was ignored");
} }
} }
return literalValues; return literalValues;

View file

@ -67,7 +67,6 @@ public class AddAssociatedConceptGenerator extends VivoBaseGenerator implements
initBasics(editConfiguration, vreq); initBasics(editConfiguration, vreq);
initPropertyParameters(vreq, session, editConfiguration); initPropertyParameters(vreq, session, editConfiguration);
initObjectPropForm(editConfiguration, vreq); initObjectPropForm(editConfiguration, vreq);
editConfiguration.setTemplate(template); editConfiguration.setTemplate(template);
setVarNames(editConfiguration); setVarNames(editConfiguration);
@ -97,10 +96,10 @@ public class AddAssociatedConceptGenerator extends VivoBaseGenerator implements
setTemplate(editConfiguration, vreq); setTemplate(editConfiguration, vreq);
// No validators required here // No validators required here
// Add preprocessors // Add preprocessors
//Passing from servlet context for now but will have to see if there's a way to pass vreq
addPreprocessors(editConfiguration, addPreprocessors(editConfiguration,
ModelAccess.on(vreq).getJenaOntModel(), ModelAccess.on(session.getServletContext()).getJenaOntModel(),
ModelAccess.on(vreq).getOntModelSelector().getTBoxModel(), ModelAccess.on(session.getServletContext()).getWebappDaoFactory());
vreq.getWebappDaoFactory());
// Adding additional data, specifically edit mode // Adding additional data, specifically edit mode
addFormSpecificData(editConfiguration, vreq); addFormSpecificData(editConfiguration, vreq);
// One override for basic functionality, changing url pattern // One override for basic functionality, changing url pattern
@ -361,7 +360,6 @@ public class AddAssociatedConceptGenerator extends VivoBaseGenerator implements
private void addPreprocessors(EditConfigurationVTwo editConfiguration, private void addPreprocessors(EditConfigurationVTwo editConfiguration,
OntModel ontModel, OntModel ontModel,
OntModel modelChangeModel,
WebappDaoFactory wdf) { WebappDaoFactory wdf) {
//An Edit submission preprocessor for enabling addition of multiple terms for a single search //An Edit submission preprocessor for enabling addition of multiple terms for a single search
//TODO: Check if this is the appropriate way of getting model //TODO: Check if this is the appropriate way of getting model
@ -370,8 +368,7 @@ public class AddAssociatedConceptGenerator extends VivoBaseGenerator implements
editConfiguration.addEditSubmissionPreprocessor( editConfiguration.addEditSubmissionPreprocessor(
new AddAssociatedConceptsPreprocessor(editConfiguration, ontModel, wdf)); new AddAssociatedConceptsPreprocessor(editConfiguration, ontModel, wdf));
editConfiguration.addModelChangePreprocessor(new ConceptSemanticTypesPreprocessor( editConfiguration.addModelChangePreprocessor(new ConceptSemanticTypesPreprocessor());
modelChangeModel));
} }

View file

@ -0,0 +1,606 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
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.http.HttpSession;
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.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.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.sparql.resultset.ResultSetMem;
import com.hp.hpl.jena.vocabulary.RDFS;
import com.hp.hpl.jena.vocabulary.XSD;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestActionConstants;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddDataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.QueryUtils;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.FoafNameToRdfsLabelPreprocessor;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.ManageLabelsForIndividualPreprocessor;
import edu.cornell.mannlib.vitro.webapp.i18n.selection.LocaleSelectionDataGetter;
import edu.cornell.mannlib.vitro.webapp.i18n.selection.LocaleSelectorUtilities;
import edu.cornell.mannlib.vitro.webapp.i18n.selection.SelectedLocale;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.DataPropertyStatementTemplateModel;
/**
* This generator is specifically for handling labels for a FOAF Person individual and is an object property form.
*This allows the page to show all the labels for a particular individual and sets up code
*enabling the addition of a new label. Links on the page will allow for removal or editing of a given label.
*/
public class ManageLabelsForPersonGenerator extends BaseEditConfigurationGenerator implements EditConfigurationGenerator {
public static Log log = LogFactory.getLog(ManageLabelsForIndividualGenerator.class);
private static String template = "manageLabelsForPerson.ftl";
private HashMap<String, List<LabelInformation>> labelsSortedByLanguage = null;
private List<Literal> existingLabelLiterals = null;
//list of language names sorted alphabetically
private List<String> existingSortedLanguageNameList = null;
//This would be for the full list and can be used for the existing labels list as well
private HashMap<String, String> fullLanguageNameToCodeMap = null;
private static String predicateUri = RDFS.label.getURI();
@Override
public EditConfigurationVTwo getEditConfiguration(VitroRequest vreq, HttpSession session) {
EditConfigurationVTwo config = new EditConfigurationVTwo();
config.setTemplate(this.getTemplate());
initBasics(config, vreq);
initPropertyParameters(vreq, session, config);
//This form is technically not an object property form in the true sense
//or a data property form because it is used to list the various labels
//and allow for adding new labels, but since the generator will
//be employed when the 'add' button is used, we will set this is an object property form
//although label will mean we need to add a data property statement as well
//URL to return to is the same page once addition is complete
initObjectPropForm(config, vreq);
this.setUrlToReturnTo(config, vreq);
config.setSubjectUri(EditConfigurationUtils.getSubjectUri(vreq));
setVarNames(config);
//config.setDatapropKey( EditConfigurationUtils.getDataHash(vreq) );
//Add n3, fields, etc. in the case where the user wants to add a label
//N3 required should be empty since the addition of a label is optional in this case
config.setN3Required(this.generateN3Required(vreq));
config.setN3Optional(this.generateN3Optional(vreq));
this.addNewResources(config);
this.setUrisAndLiteralsOnForm(config, vreq);
this.setUrisAndLiteralsInScope(config);
this.setFields(config, vreq, EditConfigurationUtils
.getPredicateUri(vreq));
//Get existing labels
//this.initExistingLabels(config, vreq);
//Add form specific data used to populate template
addFormSpecificData(config, vreq);
//This preprocessor handles getting the correct label language and putting the attribute on the label
config.addEditSubmissionPreprocessor(
new ManageLabelsForIndividualPreprocessor(config));
//This will handle generating the label from the first name, middle, and last names and also make sure to associate
//a language with that label
config.addModelChangePreprocessor(new FoafNameToRdfsLabelPreprocessor());
prepare(vreq, config);
return config;
}
/**With ISF Changes**/
//For addition of a label, with ISF changes, the name is now linked to a vcard which in turn is linked to a "fullname" that then has first/middle/last names
private void addNewResources(EditConfigurationVTwo config) {
config.addNewResource("fullName", DEFAULT_NS_FOR_NEW_RESOURCE);
config.addNewResource("individualVcard", DEFAULT_NS_FOR_NEW_RESOURCE);
}
private void setUrlToReturnTo(EditConfigurationVTwo editConfiguration, VitroRequest vreq) {
editConfiguration.setUrlPatternToReturnTo(EditConfigurationUtils.getFormUrlWithoutContext(vreq));
}
private void setVarNames(EditConfigurationVTwo editConfiguration) {
editConfiguration.setVarNameForSubject("subject");
editConfiguration.setVarNameForPredicate("predicate");
}
private List<String> generateN3Required(VitroRequest vreq) {
List<String> n3Required = new ArrayList<String>();
return n3Required;
}
private List<String> generateN3Optional(VitroRequest vreq) {
List<String> n3Optional = new ArrayList<String>();
String predicateUri = EditConfigurationUtils.getPredicateUri(vreq);
String n3 = "?subject <" + predicateUri + "> ?label ";
//n3 used if the subject is a person
//String personN3 = this.N3_PREFIX + "?subject foaf:firstName ?firstName ; foaf:lastName ?lastName .";
//This n3 will be different with the ISF changes
String personN3 = this.N3_PREFIX +
"?subject <http://purl.obolibrary.org/obo/ARG_2000028> ?individualVcard . \n" +
"?individualVcard a <http://www.w3.org/2006/vcard/ns#Individual> . \n" +
"?individualVcard <http://purl.obolibrary.org/obo/ARG_2000029> ?subject . \n" +
"?individualVcard <http://www.w3.org/2006/vcard/ns#hasName> ?fullName . \n" +
"?fullName a <http://www.w3.org/2006/vcard/ns#Name> . \n" +
"?fullName <http://www.w3.org/2006/vcard/ns#givenName> ?firstName . \n" +
"?fullName <http://www.w3.org/2006/vcard/ns#familyName> ?lastName .";
n3Optional.add(n3);
n3Optional.add(personN3);
return n3Optional;
}
private void setFields(EditConfigurationVTwo editConfiguration, VitroRequest vreq, String predicateUri) {
Map<String, FieldVTwo> fields = new HashMap<String, FieldVTwo>();
editConfiguration.setFields(fields);
editConfiguration.addField(new FieldVTwo().
setName("label").
setValidators(getLabelValidators(vreq, editConfiguration)));
editConfiguration.addField(new FieldVTwo(
).setName("newLabelLanguage"));
//no validators since all of this is optional
//there should be error-checking client side though
editConfiguration.addField(new FieldVTwo().
setName("firstName").
setValidators(getFirstNameValidators(vreq, editConfiguration)));
editConfiguration.addField(new FieldVTwo().
setName("middleName").
setValidators(getLastNameValidators(vreq, editConfiguration)));
editConfiguration.addField(new FieldVTwo().
setName("lastName").
setValidators(getLastNameValidators(vreq, editConfiguration)));
//With ISF Changes, also include middle name
}
//first and last name have validators if is person is true
private List<String> getFirstNameValidators(VitroRequest vreq, EditConfigurationVTwo config) {
List<String> validators = new ArrayList<String>();
if(isPersonType(vreq, config)) {
validators.add("nonempty");
}
return validators;
}
private List<String> getLastNameValidators(VitroRequest vreq, EditConfigurationVTwo config) {
List<String> validators = new ArrayList<String>();
if(isPersonType(vreq, config)) {
validators.add("nonempty");
}
return validators;
}
//validate label if person is not true
private List<String> getLabelValidators(VitroRequest vreq, EditConfigurationVTwo config) {
List<String> validators = new ArrayList<String>();
if(!isPersonType(vreq, config)) {
validators.add("nonempty");
}
return validators;
}
private void setUrisAndLiteralsOnForm(EditConfigurationVTwo config,
VitroRequest vreq) {
List<String> literalsOnForm = new ArrayList<String>();
literalsOnForm.add("label");
literalsOnForm.add("newLabelLanguage");
//optional for person
literalsOnForm.add("firstName");
literalsOnForm.add("lastName");
config.setLiteralsOnForm(literalsOnForm);
}
private void setUrisAndLiteralsInScope(EditConfigurationVTwo editConfiguration) {
HashMap<String, List<String>> urisInScope = new HashMap<String, List<String>>();
//note that at this point the subject, predicate, and object var parameters have already been processed
urisInScope.put(editConfiguration.getVarNameForSubject(),
Arrays.asList(new String[]{editConfiguration.getSubjectUri()}));
urisInScope.put(editConfiguration.getVarNameForPredicate(),
Arrays.asList(new String[]{editConfiguration.getPredicateUri()}));
editConfiguration.setUrisInScope(urisInScope);
//Uris in scope include subject, predicate, and object var
editConfiguration.setLiteralsInScope(new HashMap<String, List<Literal>>());
}
private void initExistingLabels(EditConfigurationVTwo config,
VitroRequest vreq) {
this.existingLabelLiterals = this.getExistingLabels(config.getSubjectUri(), vreq);
// this.labelsSortedByLanguage = this.getLabelsSortedByLanguage(config,vreq);
//language names sorted for the existing languages
// this.existingSortedLanguageNameList = getExistingSortedLanguageNamesList();
//Generate a label to language code hash map
//TODO:
//HashMap<String, String> labelToLanguageCode = new HashMap<String, String>();
//this.labels = getExistingLabels(config.getSubjectUri(), vreq);
//this.labelsSortedByLanguage = getLabelsSortedByLanguage(config.getSubjectUri(), vreq);
}
private List<String> getExistingSortedLanguageNamesList() {
HashSet<String> existingLanguages = new HashSet<String>();
for(Literal l: this.existingLabelLiterals) {
String language = l.getLanguage();
if(!existingLanguages.contains(language)) {
existingLanguages.add(language);
}
}
List<String> sortedNames = new ArrayList<String>(existingLanguages);
//sort alphabetically
Collections.sort(sortedNames);
return sortedNames;
}
private void addFormSpecificData(EditConfigurationVTwo config,
VitroRequest vreq) {
//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(config.getSubjectUri(), vreq);
int numberExistingLabels = existingLabels.size();
//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, config, vreq);
//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());
List<HashMap<String, String>> availableLocalesForAdd = getAvailableLocales(locales, existingLanguageNames);
//Save all locales
config.addFormSpecificData("selectLocaleFullList", locales);
//Save labels sorted by language name, untyped have "untyped" as the language name value
config.addFormSpecificData("labelsSortedByLanguageName", existingLabelsByLanguageName);
config.addFormSpecificData("selectLocale",availableLocalesForAdd);
config.addFormSpecificData("displayRemoveLink", (numberExistingLabels > 1));
//How do we edit? Will need to see
config.addFormSpecificData("deleteWebpageUrl", "/edit/primitiveDelete");
Individual subject = vreq.getWebappDaoFactory().getIndividualDao().getIndividualByURI(config.getSubjectUri());
if( subject != null && subject.getName() != null ){
config.addFormSpecificData("subjectName", subject.getName());
}else{
config.addFormSpecificData("subjectName", null);
}
//Put in whether or not person type
if(isPersonType(vreq, config)) {
//Doing this b/c unsure how freemarker will handle boolean value from JAVA
config.addFormSpecificData("isPersonType", "true");
} else {
config.addFormSpecificData("isPersonType", "false");
}
//Include whether or not editable to enable edit/remove links and add to show up
config.addFormSpecificData("editable", isEditable(vreq, config));
}
//Based on what locales have already been selected for labels, return a list of
//locales for which new labels can be added and have these sorted by the name of the language
private List<HashMap<String, String>> getAvailableLocales(List<HashMap<String, String>> allLocales,
HashSet<String> existingLabelsLanguageNames) {
List<HashMap<String, String>> availableLocales = new ArrayList<HashMap<String, String>>();
for(HashMap<String, String> localeInfo: allLocales) {
String languageName = (String) localeInfo.get("label");
//If this language label is NOT in the labels sorted by language, then available
//for selection when creating a new label
//The assumption here is we don't want to allow the user to add a new label when a label
//already exists in that language
if(languageName != "untyped" && !existingLabelsLanguageNames.contains(languageName)) {
availableLocales.add(localeInfo);
}
}
//Sort list by language label and return
Collections.sort(availableLocales, new Comparator<HashMap<String, String>>() {
public int compare(HashMap<String, String> h1, HashMap<String, String> h2) {
String languageName1 = (String) h1.get("label");
String languageName2 = (String) h2.get("label");
return languageName1.compareTo(languageName2);
}
});
return availableLocales;
}
private Object isEditable(VitroRequest vreq, EditConfigurationVTwo config) {
Individual individual = EditConfigurationUtils.getIndividual(vreq, config.getSubjectUri());
AddDataPropertyStatement adps = new AddDataPropertyStatement(
vreq.getJenaOntModel(), individual.getURI(),
RequestActionConstants.SOME_URI);
AddObjectPropertyStatement aops = new AddObjectPropertyStatement(
vreq.getJenaOntModel(), individual.getURI(),
RequestActionConstants.SOME_URI,
RequestActionConstants.SOME_URI);
return PolicyHelper.isAuthorizedForActions(vreq, new Actions(adps).or(aops));
}
//Copied from NewIndividualFormGenerator
//TODO: Refactor so common code can be used by both generators
public String getFOAFPersonClassURI() {
return "http://xmlns.com/foaf/0.1/Person";
}
public boolean isPersonType(VitroRequest vreq, EditConfigurationVTwo config) {
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
Boolean isPersonType = Boolean.FALSE;
String foafPersonType = getFOAFPersonClassURI();
List<VClass> vclasses = this.getVClasses(config, vreq);
if( vclasses != null ){
for( VClass v: vclasses){
String typeUri = v.getURI();
if( foafPersonType.equals(typeUri)) {
isPersonType = Boolean.TRUE;
break;
}
}
}
return isPersonType;
}
//how to get the type of the individual in question
public List<VClass> getVClasses(EditConfigurationVTwo config, VitroRequest vreq) {
Individual subject = EditConfigurationUtils.getIndividual(vreq, config.getSubjectUri());
//Get the vclasses appropriate for this subject
return subject.getVClasses();
}
//Languages sorted by language name
private HashMap<String, List<LabelInformation>> getLabelsSortedByLanguageName(List<Literal> labels, Map<String, String> localeCodeToNameMap, EditConfigurationVTwo config,
VitroRequest vreq) {
String subjectUri = config.getSubjectUri();
String propertyUri = config.getPredicateUri();
//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
DataPropertyStatementTemplateModel dpstm = new DataPropertyStatementTemplateModel(subjectUri, propertyUri, l,
template, vreq);
labelsList.add(new LabelInformation(
l, dpstm.getEditUrl(), dpstm.getDeleteUrl(), 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());
}
}
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";
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;
}
//Putting this into a method allows overriding it in subclasses
protected String getEditForm() {
return null;
//return AddEditWebpageFormGenerator.class.getName();
}
protected String getTemplate() {
return template;
}
//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;
}
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;
}
public List<String> getFullLanguagesNamesSortedList(List<Map<String, Object>> localesList) {
HashSet<String> languageNamesSet = new HashSet<String>();
for(Map<String, Object> locale: localesList) {
String label = (String) locale.get("label");
if(!languageNamesSet.contains(label)) {
languageNamesSet.add(label);
}
}
List<String> languageNames = new ArrayList<String>(languageNamesSet);
Collections.sort(languageNames);
return languageNames;
}
//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;
}
//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 editLinkURL;
private String deleteLinkURL;
private String languageCode; //languageCode
private String languageName;
public LabelInformation(Literal inputLiteral, String inputEditLinkURL, String inputDeleteLinkURL, String inputLanguageCode, String inputLanguageName) {
this.labelLiteral = inputLiteral;
this.editLinkURL = inputEditLinkURL;
this.deleteLinkURL = inputDeleteLinkURL;
this.languageCode = inputLanguageCode;
this.languageName = inputLanguageName;
}
public Literal getLabelLiteral() {
return this.labelLiteral;
}
public String getLabelStringValue() {
return this.labelLiteral.getString();
}
public String getEditLinkURL() {
return this.editLinkURL;
}
public String getDeleteLinkURL() {
return this.deleteLinkURL;
}
public String getLanguageCode() {
return this.languageCode;
}
public String getLanguageName() {
return this.languageName;
}
}
private String N3_PREFIX = "@prefix foaf:<http://xmlns.com/foaf/0.1/> .\n";
}

View file

@ -0,0 +1,70 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators;
import java.util.List;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
/**
*This generator selects the actual generator to be employed based on whether the individual is a Person
*or another individual. Adding a label for a person relies on first/name last name information i.e. object properties.
*/
public class ManageLabelsGenerator extends BaseEditConfigurationGenerator implements EditConfigurationGenerator {
public static Log log = LogFactory.getLog(ManageLabelsForIndividualGenerator.class);
@Override
public EditConfigurationVTwo getEditConfiguration(VitroRequest vreq, HttpSession session) {
EditConfigurationVTwo e = null;
String subjectUri = EditConfigurationUtils.getSubjectUri(vreq);
if(this.isPersonType(subjectUri, vreq)) {
//Generator for persons
e = new ManageLabelsForPersonGenerator().getEditConfiguration(vreq, session);
} else {
//Non-Person individuals
e = new ManageLabelsForIndividualGenerator().getEditConfiguration(vreq, session);
}
return e;
}
public boolean isPersonType(String subjectUri, VitroRequest vreq) {
Boolean isPersonType = Boolean.FALSE;
String foafPersonType = getFOAFPersonClassURI();
List<VClass> vclasses = this.getVClasses(subjectUri, vreq);
if( vclasses != null ){
for( VClass v: vclasses){
String typeUri = v.getURI();
if( foafPersonType.equals(typeUri)) {
isPersonType = Boolean.TRUE;
break;
}
}
}
return isPersonType;
}
//Copied from NewIndividualFormGenerator
//TODO: Refactor so common code can be used by both generators
public String getFOAFPersonClassURI() {
return "http://xmlns.com/foaf/0.1/Person";
}
//how to get the type of the individual in question
public List<VClass> getVClasses(String subjectUri, VitroRequest vreq) {
Individual subject = EditConfigurationUtils.getIndividual(vreq, subjectUri);
//Get the vclasses appropriate for this subject
return subject.getVClasses();
}
}

View file

@ -9,6 +9,11 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -140,26 +145,55 @@ public class AddAssociatedConceptsPreprocessor extends
//The original code for submission wouldn't put in a key if the values were null or size 0 //The original code for submission wouldn't put in a key if the values were null or size 0
urisFromForm.remove("conceptNarrowerURI"); urisFromForm.remove("conceptNarrowerURI");
} }
//Set the copied values to this value as well so when if there are multiple
//concepts, the inputs get copied correctly for each of them
this.conceptNarrowerURIValues = existingNarrowerURIs;
if(existingBroaderURIs.size() > 0) { if(existingBroaderURIs.size() > 0) {
urisFromForm.put("conceptBroaderURI", existingBroaderURIs); urisFromForm.put("conceptBroaderURI", existingBroaderURIs);
} else { } else {
urisFromForm.remove("conceptBroaderURI"); urisFromForm.remove("conceptBroaderURI");
} }
this.conceptBroaderURIValues = existingBroaderURIs;
} }
//get the broader and narrower uri values that already exist in the system from the ones returned in the search //get the broader and narrower uri values that already exist in the system from the ones returned in the search
//and use those to populate relationships between the concept and other concepts already in the system //and use those to populate relationships between the concept and other concepts already in the system
//We should also make sure to use bidirectional n3 so the graph has both sets of relationships represented //We should also make sure to use bidirectional n3 so the graph has both sets of relationships represented
private List<String> getConceptNarrowerURIValues() { private List<String> getConceptNarrowerURIValues() {
Map<String, List<String>> urisFromForm = submission.getUrisFromForm(); return this.getJSONFormURIValues("conceptNarrowerURI");
List<String> narrowerURIs = urisFromForm.get("conceptNarrowerURI");
return narrowerURIs;
} }
private List<String> getConceptBroaderURIValues() { private List<String> getConceptBroaderURIValues() {
return this.getJSONFormURIValues("conceptBroaderURI");
}
private List<String> getJSONFormURIValues(String varName) {
Map<String, List<String>> urisFromForm = submission.getUrisFromForm(); Map<String, List<String>> urisFromForm = submission.getUrisFromForm();
List<String> broaderURIs = urisFromForm.get("conceptBroaderURI"); List<String> uris = urisFromForm.get(varName);
return broaderURIs; //This should be a JSON object stringified
if(uris.size() > 0) {
String jsonString = uris.get(0);
if(jsonString != null && !jsonString.isEmpty()) {
JSON json = JSONSerializer.toJSON(jsonString);
//This should be an array
if(json.isArray()) {
JSONArray jsonArray = (JSONArray) JSONSerializer.toJSON(jsonString);
//Convert to list of strings
return convertJsonArrayToList(jsonArray);
}
}
}
return uris;
}
private List<String> convertJsonArrayToList(JSONArray jsonArray) {
List<String> stringList = new ArrayList<String>();
int len = jsonArray.size();
int i = 0;
for(i = 0; i < len; i++) {
stringList.add(jsonArray.getString(i));
}
return stringList;
} }
private List<String> getExistingBroaderURIs(List<String> broaderURIs) { private List<String> getExistingBroaderURIs(List<String> broaderURIs) {

View file

@ -27,6 +27,8 @@ import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.vocabulary.RDF; import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS; import com.hp.hpl.jena.vocabulary.RDFS;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.jena.DatasetWrapper; import edu.cornell.mannlib.vitro.webapp.dao.jena.DatasetWrapper;
import edu.cornell.mannlib.vitro.webapp.dao.jena.DatasetWrapperFactory; import edu.cornell.mannlib.vitro.webapp.dao.jena.DatasetWrapperFactory;
@ -40,16 +42,15 @@ public class ConceptSemanticTypesPreprocessor implements ModelChangePreprocessor
private static String SKOSConceptType = "http://www.w3.org/2004/02/skos/core#Concept"; private static String SKOSConceptType = "http://www.w3.org/2004/02/skos/core#Concept";
private Log log = LogFactory.getLog(ConceptSemanticTypesPreprocessor.class); private Log log = LogFactory.getLog(ConceptSemanticTypesPreprocessor.class);
private OntModel toUpdateModel = null;
//Custom constructor //Custom constructor
public ConceptSemanticTypesPreprocessor(OntModel updateModel) { public ConceptSemanticTypesPreprocessor() {
this.toUpdateModel = updateModel;
} }
@Override @Override
public void preprocess(Model retractionsModel, Model additionsModel, public void preprocess(Model retractionsModel, Model additionsModel,
HttpServletRequest request) { HttpServletRequest request) {
VitroRequest vreq = new VitroRequest(vreq);
//Run a construct query against the additions model //Run a construct query against the additions model
String prefixes = "PREFIX rdfs:<" + RDFS.getURI() + "> " + String prefixes = "PREFIX rdfs:<" + RDFS.getURI() + "> " +
"PREFIX owl:<http://www.w3.org/2002/07/owl#> " + "PREFIX owl:<http://www.w3.org/2002/07/owl#> " +
@ -99,6 +100,7 @@ public class ConceptSemanticTypesPreprocessor implements ModelChangePreprocessor
} }
//Add constructed model to the designated update model //Add constructed model to the designated update model
OntModel toUpdateModel = ModelAccess.on(vreq).getOntModelSelector().getTBoxModel();
toUpdateModel.enterCriticalSection(Lock.WRITE); toUpdateModel.enterCriticalSection(Lock.WRITE);
try { try {
toUpdateModel.add(constructedModel); toUpdateModel.add(constructedModel);