Updates for N3-Editing refactoring into JAVA code as well as integration of data and object property editing into same JAVA controller/freemarker templates. These changes should not affect the current jsp-based N3Editing which is being used throughout the system.

This commit is contained in:
hjkhjk54 2011-08-15 21:46:02 +00:00
parent 8597505e05
commit 5ece405f94
10 changed files with 1194 additions and 448 deletions

View file

@ -0,0 +1,144 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpSession;
import com.hp.hpl.jena.rdf.model.Model;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.RdfLiteralHash;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
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;
public class EditConfigurationUtils {
protected static final String MULTI_VALUED_EDIT_SUBMISSION = "MultiValueEditSubmission";
/* *************** Static utility methods used in edit configuration and in generators *********** */
public static String getSubjectUri(VitroRequest vreq) {
return vreq.getParameter("subjectUri");
}
public static String getPredicateUri(VitroRequest vreq) {
return vreq.getParameter("predicateUri");
}
/*
public static String getData(VitroRequest vreq) {
return vreq.getParameter("subjectUri");
}*/
public static String getObjectUri(VitroRequest vreq) {
return vreq.getParameter("objectUri");
}
//get individual
public static Individual getSubjectIndividual(VitroRequest vreq) {
Individual subject = null;
String subjectUri = getSubjectUri(vreq);
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
if( subjectUri != null ){
subject = wdf.getIndividualDao().getIndividualByURI(subjectUri);
if( subject != null )
vreq.setAttribute("subject", subject);
}
return subject;
}
public static Individual getObjectIndividual(VitroRequest vreq) {
String objectUri = getObjectUri(vreq);
Individual object = null;
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
if( objectUri != null ){
object = wdf.getIndividualDao().getIndividualByURI(objectUri);
if( object != null )
vreq.setAttribute("subject", object);
}
return object;
}
public static ObjectProperty getObjectProperty(VitroRequest vreq) {
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
String predicateUri = getPredicateUri(vreq);
ObjectProperty objectProp = wdf.getObjectPropertyDao().getObjectPropertyByURI(predicateUri);
return objectProp;
}
public static DataProperty getDataProperty(VitroRequest vreq) {
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
String predicateUri = getPredicateUri(vreq);
DataProperty dataProp = wdf.getDataPropertyDao().getDataPropertyByURI(predicateUri);
return dataProp;
}
public static String getFormUrl(VitroRequest vreq) {
return vreq.getContextPath() + "/edit/editRequestDispatch?" + vreq.getQueryString();
}
public static String getEditKey(VitroRequest vreq) {
HttpSession session = vreq.getSession();
String editKey =
(EditConfigurationVTwo.getEditKey(vreq) == null)
? EditConfigurationVTwo.newEditKey(session)
: EditConfigurationVTwo.getEditKey(vreq);
return editKey;
}
//is data property or vitro label
public static boolean isDataProperty(String predicateUri, VitroRequest vreq) {
if(isVitroLabel(predicateUri)) {
return true;
}
DataProperty dataProp = vreq.getWebappDaoFactory().getDataPropertyDao().getDataPropertyByURI(predicateUri);
return (dataProp != null);
}
public static String getDataPropKey(VitroRequest vreq) {
return vreq.getParameter("datapropKey");
}
//is object property
public static boolean isObjectProperty(String predicateUri, VitroRequest vreq) {
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
ObjectProperty op = wdf.getObjectPropertyDao().getObjectPropertyByURI(predicateUri);
DataProperty dp = wdf.getDataPropertyDao().getDataPropertyByURI(predicateUri);
return (op != null && dp == null);
}
private static boolean isVitroLabel(String predicateUri) {
return predicateUri.equals(VitroVocabulary.LABEL);
}
public static DataPropertyStatement getDataPropertyStatement(VitroRequest vreq, HttpSession session, int dataHash, String predicateUri) {
DataPropertyStatement dps = null;
if( dataHash != 0) {
Model model = (Model)session.getServletContext().getAttribute("jenaOntModel");
dps = RdfLiteralHash.getPropertyStmtByHash(EditConfigurationUtils.getSubjectIndividual(vreq), predicateUri, dataHash, model);
if (dps==null) {
//log.error("No match to existing data property \""+predicateUri+"\" statement for subject \""+subjectUri+"\" via key "+datapropKeyStr);
//TODO: Needs to forward to dataPropMissingStatement.jsp
//return null;
}
}
return dps;
}
}

View file

@ -624,6 +624,11 @@ public class EditConfigurationVTwo {
public void setDatapropKey(String datapropKey) {
this.datapropKey = datapropKey;
}
//to allow for external setting
public void setDatapropValue(String datapropValue) {
this.datapropValue = datapropValue;
}
public String getSubjectUri() {
return subjectUri;

View file

@ -211,6 +211,7 @@ public class ProcessRdfForm {
Model model = ModelFactory.createDefaultModel();
StringReader reader = new StringReader(n3);
model.read(reader, "", "N3");
requiredFieldAssertions.add(model);
}catch(Throwable t){
String errMsg = "error processing N3 assertion string from field " + fieldName + "\n" +
t.getMessage() + '\n' + "n3: \n" + n3;

View file

@ -2,6 +2,7 @@
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;
@ -12,17 +13,29 @@ import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
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.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.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;
/**
* Generates the edit configuration for a default property form.
@ -31,149 +44,363 @@ import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.Field;
public class DefaultObjectPropertyFormGenerator implements EditConfigurationGenerator {
private Log log = LogFactory.getLog(DefaultObjectPropertyFormGenerator.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 objectPropertyTemplate = "defaultPropertyForm.ftl";
private String dataPropertyTemplate = "defaultDataPropertyForm.ftl";
private static HashMap<String,String> defaultsForXSDtypes ;
static {
defaultsForXSDtypes = new HashMap<String,String>();
//defaultsForXSDtypes.put("http://www.w3.org/2001/XMLSchema#dateTime","2001-01-01T12:00:00");
defaultsForXSDtypes.put("http://www.w3.org/2001/XMLSchema#dateTime","#Unparseable datetime defaults to now");
}
@Override
public EditConfigurationVTwo getEditConfiguration(VitroRequest vreq,
HttpSession session) {
// TODO Generate a edit conf for the default object property form and return it.
Individual subject = (Individual)vreq.getAttribute("subject");
ObjectProperty prop = (ObjectProperty)vreq.getAttribute("predicate");
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
String queryForInverse = "PREFIX owl: <http://www.w3.org/2002/07/owl#>"
+ " SELECT ?inverse_property "
+ " WHERE { ?inverse_property owl:inverseOf ?predicate } ";
// retrieving attributes from the request object to build editjson string
String formUrl = (String)vreq.getAttribute("formUrl");
String editKey = (String)vreq.getAttribute("editKey");
String subjectUriJson = (String)vreq.getAttribute("subjectUriJson");
String predicateUriJson = (String)vreq.getAttribute("predicateUriJson");
String objectUriJson = (String)vreq.getAttribute("objectUriJson");
//building the editjson object
//TODO: There has to be a better way of doing this.
// Tried building a java object with Google Gson and then
// deserialize it to json, but the values in the string
// are sometimes lists, maps, literals.
/* String editjson = "{" +
" formUrl : " + formUrl + " ," +
" editKey : " + editKey + " ," +
" urlPatternToReturnTo : " + "/individual ," +
" subject : [ subject , " + subjectUriJson + " ] , " +
" predicate : [ predicate , " + predicateUriJson + " ] ," +
" object : [ objectVar , " + objectUriJson + ", URI ] , " +
" n3required : [ " + n3ForEdit + "] ," +
" n3optional : [ " + n3Inverse + "] ," +
" newResources : { } ," +
" urisInScope : { } ," +
" literalsInScope: { } ," +
" urisOnForm : [objectVar] ," +
" literalsOnForm : [ ] ," +
" filesOnForm : [ ] ," +
"sparqlForLiterals : { } ," +
"sparqlForUris : { inverseProp : " + queryForInverse + " } ," +
"sparqlForExistingLiterals : { } ," +
"sparqlForExistingUris : { } ," +
"fields : { objectVar : { " +
" newResource : false ," +
" queryForExisting : { }, " +
" validators : [ nonempty ] ," +
" optionsType : INDIVIDUALS_VIA_OBJECT_PROPERTY , " +
" subjectUri : " + subjectUriJson + " ," +
" subjectClassUri : ," +
" predicateUri : " + predicateUriJson + " ," +
" objectClassUri : ," +
" rangeDatatypeUri : ," +
" rangeLang : , " +
" literalOptions : [ ] , " +
" assertions : [ " + n3ForEdit + " ," + n3Inverse + " ] " +
" } " +
" } " +
" } ";
*/
//set the editjson attribute in the request
// vreq.setAttribute("editjson", editjson);
// log.debug(vreq.getAttribute("editjson"));
//Alternative: Set
//Generate a edit conf for the default object property form and return it.
EditConfigurationVTwo editConfiguration = new EditConfigurationVTwo();
//Set n3 generator
editConfiguration.setN3Generator(new EditN3GeneratorVTwo(editConfiguration));
//process subject, predicate, object parameters
this.initProcessParameters(vreq, session, 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(new HashMap<String, String>());
//In scope
this.setUrisAndLiteralsInScope(editConfiguration);
//on Form
this.setUrisAndLiteralsOnForm(editConfiguration, vreq);
editConfiguration.setFilesOnForm(new ArrayList<String>());
//Sparql queries
this.setSparqlQueries(editConfiguration);
//set fields
setFields(editConfiguration, vreq, EditConfigurationUtils.getPredicateUri(vreq));
// No need to put in session here b/c put in session within edit request dispatch controller instead
//placing in session depends on having edit key which is handled in edit request dispatch controller
// editConfiguration.putConfigInSession(editConfiguration, session);
prepareForUpdate(vreq, session, editConfiguration);
//Form title and submit label now moved to edit configuration template
//TODO: check if edit configuration template correct place to set those or whether
//additional methods here should be used and reference instead, e.g. edit configuration template could call
//default obj property form.populateTemplate or some such method
//Select from existing also set within template itself
setTemplate(editConfiguration, vreq);
return editConfiguration;
}
private void setTemplate(EditConfigurationVTwo editConfiguration,
VitroRequest vreq) {
String template = objectPropertyTemplate;
if(EditConfigurationUtils.isDataProperty(editConfiguration.getPredicateUri(), vreq)){
template = dataPropertyTemplate;
}
editConfiguration.setTemplate(template);
}
//Initialize setup: process parameters
private void initProcessParameters(VitroRequest vreq, HttpSession session, EditConfigurationVTwo editConfiguration) {
String formUrl = EditConfigurationUtils.getFormUrl(vreq);
subjectUri = EditConfigurationUtils.getSubjectUri(vreq);
predicateUri = EditConfigurationUtils.getPredicateUri(vreq);
editConfiguration.setFormUrl(formUrl);
editConfiguration.setEditKey(editKey);
editConfiguration.setUrlPatternToReturnTo("/individual");
editConfiguration.setVarNameForSubject("subject");
editConfiguration.setSubjectUri(subjectUriJson);
editConfiguration.setSubjectUri(subjectUri);
editConfiguration.setEntityToReturnTo(subjectUri);
editConfiguration.setVarNameForPredicate("predicate");
editConfiguration.setPredicateUri(predicateUriJson);
editConfiguration.setVarNameForObject("objectVar");
editConfiguration.setObject(objectUriJson);
editConfiguration.setPredicateUri(predicateUri);
//this needs to be set for the editing to be triggered properly, otherwise the 'prepare' method
//pretends this is a data property editing statement and throws an error
if(objectUriJson != null) {
//"object" : [ "objectVar" , "${objectUriJson}" , "URI"],
if(EditConfigurationUtils.isObjectProperty(predicateUri, vreq)) {
//not concerned about remainder, can move into default obj prop form if required
this.isObjectPropForm = true;
this.initObjectParameters(vreq);
this.processObjectPropForm(vreq, editConfiguration);
} else {
this.isObjectPropForm = false;
this.initDataParameters(vreq, session);
this.processDataPropForm(vreq, editConfiguration);
}
}
private void initDataParameters(VitroRequest vreq, HttpSession session) {
dataLiteral = getDataLiteral(vreq);
datapropKeyStr = EditConfigurationUtils.getDataPropKey(vreq);
if( datapropKeyStr != null ){
try {
dataHash = Integer.parseInt(datapropKeyStr);
log.debug("Found a datapropKey in parameters and parsed it to int: " + dataHash);
} catch (NumberFormatException ex) {
//return doHelp(vreq, "Cannot decode incoming datapropKey value "+datapropKeyStr+" as an integer hash in EditDataPropStmtRequestDispatchController");
}
}
dps = EditConfigurationUtils.getDataPropertyStatement(vreq, session, dataHash, predicateUri);
}
private void initObjectParameters(VitroRequest vreq) {
//in case of object property
objectUri = EditConfigurationUtils.getObjectUri(vreq);
}
private void processObjectPropForm(VitroRequest vreq, EditConfigurationVTwo editConfiguration) {
editConfiguration.setVarNameForObject("objectVar");
editConfiguration.setObject(objectUri);
//this needs to be set for the editing to be triggered properly, otherwise the 'prepare' method
//pretends this is a data property editing statement and throws an error
//TODO: Check if null in case no object uri exists but this is still an object property
if(objectUri != null) {
editConfiguration.setObjectResource(true);
}
}
private void processDataPropForm(VitroRequest vreq, EditConfigurationVTwo editConfiguration) {
editConfiguration.setObjectResource(false);
//set data prop value, data prop key str,
editConfiguration.setDatapropKey((datapropKeyStr==null)?"":datapropKeyStr);
DataProperty prop = EditConfigurationUtils.getDataProperty(vreq);
editConfiguration.setVarNameForObject(dataLiteral);
//original set datapropValue, which in this case would be empty string but no way here
editConfiguration.setDatapropValue("");
editConfiguration.setUrlPatternToReturnTo("/entity");
}
//Get N3 required
//Handles both object and data property
private List<String> generateN3Required(VitroRequest vreq) {
List<String> n3ForEdit = new ArrayList<String>();
n3ForEdit.add("?subject");
n3ForEdit.add("?predicate");
n3ForEdit.add("?objectVar");
editConfiguration.setN3Required(n3ForEdit);
String editString = "?subject ?predicate ";
if(this.isObjectPropForm) {
editString += "?objectVar";
} else {
DataProperty prop = EditConfigurationUtils.getDataProperty(vreq);
String localName = prop.getLocalName();
String dataLiteral = localName + "Edited";
editString += "?"+dataLiteral;
}
editString += " .";
n3ForEdit.add(editString);
return n3ForEdit;
}
private List<String> generateN3Optional() {
List<String> n3Inverse = new ArrayList<String>();
n3Inverse.add("?objectVar");
n3Inverse.add("?inverseProp");
n3Inverse.add("?subject");
editConfiguration.setN3Optional(n3Inverse);
//Note that for proper substitution, spaces expected between variables, i.e. string
//of n3 format
n3Inverse.add("?objectVar ?inverseProp ?subject .");
return n3Inverse;
editConfiguration.setNewResources(new HashMap<String, String>());
editConfiguration.setUrisInScope(new HashMap<String, List<String>>());
}
//Set queries
private String retrieveQueryForInverse () {
String queryForInverse = "PREFIX owl: <http://www.w3.org/2002/07/owl#>"
+ " SELECT ?inverse_property "
+ " WHERE { ?inverse_property owl:inverseOf ?predicate } ";
return queryForInverse;
}
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()}));
//this shoudl happen in edit configuration prepare for object prop update
//urisInScope.put(editConfiguration.getVarNameForObject(),
// Arrays.asList(new String[]{editConfiguration.getObject()}));
//inverse property uris should be included in sparql for additional uris in edit configuration
editConfiguration.setUrisInScope(urisInScope);
//Uris in scope include subject, predicate, and object var
editConfiguration.setLiteralsInScope(new HashMap<String, List<Literal>>());
}
//n3 should look as follows
//?subject ?predicate ?objectVar
private void setUrisAndLiteralsOnForm(EditConfigurationVTwo editConfiguration, VitroRequest vreq) {
List<String> urisOnForm = new ArrayList<String>();
urisOnForm.add("objectVar");
editConfiguration.setN3Optional(urisOnForm);
editConfiguration.setLiteralsOnForm(new ArrayList<String>());
editConfiguration.setFilesOnForm(new ArrayList<String>());
editConfiguration.setUrisOnform(urisOnForm);
List<String> literalsOnForm = new ArrayList<String>();
if(EditConfigurationUtils.isDataProperty(EditConfigurationUtils.getPredicateUri(vreq), vreq)) {
//if data property set to data literal
literalsOnForm.add(dataLiteral);
}
editConfiguration.setLiteralsOnForm(literalsOnForm);
}
private String getDataLiteral(VitroRequest vreq) {
DataProperty prop = EditConfigurationUtils.getDataProperty(vreq);
return prop.getLocalName() + "Edited";
}
//This is for various items
private void setSparqlQueries(EditConfigurationVTwo editConfiguration) {
//Sparql queries defining retrieval of literals etc.
editConfiguration.setSparqlForAdditionalLiteralsInScope(new HashMap<String, String>());
Map<String, String> urisInScope = new HashMap<String, String>();
urisInScope.put("inverseProp", queryForInverse);
urisInScope.put("inverseProp", this.retrieveQueryForInverse());
editConfiguration.setSparqlForAdditionalUrisInScope(urisInScope);
editConfiguration.setSparqlForExistingLiterals(new HashMap<String, String>());
editConfiguration.setSparqlForExistingUris(new HashMap<String, String>());
editConfiguration.setSparqlForExistingLiterals(generateSparqlForExistingLiterals());
editConfiguration.setSparqlForExistingUris(generateSparqlForExistingUris());
}
//Get page uri for object
private HashMap<String, String> generateSparqlForExistingUris() {
HashMap<String, String> map = new HashMap<String, String>();
return map;
}
private HashMap<String, String> generateSparqlForExistingLiterals() {
HashMap<String, String> map = new HashMap<String, String>();
return map;
}
private void setFields(EditConfigurationVTwo editConfiguration, VitroRequest vreq, String predicateUri) {
Map<String, FieldVTwo> fields = new HashMap<String, FieldVTwo>();
if(EditConfigurationUtils.isObjectProperty(EditConfigurationUtils.getPredicateUri(vreq), vreq)) {
fields = getObjectPropertyField(editConfiguration, vreq);
} else {
fields = getDataPropertyField(editConfiguration, vreq);
}
Map<String, Field> fields = new HashMap<String, Field>();
editConfiguration.setFields(fields);
}
private Map<String, FieldVTwo> getDataPropertyField(
EditConfigurationVTwo editConfiguration, VitroRequest vreq) {
Map<String, FieldVTwo> fields = new HashMap<String, FieldVTwo>();
FieldVTwo field = new FieldVTwo();
field.setName(dataLiteral);
field.setNewResource(false);
//queryForExisting is not being used anywhere in Field
String rangeDatatypeUri = getRangeDatatypeUri(editConfiguration, vreq);
Field field = new Field();
List<String> validators = new ArrayList<String>();
validators.add("datatype:" + rangeDatatypeUri);
field.setValidators(validators);
//subjectUri and subjectClassUri are not being used in Field
field.setOptionsType("LITERALS");
//why isn't predicate uri set for data properties?
field.setPredicateUri(null);
field.setObjectClassUri(null);
field.setRangeDatatypeUri(rangeDatatypeUri);
field.setRangeLang(getRangeLang(editConfiguration, vreq));
field.setLiteralOptions(getLiteralOptions(editConfiguration, vreq));
//set assertions
List<String> assertions = new ArrayList<String>();
assertions.addAll(editConfiguration.getN3Required());
field.setAssertions(assertions);
fields.put(field.getName(), field);
return fields;
}
private List<List<String>> getLiteralOptions(
EditConfigurationVTwo editConfiguration, VitroRequest vreq) {
DataPropertyStatement dps =EditConfigurationUtils.getDataPropertyStatement(vreq, vreq.getSession(), dataHash, predicateUri);
List<List<String>> literalOptions = new ArrayList<List<String>>();
if(dps == null) {
log.debug("No incoming dataproperty statement attribute for property ; adding a new statement");
String rangeDatatypeUri = getRangeDatatypeUri(editConfiguration, vreq);
if(rangeDatatypeUri != null && rangeDatatypeUri.length() > 0) {
String defaultVal = defaultsForXSDtypes.get(rangeDatatypeUri);
List<String> defaultArray = new ArrayList<String>();
defaultArray.add(defaultVal);
literalOptions.add(defaultArray);
}
}
return literalOptions;
}
private String getRangeLang(EditConfigurationVTwo editConfiguration,
VitroRequest vreq) {
String rangeLang = null;
DataPropertyStatement dps =EditConfigurationUtils.getDataPropertyStatement(vreq, vreq.getSession(), dataHash, predicateUri);
if(dps != null) {
rangeLang = dps.getLanguage();
if( rangeLang == null ) {
log.debug("no language attribute on data property statement in DefaultDataPropertyFormGenerator");
}else{
log.debug("language attribute of ["+rangeLang+"] on data property statement in DefaultDataPropertyFormGenerator");
}
}
return rangeLang;
}
private String getRangeDatatypeUri(EditConfigurationVTwo editConfiguration,
VitroRequest vreq) {
Individual subject = EditConfigurationUtils.getSubjectIndividual(vreq);
DataProperty prop = EditConfigurationUtils.getDataProperty(vreq);
//rangeDefaultJson goes into literalk options
//validations include dataype:rangedatatypeurijson
//rangeDatatypeUri is rangeDAttypeUriJson
//rangeLang = rangeLanJson
DataPropertyStatement dps =EditConfigurationUtils.getDataPropertyStatement(vreq, vreq.getSession(), dataHash, predicateUri);
String rangeDatatypeUri = vreq.getWebappDaoFactory().getDataPropertyDao().getRequiredDatatypeURI(subject, prop);
if( dps != null ){
rangeDatatypeUri = dps.getDatatypeURI();
if( rangeDatatypeUri == null ){
log.debug("no range datatype uri set on data property statement when property's range datatype is "+prop.getRangeDatatypeURI()+" in DefaultDataPropertyFormGenerator");
} else {
log.debug("range datatype uri of ["+rangeDatatypeUri+"] on data property statement in DefaultDataPropertyFormGenerator");
}
} else {
log.debug("No incoming dataproperty statement attribute for property "+prop.getPublicName()+"; adding a new statement");
}
return rangeDatatypeUri;
}
private Map<String, FieldVTwo> getObjectPropertyField(
EditConfigurationVTwo editConfiguration, VitroRequest vreq) {
Map<String, FieldVTwo> fields = new HashMap<String, FieldVTwo>();
FieldVTwo field = new FieldVTwo();
field.setName("objectVar");
field.setNewResource(false);
//queryForExisting is not being used anywhere in Field
@ -185,7 +412,7 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
//subjectUri and subjectClassUri are not being used in Field
field.setOptionsType("INDIVIDUALS_VIA_OBJECT_PROPERTY");
field.setPredicateUri(predicateUriJson);
field.setPredicateUri(predicateUri);
field.setObjectClassUri(null);
field.setRangeDatatypeUri(null);
@ -194,92 +421,131 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
field.setLiteralOptions(new ArrayList<List<String>>());
List<String> assertions = new ArrayList<String>();
assertions.add("?subject");
assertions.add("?predicate");
assertions.add("?objectVar");
assertions.add("?objectVar");
assertions.add("?inverseProp");
assertions.add("?subject");
assertions.addAll(editConfiguration.getN3Required());
assertions.addAll(editConfiguration.getN3Optional());
field.setAssertions(assertions);
fields.put(field.getName(), field);
fields.put("objectVar", field);
return fields;
//TODO: Review why/how this method signature has changed
//editConfiguration.setFields(fields);
editConfiguration.putConfigInSession(editConfiguration, session);
editConfiguration.setTemplate("defaultPropertyForm.ftl");
}
String formTitle = " ";
String submitLabel = " ";
private void prepareForUpdate(VitroRequest vreq, HttpSession session, EditConfigurationVTwo editConfiguration) {
//Here, retrieve model from
Model model = (Model) session.getServletContext().getAttribute("jenaOntModel");
//this block is for an edit of an existing object property statement
if(vreq.getAttribute("object") != null) {
editConfiguration.prepareForObjPropUpdate(model);
formTitle = "Change entry for: <em>" + prop.getDomainPublic() + " </em>";
submitLabel = "save change";
} else {
editConfiguration.prepareForNonUpdate( model );
if ( prop.getOfferCreateNewOption() ) {
//Try to get the name of the class to select from
VClass classOfObjectFillers = null;
if( prop.getRangeVClassURI() == null ) {
// If property has no explicit range, try to get classes
List<VClass> classes = wdf.getVClassDao().getVClassesForProperty(subject.getVClassURI(), prop.getURI());
if( classes == null || classes.size() == 0 || classes.get(0) == null ){
// If property has no explicit range, we will use e.g. owl:Thing.
// Typically an allValuesFrom restriction will come into play later.
classOfObjectFillers = wdf.getVClassDao().getTopConcept();
} else {
if( classes.size() > 1 )
log.debug("Found multiple classes when attempting to get range vclass.");
classOfObjectFillers = classes.get(0);
}
}else{
classOfObjectFillers = wdf.getVClassDao().getVClassByURI(prop.getRangeVClassURI());
if( classOfObjectFillers == null )
classOfObjectFillers = wdf.getVClassDao().getTopConcept();
}
log.debug("property set to offer \"create new\" option; custom form: ["+prop.getCustomEntryForm()+"]");
formTitle = "Select an existing "+classOfObjectFillers.getName()+" for "+subject.getName();
submitLabel = "select existing";
} else {
formTitle = "Add an entry to: <em>"+prop.getDomainPublic()+"</em>";
submitLabel = "save entry";
}
}
vreq.setAttribute("formTitle", formTitle);
// if( prop.getSelectFromExisting() ){
// // set ProhibitedFromSearch object so picklist doesn't show
// // individuals from classes that should be hidden from list views
// OntModel displayOntModel =
// (OntModel) session.getServletContext()
// .getAttribute("displayOntModel");
// if (displayOntModel != null) {
// ProhibitedFromSearch pfs = new ProhibitedFromSearch(
// DisplayVocabulary.PRIMARY_SEARCH_INDEX_URI, displayOntModel);
// if( editConfiguration != null )
// editConfiguration.setProhibitedFromSearch(pfs);
// }
// Map<String,String> rangeOptions = SelectListGenerator.getOptions(editConfiguration, "objectVar" , wdf);
// if( rangeOptions != null && rangeOptions.size() > 0 ) {
// vreq.setAttribute("rangeOptionsExist", true);
// vreq.setAttribute("rangeOptions.objectVar", rangeOptions);
// } else {
// vreq.setAttribute("rangeOptionsExist",false);
// }
// }
return editConfiguration;
//if object property
if(EditConfigurationUtils.isObjectProperty(EditConfigurationUtils.getPredicateUri(vreq), vreq)){
Individual objectIndividual = EditConfigurationUtils.getObjectIndividual(vreq);
if(objectIndividual != null) {
//update existing object
editConfiguration.prepareForObjPropUpdate(model);
} else {
//new object to be created
editConfiguration.prepareForNonUpdate( model );
}
} else {
if(datapropKeyStr != null && datapropKeyStr.trim().length() > 0 ) {
DataPropertyStatement dps = EditConfigurationUtils.getDataPropertyStatement(vreq,
session,
dataHash,
EditConfigurationUtils.getPredicateUri(vreq));
editConfiguration.prepareForDataPropUpdate(model, dps);
}
}
}
//Command processing
private boolean isTypeOfNew(VitroRequest vreq) {
String typeOfNew = vreq.getParameter("typeOfNew");
return (typeOfNew != null && !typeOfNew.isEmpty());
}
//orignal code for process to forward new is below
/*
private ResponseValues processForwardToCreateNew(VitroRequest vreq) {
String command = vreq.getParameter("cmd");
ObjectProperty objectProp = (ObjectProperty) vreq.getAttribute("predicate");
// TODO Auto-generated method stub
// The default object proepty form offers the option to create a new item
// instead of selecting from existing individuals in the system.
// This is where the request to create a new indivdiual is handled.
//
// Forward to create new is part of the default object property form
// it should be handled in that form's EditConfigurationVTwo, not here.
// The code that sets up the EditConfigurationVTwo should decide on
// different configurations and templates to use based on isForwardToCreateNew.
//TODO: make sure that forward to create new works on the default object property form
if( isFowardToCreateNew(vreq, objectProp, command)){
return handleForwardToCreateNew(vreq, command, objectProp, isEditOfExistingStmt(vreq));
}
//what should this return otherwise and should this in fact redirect
return null;
}*/
/*
Forward to create new is part of the default object property form
it should be handled in that form's EditConfigurationVTwo, not here.
The code that sets up the EditConfigurationVTwo should decide on
different configurations and templates to use based on isForwardToCreateNew.
*//*
boolean isFowardToCreateNew(VitroRequest vreq, ObjectProperty objectProp, String command){
//Offer create new and select from existing are ignored if there is a custom form
if( objectProp != null && objectProp.getCustomEntryForm() != null && !objectProp.getCustomEntryForm().isEmpty()){
return false;
} else {
boolean isForwardToCreateNew =
( objectProp != null && objectProp.getOfferCreateNewOption() && objectProp.getSelectFromExisting() == false)
|| ( objectProp != null && objectProp.getOfferCreateNewOption() && "create".equals(command));
return isForwardToCreateNew;
}
}
ResponseValues handleForwardToCreateNew(VitroRequest vreq, String command, ObjectProperty objectProp, boolean isEditOfExistingStmt){
vreq.setAttribute("isForwardToCreateNew", new Boolean(true));
//If a objectProperty is both provideSelect and offerCreateNewOption
// and a user goes to a defaultObjectProperty.jsp form then the user is
// offered the option to create a new Individual and replace the
// object in the existing objectPropertyStatement with this new individual.
boolean isReplaceWithNew =
isEditOfExistingStmt && "create".equals(command)
&& objectProp != null && objectProp.getOfferCreateNewOption() == true;
// If an objectProperty is selectFromExisitng==false and offerCreateNewOption == true
// the we want to forward to the create new form but edit the existing object
// of the objPropStmt.
boolean isForwardToCreateButEdit =
isEditOfExistingStmt && objectProp != null
&& objectProp.getOfferCreateNewOption() == true
&& objectProp.getSelectFromExisting() == false
&& ! "create".equals(command);
//bdc34: maybe when doing a create new, the custom form should be on the class, not the property?
String form;
if( isReplaceWithNew ){
vreq.setAttribute("isReplaceWithNew", new Boolean(true));
form = DEFAULT_ADD_INDIVIDUAL;
}else if( isForwardToCreateButEdit ){
vreq.setAttribute("isForwardToCreateButEdit", new Boolean(true));
form = DEFAULT_ADD_INDIVIDUAL;
}else {
form = DEFAULT_ADD_INDIVIDUAL;
}
//forward to form?
//There should be no error message here
//TODO: Return redirect response values or find out to process this here
HashMap<String,Object> map = new HashMap<String,Object>();
map.put("errorMessage", "forweard to create new is not yet implemented");
return new TemplateResponseValues("error-message.ftl", map);
}
*/
}

View file

@ -97,7 +97,7 @@ public class MenuEditingFormGenerator implements EditConfigurationGenerator {
this.setSparqlQueries(editConfiguration);
//Set up fields
this.setUpFields(editConfiguration, vreq);
this.setFields(editConfiguration, vreq);
//set submission url
editConfiguration.setSubmitToUrl("/edit/process");
@ -362,7 +362,7 @@ public class MenuEditingFormGenerator implements EditConfigurationGenerator {
//Just get the properties?
//Fields
private void setUpFields(EditConfigurationVTwo editConfiguration, VitroRequest vreq) {
private void setFields(EditConfigurationVTwo editConfiguration, VitroRequest vreq) {
Map<String, FieldVTwo> fields = new HashMap<String, FieldVTwo>();

View file

@ -4,24 +4,32 @@ package edu.cornell.mannlib.vitro.webapp.edit.n3editing.controller;
import java.util.HashMap;
import java.util.Map;
import java.net.URLEncoder;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.rdf.model.Model;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.RedirectResponseValues;
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.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.EditConfigurationGenerator;
import edu.cornell.mannlib.vitro.webapp.web.MiscWebUtils;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.edit.EditConfigurationTemplateModel;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.RdfLiteralHash;
/**
* This servlet is intended to handle all requests to create a form for use
* by the N3 editing system. It will examine the request parameters, determine
@ -38,193 +46,54 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet {
final String DEFAULT_OBJ_FORM = "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.DefaultObjectPropertyFormGenerator";
final String DEFAULT_DATA_FORM = "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.DefaultDataPropertyFormGenerator";
//TODO: Create this generator
final String RDFS_LABEL_FORM = "";
final String DEFAULT_ERROR_FORM = "error.jsp";
final String DEFAULT_ADD_INDIVIDUAL = "defaultAddMissingIndividualForm.jsp";
@Override
protected ResponseValues processRequest(VitroRequest vreq) {
Map mapTest = vreq.getParameterMap();
java.util.Iterator testIterator = mapTest.keySet().iterator();
while(testIterator.hasNext()) {
String paramKey = (String) testIterator.next();
System.out.println("Param key is " + paramKey + " and test iterator is value is " + mapTest.get(paramKey).toString());
}
try{
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
//check some error conditions and if they exist return response values
//with error message
if(isErrorCondition(vreq)){
return doHelp(vreq, getErrorMessage(vreq));
}
//get edit key.
//The edit key links submissions to EditConfiguration objects in the session.
HttpSession session = vreq.getSession();
String editKey =
(EditConfigurationVTwo.getEditKey(vreq) == null)
? EditConfigurationVTwo.newEditKey(session)
: EditConfigurationVTwo.getEditKey(vreq);
vreq.setAttribute("editKey", editKey);
//if delete, originally forwarded but here would have to do something else
// processDelete(vreq);
//set title to Edit to maintain functionality from 1.1.1 and avoid updates to Selenium tests
vreq.setAttribute("title","Edit");
String subjectUri = vreq.getParameter("subjectUri");
String predicateUri = vreq.getParameter("predicateUri");
String formParam = vreq.getParameter("editform");
String command = vreq.getParameter("cmd");
//check some error conditions
if (formParam == null || "".equals(formParam)) {
if ((predicateUri == null || predicateUri.trim().length() == 0)) {
return doHelp(vreq, "No form was specified, both predicateUri and"
+ " editform are empty. One of these is required"
+ " by editRequestDispatch to choose a form.");
}
if (subjectUri == null || subjectUri.trim().length() == 0){
return doHelp(vreq, "subjectUri was empty. If no editForm is specified," +
" it is required by EditRequestDispatch.");
}
}
vreq.setAttribute("subjectUri", subjectUri);
vreq.setAttribute("subjectUriJson", MiscWebUtils.escape(subjectUri));
if (predicateUri != null) {
vreq.setAttribute("predicateUri", predicateUri);
vreq.setAttribute("predicateUriJson", MiscWebUtils.escape(predicateUri));
}
if (formParam != null && formParam.length() > 0) {
vreq.setAttribute("editForm", formParam);
} else {
formParam = null;
}
//bdc34: typeOfNew is used by some forms like defaultAddMissingindividuaForm
//it should be moved out of this code and into the configuration for those forms
String typeOfNew = vreq.getParameter("typeOfNew");
if( typeOfNew != null )
vreq.setAttribute("typeOfNew", typeOfNew);
vreq.setAttribute("urlPatternToReturnTo", vreq
.getParameter("urlPattern") == null ? "/entity" : vreq
.getParameter("urlPattern"));
log.debug("setting urlPatternToReturnTo as "
+ vreq.getAttribute("urlPatternToReturnTo"));
/* since we have the URIs lets put the individuals in the request */
if( subjectUri != null ){
Individual subject = wdf.getIndividualDao().getIndividualByURI(subjectUri);
if( subject != null )
vreq.setAttribute("subject", subject);
}
String objectUri = vreq.getParameter("objectUri");
if (objectUri != null) {
vreq.setAttribute("objectUri", objectUri);
vreq.setAttribute("objectUriJson", MiscWebUtils.escape(objectUri));
}
boolean isEditOfExistingStmt = false;
if (objectUri != null) {
Individual object = wdf.getIndividualDao().getIndividualByURI(objectUri);
if (object != null) {
vreq.setAttribute("object", object);
isEditOfExistingStmt = true;
}
}
// Keep track of what form we are using so it can be returned to after a failed validation
// I'd like to get this from the request but sometimes that doesn't work well, internal forwards etc.
//TODO: this needs to be the same as the mapping in web.xml
vreq.setAttribute("formUrl", "/edit/editRequestDispatch?" + vreq.getQueryString());
if ("delete".equals(command)) {
//TODO: delete command is used with the defualt delete form
//maybe it doesn't need to be in here?
HashMap<String,Object> map = new HashMap<String,Object>();
map.put("errorMessage", "delete command is not yet implemented");
return new TemplateResponseValues("error-message.ftl", map);
}
//Certain predicates may be annotated to change the behavior of the edit
//link. Check for this annotation and, if present, simply redirect
//to the normal individual display for the object URI instead of bringing
//up an editing form.
//Note that we do not want this behavior for the delete link (handled above).
// This might be done in the custom form jsp for publicaitons already.
// so maybe this logic shouldn't be here?
if ( isEditOfExistingStmt && (wdf.getObjectPropertyDao().skipEditForm(predicateUri)) ) {
log.debug("redirecting to object for predicate " + predicateUri);
//TODO: implement this feature
// %><c:redirect url="/individual">
// <c:param name="uri" value="${param.objectUri}"/>
// <c:param name="relatedSubjectUri" value="${param.subjectUri}"/>
// <c:param name="relatingPredicateUri" value="${param.predicateUri}"/>
// </c:redirect>
// <%
HashMap<String,Object> map = new HashMap<String,Object>();
map.put("errorMessage", "skip edit form for object properties is not yet implemented");
return new TemplateResponseValues("error-message.ftl", map);
}
//use default object property form if nothing else works
String editConfGeneratorName = DEFAULT_OBJ_FORM;
// *** handle the case where the form is specified as a request parameter ***
if( predicateUri == null && ( formParam != null && !formParam.isEmpty()) ){
//form parameter must be a fully qualified java class name of a EditConfigurationVTwoGenerator implementation.
editConfGeneratorName = formParam;
}
// *** handle the case where the form is decided by the predicate parameter ***
//check to see if we have a predicate and if it has a custom form
//if it has a custom form associated with it then use that form,
//otherwise use the default object property form
String customForm = null;
ObjectProperty objectProp = wdf.getObjectPropertyDao().getObjectPropertyByURI(predicateUri);
if( objectProp != null ){
vreq.setAttribute("predicate", objectProp);
//custom entry form use to be a jsp but it should now be a fully qualified java class name of a
//EditConfigurationVTwoGenerator implementation.
customForm = objectProp.getCustomEntryForm();
if (customForm != null && customForm.length() > 0) {
//if there is a custom form on the predicate, use that
editConfGeneratorName = objectProp.getCustomEntryForm();
}
}
// The default object proepty form offers the option to create a new item
// instead of selecting from existing individuals in the system.
// This is where the request to create a new indivdiual is handled.
//
// Forward to create new is part of the default object property form
// it should be handled in that form's EditConfigurationVTwo, not here.
// The code that sets up the EditConfigurationVTwo should decide on
// different configurations and templates to use based on isForwardToCreateNew.
//TODO: make sure that forward to create new works on the default object property form
if( isFowardToCreateNew(vreq, objectProp, command)){
return handleForwardToCreateNew(vreq, command, objectProp, isEditOfExistingStmt);
}
vreq.setAttribute("form", editConfGeneratorName);
/**** make new or get an existing edit configuration ***/
//in case form needs to be redirected b/c of special individuals
// processSkipEditForm(vreq);
EditConfigurationVTwo editConfig = makeEditConfigurationVTwo( editConfGeneratorName, vreq, session);
editConfig.setEditKey(editKey);
EditConfigurationVTwo.putConfigInSession(editConfig, session);
//Get the edit generator name
String editConfGeneratorName = processEditConfGeneratorName(vreq);
//if need to forward to create new object, handle that
//why is this not done earlier? why aren't forwards handled in the same place?
// processForwardToCreateNew(vreq);
//session attribute
setSessionRequestFromEntity(vreq);
//Test
boolean isObjectProp = EditConfigurationUtils.isObjectProperty(EditConfigurationUtils.getPredicateUri(vreq), vreq);
boolean isDataProp = EditConfigurationUtils.isDataProperty(EditConfigurationUtils.getPredicateUri(vreq), vreq);
/**** make new or get an existing edit configuration ***/
EditConfigurationVTwo editConfig = setupEditConfiguration(editConfGeneratorName, vreq);
//what template?
String template = editConfig.getTemplate();
String formTitle = (String)vreq.getAttribute("formTitle");
//what goes in the map for templates?
Map<String,Object> templateData = new HashMap<String,Object>();
templateData.put("editConfiguration", new EditConfigurationTemplateModel( editConfig, vreq));
//templateData.put("formTitle", formTitle);
//templateData.put("pageData", retrieveEditData(vreq));
//retrieveEditData(vreq, templateData);
EditConfigurationTemplateModel etm = new EditConfigurationTemplateModel( editConfig, vreq);
templateData.put("editConfiguration", etm);
//Corresponding to original note for consistency with selenium tests and 1.1.1
templateData.put("title", "Edit");
templateData.put("submitUrl", getSubmissionUrl(vreq));
templateData.put("editKey", editConfig.getEditKey());
return new TemplateResponseValues(template, templateData);
}catch(Throwable th){
@ -236,6 +105,240 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet {
}
}
private EditConfigurationVTwo setupEditConfiguration(String editConfGeneratorName,
VitroRequest vreq) {
//Still based on request attribute, if edit key exists on request, then use otherwise generate new edit key
String editKey = EditConfigurationUtils.getEditKey(vreq);
HttpSession session = vreq.getSession();
EditConfigurationVTwo editConfig = makeEditConfigurationVTwo( editConfGeneratorName, vreq, session);
//Set edit key for edit configuration here
editConfig.setEditKey(editKey);
//put edit configuration in session
EditConfigurationVTwo.putConfigInSession(editConfig, session);
return editConfig;
}
private void setSessionRequestFromEntity(VitroRequest vreq) {
HttpSession session = vreq.getSession();
String subjectUri = vreq.getParameter("subjectUri");
if(session.getAttribute("requestedFromEntity") == null) {
session.setAttribute("requestedFromEntity", subjectUri);
}
}
//Additional forwards.. should they be processed here to see which form should be forwarded to
//e.g. default add individual form etc. and additional scenarios
//TODO: Check if additional scenarios should be checked here
private String processEditConfGeneratorName(VitroRequest vreq) {
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
//use default object property form if nothing else works
String editConfGeneratorName = DEFAULT_OBJ_FORM;
String predicateUri = EditConfigurationUtils.getPredicateUri(vreq);
String formParam = getFormParam(vreq);
// *** handle the case where the form is specified as a request parameter ***
if( predicateUri == null && ( formParam != null && !formParam.isEmpty()) ){
//form parameter must be a fully qualified java class name of a EditConfigurationVTwoGenerator implementation.
editConfGeneratorName = formParam;
} else if(isVitroLabel(predicateUri)) { //in case of data property
editConfGeneratorName = RDFS_LABEL_FORM;
} else{
String customForm = getCustomForm(predicateUri, wdf);
if(customForm != null && !customForm.isEmpty()) {
editConfGeneratorName = customForm;
}
}
return editConfGeneratorName;
}
private String getCustomForm(String predicateUri, WebappDaoFactory wdf) {
Property prop = getPropertyByUri(predicateUri, wdf);
return prop.getCustomEntryForm();
}
private Property getPropertyByUri(String predicateUri, WebappDaoFactory wdf) {
Property p = null;
p = wdf.getObjectPropertyDao().getObjectPropertyByURI(predicateUri);
if(p == null) {
p = wdf.getDataPropertyDao().getDataPropertyByURI(predicateUri);
}
return p;
}
private boolean isVitroLabel(String predicateUri) {
return predicateUri.equals(VitroVocabulary.LABEL);
}
//TODO: Implement below correctly or integrate
private ResponseValues processSkipEditForm(VitroRequest vreq) {
//Certain predicates may be annotated to change the behavior of the edit
//link. Check for this annotation and, if present, simply redirect
//to the normal individual display for the object URI instead of bringing
//up an editing form.
//Note that we do not want this behavior for the delete link (handled above).
// This might be done in the custom form jsp for publicaitons already.
// so maybe this logic shouldn't be here?
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
String predicateUri = vreq.getParameter("predicateUri");
boolean isEditOfExistingStmt = isEditOfExistingStmt(vreq);
if ( isEditOfExistingStmt && (wdf.getObjectPropertyDao().skipEditForm(predicateUri)) ) {
log.debug("redirecting to object for predicate " + predicateUri);
String redirectPage = vreq.getContextPath() + "/individual";
redirectPage += "uri=" + URLEncoder.encode(vreq.getParameter("objectUri")) +
"&relatedSubjectUri=" + URLEncoder.encode(vreq.getParameter("subjectUri")) +
"&relatingPredicateUri=" + URLEncoder.encode(vreq.getParameter("predicateUri"));
return new RedirectResponseValues(redirectPage, HttpServletResponse.SC_SEE_OTHER);
}
return null;
}
//Check error conditions
//TODO: Do we need both methods or jsut one?
private boolean isErrorCondition(VitroRequest vreq) {
String subjectUri = EditConfigurationUtils.getSubjectUri(vreq);
String predicateUri = EditConfigurationUtils.getPredicateUri(vreq);
String formParam = getFormParam(vreq);
if (formParam == null || "".equals(formParam)) {
if ((predicateUri == null || predicateUri.trim().length() == 0)) {
return true;
}
if (subjectUri == null || subjectUri.trim().length() == 0){
return true;
}
}
//Check predicate - if not vitro label and neither data prop nor object prop return error
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
if(!EditConfigurationUtils.isObjectProperty(predicateUri, vreq)
&& !isVitroLabel(predicateUri)
&& !EditConfigurationUtils.isDataProperty(predicateUri, vreq))
{
return true;
}
return false;
}
private String getErrorMessage(VitroRequest vreq) {
String errorMessage = null;
String subjectUri = EditConfigurationUtils.getSubjectUri(vreq);
String predicateUri = EditConfigurationUtils.getPredicateUri(vreq);
String formParam = getFormParam(vreq);
if (formParam == null || "".equals(formParam)) {
if ((predicateUri == null || predicateUri.trim().length() == 0)) {
errorMessage = "No form was specified, both predicateUri and"
+ " editform are empty. One of these is required"
+ " by editRequestDispatch to choose a form.";
}
if (subjectUri == null || subjectUri.trim().length() == 0){
return "subjectUri was empty. If no editForm is specified," +
" it is required by EditRequestDispatch.";
}
}
return errorMessage;
}
//Based on subject, predicate, object and command, set the appropriate attributes
//TODO: Check if setting attributes the way to go or alternative
//Leaving these in for now but shouldn't depending on vreq attributes at all
//Generators should process them
//leaving here for reference, delete later
private void processStoreParameters(VitroRequest vreq) {
//TODO: Check if json version required any longer
//subject
/*
processSubject(vreq);
processPredicate(vreq);
processObject(vreq);
processFormParam(vreq);
processTypeOfNew(vreq);
processUrlPatternReturn(vreq);
saveCurrentUrl(vreq);
//if data propety
if(isDataProperty(vreq.getParameter("predicateUri"), vreq)) {
processDataProperty(vreq);
}*/
}
private void processDataProperty(VitroRequest vreq) {
String datapropKeyStr = vreq.getParameter("datapropKey");
String predicateUri = vreq.getParameter("predicateUri");
String subjectUri = vreq.getParameter("subjectUri");
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
HttpSession session = vreq.getSession();
Individual subject = wdf.getIndividualDao().getIndividualByURI(subjectUri);
int dataHash = 0;
if( datapropKeyStr != null ){
try {
dataHash = Integer.parseInt(datapropKeyStr);
vreq.setAttribute("datahash", dataHash);
log.debug("Found a datapropKey in parameters and parsed it to int: " + dataHash);
} catch (NumberFormatException ex) {
//return doHelp(vreq, "Cannot decode incoming datapropKey value "+datapropKeyStr+" as an integer hash in EditDataPropStmtRequestDispatchController");
}
}
DataPropertyStatement dps = null;
if( dataHash != 0) {
Model model = (Model)session.getServletContext().getAttribute("jenaOntModel");
dps = RdfLiteralHash.getPropertyStmtByHash(subject, predicateUri, dataHash, model);
if (dps==null) {
log.error("No match to existing data property \""+predicateUri+"\" statement for subject \""+subjectUri+"\" via key "+datapropKeyStr);
//TODO: Needs to forward to dataPropMissingStatement.jsp
//return null;
}
vreq.setAttribute("dataprop", dps );
}
}
//should return null
private String getFormParam(VitroRequest vreq) {
String formParam = (String) vreq.getAttribute("editForm");
return formParam;
}
private boolean isEditOfExistingStmt(VitroRequest vreq) {
String objectUri = vreq.getParameter("objectUri");
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
if(objectUri != null) {
Individual object = wdf.getIndividualDao().getIndividualByURI(objectUri);
return (object != null);
}
return false;
}
//Check whether command is delete and either process or save
//Original code involved doing a jsp forward
//TODO: Check how to integrate deletion
private boolean isDeleteForm(VitroRequest vreq) {
String command = vreq.getParameter("cmd");
if ("delete".equals(command)) {
return true;
}
return false;
}
//
private EditConfigurationVTwo makeEditConfigurationVTwo(
String editConfGeneratorName, VitroRequest vreq, HttpSession session) {
@ -263,63 +366,6 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet {
}
/*
Forward to create new is part of the default object property form
it should be handled in that form's EditConfigurationVTwo, not here.
The code that sets up the EditConfigurationVTwo should decide on
different configurations and templates to use based on isForwardToCreateNew.
*/
boolean isFowardToCreateNew(VitroRequest vreq, ObjectProperty objectProp, String command){
//Offer create new and select from existing are ignored if there is a custom form
if( objectProp != null && objectProp.getCustomEntryForm() != null && !objectProp.getCustomEntryForm().isEmpty()){
return false;
} else {
boolean isForwardToCreateNew =
( objectProp != null && objectProp.getOfferCreateNewOption() && objectProp.getSelectFromExisting() == false)
|| ( objectProp != null && objectProp.getOfferCreateNewOption() && "create".equals(command));
return isForwardToCreateNew;
}
}
ResponseValues handleForwardToCreateNew(VitroRequest vreq, String command, ObjectProperty objectProp, boolean isEditOfExistingStmt){
vreq.setAttribute("isForwardToCreateNew", new Boolean(true));
//If a objectProperty is both provideSelect and offerCreateNewOption
// and a user goes to a defaultObjectProperty.jsp form then the user is
// offered the option to create a new Individual and replace the
// object in the existing objectPropertyStatement with this new individual.
boolean isReplaceWithNew =
isEditOfExistingStmt && "create".equals(command)
&& objectProp != null && objectProp.getOfferCreateNewOption() == true;
// If an objectProperty is selectFromExisitng==false and offerCreateNewOption == true
// the we want to forward to the create new form but edit the existing object
// of the objPropStmt.
boolean isForwardToCreateButEdit =
isEditOfExistingStmt && objectProp != null
&& objectProp.getOfferCreateNewOption() == true
&& objectProp.getSelectFromExisting() == false
&& ! "create".equals(command);
//bdc34: maybe when doing a create new, the custom form should be on the class, not the property?
String form;
if( isReplaceWithNew ){
vreq.setAttribute("isReplaceWithNew", new Boolean(true));
form = DEFAULT_ADD_INDIVIDUAL;
}else if( isForwardToCreateButEdit ){
vreq.setAttribute("isForwardToCreateButEdit", new Boolean(true));
form = DEFAULT_ADD_INDIVIDUAL;
}else {
form = DEFAULT_ADD_INDIVIDUAL;
}
//forward to form?
HashMap<String,Object> map = new HashMap<String,Object>();
map.put("errorMessage", "forweard to create new is not yet implemented");
return new TemplateResponseValues("error-message.ftl", map);
}
private ResponseValues doHelp(VitroRequest vreq, String message){
//output some sort of help message for the developers.
@ -329,6 +375,10 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet {
return new TemplateResponseValues("error-message.ftl", map); }
//Get submission url
private String getSubmissionUrl(VitroRequest vreq) {
return vreq.getContextPath() + "/edit/process";
}
}

View file

@ -195,7 +195,7 @@ public class ProcessRdfFormController extends FreemarkerHttpServlet{
ParamMap paramMap = new ParamMap();
paramMap.put("uri", resourceToRedirectTo);
paramMap.put("extra","true"); //for ie6
return new RedirectResponseValues( UrlBuilder.getUrl(urlPattern,paramMap) + predicateAnchor );
return new RedirectResponseValues( UrlBuilder.getPath(urlPattern,paramMap) + predicateAnchor );
} else if ( !urlPattern.endsWith("individual") && !urlPattern.endsWith("entity") ){
return new RedirectResponseValues( urlPattern );
}

View file

@ -2,21 +2,40 @@
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.edit;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
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.SelectListGeneratorVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.DefaultObjectPropertyFormGenerator;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.rdf.model.Literal;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
public class EditConfigurationTemplateModel extends BaseTemplateModel {
EditConfigurationVTwo editConfig;
HashMap<String, Object> pageData = new HashMap<String, Object>();
VitroRequest vreq;
private Log log = LogFactory.getLog(EditConfigurationTemplateModel.class);
public EditConfigurationTemplateModel( EditConfigurationVTwo editConfig, VitroRequest vreq){
this.editConfig = editConfig;
this.vreq = vreq;
@ -38,20 +57,148 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel {
//TODO: Check whether to include additoinal data here or elsewhere
//For now, using attributes off of vitro request to add to template
//TODO: find better mechanism
//Calculate data here
private void retrieveEditData() {
//Get vitro request attributes for
pageData.put("formTitle", (String) vreq.getAttribute("formTitle"));
pageData.put("submitLabel", (String) vreq.getAttribute("submitLabel"));
if(vreq.getAttribute("rangeOptionsExist") != null && (Boolean) vreq.getAttribute("rangeOptionsExist") == true) {
Map<String,String> rangeOptions = (Map<String,String>)vreq.getAttribute("rangeOptions.objectVar");
pageData.put("rangeOptions", rangeOptions);
setFormTitle();
setSubmitLabel();
//this should only be called if this is an object property form
//how would we do this?
if(EditConfigurationUtils.isObjectProperty(editConfig.getPredicateUri(), vreq)) {
setRangeOptions();
}
//range data type probably not set here but for edit configuration's field
/*
if(EditConfigurationUtils.isDataProperty(editConfig.getPredicateUri(), vreq)) {
setRangeDatatype();
}*/
}
//TODO: remove
private void setRangeDatatype() {
}
private boolean isRangeOptionsExist() {
boolean rangeOptionsExist = (pageData.get("rangeOptionsExist") != null && (Boolean) pageData.get("rangeOptionsExist") == true);
return rangeOptionsExist;
}
private void setFormTitle() {
if(editConfig.isObjectResource()) {
setObjectFormTitle();
} else {
setDataFormTitle();
}
}
private void setDataFormTitle() {
String formTitle = null;
String datapropKeyStr = editConfig.getDatapropKey();
DataProperty prop = EditConfigurationUtils.getDataProperty(vreq);
if( datapropKeyStr != null && datapropKeyStr.trim().length() > 0 ) {
formTitle = "Change text for: <em>"+prop.getPublicName()+"</em>";
} else {
formTitle ="Add new entry for: <em>"+prop.getPublicName()+"</em>";
}
pageData.put("formTitle", formTitle);
}
//Process and set data
private void setObjectFormTitle() {
String formTitle = null;
Individual objectIndividual = EditConfigurationUtils.getObjectIndividual(vreq);
ObjectProperty prop = EditConfigurationUtils.getObjectProperty(vreq);
Individual subject = EditConfigurationUtils.getSubjectIndividual(vreq);
if(objectIndividual != null) {
formTitle = "Change entry for: <em>" + prop.getDomainPublic() + " </em>";
} else {
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
if ( prop.getOfferCreateNewOption() ) {
//Try to get the name of the class to select from
VClass classOfObjectFillers = null;
if( prop.getRangeVClassURI() == null ) {
// If property has no explicit range, try to get classes
List<VClass> classes = wdf.getVClassDao().getVClassesForProperty(subject.getVClassURI(), prop.getURI());
if( classes == null || classes.size() == 0 || classes.get(0) == null ){
// If property has no explicit range, we will use e.g. owl:Thing.
// Typically an allValuesFrom restriction will come into play later.
classOfObjectFillers = wdf.getVClassDao().getTopConcept();
} else {
if( classes.size() > 1 )
log.debug("Found multiple classes when attempting to get range vclass.");
classOfObjectFillers = classes.get(0);
}
}else{
classOfObjectFillers = wdf.getVClassDao().getVClassByURI(prop.getRangeVClassURI());
if( classOfObjectFillers == null )
classOfObjectFillers = wdf.getVClassDao().getTopConcept();
}
log.debug("property set to offer \"create new\" option; custom form: ["+prop.getCustomEntryForm()+"]");
formTitle = "Select an existing "+classOfObjectFillers.getName()+" for "+subject.getName();
} else {
formTitle = "Add an entry to: <em>"+prop.getDomainPublic()+"</em>";
}
}
pageData.put("formTitle", formTitle);
}
private void setSubmitLabel() {
String submitLabel = null;
Individual objectIndividual = EditConfigurationUtils.getObjectIndividual(vreq);
ObjectProperty prop = EditConfigurationUtils.getObjectProperty(vreq);
if(objectIndividual != null) {
submitLabel = "save change";
} else {
if ( prop.getOfferCreateNewOption() ) {
submitLabel = "select existing";
} else {
submitLabel = "save entry";
}
}
pageData.put("submitLabel", submitLabel);
}
private void setRangeOptions() {
ObjectProperty prop = EditConfigurationUtils.getObjectProperty(vreq);
if( prop.getSelectFromExisting() ){
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
// set ProhibitedFromSearch object so picklist doesn't show
// individuals from classes that should be hidden from list views
//uncomment out when we know what to do here
/*
OntModel displayOntModel =
(OntModel) session.getServletContext()
.getAttribute("displayOntModel");
if (displayOntModel != null) {
ProhibitedFromSearch pfs = new ProhibitedFromSearch(
DisplayVocabulary.PRIMARY_SEARCH_INDEX_URI, displayOntModel);
if( editConfiguration != null )
editConfiguration.setProhibitedFromSearch(pfs);
}*/
Map<String,String> rangeOptions = SelectListGeneratorVTwo.getOptions(editConfig, "objectVar" , wdf);
if( rangeOptions != null && rangeOptions.size() > 0 ) {
pageData.put("rangeOptionsExist", true);
pageData.put("rangeOptions", rangeOptions);
} else {
pageData.put("rangeOptionsExist",false);
}
}
}
//Get page data
public boolean getRangeOptionsExist() {
return isRangeOptionsExist();
}
public String getFormTitle() {
return (String) pageData.get("formTitle");
}
@ -61,7 +208,8 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel {
}
public Map<String, String> getRangeOptions() {
return (Map<String, String>) pageData.get("rangeOptions");
Map<String, String> rangeOptions = (Map<String, String>) pageData.get("rangeOptions");
return rangeOptions;
}
//Get literals in scope, i.e. variable names with values assigned
@ -82,4 +230,98 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel {
}
return literalValues;
}
public String getDataLiteralValuesAsString() {
List<String> values = getDataLiteralValues();
return StringUtils.join(values, ",");
}
public List<String> getDataLiteralValues() {
//this is the name of the text element/i.e. variable name of data value by which literal stored
String dataLiteral = getDataLiteral();
List<String> literalValues = getLiteralStringValue(dataLiteral);
return literalValues;
}
private String literalToString(Literal lit){
if( lit == null || lit.getValue() == null) return "";
String value = lit.getValue().toString();
if( "http://www.w3.org/2001/XMLSchema#anyURI".equals( lit.getDatatypeURI() )){
//strings from anyURI will be URLEncoded from the literal.
try{
value = URLDecoder.decode(value, "UTF8");
}catch(UnsupportedEncodingException ex){
log.error(ex);
}
}
return value;
}
//Get predicate
//What if this is a data property instead?
public Property getPredicateProperty() {
String predicateUri = getPredicateUri();
//If predicate uri corresponds to object property, return that
if(EditConfigurationUtils.isObjectProperty(predicateUri, vreq)){
return this.vreq.getWebappDaoFactory().getObjectPropertyDao().getObjectPropertyByURI(predicateUri);
}
//otherwise return Data property
return this.vreq.getWebappDaoFactory().getDataPropertyDao().getDataPropertyByURI(predicateUri);
}
public ObjectProperty getObjectPredicateProperty() {
return this.vreq.getWebappDaoFactory().getObjectPropertyDao().getObjectPropertyByURI(getPredicateUri());
}
public DataProperty getDataPredicateProperty() {
return this.vreq.getWebappDaoFactory().getDataPropertyDao().getDataPropertyByURI(getPredicateUri());
}
public String getPredicateUri() {
return editConfig.getPredicateUri();
}
public String getSubjectUri() {
return editConfig.getSubjectUri();
}
public String getObjectUri() {
return editConfig.getObject();
}
//data literal
public String getDataLiteral() {
return getDataPredicateProperty().getLocalName() + "Edited";
}
//public description only appears visible for object property
public String getPropertyPublicDescription() {
return getObjectPredicateProperty().getPublicDescription();
}
public boolean getPropertySelectFromExisting() {
return getObjectPredicateProperty().getSelectFromExisting();
}
//booleans for checking whether predicate is data or object
public boolean isDataProperty() {
return EditConfigurationUtils.isDataProperty(getPredicateUri(), vreq);
}
public boolean isObjectProperty() {
return EditConfigurationUtils.isObjectProperty(getPredicateUri(), vreq);
}
//Additional methods that were originally in edit request dispatch controller
//to be employed here instead
public String getUrlToReturnTo() {
return vreq
.getParameter("urlPattern") == null ? "/entity" : vreq
.getParameter("urlPattern");
}
public String getCurrentUrl() {
return "/edit/editRequestDispatch?" + vreq.getQueryString();
}
}