Updates for n3 editing, fixing bugs in new individual form generator and adding field validators to person has educational training

This commit is contained in:
hjkhjk54 2011-11-17 21:43:37 +00:00
parent f0b67864ca
commit cb8f209a1a
4 changed files with 458 additions and 20 deletions

View file

@ -0,0 +1,383 @@
/* $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.Arrays;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.vivoweb.webapp.util.ModelUtils;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.DateTimeWithPrecisionVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.DateTimeIntervalValidationVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils;
import edu.cornell.mannlib.vitro.webapp.dao.jena.QueryUtils;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.vocabulary.RDFS;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.XSD;
import com.hp.hpl.jena.ontology.OntModel;
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.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.Field;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.RoleToActivityPredicatePreprocessor;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.RdfLiteralHash;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditN3GeneratorVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.SelectListGeneratorVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.FieldVTwo;
import edu.cornell.mannlib.vitro.webapp.web.MiscWebUtils;
import edu.cornell.mannlib.vitro.webapp.search.beans.ProhibitedFromSearch;
import edu.cornell.mannlib.vitro.webapp.utils.FrontEndEditingUtils;
import edu.cornell.mannlib.vitro.webapp.utils.FrontEndEditingUtils.EditMode;
import edu.cornell.mannlib.vitro.webapp.utils.generators.AddRoleUtils;
/**
* Generates the edit configuration for importing concepts from external
* search services, e.g. UMLS etc.
*
* The N3 for this is set with the default settinf of
*
*/
public class AddAssociatedConceptGenerator extends VivoBaseGenerator implements EditConfigurationGenerator {
private Log log = LogFactory.getLog(AddAssociatedConceptGenerator.class);
private boolean isObjectPropForm = false;
private String subjectUri = null;
private String predicateUri = null;
private String objectUri = null;
private String datapropKeyStr= null;
private int dataHash = 0;
private DataPropertyStatement dps = null;
private String dataLiteral = null;
private String template = "addAssociatedConcept.ftl";
private static HashMap<String,String> defaultsForXSDtypes ;
@Override
public EditConfigurationVTwo getEditConfiguration(VitroRequest vreq, HttpSession session) {
EditConfigurationVTwo editConfiguration = new EditConfigurationVTwo();
initBasics(editConfiguration, vreq);
initPropertyParameters(vreq, session, editConfiguration);
initObjectPropForm(editConfiguration, vreq);
editConfiguration.setTemplate(template);
setVarNames(editConfiguration);
//Assumes this is a simple case of subject predicate var
editConfiguration.setN3Required(this.generateN3Required(vreq));
//n3 optional
editConfiguration.setN3Optional(this.generateN3Optional());
//Todo: what do new resources depend on here?
//In original form, these variables start off empty
editConfiguration.setNewResources(generateNewResources(vreq));
//In scope
this.setUrisAndLiteralsInScope(editConfiguration, vreq);
//on Form
this.setUrisAndLiteralsOnForm(editConfiguration, vreq);
editConfiguration.setFilesOnForm(new ArrayList<String>());
//Sparql queries
this.setSparqlQueries(editConfiguration, vreq);
//set fields
setFields(editConfiguration, vreq, EditConfigurationUtils.getPredicateUri(vreq));
setTemplate(editConfiguration, vreq);
//No validators required here
//Add preprocessors
addPreprocessors(editConfiguration, vreq.getWebappDaoFactory());
//Adding additional data, specifically edit mode
addFormSpecificData(editConfiguration, vreq);
//One override for basic functionality, changing url pattern
//and entity
//Adding term should return to this same page, not the subject
//Return takes the page back to the individual form
editConfiguration.setUrlPatternToReturnTo(EditConfigurationUtils.getFormUrlWithoutContext(vreq));
return editConfiguration;
}
private void setVarNames(EditConfigurationVTwo editConfiguration) {
editConfiguration.setVarNameForSubject("person");
editConfiguration.setVarNameForPredicate("predicate");
editConfiguration.setVarNameForObject("edTraining");
}
protected void setTemplate(EditConfigurationVTwo editConfiguration,
VitroRequest vreq) {
editConfiguration.setTemplate(template);
}
/*
* N3 Required and Optional Generators as well as supporting methods
*/
private String getPrefixesString() {
//TODO: Include dynamic way of including this
return "@prefix core: <http://vivoweb.org/ontology/core#> .";
}
//TODO: Check if single string or multiple strings - check rdfslabel form etc. for prefix
//processing
private List<String> generateN3Required(VitroRequest vreq) {
return list(
getPrefixesString() + "\n" +
"?subject ?predicate ?conceptNode .\n" +
"?conceptNode <" + RDFS.label.getURI() + "> ?conceptLabel .\n" +
"?conceptNode <" + RDFS.isDefinedBy.getURI() + "> ?vocabURI ."
);
}
//Don't think there's any n3 optional here
private List<String> generateN3Optional() {
return list(
);
}
/*
* Get new resources
*/
private Map<String, String> generateNewResources(VitroRequest vreq) {
HashMap<String, String> newResources = new HashMap<String, String>();
//TODO: Get default namespace
String defaultNamespace = vreq.getWebappDaoFactory().getDefaultNamespace();
newResources.put("conceptNode", defaultNamespace + "individual");
//Only the node itself will be new for a newly created concept node
return newResources;
}
/*
* Set URIS and Literals In Scope and on form and supporting methods
*/
private void setUrisAndLiteralsInScope(EditConfigurationVTwo editConfiguration, VitroRequest vreq) {
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
//these two were always set when instantiating an edit configuration object from json,
//although the json itself did not specify subject/predicate as part of uris in scope
urisInScope.put(editConfiguration.getVarNameForSubject(),
Arrays.asList(new String[]{editConfiguration.getSubjectUri()}));
urisInScope.put(editConfiguration.getVarNameForPredicate(),
Arrays.asList(new String[]{editConfiguration.getPredicateUri()}));
//Setting inverse role predicate
urisInScope.put("inverseRolePredicate", getInversePredicate(vreq));
editConfiguration.setUrisInScope(urisInScope);
//Uris in scope include subject, predicate, and object var
//literals in scope empty initially, usually populated by code in prepare for update
//with existing values for variables
editConfiguration.setLiteralsInScope(new HashMap<String, List<Literal>>());
}
private List<String> getInversePredicate(VitroRequest vreq) {
List<String> inversePredicateArray = new ArrayList<String>();
ObjectProperty op = EditConfigurationUtils.getObjectProperty(vreq);
if(op != null && op.getURIInverse() != null) {
inversePredicateArray.add(op.getURIInverse());
}
return inversePredicateArray;
}
//n3 should look as follows
//?subject ?predicate ?objectVar
private void setUrisAndLiteralsOnForm(EditConfigurationVTwo editConfiguration, VitroRequest vreq) {
List<String> urisOnForm = new ArrayList<String>();
List<String> literalsOnForm = new ArrayList<String>();
//The URI of the node that defines the concept
urisOnForm.add("vocabURI");
//Also need to add the label of the concept
literalsOnForm.add("conceptLabel");
editConfiguration.setLiteralsOnForm(literalsOnForm);
}
/**
* Set SPARQL Queries and supporting methods
*/
private void setSparqlQueries(EditConfigurationVTwo editConfiguration, VitroRequest vreq) {
//Sparql queries defining retrieval of literals etc.
editConfiguration.setSparqlForAdditionalLiteralsInScope(new HashMap<String, String>());
Map<String, String> urisInScope = new HashMap<String, String>();
editConfiguration.setSparqlForAdditionalUrisInScope(urisInScope);
editConfiguration.setSparqlForExistingLiterals(generateSparqlForExistingLiterals(vreq));
editConfiguration.setSparqlForExistingUris(generateSparqlForExistingUris(vreq));
}
//Get page uri for object
private HashMap<String, String> generateSparqlForExistingUris(VitroRequest vreq) {
HashMap<String, String> map = new HashMap<String, String>();
//Existing uris here might include is defined by
map.put("vocabURI", getExistingVocabURIQuery());
return map;
}
private String getExistingVocabURIQuery() {
String query = "SELECT ?existingVocabURI \n " +
"WHERE { \n" +
"?conceptNode <" + RDFS.isDefinedBy.getURI() + "> ?existingVocabURI ."
+ "}";
return query;
}
private HashMap<String, String> generateSparqlForExistingLiterals(VitroRequest vreq) {
HashMap<String, String> map = new HashMap<String, String>();
//Queries for existing concept label
//Vocab uri label is something that can be retrieved
map.put("conceptLabel", getConceptLabelQuery());
return map;
}
private String getConceptLabelQuery() {
String query = "SELECT ?existingConceptLabel \n " +
"WHERE { \n" +
"?conceptNode <" + RDFS.label.getURI() + "> ?existingConceptLabel ."
+ "}";
return query;
}
/**
*
* Set Fields and supporting methods
*/
private void setFields(EditConfigurationVTwo editConfiguration, VitroRequest vreq, String predicateUri) {
setConceptLabelField(editConfiguration, vreq);
setVocabURIField(editConfiguration, vreq);
}
private void setVocabURIField(EditConfigurationVTwo editConfiguration,
VitroRequest vreq) {
editConfiguration.addField(new FieldVTwo().
setName("vocabURI").
setValidators(new ArrayList<String>()).
setOptionsType("UNDEFINED"));
}
private void setConceptLabelField(EditConfigurationVTwo editConfiguration,
VitroRequest vreq) {
editConfiguration.addField(new FieldVTwo().
setName("conceptLabel").
setValidators(new ArrayList<String>()).
setOptionsType("UNDEFINED").
setRangeDatatypeUri(XSD.xstring.toString())
);
}
//Add preprocessor
private void addPreprocessors(EditConfigurationVTwo editConfiguration, WebappDaoFactory wadf) {
//Will be a completely different type of preprocessor
/*
editConfiguration.addEditSubmissionPreprocessor(
new RoleToActivityPredicatePreprocessor(editConfiguration, wadf));
*/
}
//Form specific data
public void addFormSpecificData(EditConfigurationVTwo editConfiguration, VitroRequest vreq) {
HashMap<String, Object> formSpecificData = new HashMap<String, Object>();
//Existing concepts should probably be a hash map or a hash map of classes
//with URI of concept node to label and information about existing URI
//This would be a sparql query and would need to be run here?
//For test purposes
List<AssociatedConceptInfo> testInfo = new ArrayList<AssociatedConceptInfo>();
testInfo.add(new AssociatedConceptInfo("testLabel", "testURI", "testVocabURI", "testVocabLabel"));
formSpecificData.put("existingConcepts", testInfo);
editConfiguration.setFormSpecificData(formSpecificData);
}
public class AssociatedConceptInfo {
private String conceptLabel;
private String conceptURI;
private String vocabURI;
private String vocabLabel;
public AssociatedConceptInfo(String inputLabel, String inputURI, String inputVocabURI, String inputVocabLabel) {
this.conceptLabel = inputLabel;
this.conceptURI = inputURI;
this.vocabURI = inputVocabURI;
this.vocabLabel = inputVocabLabel;
}
//Getters
public String getConceptLabel() {
return conceptLabel;
}
public String getConceptURI() {
return conceptURI;
}
public String getVocabURI() {
return vocabURI;
}
public String getVocabLabel(){
return vocabLabel;
}
}
}

View file

@ -2,11 +2,15 @@
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators; package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.vocabulary.RDFS;
import com.hp.hpl.jena.vocabulary.XSD; import com.hp.hpl.jena.vocabulary.XSD;
import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClass;
@ -32,29 +36,36 @@ public class NewIndividualFormGenerator extends BaseEditConfigurationGenerator i
config.setTemplate( "newIndividualForm.ftl" ); config.setTemplate( "newIndividualForm.ftl" );
config.setN3Required( list( config.setN3Required( list(
"?newInd ?rdfType ?typeOfNew .", "?newInd ?rdfType ?typeOfNew ."
N3_PREFIX + "?newInd foaf:firstName ?firstName .", ));
N3_PREFIX + "?newInd foaf:lastName ?lastName ." //Optional because user may have selected either person or individual of another kind
//Person uses first name and last name whereas individual of other class would use label
config.setN3Optional(list(
N3_PREFIX + "?newInd foaf:firstName ?firstName ; foaf:lastName ?lastName .",
N3_PREFIX + "?newInd <" + RDFS.label.getURI() + "> ?label ."
)); ));
config.addNewResource("newInd", null); config.addNewResource("newInd", vreq.getWebappDaoFactory().getDefaultNamespace());
config.addUrisInScope("typeOfNew",list( getTypeOfNew(vreq) ) )
.addUrisInScope("rdfType", list( VitroVocabulary.RDF_TYPE ));
config.setLiteralsOnForm( list( "firstName", "lastName" ));
config.setUrisOnform(list ());
config.setLiteralsOnForm( list( "label", "firstName", "lastName" ));
setUrisAndLiteralsInScope(config);
//No SPARQL queries for existing since this is only used to create new, never for edit //No SPARQL queries for existing since this is only used to create new, never for edit
config.addField(new FieldVTwo(). config.addField(new FieldVTwo().
setName("firstName"). setName("firstName").
setRangeDatatypeUri(XSD.xstring.getURI()). setRangeDatatypeUri(XSD.xstring.getURI()).
setValidators(list("nonempty"))); setValidators(getFirstNameValidators(vreq)));
config.addField(new FieldVTwo(). config.addField(new FieldVTwo().
setName("lastName"). setName("lastName").
setRangeDatatypeUri(XSD.xstring.getURI()). setRangeDatatypeUri(XSD.xstring.getURI()).
setValidators(list("nonempty"))); setValidators(getLastNameValidators(vreq)));
config.addField(new FieldVTwo().
setName("label").
setRangeDatatypeUri(XSD.xstring.getURI()).
setValidators(getLabelValidators(vreq)));
addFormSpecificData(config, vreq); addFormSpecificData(config, vreq);
@ -71,7 +82,33 @@ public class NewIndividualFormGenerator extends BaseEditConfigurationGenerator i
return config; return config;
} }
//Get parameter from HTTP request for type of new individual //first and last name have validators if is person is true
private List<String> getFirstNameValidators(VitroRequest vreq) {
List<String> validators = new ArrayList<String>();
if(isPersonType(vreq)) {
validators.add("nonempty");
}
return validators;
}
private List<String> getLastNameValidators(VitroRequest vreq) {
List<String> validators = new ArrayList<String>();
if(isPersonType(vreq)) {
validators.add("nonempty");
}
return validators;
}
//validate label if person is not true
private List<String> getLabelValidators(VitroRequest vreq) {
List<String> validators = new ArrayList<String>();
if(!isPersonType(vreq)) {
validators.add("nonempty");
}
return validators;
}
//Get parameter from HTTP request for type of new individual
private String getTypeOfNew(VitroRequest vreq) { private String getTypeOfNew(VitroRequest vreq) {
String typeUri = vreq.getParameter("typeOfNew"); String typeUri = vreq.getParameter("typeOfNew");
if( typeUri == null || typeUri.trim().isEmpty() ) if( typeUri == null || typeUri.trim().isEmpty() )
@ -120,6 +157,18 @@ public class NewIndividualFormGenerator extends BaseEditConfigurationGenerator i
} }
return isPersonType; return isPersonType;
} }
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 String N3_PREFIX = "@prefix foaf:<http://xmlns.com/foaf/0.1/> .\n"; private String N3_PREFIX = "@prefix foaf:<http://xmlns.com/foaf/0.1/> .\n";
} }

View file

@ -127,8 +127,8 @@ public class PersonHasEducationalTraining extends VivoBaseGenerator implements
conf.addField( new FieldVTwo(). conf.addField( new FieldVTwo().
setName("majorField"). setName("majorField").
setRangeDatatypeUri( XSD.xstring.toString() )); setRangeDatatypeUri( XSD.xstring.toString() ).
//setValidators( ) datatype:stringDatatypeUriJson setValidators(list("datatype:" + XSD.xstring.toString())));
conf.addField( new FieldVTwo(). conf.addField( new FieldVTwo().
setName("org"). setName("org").
@ -138,23 +138,25 @@ public class PersonHasEducationalTraining extends VivoBaseGenerator implements
conf.addField( new FieldVTwo(). conf.addField( new FieldVTwo().
setName("orgLabel"). setName("orgLabel").
setRangeDatatypeUri(XSD.xstring.toString() )); setRangeDatatypeUri(XSD.xstring.toString() ).
//setValidators( ["nonempty"] ) setValidators( list("nonempty") ));
conf.addField( new FieldVTwo(). conf.addField( new FieldVTwo().
setName("orgType"). setName("orgType").
setOptionsType(FieldVTwo.OptionsType.CHILD_VCLASSES). setOptionsType(FieldVTwo.OptionsType.CHILD_VCLASSES).
setObjectClassUri( orgClass )); setObjectClassUri( orgClass ).
//setValidators( ["nonempty"]) setValidators( list("nonempty")));
//setLiteralOptions( [ "Select one" ] ) //setLiteralOptions( [ "Select one" ] )
conf.addField( new FieldVTwo(). conf.addField( new FieldVTwo().
setName("dept"). setName("dept").
setRangeDatatypeUri( XSD.xstring.toString() )); setRangeDatatypeUri( XSD.xstring.toString() ).
setValidators(list("datatype:" + XSD.xstring.toString())));
conf.addField( new FieldVTwo(). conf.addField( new FieldVTwo().
setName("info"). setName("info").
setRangeDatatypeUri( XSD.xstring.toString() )); setRangeDatatypeUri( XSD.xstring.toString() ).
setValidators(list("datatype:" + XSD.xstring.toString())));
FieldVTwo startField = new FieldVTwo(). FieldVTwo startField = new FieldVTwo().
setName("startField"); setName("startField");

View file

@ -35,4 +35,8 @@ public abstract class VivoBaseGenerator extends BaseEditConfigurationGenerator i
final static String intervalToEnd =vivoCore+"end"; final static String intervalToEnd =vivoCore+"end";
final static String orgClass ="http://xmlns.com/foaf/0.1/Organization" ; final static String orgClass ="http://xmlns.com/foaf/0.1/Organization" ;
//TODO: Define these elsewhere
final static String UMLSClass = vivoCore + "UMLS";
final static String AgrovocClass = vivoCore + "Agrovoc";
} }