Merge branch 'develop' of github.com:vivo-project/Vitro into develop

This commit is contained in:
Brian Caruso 2013-09-05 12:53:46 -04:00
commit 1ea7d5d201
13 changed files with 1242 additions and 84 deletions

View file

@ -279,7 +279,9 @@ class IndividualResponseBuilder {
log.debug("queryStr = " + queryStr);
int theCount = 0;
try {
ResultSet results = QueryUtils.getQueryResults(queryStr, vreq);
//ResultSet results = QueryUtils.getQueryResults(queryStr, vreq);
//Get query results across all languages in order for template to show manage labels link correctly
ResultSet results = QueryUtils.getLanguageNeutralQueryResults(queryStr, vreq);
if (results.hasNext()) {
QuerySolution soln = results.nextSolution();
String countStr = soln.get("labelCount").toString();

View file

@ -0,0 +1,574 @@
/* $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 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 ManageLabelsForIndividualGenerator extends BaseEditConfigurationGenerator implements EditConfigurationGenerator {
public static Log log = LogFactory.getLog(ManageLabelsForIndividualGenerator.class);
private static String template = "manageLabelsForIndividual.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
//URL to return to is the same page once addition is complete
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.setUrisAndLiteralsOnForm(config, vreq);
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 and last name and also make sure to associate
//a language with that label
config.addModelChangePreprocessor(new FoafNameToRdfsLabelPreprocessor());
prepare(vreq, config);
return config;
}
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 .";
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("lastName").
setValidators(getLastNameValidators(vreq, editConfiguration)));
}
//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);
//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);
//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,125 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors;
import javax.servlet.http.HttpServletRequest;
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.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.QuerySolutionMap;
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 com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS;
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.DatasetWrapperFactory;
//We are representing semantic types from the UMLS Semantic Network as OWL Classes
//and this preprocessor will add the appropriate class information to the TBox
public class ConceptSemanticTypesPreprocessor implements ModelChangePreprocessor {
private static String VIVOCore = "http://vivoweb.org/ontology/core#";
private static String SKOSConceptType = "http://www.w3.org/2004/02/skos/core#Concept";
private Log log = LogFactory.getLog(ConceptSemanticTypesPreprocessor.class);
private OntModel toUpdateModel = null;
//Custom constructor
public ConceptSemanticTypesPreprocessor(OntModel updateModel) {
this.toUpdateModel = updateModel;
}
@Override
public void preprocess(Model retractionsModel, Model additionsModel,
HttpServletRequest request) {
//Run a construct query against the additions model
String prefixes = "PREFIX rdfs:<" + RDFS.getURI() + "> " +
"PREFIX owl:<http://www.w3.org/2002/07/owl#> " +
"PREFIX rdf:<" + RDF.getURI() + ">" +
"PREFIX skos:<http://www.w3.org/2004/02/skos/core#>";
String constructQuery = prefixes + " CONSTRUCT { " +
"?semanticType rdf:type owl:Class. " +
"?semanticType rdfs:subClassOf skos:Concept . " +
"?semanticType rdfs:label ?label. " +
"} WHERE { " +
"?concept rdf:type ?semanticType. " +
"?semanticType rdfs:label ?label . " +
"?semanticType rdfs:subClassOf skos:Concept . " +
"}";
//Execute construct query
Model constructedModel = ModelFactory.createDefaultModel();
log.debug("CONSTRUCT query string " + constructQuery);
Query query = null;
try {
query = QueryFactory.create(constructQuery, Syntax.syntaxARQ);
} catch(Throwable th){
log.error("Could not create CONSTRUCT SPARQL query for query " +
"string. " + th.getMessage());
log.error(constructQuery);
return;
}
additionsModel.getLock().enterCriticalSection(Lock.READ);
QueryExecution qe = null;
try {
qe = QueryExecutionFactory.create(
query, additionsModel);
qe.execConstruct(constructedModel);
} catch (Exception e) {
log.error("Error getting constructed model for query string " + constructQuery);
} finally {
if (qe != null) {
qe.close();
}
additionsModel.getLock().leaveCriticalSection();
}
//Add constructed model to the designated update model
toUpdateModel.enterCriticalSection(Lock.WRITE);
try {
toUpdateModel.add(constructedModel);
} catch (Exception e) {
log.error("Error adding statements to update model for " + constructQuery);
} finally {
toUpdateModel.leaveCriticalSection();
}
//Take this constructed model and remove from the additions model
additionsModel.enterCriticalSection(Lock.WRITE);
try {
additionsModel.remove(constructedModel.listStatements().toList());
} catch (Exception e) {
log.error("Error removing statements from additions model for " + constructQuery);
} finally {
additionsModel.leaveCriticalSection();
}
}
}

View file

@ -4,6 +4,7 @@ package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocess
import javax.servlet.http.HttpServletRequest;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.ResIterator;
@ -30,7 +31,21 @@ public class FoafNameToRdfsLabelPreprocessor implements ModelChangePreprocessor
Statement fname = sub.getProperty( firstNameP );
Statement lname = sub.getProperty( lastNameP );
if( fname != null && lname != null && fname.getString() != null && lname.getString() != null ){
additionsModel.add(sub, rdfsLabelP, lname.getString() + ", " + fname.getString() );
//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();
String newLabel = lname.getString() + ", " + fname.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 );
}
}
}

View file

@ -0,0 +1,111 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
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.Statement;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
/*
* This preprocessor is used to set the language attribute on the label based on the user selection
* on the manage labels page when adding a new label.
*/
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.BaseEditSubmissionPreprocessorVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.MultiValueEditSubmission;
public class ManageLabelsForIndividualPreprocessor extends BaseEditSubmissionPreprocessorVTwo {
public ManageLabelsForIndividualPreprocessor(EditConfigurationVTwo editConfig) {
super(editConfig);
}
@Override
public void preprocess(MultiValueEditSubmission inputSubmission) {
//Check and see if a language was selected by the user, and this is the regular label submission
//TODO: Check if firstname and lastname should be changed here or elsewhere
if(inputSubmission.hasLiteralValue("label") && inputSubmission.hasLiteralValue("newLabelLanguage")) {
Map<String, List<Literal>> literalsFromForm = inputSubmission.getLiteralsFromForm();
List<Literal> newLabelLanguages = literalsFromForm.get("newLabelLanguage");
List<Literal> labels = literalsFromForm.get("label");
//Expecting only one language
if(labels.size() > 0 && newLabelLanguages.size() > 0) {
Literal newLabelLanguage = newLabelLanguages.get(0);
Literal labelLiteral = labels.get(0);
//Get the string
String lang = this.getLanguage(newLabelLanguage.getString());
String label = labelLiteral.getString();
//Now add the language category to the literal
Literal labelWithLanguage = inputSubmission.createLiteral(label,
newLabelLanguage.getDatatypeURI(),
lang);
labels = new ArrayList<Literal>();
labels.add(labelWithLanguage);
//replace the label with one with language, again assuming only one label being returned
literalsFromForm.put("label", labels);
inputSubmission.setLiteralsFromForm(literalsFromForm);
}
}
//First name and last name would also have a language selected so make sure those literals are also
//correctly typed
if(inputSubmission.hasLiteralValue("firstName") && inputSubmission.hasLiteralValue("lastName") && inputSubmission.hasLiteralValue("newLabelLanguage")) {
Map<String, List<Literal>> literalsFromForm = inputSubmission.getLiteralsFromForm();
List<Literal> newLabelLanguages = literalsFromForm.get("newLabelLanguage");
List<Literal> firstNames = literalsFromForm.get("firstName");
List<Literal> lastNames = literalsFromForm.get("lastName");
//Expecting only one language
if(firstNames.size() > 0 && lastNames.size() > 0 && newLabelLanguages.size() > 0) {
Literal newLabelLanguage = newLabelLanguages.get(0);
Literal firstNameLiteral = firstNames.get(0);
Literal lastNameLiteral = lastNames.get(0);
//Get the string
String lang = this.getLanguage(newLabelLanguage.getString());
String firstNameValue = firstNameLiteral.getString();
String lastNameValue = lastNameLiteral.getString();
//Now add the language category to the literal
Literal firstNameWithLanguage = inputSubmission.createLiteral(firstNameValue,
null,
lang);
Literal lastNameWithLanguage = inputSubmission.createLiteral(lastNameValue,
null,
lang);
firstNames = new ArrayList<Literal>();
lastNames = new ArrayList<Literal>();
firstNames.add(firstNameWithLanguage);
lastNames.add(lastNameWithLanguage);
//replace the label with one with language, again assuming only one label being returned
literalsFromForm.put("firstName", firstNames);
literalsFromForm.put("lastName", lastNames);
inputSubmission.setLiteralsFromForm(literalsFromForm);
}
}
}
//The language code returned from JAVA locales has an underscore whereas we need a hyphen
private String getLanguage(String inputLanguageCode) {
if(inputLanguageCode.contains("_")) {
return inputLanguageCode.replace("_", "-");
}
return inputLanguageCode;
}
}

View file

@ -675,7 +675,9 @@ photo = Photo
no_image = no image
placeholder_image = placeholder image
manage_labels = manage labels
manage_list_of_labels = manage list of labels
add_label = Add Label
add_label_for_language = Language
unsupported_ie_version = This form is not supported in versions of Internet Explorer below version 8. Please upgrade your browser, or switch to another browser, such as FireFox.
#
@ -857,6 +859,6 @@ subproperty = subproperty
manage_labels_for = Manage Labels for
manage_labels_capitalized = Manage Labels
manage_labels_intro = Multiple labels exist for this profile but there should only be one. Select the label you want displayed on the profile page, and the others will be deleted.
manage_labels_intro = In the case where multiple labels exist in the same language, please use the remove link to delete the labels you do not want displayed on the profile page for a given language.
processing_icon = processing
selection_in_process = Your selection is being processed.

View file

@ -7,6 +7,7 @@ var manageLabels = {
onLoad: function() {
this.mixIn();
this.initObjects();
this.initPage();
var selectedRadio;
@ -19,48 +20,134 @@ var manageLabels = {
$.extend(this, i18nStrings);
},
initObjects:function() {
this.addLabelForm = $('#addLabelForm');
this.showFormButtonWrapper = $('#showAddForm');
this.showFormButton = $("#showAddFormButton");
this.addLabelCancel = this.addLabelForm.find(".cancel");
this.submit = this.addLabelForm.find('input#submit');
this.labelLanguage = this.addLabelForm.find("#newLabelLanguage");
this.existingLabelsList = $("#existingLabelsList");
},
// Initial page setup. Called only at page load.
initPage: function() {
$('input#submit').attr('disabled', 'disabled');
$('input#submit').addClass('disabledSubmit');
var disableSubmit = true;
if(this.submissionErrorsExist == "false") {
//hide the form to add label
this.addLabelForm.hide();
//If the number of available locales is zero, then hide the ability to show the form as well
if(this.numberAvailableLocales == 0) {
manageLabels.showFormButtonWrapper.hide();
}
} else {
//Display the form
this.onShowAddForm();
//Also make sure the save button is enabled in case there is a value selected for the drop down
if(this.labelLanguage.val() != "") {
disableSubmit = false;
}
}
if(disableSubmit) {
//disable submit until user selects a language
this.submit.attr('disabled', 'disabled');
this.submit.addClass('disabledSubmit');
}
this.bindEventListeners();
},
bindEventListeners: function() {
$('input:radio').click( function() {
manageLabels.selectedRadio = $(this);
$('input#submit').attr('disabled', '');
$('input#submit').removeClass('disabledSubmit');
this.labelLanguage.change( function() {
//if language selected, allow submission, otherwise disallow
var selectedLanguage = manageLabels.labelLanguage.val();
if(selectedLanguage != "") {
manageLabels.submit.attr('disabled', '');
manageLabels.submit.removeClass('disabledSubmit');
} else {
manageLabels.submit.attr('disabled', 'disabled');
manageLabels.submit.addClass('disabledSubmit');
}
});
$('input#submit').click( function() {
manageLabels.processLabel(manageLabels.selectedRadio);
$('span.or').hide();
$('a.cancel').hide();
$('span#indicator').removeClass('hidden');
$('input.submit').addClass('disabledSubmit');
$('input.submit').attr('disabled', 'disabled');
//enable form to add label to be displayed or hidden
this.showFormButton.click(function() {
//clear the inputs for the label if the button is being clicked
manageLabels.clearAddForm();
manageLabels.onShowAddForm();
});
//Check for clicking on existing labels list remove links
//Note addition will refresh the page and removing will remove the item so adding event listeners
//to remove links should keep remove link events in synch with page
this.existingLabelsList.find("a.remove").click(function(event) {
var message = "Are you sure you wish to delete this label?"
if (!confirm(message)) {
return false;
}
//First check with confirmation whether or not they want to delete
manageLabels.processLabelDeletion(this);
return false;
});
this.addLabelForm.find("a.cancel").click(function(event){
event.preventDefault();
//clear the add form
manageLabels.clearAddForm();
//hide the add form
manageLabels.onHideAddForm();
return false;
});
},
clearAddForm:function() {
//clear inputs and select
manageLabels.addLabelForm.find("input[type='text'],select").val("");
//set the button for save to be disabled again
manageLabels.submit.attr('disabled', 'disabled');
manageLabels.submit.addClass('disabledSubmit');
},
onShowAddForm:function() {
manageLabels.addLabelForm.show();
manageLabels.showFormButtonWrapper.hide();
manageLabels.addLabelCancel.click(function(){
//Canceling the add label form will hide the form
manageLabels.addLabelForm.hide();
manageLabels.showFormButtonWrapper.show();
});
},
processLabel: function(selectedRadio) {
onHideAddForm:function() {
manageLabels.addLabelForm.hide();
manageLabels.showFormButtonWrapper.show();
//manageLabels.addLabelCancel.unbind("click");
},
//Remove label
processLabelDeletion: function(selectedLink) {
// PrimitiveDelete only handles one statement, so we have to use PrimitiveRdfEdit to handle multiple
// retractions if they exist. But PrimitiveRdfEdit also handles assertions, so pass an empty string
// for "additions"
var add = "";
var retract = "";
$('input:radio').each( function() {
if ( !$(this).is(':checked') ) {
retract += " <" + manageLabels.individualUri + "> <http://www.w3.org/2000/01/rdf-schema#label> "
+ "\"" + $(this).attr('id') + "\"" + $(this).attr('tagOrType') + " ." ;
var labelValue = $(selectedLink).attr('labelValue');
var tagOrTypeValue = $(selectedLink).attr('tagOrType');
if(tagOrTypeValue == "untyped") {
tagOrTypeValue = "";
}
});
var retract = "<" + manageLabels.individualUri + "> <http://www.w3.org/2000/01/rdf-schema#label> "
+ "\"" + $(selectedLink).attr('labelValue') + "\"" + $(selectedLink).attr('tagOrType') + " ." ;
retract = retract.substring(0,retract.length -1);
@ -72,28 +159,108 @@ var manageLabels = {
retractions: retract
},
dataType: 'json',
context: selectedRadio, // context for callback
context: selectedLink, // context for callback
complete: function(request, status) {
if (status == 'success') {
$('span.or').show();
$('a.cancel').show();
$('span#indicator').addClass('hidden');
window.location = $('a.cancel').attr('href');
//Remove the label from the list
manageLabels.removeLabelFromList(selectedLink);
manageLabels.updateLocaleSelection();
}
else {
//Instead of alert, write error to template
alert(manageLabels.errorProcessingLabels);
selectedRadio.removeAttr('checked');
$('span.or').show();
$('a.cancel').show();
$('span#indicator').addClass('hidden');
$('input.submit').removeClass('disabledSubmit');
$('input.submit').attr('disabled', '');
}
}
});
},
removeLabelFromList:function(selectedLink) {
var languageName = $(selectedLink).attr("languageName");
$(selectedLink).parent().remove();
//See if there are any other remove link
if(languageName != "untyped") {
//find if there are any other remove links for the same language
var removeLinks = manageLabels.existingLabelsList.find("a.remove[languageName='" + languageName + "']");
if(removeLinks.length == 0) {
//if there aren't any other labels for this language, also remove the heading
manageLabels.existingLabelsList.find("h3[languageName='" + languageName + "']").remove();
}
}
},
//Determine if there are new locales that can be added to the options once a delete has occurred
updateLocaleSelection:function() {
//Check what languages remain
var existingLanguages = {};
//Look at which languages are currently represented
manageLabels.existingLabelsList.find("a.remove").each(function(){
var languageCode = $(this).attr("languageCode");
if(!(languageCode in existingLanguages)) {
existingLanguages[languageCode] = true;
}
});
//Now check against full list, if any in full list not represented, will need to include in dropdown
//This is a list of
var availableLocalesList = [];
var listLen = selectLocalesFullList.length;
var i;
for(i = 0; i < listLen; i++) {
var possibleLanguageInfo = selectLocalesFullList[i];
var possibleLanguageCode = possibleLanguageInfo["code"];
var possibleLangaugeLabel = possibleLanguageInfo["label"];
if(!(possibleLanguageCode in existingLanguages)) {
//manageLabels.addLanguageCode(possibleLanguageCode, possibleLanguageLabel);
availableLocalesList.push(possibleLanguageInfo);
}
}
//Now sort this list by the label property on the object
availableLocalesList.sort(function(a, b) {
var compA = a["label"];
var compB = b["label"];
return compA < compB ? -1 : 1;
});
//Re-show the add button and the form if they were hidden before
if(availableLocalesList.length > 0 && manageLabels.showFormButtonWrapper.is(":hidden")) {
manageLabels.showFormButtonWrapper.show();
}
//Now replace dropdown with this new list
manageLabels.generateLocalesDropdown(availableLocalesList);
},
generateLocalesDropdown:function(availableLocalesList) {
//First check if there are any available locales left, if not then hide the entire add form
//technically, this first part should never be invoked client side because
//this can only happen on ADD not remove, and add will refresh the page
//On the other hand the show add button etc. can be displayed
if(availableLocalesList.length == 0) {
//Hide the add form if there are no locales left that can be added
manageLabels.addLabelForm.hide();
manageLabels.showFormButtonWrapper.hide();
} else {
//There are some locales so generate the dropdown accordingly, removing all elements but the first
$("#newLabelLanguage option:gt(0)").remove();
var i;
var len = availableLocalesList.length;
for(i = 0; i < len; i++) {
var localeInfo = availableLocalesList[i];
manageLabels.addLocaleInfo(localeInfo);
}
//Put some value in that shows whether neither add button nor add form were shown
//because the form thought there were no available locales
}
},
addLocaleInfo:function(localeInfo) {
//Add code to dropdown
//Would we need to regenerate alphabetically? Argh.
manageLabels.labelLanguage.append("<option value='" + localeInfo["code"] + "'>" + localeInfo["label"] + "</option>");
}
};

View file

@ -1,62 +1,97 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#-- Custom form for managing labels for individuals -->
<#import "manageLabelsForIndividualMacros.ftl" as m >
<#assign requiredHint = "<span class='requiredHint'> *</span>" />
<#assign subjectUri = editConfiguration.subjectUri/>
<#assign labelStr = "" >
<#assign languageTag = "" >
<#assign labelSeq = [] >
<#if subjectName?? >
<h2>${i18n().manage_labels_for} ${subjectName}</h2>
<#assign submissionErrorsExist = "false"/>
<#assign selectLocalesFullList = {} />
<#assign editable = false/>
<#if editConfiguration.pageData.editable?has_content>
<#assign editable = editConfiguration.pageData.editable />
</#if>
<#if editSubmission?has_content && editSubmission.submissionExists = true && editSubmission.validationErrors?has_content>
<#assign submissionErrors = editSubmission.validationErrors/>
<#assign submissionErrorsExist = "true" />
</#if>
<#assign availableLocalesNumber = 0/>
<#if editConfiguration.pageData.selectLocale?has_content>
<#assign availableLocalesNumber = editConfiguration.pageData.selectLocale?size />
</#if>
<#if editConfiguration.pageData.subjectName?? >
<h2>${i18n().manage_labels_for} ${editConfiguration.pageData.subjectName}</h2>
<#else>
<h2>${i18n().manage_labels_capitalized}</h2>
</#if>
<p id="mngLabelsText">${i18n().manage_labels_intro}</p>
<section id="rdfsLabels" role="container">
<ul>
<#list labels as label>
<#-- the query will return labels with their language tag or datatype, if any. So strip those out -->
<#if label?? && ( label?index_of("@") > -1 ) >
<#assign labelStr = label?substring(0, label?index_of("@")) >
<#assign tagOrTypeStr = label?substring(label?index_of("@")) >
<#elseif label?? && ( label?index_of("^^") > -1 ) >
<#assign labelStr = label?substring(0, label?index_of("^^")) >
<#assign tagOrTypeStr = label?substring(label?index_of("^^")) >
<#assign tagOrTypeStr = tagOrTypeStr?replace("^^http","^^<http") >
<#assign tagOrTypeStr = tagOrTypeStr?replace("#string","#string>") >
<#else>
<#assign labelStr = label >
<#assign tagOrTypeStr = "" >
<script type="text/javascript">
var existingLabelsData = [];
</script>
<ul id="existingLabelsList" name="existingLabelsList">
<#if editConfiguration.pageData.labelsSortedByLanguageName?has_content>
<#--List of labelInformation objects as value where key = language name -->
<#assign labelsSorted = editConfiguration.pageData.labelsSortedByLanguageName />
<#--Keys would be the actual names of languages-->
<#assign labelLanguages = labelsSorted?keys?sort />
<#assign editGenerator = "editForm=edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.RDFSLabelGenerator" />
<#--What we need here is printing out the labels by the language Name and not language code, starting with untyped first-->
<@m.displayExistingLabelsForLanguage "untyped" labelsSorted editable editGenerator/>
<@m.displayExistingTypedLabels labelLanguages labelsSorted editable editGenerator/>
</#if>
<li>
<input type="radio" class="labelCheckbox" name="labelCheckbox" id="${labelStr}" tagOrType="${tagOrTypeStr!}" role="radio" />
<label class="inline">${labelStr}
<#if labelSeq?seq_contains(labelStr)>
(duplicate value)
</#if>
</label>
</li>
<#assign labelSeq = labelSeq + [labelStr]>
</#list>
</ul>
<br />
<p>
<input type="button" class="submit" id="submit" value="${i18n().save_button}" role="button" role="input" />
<span class="or"> or </span>
<a href="${urls.referringPage}" class="cancel" title="${i18n().cancel_title}" >${i18n().cancel_link}</a>
<span id="indicator" class="indicator hidden">
<img class="indicator" src="${urls.base}/images/indicatorWhite.gif" alt="${i18n().processing_icon}"/>&nbsp;${i18n().selection_in_process}
</span>
<#if editable>
<#include "manageLabelsForIndividualSubmissionErrors.ftl">
<div id="showAddForm">
<input type="submit" value="${i18n().add_label}" id="showAddFormButton" name="showAddFormButton"> ${i18n().or}
<a class="cancel" href="${cancelUrl}&url=/individual" title="${i18n().return_to_profile}">${i18n().return_to_profile}</a>
</div>
<#include "manageLabelsForIndividualAddForm.ftl" >
</#if>
</p>
</section>
<script type="text/javascript">
var selectLocalesFullList = [];
<#if editConfiguration.pageData.selectLocaleFullList?has_content>
<#assign selectLocalesFullList = editConfiguration.pageData.selectLocaleFullList />
<#list selectLocalesFullList as localeInfo>
<#assign code = localeInfo["code"] />
<#assign label= localeInfo["label"] />
selectLocalesFullList.push({'code':'${code}', 'label':'${label}'});
</#list>
</#if>
var customFormData = {
processingUrl: '${urls.base}/edit/primitiveRdfEdit',
individualUri: '${subjectUri!}'
individualUri: '${subjectUri!}',
submissionErrorsExist: '${submissionErrorsExist}',
selectLocalesFullList: selectLocalesFullList,
numberAvailableLocales:${availableLocalesNumber}
};
var i18nStrings = {
errorProcessingLabels: '${i18n().error_processing_labels}'
errorProcessingLabels: '${i18n().error_processing_labels}',
selectLocaleOptionString : '${i18n().select_locale}'
};
</script>

View file

@ -0,0 +1,29 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#--The form for adding a new label-->
<form id="addLabelForm" name="addLabelForm" class="customForm" action="${submitUrl}">
<h2>${i18n().add_label}</h2>
<p>
<label for="name">${i18n().name} ${requiredHint}</label>
<input size="30" type="text" id="label" name="label" value="" />
</p>
<label for="newLabelLanguage">${i18n().add_label_for_language}</label>
<select name="newLabelLanguage" id="newLabelLanguage" >
<option value=""<#if !newLabelLanguageValue?has_content> selected="selected"</#if>>${i18n().select_locale}</option>
<#if editConfiguration.pageData.selectLocale?has_content>
<#assign selectLocale = editConfiguration.pageData.selectLocale />
<#--Use the list of names because that is the order we want displayed-->
<#list selectLocale as locale>
<option value="${locale.code}"<#if newLabelLanguageValue?has_content && locale.code == newLabelLanguageValue> selected="selected"</#if>>${locale.label}</option>
</#list>
</#if>
</select>
<input type="hidden" name="editKey" id="editKey" value="${editKey}"/>
<input type="submit" class="submit" id="submit" value="${i18n().save_button}" role="button" role="input" />
${i18n().or}
<a href="${urls.referringPage}" class="cancel" title="${i18n().cancel_title}" >${i18n().cancel_link}</a>
</form>

View file

@ -0,0 +1,79 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#--LabelsSorted is a hash keyed by language name where the value is a list of LabelInformation class objects-->
<#macro displayExistingLabelsForLanguage lang labelsSorted editable editGenerator>
<#--get label information for this language-->
<#assign labelList = labelsSorted[lang] />
<#--Reset for every language-->
<#assign labelSeq = []/>
<#list labelList as labelObject>
<#assign labelLiteral = labelObject.labelLiteral />
<#assign labelStringValue = labelObject.labelStringValue />
<#--Try label as label literal-->
<#assign label = labelLiteral />
<#assign labelLang = labelObject.languageName />
<#assign languageCode = labelObject.languageCode />
<#assign labelEditLink = labelObject.editLinkURL />
<#if label?? && ( label?index_of("@") > -1 ) >
<#assign labelStr = label?substring(0, label?index_of("@")) >
<#assign tagOrTypeStr = label?substring(label?index_of("@")) >
<#elseif label?? && ( label?index_of("^^") > -1 ) >
<#assign labelStr = label?substring(0, label?index_of("^^")) >
<#assign tagOrTypeStr = label?substring(label?index_of("^^")) >
<#assign tagOrTypeStr = tagOrTypeStr?replace("^^http","^^<http") >
<#assign tagOrTypeStr = tagOrTypeStr?replace("#string","#string>") >
<#else>
<#assign labelStr = label >
<#assign tagOrTypeStr = "" >
</#if>
<li>${labelStr} <#if labelSeq?seq_contains(labelStr)> (duplicate value) </#if>
<#if editable && labelEditLink?has_content> <a href="${labelEditLink}&${editGenerator}">Edit</a>
<a href="${urls.base}/edit/primitiveRdfEdit" languageName="${labelLang}" languageCode="${languageCode}"
labelValue="${labelStr}" tagOrType="${tagOrTypeStr!}" class="remove" title="${i18n().remove_capitalized}">${i18n().remove_capitalized}</a>
</#if>
</li>
<#assign labelSeq = labelSeq + [labelStr]>
</#list>
</#macro>
<#--ignore 'untyped' and display everything-->
<#macro displayExistingTypedLabels langList labelsSorted editable editGenerator>
<#list langList as lang>
<#if lang != "untyped">
<h3 languageName="${lang}">${lang}</h3>
<#--get label information for this language-->
<#assign labelList = labelsSorted[lang] />
<#--Reset for every language-->
<#assign labelSeq = []/>
<#list labelList as labelObject>
<#assign labelLiteral = labelObject.labelLiteral />
<#assign labelStringValue = labelObject.labelStringValue />
<#--Try label as label literal-->
<#assign label = labelLiteral />
<#assign labelLang = labelObject.languageName />
<#assign languageCode = labelObject.languageCode />
<#assign labelEditLink = labelObject.editLinkURL />
<#if label?? && ( label?index_of("@") > -1 ) >
<#assign labelStr = label?substring(0, label?index_of("@")) >
<#assign tagOrTypeStr = label?substring(label?index_of("@")) >
<#elseif label?? && ( label?index_of("^^") > -1 ) >
<#assign labelStr = label?substring(0, label?index_of("^^")) >
<#assign tagOrTypeStr = label?substring(label?index_of("^^")) >
<#assign tagOrTypeStr = tagOrTypeStr?replace("^^http","^^<http") >
<#assign tagOrTypeStr = tagOrTypeStr?replace("#string","#string>") >
<#else>
<#assign labelStr = label >
<#assign tagOrTypeStr = "" >
</#if>
<li>${labelStr} <#if labelSeq?seq_contains(labelStr)> (duplicate value) </#if>
<#if editable && labelEditLink?has_content> <a href="${labelEditLink}&${editGenerator}">Edit</a>
<a href="${urls.base}/edit/primitiveRdfEdit" languageName="${labelLang}" languageCode="${languageCode}"
labelValue="${labelStr}" tagOrType="${tagOrTypeStr!}" class="remove" title="${i18n().remove_capitalized}">${i18n().remove_capitalized}</a>
</#if>
</li>
<#assign labelSeq = labelSeq + [labelStr]>
</#list>
</#if>
</#list>
</#macro>

View file

@ -0,0 +1,14 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#if submissionErrors?has_content >
<section id="error-alert" role="alert">
<img src="${urls.images}/iconAlert.png" width="24" height="24" alt="${i18n().error_alert_icon}" />
<p>
<#list submissionErrors?keys as errorFieldName>
<#if errorFieldName == "label">
${i18n().enter_value_name_field}
</#if>
<br />
</#list>
</p>
</section>
</#if>

View file

@ -69,7 +69,7 @@
<p>${i18n().you_can} <a href="${urls.siteAdmin}" title="${i18n().add_content_manage_site}">${i18n().add_content_manage_site}</a>${i18n().from_site_admin_page}</p>
</#if>
<#else>
<p>${i18n().please} <a href="${urls.login}" title="${i18n().login_to_manage_site}">${i18n().log_in}</a> ${i18n().to_manage_content.}</p>
<p>${i18n().please} <a href="${urls.login}" title="${i18n().login_to_manage_site}">${i18n().log_in}</a> ${i18n().to_manage_content}.</p>
</#if>
</#if>

View file

@ -209,13 +209,18 @@ name will be used as the label. -->
<#-- Label -->
<#macro label individual editable labelCount>
<#assign labelPropertyUri = ("http://www.w3.org/2000/01/rdf-schema#label"?url) />
<#-- Will need to deal with multiple languages as well-->
<#local label = individual.nameStatement>
${label.value}
<#if (labelCount > 1) && editable >
<#-- Manage labels now goes to generator -->
<#assign individualUri = individual.uri!""/>
<#assign individualUri = (individualUri?url)/>
<span class="inline">
<a id="manageLabels" href="${urls.base}/manageLabels?subjectUri=${individual.uri!}">
${i18n().manage_labels}
</a>
<a class="add-label" href="${urls.base}/editRequestDispatch?subjectUri=${individualUri}&editForm=edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.ManageLabelsForIndividualGenerator&predicateUri=${labelPropertyUri}"
title="${i18n().manage_list_of_labels}">
<img class="add-individual" src="${urls.images}/individual/manage-icon.png" alt="${i18n().manage}" /></a>
</span>
<#else>
<@editingLinks "label" label editable />