From 202a657178e56e9d198dcd068b826d5784482405 Mon Sep 17 00:00:00 2001
From: hjkhjk54
Date: Fri, 28 Oct 2011 15:39:24 +0000
Subject: [PATCH] updates for freemarker conversion and related n3editing
---
.../n3editing/VTwo/BaseEditElementVTwo.java | 75 ++
.../VTwo/DateTimeIntervalValidationVTwo.java | 216 ++++
.../VTwo/DateTimeWithPrecisionVTwo.java | 620 +++++++++++
.../VTwo/EditConfigurationUtils.java | 50 +
.../n3editing/VTwo/EditConfigurationVTwo.java | 23 +-
.../edit/n3editing/VTwo/EditElementVTwo.java | 5 +
.../edit/n3editing/VTwo/N3ValidatorVTwo.java | 12 +
.../AddClinicalRoleToPersonGenerator.java | 123 +++
.../AddRoleToPersonTwoStageGenerator.java | 983 ++++++++++++++++++
.../EditRequestDispatchController.java | 15 +-
.../edit/EditConfigurationTemplateModel.java | 109 +-
.../edit/forms/addClinicalRoleToPerson.ftl | 7 +
.../edit/forms/addRoleToPersonTwoStage.ftl | 192 ++++
13 files changed, 2402 insertions(+), 28 deletions(-)
create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/BaseEditElementVTwo.java
create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/DateTimeIntervalValidationVTwo.java
create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/DateTimeWithPrecisionVTwo.java
create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/N3ValidatorVTwo.java
create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/AddClinicalRoleToPersonGenerator.java
create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/AddRoleToPersonTwoStageGenerator.java
create mode 100644 webapp/web/templates/freemarker/edit/forms/addClinicalRoleToPerson.ftl
create mode 100644 webapp/web/templates/freemarker/edit/forms/addRoleToPersonTwoStage.ftl
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/BaseEditElementVTwo.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/BaseEditElementVTwo.java
new file mode 100644
index 000000000..d5e6a410e
--- /dev/null
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/BaseEditElementVTwo.java
@@ -0,0 +1,75 @@
+/* $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.io.IOException;
+import java.io.StringWriter;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+
+public abstract class BaseEditElementVTwo implements EditElementVTwo {
+ private static final Log log = LogFactory.getLog(BaseEditElementVTwo.class);
+
+ protected FieldVTwo field;
+
+ public BaseEditElementVTwo(FieldVTwo field){
+ this.field = field;
+ }
+
+ /**
+ * Utility method for use in EditElements to merge a freemarker template.
+ */
+ protected String merge(Configuration fmConfig, String templateName, Map map){
+ Template template = null;
+ try {
+ template = fmConfig.getTemplate(templateName);
+ } catch (IOException e) {
+ log.error("Cannot get template " + templateName);
+ }
+
+ StringWriter writer = new StringWriter();
+ try {
+ template.process(map, writer);
+ } catch (TemplateException e) {
+ log.error(e,e);
+ } catch (IOException e) {
+ log.error(e,e);
+ }
+ return writer.toString();
+ }
+
+ /**
+ * Utility method to check if a value from the query parameters is none or a single value.
+ * This returns true if the key is there and the value is null.
+ * This does not check if the value is the empty string.
+ */
+ protected boolean hasNoneOrSingle(String key, Map queryParameters){
+ if( queryParameters != null ){
+ if( ! queryParameters.containsKey(key) )
+ return true; //none
+ String[] vt = queryParameters.get(key);
+ return vt == null || vt.length == 0 || vt.length==1;
+ }else{
+ log.error("passed null queryParameters");
+ return false;
+ }
+ }
+
+ protected boolean hasSingleNonNullNonEmptyValueForKey(String key, Map queryParameters){
+ if( queryParameters != null ){
+ if( ! queryParameters.containsKey(key) )
+ return true; //none
+ String[] vt = queryParameters.get(key);
+ return vt != null && vt.length == 1 && vt[0] != null && ! vt[0].isEmpty() ;
+ }else{
+ log.error("passed null queryParameters");
+ return false;
+ }
+ }
+}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/DateTimeIntervalValidationVTwo.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/DateTimeIntervalValidationVTwo.java
new file mode 100644
index 000000000..f01779260
--- /dev/null
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/DateTimeIntervalValidationVTwo.java
@@ -0,0 +1,216 @@
+/* $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.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.hp.hpl.jena.datatypes.xsd.XSDDateTime;
+import com.hp.hpl.jena.rdf.model.Literal;
+
+import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
+import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.Precision;
+import edu.cornell.mannlib.vitro.webapp.edit.elements.DateTimeWithPrecision;
+import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration;
+import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.EditSubmission;
+
+/*
+ * Assumption for date time interval validation: Only one start field/end field/and precision.
+ * We are currently not accepting multiple values for start time, end time, or precision.
+ */
+
+
+public class DateTimeIntervalValidationVTwo implements N3ValidatorVTwo {
+ private static Log log = LogFactory.getLog(DateTimeIntervalValidationVTwo.class);
+
+ private String startFieldName;
+ private String endFieldName;
+
+ private String startValueName;
+ private String endValueName;
+
+ private String startPrecisionName;
+ private String endPrecisionName;
+
+ public DateTimeIntervalValidationVTwo(String startFieldName, String endFieldName){
+ this.startFieldName = startFieldName;
+ this.endFieldName = endFieldName;
+ startValueName = startFieldName + "-value";
+ endValueName = endFieldName + "-value";
+ startPrecisionName = startFieldName + "-precision";
+ endPrecisionName = endFieldName + "-precision";
+ }
+
+ public Map validate(EditConfigurationVTwo editConfig,
+ MultiValueEditSubmission editSub) {
+ Map> existingLiterals = editConfig.getLiteralsInScope();
+ List existingStartYear = existingLiterals.get(startValueName);
+ List existingEndYear = existingLiterals.get(endValueName);
+
+ Map> literalsFromForm = editSub.getLiteralsFromForm();
+ List formStartYear = literalsFromForm.get(startValueName);
+ List formEndYear = literalsFromForm.get(endValueName);
+
+ VitroVocabulary.Precision startPrecision = getPrecision(startPrecisionName, editConfig, editSub);
+ VitroVocabulary.Precision endPrecision = getPrecision(endPrecisionName, editConfig, editSub);
+
+ Map errors = new HashMap();
+
+ // NIHVIVO-2541 Commented out to allow end date with no start date
+// if( formStartYear == null && formEndYear != null ){
+// errors.put(startFieldName, "If there is an end date, there should be a start date");
+// return errors;
+// }
+
+
+ //Assuming form start year and form end year are working in conjunction with multiple values
+ int index;
+ if (formStartYear != null && formEndYear != null) {
+ int numberStartYears = formStartYear.size();
+ int numberEndYears = formEndYear.size();
+ if(numberStartYears > 1 && numberEndYears > 1) {
+ errors.put(startFieldName, "DateTimeIntervalValidationVTwo does not support multiple start years or end years");
+ return errors;
+ }
+
+ if(numberStartYears > 0 && numberEndYears > 0) {
+ errors.putAll(checkDateLiterals(formStartYear.get(0), formEndYear.get(0), startPrecision, endPrecision));
+ }
+ } else if (formStartYear != null && existingEndYear != null) {
+ int numberStartYears = formStartYear.size();
+ int numberEndYears = existingEndYear.size();
+ if(numberStartYears > 1 && numberEndYears > 1) {
+ errors.put(startFieldName, "DateTimeIntervalValidationVTwo does not support multiple start years or end years");
+ return errors;
+ }
+
+ if(numberStartYears > 0 && numberEndYears > 0) {
+ errors.putAll(checkDateLiterals(formStartYear.get(0), existingEndYear.get(0), startPrecision, endPrecision));
+ }
+ } else if (existingStartYear != null && formEndYear != null) {
+ int numberStartYears = existingStartYear.size();
+ int numberEndYears = formEndYear.size();
+ if(numberStartYears > 1 && numberEndYears > 1) {
+ errors.put(startFieldName, "DateTimeIntervalValidationVTwo does not support multiple start years or end years");
+ return errors;
+ }
+
+ if(numberStartYears > 0 && numberEndYears > 0) {
+ errors.putAll(checkDateLiterals(existingStartYear.get(0), formEndYear.get(0), startPrecision, endPrecision));
+ }
+ } else if (existingStartYear != null && existingEndYear != null) {
+ int numberStartYears = existingStartYear.size();
+ int numberEndYears = existingEndYear.size();
+ if(numberStartYears > 1 && numberEndYears > 1) {
+ errors.put(startFieldName, "DateTimeIntervalValidationVTwo does not support multiple start years or end years");
+ return errors;
+ }
+
+ if(numberStartYears > 0 && numberEndYears > 0) {
+ errors.putAll(checkDateLiterals(existingStartYear.get(0), existingEndYear.get(0), startPrecision, endPrecision));
+ }
+ }
+
+ if (errors.size() != 0)
+ return errors;
+ else
+ return null;
+ }
+
+ private Precision getPrecision(String precisionVarName,
+ EditConfigurationVTwo editConfig, MultiValueEditSubmission editSub) {
+ if( editSub != null
+ && editSub.getUrisFromForm() != null
+ && editSub.getUrisFromForm().containsKey(precisionVarName)){
+ List precisionStr = editSub.getUrisFromForm().get(precisionVarName);
+ //TODO: Check if we need to handle multiple precision strings and what to do then
+ //Currently checks first precision str and then returns response
+ if(precisionStr.size() > 0) {
+ String precisionString = precisionStr.get(0);
+ VitroVocabulary.Precision precision = DateTimeWithPrecision.toPrecision( precisionString );
+ if( precision == null )
+ log.warn("cannot convert " + precisionStr + " to a precision");
+ else
+ return precision;
+ } else {
+ log.error("No precision strings returned");
+ }
+
+ }else if( editConfig != null
+ && editConfig.getUrisInScope() != null
+ && editConfig.getUrisInScope().containsKey(precisionVarName)){
+ List precisionStr = editConfig.getUrisInScope().get(precisionVarName);
+ //TODO: Check if we need to handle multiple precision strings and what to do then
+ //Currently checks first precision str and then returns response
+ if(precisionStr.size() > 0) {
+ String precisionString = precisionStr.get(0);
+ VitroVocabulary.Precision precision = DateTimeWithPrecisionVTwo.toPrecision( precisionString );
+ if( precision == null )
+ log.warn("cannot convert " + precisionString + " to a precision");
+ else
+ return precision;
+ } else {
+ log.error("No precision strings returned");
+ }
+
+ }
+ //this is what is returned if a precision was not found in the config or submission
+ return null;
+ }
+
+ private Map checkDateLiterals(
+ Literal startLit, Literal endLit,
+ VitroVocabulary.Precision startPrecision, VitroVocabulary.Precision endPrecision) {
+ Map errors = new HashMap();
+
+ if( endPrecision == null ){
+ //there is no end date, nothing to check
+ return errors;
+ }
+
+ try{
+ XSDDateTime startDate = (XSDDateTime)startLit.getValue();
+ XSDDateTime endDate = (XSDDateTime)endLit.getValue();
+ if( startDate != null && endDate!= null ){
+ Calendar startCal = startDate.asCalendar();
+ Calendar endCal = endDate.asCalendar();
+
+ if( endCal != null ){
+ if( !startCal.before( endCal ) ){
+ if( startPrecision == VitroVocabulary.Precision.YEAR
+ && endPrecision == VitroVocabulary.Precision.YEAR ){
+ errors.putAll( checkYears(startCal,endCal));
+ }else{
+ errors.put(startFieldName, "Start must be before end");
+ errors.put(endFieldName, "End must be after start");
+ }
+ }
+ }
+ }
+ }catch(ClassCastException cce){
+ errors.put(startFieldName, "could not format start or end date");
+ errors.put(endFieldName, "could not format start or end date");
+ log.debug("could not format dates " + cce);
+ }
+
+ return errors;
+ }
+
+ private Map extends String, ? extends String> checkYears(
+ Calendar startCal, Calendar endCal) {
+
+ Map errors = new HashMap();
+
+ if( ! (endCal.get(Calendar.YEAR) >= startCal.get(Calendar.YEAR) )){
+ errors.put(startFieldName, "Start must be before end");
+ errors.put(endFieldName, "End must be after start");
+ }
+
+ return errors;
+ }
+}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/DateTimeWithPrecisionVTwo.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/DateTimeWithPrecisionVTwo.java
new file mode 100644
index 000000000..728cd75b7
--- /dev/null
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/DateTimeWithPrecisionVTwo.java
@@ -0,0 +1,620 @@
+/* $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.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.List;
+import java.util.ArrayList;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.joda.time.DateTime;
+import org.joda.time.format.ISODateTimeFormat;
+
+import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
+import com.hp.hpl.jena.rdf.model.Literal;
+import com.hp.hpl.jena.rdf.model.ResourceFactory;
+
+import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerConfiguration;
+import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
+import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration;
+import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.Field;
+import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.EditSubmission;
+import freemarker.template.Configuration;
+
+/**
+ * This is intended to work in conjunction with a template to create the HTML for a
+ * datetime with precision and to convert the submitted parameters into
+ * varname -> Literal and varname -> URI maps.
+ *
+ * The variables that get passed to the template are defined in:
+ * DateTimeWithPrecision.getMapForTemplate()
+ *
+ * Two variables will be defined for the N3 edit graphs (These are NOT variables passed to FM templates):
+ * $fieldname.precision - URI of datetime precision
+ * $fieldname.value - DateTime literal
+ *
+ */
+public class DateTimeWithPrecisionVTwo extends BaseEditElementVTwo {
+
+ String fieldName;
+
+ /**
+ * This is the minimum datetime precision that this element
+ * will accept. If the parameters submitted do not meet this
+ * requirement, then a validation error will be created.
+ */
+ VitroVocabulary.Precision minimumPrecision;
+
+ /**
+ * This is the maximum precision that the form should
+ * allow the user to enter. This value is not used by
+ * DateTimeWithPrecision for validation, it is only passed
+ * to the template. This should be removed when it can be
+ * specified in a ftl file.
+ *
+ * This could be thought of as the maximum precision to display.
+ */
+ VitroVocabulary.Precision displayRequiredLevel;
+
+
+ VitroVocabulary.Precision DEFAULT_MIN_PRECISION = VitroVocabulary.Precision.DAY;
+ VitroVocabulary.Precision DEFAULT_DISPLAY_LEVEL = VitroVocabulary.Precision.DAY;
+ VitroVocabulary.Precision[] precisions = VitroVocabulary.Precision.values();
+
+ protected static final String BLANK_SENTINEL = ">SUBMITTED VALUE WAS BLANK<";
+
+ public DateTimeWithPrecisionVTwo(FieldVTwo field) {
+ super(field);
+ fieldName = field.getName();
+ minimumPrecision = DEFAULT_MIN_PRECISION;
+ displayRequiredLevel = DEFAULT_DISPLAY_LEVEL;
+ }
+
+ public DateTimeWithPrecisionVTwo(FieldVTwo field, VitroVocabulary.Precision minimumPrecision){
+ this(field);
+ if( minimumPrecision != null )
+ this.minimumPrecision = minimumPrecision;
+ else
+ this.minimumPrecision = DEFAULT_MIN_PRECISION;
+ this.displayRequiredLevel = this.minimumPrecision;
+ }
+
+ //it would be nice to have only the version of the constructor that takes the enum
+ //but this is to quickly get the JSP configuration working.
+ public DateTimeWithPrecisionVTwo(FieldVTwo field, String minimumPrecisionURI, String displayRequiredLevelUri){
+ this(field);
+
+ this.minimumPrecision = toPrecision( minimumPrecisionURI);
+ if( this.minimumPrecision == null )
+ throw new IllegalArgumentException(minimumPrecisionURI
+ +" is not a valid precision for minimumPrecision, see VitroVocabulary.Precision");
+
+ this.displayRequiredLevel = toPrecision( displayRequiredLevelUri );
+ if( this.displayRequiredLevel == null )
+ throw new IllegalArgumentException(displayRequiredLevelUri
+ +" is not a valid precision for displayRequiredLevel, see VitroVocabulary.Precision");
+
+// if( this.displayRequiredLevel.ordinal() < this.minimumPrecision.ordinal() ){
+// throw new IllegalArgumentException("the display precision level " + this.displayRequiredLevel
+// + " is less precise than the required minimum precision of " + this.minimumPrecision);
+// }
+ }
+
+ private static final Log log = LogFactory.getLog(DateTimeWithPrecisionVTwo.class);
+ protected String TEMPLATE_NAME = "dateTimeWithPrecision.ftl";
+
+ @Override
+ public String draw(String fieldName, EditConfigurationVTwo editConfig,
+ MultiValueEditSubmission editSub, Configuration fmConfig) {
+ Map map = getMapForTemplate( editConfig, editSub);
+ return merge( fmConfig, TEMPLATE_NAME, map);
+ }
+
+ /**
+ * This produces a map for use in the template. Will be using this b/c
+ */
+ public Map getMapForTemplate(EditConfigurationVTwo editConfig, MultiValueEditSubmission editSub) {
+ Mapmap = new HashMap();
+
+ //always need the fieldName, required precision, and constants
+ map.put("fieldName", fieldName);
+ addPrecisionConstants(map);
+ map.put("minimumPrecision", minimumPrecision.uri());
+ map.put("requiredLevel", displayRequiredLevel.uri());
+
+ //Still expecting single precision uri not multiple
+ String precisionUri= getPrecision(editConfig,editSub);
+
+ VitroVocabulary.Precision existingPrec = toPrecision(precisionUri);
+
+ if( precisionUri != null && !"".equals(precisionUri) && existingPrec == null ){
+ log.error("field " + fieldName + ": existing precision uri was " +
+ "'" + precisionUri + "' but could not convert to Precision object");
+ }
+
+ if( precisionUri == null || precisionUri.isEmpty() || existingPrec == null){
+ map.put("existingPrecision", "");
+
+ /* no precision so there should also be no datetime */
+ DateTime value = getTimeValue(editConfig,editSub);
+ if( value != null )
+ log.info("Unexpected state: Precision for " + fieldName
+ + " was '" + precisionUri + "' but date time was " + value);
+
+ map.put("year", "");
+ map.put("month", "");
+ map.put("day", "");
+ map.put("hour", "");
+ map.put("minute", "");
+ map.put("second", "") ;
+ } else if( VitroVocabulary.Precision.NONE.uri().equals(precisionUri) ){
+ //bdc34: not sure what to do with the NONE precision
+ map.put("existingPrecision", precisionUri);
+
+ map.put("year", "");
+ map.put("month", "");
+ map.put("day", "");
+ map.put("hour", "");
+ map.put("minute", "");
+ map.put("second", "") ;
+ }else{
+ map.put("existingPrecision", precisionUri);
+
+ DateTime value = getTimeValue(editConfig,editSub);
+ /* This is the case where there is a precision so there should be a datetime */
+ if( value == null )
+ log.error("Field " + fieldName + " has precision " + precisionUri
+ + " but the date time is " + value);
+
+ /* only put the values in the map for ones which are significant based on the precision */
+ if( existingPrec.ordinal() >= VitroVocabulary.Precision.SECOND.ordinal() )
+ map.put("second", Integer.toString(value.getSecondOfMinute() )) ;
+ else
+ map.put("second", "");
+
+ if( existingPrec.ordinal() >= VitroVocabulary.Precision.MINUTE.ordinal() )
+ map.put("minute", Integer.toString(value.getMinuteOfHour()) );
+ else
+ map.put("minute", "");
+
+ if( existingPrec.ordinal() >= VitroVocabulary.Precision.HOUR.ordinal() )
+ map.put("hour", Integer.toString(value.getHourOfDay()) );
+ else
+ map.put("hour", "");
+
+ if( existingPrec.ordinal() >= VitroVocabulary.Precision.DAY.ordinal() )
+ map.put("day", Integer.toString(value.getDayOfMonth()) );
+ else
+ map.put("day", "");
+
+ if( existingPrec.ordinal() >= VitroVocabulary.Precision.MONTH.ordinal() )
+ map.put("month", Integer.toString(value.getMonthOfYear()));
+ else
+ map.put("month", "");
+
+ if( existingPrec.ordinal() >= VitroVocabulary.Precision.YEAR.ordinal() )
+ map.put("year", Integer.toString(value.getYear()));
+ else
+ map.put("year", "");
+ }
+
+ return map;
+ }
+
+ /** Adds precisionURIs for use by the templates */
+ private void addPrecisionConstants(Map map){
+ Map constants = new HashMap();
+ for( VitroVocabulary.Precision pc: VitroVocabulary.Precision.values()){
+ constants.put(pc.name().toLowerCase(),pc.uri());
+ }
+ map.put("precisionConstants", constants);
+ }
+
+ /**
+ * Gets the currently set precision. May return null.
+ */
+ private String getPrecision(EditConfigurationVTwo editConfig, MultiValueEditSubmission editSub) {
+ if( editSub != null ){
+ List submittedPrecisionURI = editSub.getUrisFromForm().get( getPrecisionVariableName() );
+ if( submittedPrecisionURI != null
+ && submittedPrecisionURI.size() > 0
+ && submittedPrecisionURI.get(0) != null){
+ return submittedPrecisionURI.get(0);
+ }
+ }
+
+ List existingPrecisionURI = editConfig.getUrisInScope().get( getPrecisionVariableName() );
+ if( existingPrecisionURI != null
+ && existingPrecisionURI.size() > 0
+ && existingPrecisionURI.get(0) != null){
+ //TODO: Check if relevant to return more than one element
+ return existingPrecisionURI.get(0);
+ }else{
+ return null;
+ }
+ }
+
+ private DateTime getTimeValue(EditConfigurationVTwo editConfig, MultiValueEditSubmission editSub) {
+ if( editSub != null ){
+ List submittedValue = editSub.getLiteralsFromForm().get( getValueVariableName() );
+ if( submittedValue != null ) {
+ //TODO: Check what to do with multiple values, currently handling one value
+ if(submittedValue.size() > 0 && submittedValue.get(0) != null) {
+ return new DateTime( submittedValue.get(0).getLexicalForm() );
+ }
+ }
+ }
+
+ List dtValue = editConfig.getLiteralsInScope().get( getValueVariableName() );
+ if( dtValue != null ){
+ if(dtValue.size() > 0 && dtValue.get(0) != null)
+ {
+ return new DateTime( dtValue.get(0).getLexicalForm() );
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * This gets the literals for a submitted form from the queryParmeters.
+ * It will only be called if getValidationErrors() doesn't return any errors.
+ */
+ @Override
+ public Map> getLiterals(String fieldName,
+ EditConfigurationVTwo editConfig, Map queryParameters) {
+ Map> literalMap = new HashMap>();
+
+ Literal datetime =getDateTime( queryParameters);
+ List literals = new ArrayList();
+ literals.add(datetime);
+ literalMap.put(fieldName+"-value", literals);
+
+ return literalMap;
+ }
+
+ protected Literal getDateTime( Map queryParameters ) {
+ String submittedPrec = BLANK_SENTINEL;
+ try {
+ submittedPrec = getSubmittedPrecision( queryParameters);
+ } catch (Exception e) {
+ log.error("could not get submitted precsion",e);
+ }
+
+ if( BLANK_SENTINEL.equals( submittedPrec ) )
+ return null;
+
+ Integer year = parseToInt(fieldName+"-year", queryParameters);
+
+ //this is the case where date has not been filled out at all.
+ if( year == null )
+ return null;
+
+ Integer month = parseToInt(fieldName+"-month", queryParameters);
+ if( month == null || month == 0 )
+ month = 1;
+ Integer day = parseToInt(fieldName+"-day", queryParameters);
+ if( day == null || day == 0 )
+ day = 1;
+ Integer hour = parseToInt(fieldName+"-hour", queryParameters);
+ if( hour == null )
+ hour = 0;
+ Integer minute = parseToInt(fieldName+"-minute", queryParameters);
+ if( minute == null )
+ minute = 0;
+ Integer second = parseToInt(fieldName+"-second", queryParameters);
+ if( second == null )
+ second = 0;
+
+ DateTime value = new DateTime(
+ year.intValue(),month.intValue(),day.intValue(),
+ hour.intValue(),minute.intValue(),second.intValue(),0/*millis*/
+ );
+
+ return ResourceFactory.createTypedLiteral(
+ ISODateTimeFormat.dateHourMinuteSecond().print(value), /*does not include timezone*/
+ XSDDatatype.XSDdateTime);
+ }
+
+ /**
+ * This gets the URIs for a submitted form from the queryParmeters.
+ * It will only be called if getValidationErrors() doesn't return any errors.
+ */
+ @Override
+ public Map> getURIs(String fieldName,
+ EditConfigurationVTwo editConfig, Map queryParameters) {
+ String precisionUri;
+ try {
+ precisionUri = getSubmittedPrecision( queryParameters);
+ } catch (Exception e) {
+ log.error("getURIs() should only be called on input that passed getValidationErrors()");
+ return Collections.emptyMap();
+ }
+ Map> uriMap = new HashMap>();
+ if( precisionUri != null ){
+ List uris = new ArrayList();
+ uris.add(precisionUri);
+ uriMap.put(fieldName+"-precision", uris);
+ }
+ return uriMap;
+ }
+
+ /**
+ * Precision is based on the values returned by the form. Throws an exception with
+ * the error message if the queryParameters cannot make a valid date/precision because
+ * there are values missing.
+ */
+ protected String getSubmittedPrecision(Map queryParameters) throws Exception {
+
+ Integer year = parseToInt(fieldName+"-year",queryParameters);
+ Integer month = parseToInt(fieldName+"-month",queryParameters);
+ Integer day = parseToInt(fieldName+"-day",queryParameters);
+ Integer hour = parseToInt(fieldName+"-hour",queryParameters);
+ Integer minute = parseToInt(fieldName+"-minute",queryParameters);
+ Integer second = parseToInt(fieldName+"-second",queryParameters);
+ Integer[] values = { year, month, day, hour, minute, second };
+
+ /* find the most significant date field that is null. */
+ int indexOfFirstNull= -1;
+ for(int i=0; i < values.length ; i++){
+ if( values[i] == null ){
+ indexOfFirstNull = i;
+ break;
+ }
+ }
+
+ /* the field wasn't filled out at all */
+ if( indexOfFirstNull == 0 )
+ //return VitroVocabulary.Precision.NONE.uri();
+ return BLANK_SENTINEL;
+
+ /* if they all had values then we have seconds precision */
+ if( indexOfFirstNull == -1 )
+ return VitroVocabulary.Precision.SECOND.uri();
+
+
+ /* check that there are no values after the most significant null field
+ * that are non-null. */
+ boolean nonNullAfterFirstNull=false;
+ for(int i=0; i < values.length ; i++){
+ if( i > indexOfFirstNull && values[i] != null ){
+ nonNullAfterFirstNull = true;
+ break;
+ }
+ }
+ if( nonNullAfterFirstNull )
+ throw new Exception("Invalid date-time value. When creating a date-time value, there cannot be gaps between any of the selected fields.");
+ else{
+ return precisions[ indexOfFirstNull ].uri();
+ }
+ }
+
+ @Override
+ public Map getValidationMessages(String fieldName,
+ EditConfigurationVTwo editConfig, Map queryParameters) {
+ Map errorMsgMap = new HashMap();
+
+ //check that any parameters we got are single values
+ String[] names = {"year","month","day","hour","minute","second", "precision"};
+ for( String name:names){
+ if ( !hasNoneOrSingle(fieldName+"-"+name, queryParameters))
+ errorMsgMap.put(fieldName+"-"+name, "must have only one value for " + name);
+ }
+
+ String precisionURI = null;
+ try{
+ precisionURI = getSubmittedPrecision( queryParameters);
+ }catch(Exception ex){
+ errorMsgMap.put(fieldName,ex.getMessage());
+ return errorMsgMap;
+ }
+
+ errorMsgMap.putAll(checkDate( precisionURI, queryParameters) );
+
+ return errorMsgMap;
+ }
+
+ /**
+ * This checks for invalid date times.
+ */
+ final static String NON_INTEGER_YEAR = "must enter a valid year";
+ final static String NON_INTEGER_MONTH = "must enter a valid month";
+ final static String NON_INTEGER_DAY = "must enter a valid day";
+ final static String NON_INTEGER_HOUR = "must enter a valid hour";
+ final static String NON_INTEGER_MINUTE = "must enter a valid minute";
+ final static String NON_INTEGER_SECOND = "must enter a valid second";
+
+ private Map checkDate( String precisionURI, Map qp){
+ if( precisionURI == null )
+ return Collections.emptyMap();
+
+ Map errors = new HashMap();
+
+ Integer year,month,day,hour,minute,second;
+
+ //just check if the values for the precision parse to integers
+ if( precisionURI.equals(VitroVocabulary.Precision.YEAR.uri() ) ){
+ if( ! canParseToNumber(fieldName+"-year" ,qp))
+ errors.put(fieldName+"-year", NON_INTEGER_YEAR);
+ }else if( precisionURI.equals( VitroVocabulary.Precision.MONTH.uri() )){
+ if( ! canParseToNumber(fieldName+"-year" ,qp))
+ errors.put(fieldName+"-year", NON_INTEGER_YEAR);
+ if( ! canParseToNumber(fieldName+"-month" ,qp))
+ errors.put(fieldName+"-month", NON_INTEGER_MONTH);
+ }else if( precisionURI.equals( VitroVocabulary.Precision.DAY.uri() )){
+ if( ! canParseToNumber(fieldName+"-year" ,qp))
+ errors.put(fieldName+"-year", NON_INTEGER_YEAR);
+ if( ! canParseToNumber(fieldName+"-month" ,qp))
+ errors.put(fieldName+"-month", NON_INTEGER_MONTH);
+ if( ! canParseToNumber(fieldName+"-day" ,qp))
+ errors.put(fieldName+"-day", NON_INTEGER_DAY);
+ }else if( precisionURI.equals( VitroVocabulary.Precision.HOUR.uri() )){
+ if( ! canParseToNumber(fieldName+"-year" ,qp))
+ errors.put(fieldName+"-year", NON_INTEGER_YEAR);
+ if( ! canParseToNumber(fieldName+"-month" ,qp))
+ errors.put(fieldName+"-month", NON_INTEGER_MONTH);
+ if( ! canParseToNumber(fieldName+"-day" ,qp))
+ errors.put(fieldName+"-day", NON_INTEGER_DAY);
+ if( ! canParseToNumber(fieldName+"-hour" ,qp))
+ errors.put(fieldName+"-hour", NON_INTEGER_HOUR);
+ }else if( precisionURI.equals( VitroVocabulary.Precision.MINUTE.uri() )){
+ if( ! canParseToNumber(fieldName+"-year" ,qp))
+ errors.put(fieldName+"-year", NON_INTEGER_YEAR);
+ if( ! canParseToNumber(fieldName+"-month" ,qp))
+ errors.put(fieldName+"-month", NON_INTEGER_MONTH);
+ if( ! canParseToNumber(fieldName+"-day" ,qp))
+ errors.put(fieldName+"-day", NON_INTEGER_DAY);
+ if( ! canParseToNumber(fieldName+"-hour" ,qp))
+ errors.put(fieldName+"-hour", NON_INTEGER_HOUR);
+ if( ! canParseToNumber(fieldName+"-minute" ,qp))
+ errors.put(fieldName+"-minute", NON_INTEGER_HOUR);
+ }else if( precisionURI.equals( VitroVocabulary.Precision.SECOND.uri() )){
+ if( ! canParseToNumber(fieldName+"-year" ,qp))
+ errors.put(fieldName+"-year", NON_INTEGER_YEAR);
+ if( ! canParseToNumber(fieldName+"-month" ,qp))
+ errors.put(fieldName+"-month", NON_INTEGER_MONTH);
+ if( ! canParseToNumber(fieldName+"-day" ,qp))
+ errors.put(fieldName+"-day", NON_INTEGER_DAY);
+ if( ! canParseToNumber(fieldName+"-hour" ,qp))
+ errors.put(fieldName+"-hour", NON_INTEGER_HOUR);
+ if( ! canParseToNumber(fieldName+"-minute" ,qp))
+ errors.put(fieldName+"-minute", NON_INTEGER_HOUR);
+ if( ! canParseToNumber(fieldName+"-second" ,qp))
+ errors.put(fieldName+"-second", NON_INTEGER_SECOND);
+ }
+
+ //check if we can make a valid date with these integers
+ year = parseToInt(fieldName+"-year", qp);
+ if( year == null )
+ year = 1999;
+ month= parseToInt(fieldName+"-month", qp);
+ if(month == null )
+ month = 1;
+ day = parseToInt(fieldName+"-day", qp);
+ if( day == null )
+ day = 1;
+ hour = parseToInt(fieldName+"-hour", qp);
+ if( hour == null )
+ hour = 0;
+ minute = parseToInt(fieldName+"-minute",qp);
+ if( minute == null )
+ minute = 0;
+ second = parseToInt(fieldName+"-second", qp);
+ if( second == null )
+ second = 0;
+
+ //initialize to something so that we can be assured not to get
+ //system date dependent behavior
+ DateTime dateTime = new DateTime("1970-01-01T00:00:00Z");
+
+ try{
+ dateTime = dateTime.withYear(year);
+ }catch(IllegalArgumentException iae){
+ errors.put(fieldName+"-year", iae.getLocalizedMessage());
+ }
+ try{
+ dateTime = dateTime.withMonthOfYear(month);
+ }catch(IllegalArgumentException iae){
+ errors.put(fieldName+"-month", iae.getLocalizedMessage());
+ }
+ try{
+ dateTime = dateTime.withDayOfMonth(day);
+ }catch(IllegalArgumentException iae){
+ errors.put(fieldName+"-day", iae.getLocalizedMessage());
+ }
+ try{
+ dateTime = dateTime.withHourOfDay(hour);
+ }catch(IllegalArgumentException iae){
+ errors.put(fieldName+"-hour", iae.getLocalizedMessage());
+ }
+ try{
+ dateTime = dateTime.withSecondOfMinute(second);
+ }catch(IllegalArgumentException iae){
+ errors.put(fieldName+"-second", iae.getLocalizedMessage());
+ }
+
+ return errors;
+ }
+
+
+ private boolean fieldMatchesPattern( String fieldName, MapqueryParameters, Pattern pattern){
+ String[] varg = queryParameters.get(fieldName);
+ if( varg == null || varg.length != 1 || varg[0] == null)
+ return false;
+ String value = varg[0];
+ Matcher match = pattern.matcher(value);
+ return match.matches();
+ }
+
+ private boolean emptyOrBlank(String key,Map queryParameters){
+ String[] vt = queryParameters.get(key);
+ return ( vt == null || vt.length ==0 || vt[0] == null || vt[0].length() == 0 );
+ }
+
+ private boolean canParseToNumber(String key,Map queryParameters){
+ Integer out = null;
+ try{
+ String[] vt = queryParameters.get(key);
+ if( vt == null || vt.length ==0 || vt[0] == null)
+ return false;
+ else{
+ out = Integer.parseInt(vt[0]);
+ return true;
+ }
+ }catch(IndexOutOfBoundsException iex){
+ out = null;
+ }catch(NumberFormatException nfe){
+ out = null;
+ }catch(NullPointerException npe){
+ out = null;
+ }
+ return false;
+ }
+
+
+
+ private Integer parseToInt(String key,Map queryParameters){
+ Integer out = null;
+ try{
+ String[] vt = queryParameters.get(key);
+ if( vt == null || vt.length ==0 || vt[0] == null)
+ out = null;
+ else
+ out = Integer.parseInt(vt[0]);
+ }catch(IndexOutOfBoundsException iex){
+ out = null;
+ }catch(NumberFormatException nfe){
+ out = null;
+ }catch(NullPointerException npe){
+ out = null;
+ }
+ return out;
+ }
+
+ public VitroVocabulary.Precision getRequiredMinimumPrecision() {
+ return minimumPrecision;
+ }
+
+ public void setRequiredMinimumPrecision(
+ VitroVocabulary.Precision requiredMinimumPrecision) {
+ this.minimumPrecision = requiredMinimumPrecision;
+ }
+
+ /* returns null if it cannot convert */
+ public static VitroVocabulary.Precision toPrecision(String precisionUri){
+ for( VitroVocabulary.Precision precision : VitroVocabulary.Precision.values()){
+ if( precision.uri().equals(precisionUri))
+ return precision;
+ }
+ return null;
+ }
+
+ public String getValueVariableName(){ return fieldName + "-value" ; }
+ public String getPrecisionVariableName(){ return fieldName + "-precision" ; }
+}
+
+
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java
index 630108cdc..937b30620 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java
@@ -2,6 +2,7 @@
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -11,18 +12,23 @@ import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
+import com.hp.hpl.jena.vocabulary.XSD;
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.configuration.Field;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.RdfLiteralHash;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.edit.EditConfigurationTemplateModel;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
+import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerConfigurationLoader;
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 freemarker.template.Configuration;
public class EditConfigurationUtils {
private static Log log = LogFactory.getLog(EditConfigurationUtils.class);
@@ -186,5 +192,49 @@ public class EditConfigurationUtils {
}
return dataHash;
}
+
+ //Copied from the original input element formatting tag
+ //Allows the retrieval of the string values for the literals
+ //Useful for cases with date/time and other mechanisms
+ public static Map> getExistingLiteralValues(VitroRequest vreq, EditConfigurationVTwo editConfig) {
+ Map> literalsInScopeStringValues = new HashMap>();
+ Map> literalsInScope = editConfig.getLiteralsInScope();
+
+ for(String key: literalsInScope.keySet() ) {
+ List stringValues = processLiteral(editConfig, key);
+ literalsInScopeStringValues.put(key, stringValues);
+ }
+ return literalsInScopeStringValues;
+ }
+
+ //Copied from input element formatting tag
+ private static List processLiteral(EditConfigurationVTwo editConfig, String fieldName) {
+ Map> literalsInScope = editConfig.getLiteralsInScope();
+ List stringValues = new ArrayList();
+ List literalValues = literalsInScope.get(fieldName);
+ for(Literal l: literalValues) {
+ //Could do additional processing here if required, for example if date etc. if need be
+ stringValues.add(l.getValue().toString());
+ }
+ return stringValues;
+ }
+
+ public static Map> getExistingUriValues(EditConfigurationVTwo editConfig) {
+ return editConfig.getUrisInScope();
+ }
+
+ //Generate HTML for a specific field name given
+ public static String generateHTMLForElement(VitroRequest vreq, String fieldName, EditConfigurationVTwo editConfig) {
+ String html = "";
+ Configuration fmConfig = FreemarkerConfigurationLoader.getConfig(vreq, vreq.getSession().getServletContext());
+
+ FieldVTwo field = editConfig == null ? null : editConfig.getField(fieldName);
+ MultiValueEditSubmission editSub = new MultiValueEditSubmission(vreq.getParameterMap(), editConfig);
+ if( field != null && field.getEditElement() != null ){
+ html = field.getEditElement().draw(fieldName, editConfig, editSub, fmConfig);
+ }
+ return html;
+ }
+
}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationVTwo.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationVTwo.java
index 4d16514d5..1a70f91b5 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationVTwo.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationVTwo.java
@@ -114,16 +114,18 @@ public class EditConfigurationVTwo {
String formUrl;
String editKey;
- List validators = Collections.emptyList();
+ List validators;
EditN3GeneratorVTwo n3generator;
private List modelChangePreprocessors;
- private List editSubmissionPreprocessors = Collections.emptyList();
+ private List editSubmissionPreprocessors;
private ProhibitedFromSearch prohibitedFromSearch;
+ private HashMap formSpecificData;
+
/** Name of freemarker template to generate form. */
String template;
@@ -879,13 +881,13 @@ public class EditConfigurationVTwo {
this.resourceModelSelector = resourceModelSelector;
}
- public List getValidators() {
+ public List getValidators() {
return validators;
}
- public void addValidator( N3Validator validator){
+ public void addValidator( N3ValidatorVTwo validator){
if( this.validators == null )
- this.validators = new ArrayList();
+ this.validators = new ArrayList();
this.validators.add(validator);
}
@@ -922,4 +924,15 @@ public class EditConfigurationVTwo {
public boolean isDataPropertyUpdate() {
return this.getDatapropKey() != null && this.getDatapropKey().length() > 0;
}
+
+ //This is for specific data for a form that will be set by the generator
+
+ public void setFormSpecificData(HashMap formSpecificData) {
+ this.formSpecificData = formSpecificData;
+ }
+
+ public HashMap getFormSpecificData() {
+ // TODO Auto-generated method stub
+ return this.formSpecificData;
+ }
}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditElementVTwo.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditElementVTwo.java
index 677b0831a..6c035ad9a 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditElementVTwo.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditElementVTwo.java
@@ -39,6 +39,11 @@ public interface EditElementVTwo {
*/
public String draw(String fieldName, EditConfigurationVTwo editConfig, MultiValueEditSubmission editSub, Configuration fmConfig);
+ /**
+ * This method gets the map with the data that can then be passed to the template
+ */
+ public Map getMapForTemplate(EditConfigurationVTwo editConfig, MultiValueEditSubmission editSub);
+
/* in the future, we may need to get existing values */
/*
public Map getExistingLiterals(???)
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/N3ValidatorVTwo.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/N3ValidatorVTwo.java
new file mode 100644
index 000000000..fb0529a0e
--- /dev/null
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/N3ValidatorVTwo.java
@@ -0,0 +1,12 @@
+/* $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.Map;
+
+import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration;
+import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.EditSubmission;
+
+public interface N3ValidatorVTwo {
+ public Map validate(EditConfigurationVTwo editConfig, MultiValueEditSubmission editSub);
+}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/AddClinicalRoleToPersonGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/AddClinicalRoleToPersonGenerator.java
new file mode 100644
index 000000000..1e886f355
--- /dev/null
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/AddClinicalRoleToPersonGenerator.java
@@ -0,0 +1,123 @@
+/* $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 edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.DateTimeWithPrecisionVTwo;
+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.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.edit.n3editing.configuration.validators.DateTimeIntervalValidation;
+/**
+ * Generates the edit configuration for adding a Role to a Person.
+
+ Stage one is selecting the type of the non-person thing
+ associated with the Role with the intention of reducing the
+ number of Individuals that the user has to select from.
+ Stage two is selecting the non-person Individual to associate
+ with the Role.
+
+ This is intended to create a set of statements like:
+
+ ?person core:hasResearchActivityRole ?newRole.
+ ?newRole rdf:type core:ResearchActivityRole ;
+ roleToActivityPredicate ?someActivity .
+ ?someActivity rdf:type core:ResearchActivity .
+ ?someActivity rdfs:label "activity title" .
+
+
+ Each subclass of the abstract two stage Generator class will have the option of overriding certain
+ methods, and must always implement the following methods:
+ getRoleType
+ getRoleActivityTypeOptionsType
+ getRoleActivityTypeObjectClassUri
+ getRoleActivityTypeLiteralOptions
+
+ *
+ */
+public class AddClinicalRoleToPersonGenerator extends AddRoleToPersonTwoStageGenerator {
+
+ private Log log = LogFactory.getLog(AddClinicalRoleToPersonGenerator.class);
+ private static String template = "addClinicalRoleToPerson.ftl";
+
+ //Should this be overridden
+ @Override
+ protected void setTemplate(EditConfigurationVTwo editConfiguration,
+ VitroRequest vreq) {
+ editConfiguration.setTemplate(template);
+ }
+
+
+ //The default activityToRolePredicate and roleToActivityPredicates are
+ //correct for this subclass so they don't need to be overwritten
+
+ //role type will always be set based on particular form
+ public String getRoleType(VitroRequest vreq) {
+ //TODO: Get dynamic way of including vivoweb ontology
+ return "http://vivoweb.org/ontology/core#ClinicalRole";
+ }
+
+ //Each subclass generator will return its own type of option here:
+ //whether literal hardcoded, based on class group, or subclasses of a specific class
+ //The latter two will apparently lend some kind of uri to objectClassUri ?
+ public RoleActivityOptionTypes getRoleActivityTypeOptionsType(VitroRequest vreq) {
+ return RoleActivityOptionTypes.HARDCODED_LITERALS;
+ }
+
+ //This too will depend on the specific subclass of generator
+ public String getRoleActivityTypeObjectClassUri(VitroRequest vreq) {
+ return null;
+ }
+
+
+ //Clinical role involves hard-coded options for the "right side" of the role or activity
+ protected HashMap getRoleActivityTypeLiteralOptions(VitroRequest vreq) {
+ HashMap literalOptions = new HashMap();
+ literalOptions.put("", "Select one");
+ literalOptions.put("http://vivoweb.org/ontology/core#Project", "Project");
+ literalOptions.put("http://vivoweb.org/ontology/core#Service","Service");
+ return literalOptions;
+ }
+
+ //isShowRoleLabelField remains true for this so doesn't need to be overwritten
+
+
+}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/AddRoleToPersonTwoStageGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/AddRoleToPersonTwoStageGenerator.java
new file mode 100644
index 000000000..370411b4a
--- /dev/null
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/AddRoleToPersonTwoStageGenerator.java
@@ -0,0 +1,983 @@
+/* $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 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.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;
+/**
+ * Generates the edit configuration for adding a Role to a Person.
+
+ Stage one is selecting the type of the non-person thing
+ associated with the Role with the intention of reducing the
+ number of Individuals that the user has to select from.
+ Stage two is selecting the non-person Individual to associate
+ with the Role.
+
+ This is intended to create a set of statements like:
+
+ ?person core:hasResearchActivityRole ?newRole.
+ ?newRole rdf:type core:ResearchActivityRole ;
+ roleToActivityPredicate ?someActivity .
+ ?someActivity rdf:type core:ResearchActivity .
+ ?someActivity rdfs:label "activity title" .
+
+
+ Important: This form cannot be directly used as a custom form. It has parameters that must be set.
+ See addClinicalRoleToPerson.jsp for an example.
+
+ *
+ */
+public abstract class AddRoleToPersonTwoStageGenerator implements EditConfigurationGenerator {
+
+ private Log log = LogFactory.getLog(AddRoleToPersonTwoStageGenerator.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 = "addRoleToPersonTwoStage.ftl";
+ private static HashMap defaultsForXSDtypes ;
+
+ //Types of options to populate drop-down for types for the "right side" of the role
+ public static enum RoleActivityOptionTypes {
+ VCLASSGROUP,
+ CHILD_VCLASSES,
+ HARDCODED_LITERALS
+ };
+
+ @Override
+ public EditConfigurationVTwo getEditConfiguration(VitroRequest vreq, HttpSession session) {
+ 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(generateNewResources(vreq));
+ //In scope
+ this.setUrisAndLiteralsInScope(editConfiguration, vreq);
+
+ //on Form
+ this.setUrisAndLiteralsOnForm(editConfiguration, vreq);
+
+ editConfiguration.setFilesOnForm(new ArrayList());
+
+ //Sparql queries
+ this.setSparqlQueries(editConfiguration, vreq);
+
+ //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);
+ //Set edit key
+ setEditKey(editConfiguration, vreq);
+ //Add validator
+ editConfiguration.addValidator(new DateTimeIntervalValidationVTwo("startField","endField") );
+ //Adding additional data, specifically edit mode
+ addFormSpecificData(editConfiguration, vreq);
+ return editConfiguration;
+ }
+
+ private void setEditKey(EditConfigurationVTwo editConfiguration, VitroRequest vreq) {
+ String editKey = EditConfigurationUtils.getEditKey(vreq);
+ editConfiguration.setEditKey(editKey);
+ }
+
+ protected void setTemplate(EditConfigurationVTwo editConfiguration,
+ VitroRequest vreq) {
+ editConfiguration.setTemplate(template);
+
+ }
+
+ //Initialize setup: process parameters
+ //There will be specialized parameters as well, we may include them here or in a
+ //separate method
+ 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.setUrlPatternToReturnTo("/individual");
+
+ editConfiguration.setVarNameForSubject("person");
+ editConfiguration.setSubjectUri(subjectUri);
+ editConfiguration.setEntityToReturnTo(subjectUri);
+ editConfiguration.setVarNameForPredicate("rolePredicate");
+ editConfiguration.setPredicateUri(predicateUri);
+ //by definition, this is an object property
+ this.initObjectParameters(vreq);
+ this.processObjectPropForm(vreq, editConfiguration);
+
+ }
+
+
+
+ private void initObjectParameters(VitroRequest vreq) {
+ //in case of object property
+ objectUri = EditConfigurationUtils.getObjectUri(vreq);
+ }
+
+ private void processObjectPropForm(VitroRequest vreq, EditConfigurationVTwo editConfiguration) {
+ editConfiguration.setVarNameForObject("role");
+ 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);
+ }
+ }
+
+
+ /*
+ * 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 generateN3Required(VitroRequest vreq) {
+ List n3ForEdit = new ArrayList();
+ String editString = getPrefixesString() + " /n";
+ editString += "?person ?rolePredicate ?role .";
+ editString += "?role a <" + getRoleType(vreq) + "> .";
+ editString += "?role <" + getRoleToActivityPredicate(vreq) + "> ?roleActivity .";
+ editString += "?roleActivity <" + getActivityToRolePredicate(vreq) + "> ?role .";
+ n3ForEdit.add(editString);
+ return n3ForEdit;
+ }
+
+
+ private List generateN3Optional() {
+ List n3Optional = new ArrayList();
+ //n3 for activity label
+ n3Optional.add(getN3ForActivityLabel());
+ //n3 for activity type
+ n3Optional.add(getN3ForActivityType());
+ //n3 for inverse
+ n3Optional.add("?role ?inverseRolePredicate ?person .");
+ //N3ForStart
+ n3Optional.addAll(getN3ForStart());
+ //N3 For End
+ n3Optional.addAll(getN3ForEnd());
+ //role label assertion
+ n3Optional.add(getN3RoleLabelAssertion());
+ return n3Optional;
+ }
+
+
+ public String getN3ForActivityLabel() {
+ return "?roleActivity <" + RDFS.label.getURI() + "> ?activityLabel .";
+ }
+
+ public String getN3ForActivityType() {
+ return "?roleActivity a ?roleActivityType .";
+ }
+
+ public String getN3RoleLabelAssertion() {
+ return "?role <" + RDFS.label.getURI() + "> ?roleLabel .";
+ }
+
+ //Method b/c used in two locations, n3 optional and n3 assertions
+ private List getN3ForStart() {
+ List n3ForStart = new ArrayList();
+ n3ForStart.add("?role <" + getRoleToIntervalURI() + "> ?intervalNode ." +
+ "?intervalNode <" + RDF.type.getURI() + "> <" + getIntervalTypeURI() + "> ." +
+ "?intervalNode <" + getIntervalToStartURI() + "> ?startNode ." +
+ "?startNode <" + RDF.type.getURI() + "> <" + getDateTimeValueTypeURI() + "> ." +
+ "?startNode <" + getDateTimeValueURI() + "> ?startField-value ." +
+ "?startNode <" + getDateTimePrecisionURI() + "> ?startField-precision .");
+ return n3ForStart;
+ }
+
+ private List getN3ForEnd() {
+ List n3ForEnd = new ArrayList();
+ n3ForEnd.add("?role <" + getRoleToIntervalURI() + "> ?intervalNode . " +
+ "?intervalNode <" + RDF.type.getURI() + "> <" + getIntervalTypeURI() + "> ." +
+ "?intervalNode <" + getIntervalToEndURI() + "> ?endNode ." +
+ "?endNode <" + RDF.type.getURI() + "> <" + getDateTimeValueTypeURI() + "> ." +
+ "?endNode <" + getDateTimeValueURI() + "> ?endField-value ." +
+ "?endNode <" + getDateTimePrecisionURI() + "> ?endField-precision .");
+ return n3ForEnd;
+
+ }
+
+
+ /*
+ * Get new resources
+ */
+ private Map generateNewResources(VitroRequest vreq) {
+ HashMap newResources = new HashMap();
+ //TODO: Get default namespace
+ String defaultNamespace = vreq.getWebappDaoFactory().getDefaultNamespace();
+ newResources.put("role", defaultNamespace + "individual");
+ newResources.put("roleActivity", defaultNamespace + "individual");
+ newResources.put("intervalNode", defaultNamespace + "individual");
+ newResources.put("startNode", defaultNamespace + "individual");
+ newResources.put("endNode", defaultNamespace + "individual");
+ return newResources;
+ }
+
+
+
+
+ /*
+ * Set URIS and Literals In Scope and on form and supporting methods
+ */
+
+ private void setUrisAndLiteralsInScope(EditConfigurationVTwo editConfiguration, VitroRequest vreq) {
+ HashMap> urisInScope = new HashMap>();
+ //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>());
+ }
+
+ private List getInversePredicate(VitroRequest vreq) {
+ List inversePredicateArray = new ArrayList();
+ 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 urisOnForm = new ArrayList();
+ List literalsOnForm = new ArrayList();
+ //add role activity and roleActivityType to uris on form
+ urisOnForm.add("roleActivity");
+ urisOnForm.add("roleActivityType");
+ editConfiguration.setUrisOnform(urisOnForm);
+ //activity label and role label are literals on form
+ literalsOnForm.add("activityLabel");
+ literalsOnForm.add("roleLabel");
+ 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());
+
+ Map urisInScope = new HashMap();
+ editConfiguration.setSparqlForAdditionalUrisInScope(urisInScope);
+
+ editConfiguration.setSparqlForExistingLiterals(generateSparqlForExistingLiterals(vreq));
+ editConfiguration.setSparqlForExistingUris(generateSparqlForExistingUris(vreq));
+ }
+
+
+ //Get page uri for object
+ private HashMap generateSparqlForExistingUris(VitroRequest vreq) {
+ HashMap map = new HashMap();
+ //Queries for role activity, activity type query, interval node, start node, end node, start field precision, endfield precision
+ map.put("roleActivity", getRoleActivityQuery(vreq));
+ map.put("roleActivityType", getActivityTypeQuery(vreq));
+ map.put("intervalNode", getIntervalNodeQuery(vreq));
+ map.put("startNode", getStartNodeQuery(vreq));
+ map.put("endNode", getEndNodeQuery(vreq));
+ map.put("startField-precision", getStartPrecisionQuery(vreq));
+ map.put("endField-precision", getEndPrecisionQuery(vreq));
+ return map;
+ }
+
+ private String getEndPrecisionQuery(VitroRequest vreq) {
+ String query = "SELECT ?existingEndPrecision WHERE {" +
+ "?role <" + getRoleToIntervalURI() + "> ?intervalNode ." +
+ "?intervalNode <" + VitroVocabulary.RDF_TYPE + "> <" + getIntervalTypeURI() + "> ." +
+ "?intervalNode <" + getIntervalToEndURI() + "> ?endNode ." +
+ "?endNode <" + VitroVocabulary.RDF_TYPE + "> <" + getDateTimeValueTypeURI() + "> . " +
+ "?endNode <" + getDateTimePrecisionURI() + "> ?existingEndPrecision . }";
+ return query;
+ }
+
+ private String getStartPrecisionQuery(VitroRequest vreq) {
+ String query = "SELECT ?existingStartPrecision WHERE {" +
+ "?role <" + getRoleToIntervalURI() + "> ?intervalNode ." +
+ "?intervalNode <" + VitroVocabulary.RDF_TYPE + "> <" + getIntervalTypeURI() + "> ." +
+ "?intervalNode <" + getIntervalToStartURI() + "> ?startNode ." +
+ "?startNode <" + VitroVocabulary.RDF_TYPE + "> <" + getDateTimeValueTypeURI() + "> . " +
+ "?startNode <" + getDateTimePrecisionURI() + "> ?existingStartPrecision . }";
+ return query;
+ }
+
+ private String getEndNodeQuery(VitroRequest vreq) {
+ String query = "SELECT ?existingEndNode WHERE {"+
+ "?role <" + getRoleToIntervalURI() + "> ?intervalNode ."+
+ "?intervalNode <" + VitroVocabulary.RDF_TYPE + "> <" + getIntervalTypeURI() + "> ."+
+ " ?intervalNode <" + getIntervalToEndURI() + "> ?existingEndNode . "+
+ "?existingEndNode <" + VitroVocabulary.RDF_TYPE + "> <" + getDateTimeValueTypeURI() + "> .}";
+ return query;
+ }
+
+ private String getStartNodeQuery(VitroRequest vreq) {
+ String query = "SELECT ?existingStartNode WHERE {"+
+ "?role <" + getRoleToIntervalURI() + "> ?intervalNode ."+
+ "?intervalNode <" + VitroVocabulary.RDF_TYPE + "> <" + getIntervalTypeURI() + "> ."+
+ "?intervalNode <" + getIntervalToStartURI() + "> ?existingStartNode . "+
+ "?existingStartNode <" + VitroVocabulary.RDF_TYPE + "> <" + getDateTimeValueTypeURI() + "> .}";
+ return query;
+ }
+
+ private String getIntervalNodeQuery(VitroRequest vreq) {
+ String query = "SELECT ?existingIntervalNode WHERE { " +
+ "?role <" + getRoleToIntervalURI() + "> ?existingIntervalNode . " +
+ " ?existingIntervalNode <" + VitroVocabulary.RDF_TYPE + "> <" + getIntervalTypeURI() + "> . }";
+ return query;
+ }
+
+
+ /*
+ * The activity type query results must be limited to the values in the activity type select element.
+ * Sometimes the query returns a superclass such as owl:Thing instead.
+ * Make use of vitro:mostSpecificType so that, for example, an individual is both a
+ * core:InvitedTalk and a core:Presentation, core:InvitedTalk is selected.
+ * vitro:mostSpecificType alone may not suffice, since it does not guarantee that the value returned
+ * is in the select list.
+ * We could still have problems if the value from the select list is not a vitro:mostSpecificType,
+ * but that is unlikely.
+ */
+ //This method had some code already setup in the jsp file
+ private String getActivityTypeQuery(VitroRequest vreq) {
+ String activityTypeQuery = null;
+
+ //roleActivityType_optionsType: This gets you whether this is a literal
+ //
+ RoleActivityOptionTypes optionsType = getRoleActivityTypeOptionsType(vreq);
+
+ // Note that this value is overloaded to specify either object class uri or classgroup uri
+ String objectClassUri = getRoleActivityTypeObjectClassUri(vreq);
+
+ if (StringUtils.isNotBlank(objectClassUri)) {
+ log.debug("objectClassUri = " + objectClassUri);
+
+ if (RoleActivityOptionTypes.VCLASSGROUP.equals(optionsType)) {
+ activityTypeQuery = getClassgroupActivityTypeQuery(vreq);
+ activityTypeQuery = QueryUtils.subUriForQueryVar(activityTypeQuery, "classgroup", objectClassUri);
+
+ } else if (RoleActivityOptionTypes.CHILD_VCLASSES.equals(optionsType)) {
+ activityTypeQuery = getSubclassActivityTypeQuery(vreq);
+ activityTypeQuery = QueryUtils.subUriForQueryVar(activityTypeQuery, "objectClassUri", objectClassUri);
+
+ } else {
+ activityTypeQuery = getDefaultActivityTypeQuery(vreq);
+ }
+
+ // Select options are hardcoded
+ } else if (RoleActivityOptionTypes.HARDCODED_LITERALS.equals(optionsType)) {
+
+ //literal options
+ HashMap typeLiteralOptions = getRoleActivityTypeLiteralOptions(vreq);
+ if (typeLiteralOptions.size() > 0) {
+ try {
+ List typeUris = new ArrayList();
+ Set optionUris = typeLiteralOptions.keySet();
+ for(String uri: optionUris) {
+ typeUris.add("(?existingActivityType = <" + uri + ">)");
+ }
+ String typeFilters = "FILTER (" + StringUtils.join(typeUris, "||") + ")";
+ String defaultActivityTypeQuery = getDefaultActivityTypeQuery(vreq);
+ activityTypeQuery = defaultActivityTypeQuery.replaceAll("}$", "") + typeFilters + "}";
+ } catch (Exception e) {
+ activityTypeQuery = getDefaultActivityTypeQuery(vreq);
+ }
+
+ } else {
+ activityTypeQuery = getDefaultActivityTypeQuery(vreq);
+ }
+
+ } else {
+ activityTypeQuery = getDefaultActivityTypeQuery(vreq);
+ }
+
+ String roleToActivityPredicate = getRoleToActivityPredicate(vreq);
+ activityTypeQuery = QueryUtils.subUriForQueryVar(activityTypeQuery, "predicate", roleToActivityPredicate);
+ log.debug("Activity type query: " + activityTypeQuery);
+
+ return activityTypeQuery;
+ }
+
+
+ private String getDefaultActivityTypeQuery(VitroRequest vreq) {
+ String query = "PREFIX core: <" + getVivoCoreNamespace() + ">\n" +
+ "PREFIX vitro: <" + VitroVocabulary.vitroURI + "> \n" +
+ "SELECT ?existingActivityType WHERE { \n" +
+ " ?role ?predicate ?existingActivity . \n" +
+ " ?existingActivity vitro:mostSpecificType ?existingActivityType . \n" +
+ "}";
+ return query;
+ }
+
+ private String getSubclassActivityTypeQuery(VitroRequest vreq) {
+ String query = "PREFIX core: <" + getVivoCoreNamespace() + ">\n" +
+ "PREFIX rdfs: <" + VitroVocabulary.RDFS + ">\n" +
+ "PREFIX vitro: <" + VitroVocabulary.vitroURI + "> \n" +
+ "SELECT ?existingActivityType WHERE {\n" +
+ " ?role ?predicate ?existingActivity . \n" +
+ " ?existingActivity vitro:mostSpecificType ?existingActivityType . \n" +
+ " ?existingActivityType rdfs:subClassOf ?objectClassUri . \n" +
+ "}";
+ return query;
+ }
+
+ private String getClassgroupActivityTypeQuery(VitroRequest vreq) {
+ String query = "PREFIX core: <" + getVivoCoreNamespace() + ">\n" +
+ "PREFIX vitro: <" + VitroVocabulary.vitroURI + "> \n" +
+ "SELECT ?existingActivityType WHERE { \n" +
+ " ?role ?predicate ?existingActivity . \n" +
+ " ?existingActivity vitro:mostSpecificType ?existingActivityType . \n" +
+ " ?existingActivityType vitro:inClassGroup ?classgroup . \n" +
+ "}";
+ return query;
+ }
+
+
+ private String getRoleActivityQuery(VitroRequest vreq) {
+ String query = "PREFIX core: <" + getVivoCoreNamespace() + ">" +
+ "SELECT ?existingActivity WHERE { ?role <" + getRoleToActivityPredicate(vreq) + "> ?existingActivity . }";
+ return query;
+ }
+
+ private HashMap generateSparqlForExistingLiterals(VitroRequest vreq) {
+ HashMap map = new HashMap();
+ //Queries for activity label, role label, start Field value, end Field value
+ map.put("activityLabel", getActivityLabelQuery(vreq));
+ map.put("roleLabel", getRoleLabelQuery(vreq));
+ map.put("startField-value", getExistingStartDateQuery(vreq));
+ map.put("endField-value", getExistingEndDateQuery(vreq));
+ return map;
+ }
+
+
+ private String getExistingEndDateQuery(VitroRequest vreq) {
+ String query = " SELECT ?existingEndDate WHERE {\n" +
+ "?role <" + getRoleToIntervalURI() + "> ?intervalNode .\n" +
+ "?intervalNode <" + VitroVocabulary.RDF_TYPE + "> <" + getIntervalTypeURI() + "> .\n" +
+ "?intervalNode <" + getIntervalToEndURI() + "> ?endNode .\n" +
+ "?endNode <" + VitroVocabulary.RDF_TYPE + "> <" + getDateTimeValueTypeURI() + "> .\n" +
+ "?endNode <" + getDateTimeValueURI() + "> ?existingEndDate . }";
+ return query;
+ }
+
+ private String getExistingStartDateQuery(VitroRequest vreq) {
+ String query = "SELECT ?existingDateStart WHERE {\n" +
+ "?role <" + getRoleToIntervalURI() + "> ?intervalNode .\n" +
+ "?intervalNode <" + VitroVocabulary.RDF_TYPE + "> <" + getIntervalTypeURI() + "> .\n" +
+ "?intervalNode <" + getIntervalToStartURI() + "> ?startNode .\n" +
+ "?startNode <" + VitroVocabulary.RDF_TYPE + "> <" + getDateTimeValueTypeURI() + "> .\n" +
+ "?startNode <" + getDateTimeValueURI() + "> ?existingDateStart . }";
+
+ return query;
+ }
+
+ private String getRoleLabelQuery(VitroRequest vreq) {
+ String query = "SELECT ?existingRoleLabel WHERE { ?role <" + VitroVocabulary.LABEL + "> ?existingRoleLabel . }";
+ return query;
+ }
+
+ private String getActivityLabelQuery(VitroRequest vreq) {
+ String query = "PREFIX core: <" + getVivoCoreNamespace() + "> \n" +
+ "PREFIX rdfs: <" + RDFS.getURI() + "> \n" +
+ "SELECT ?existingTitle WHERE { \n" +
+ "?role <" + getRoleToActivityPredicate(vreq) + "> ?existingActivity . \n" +
+ "?existingActivity rdfs:label ?existingTitle . }";
+ return query;
+ }
+
+ /**
+ *
+ * Set Fields and supporting methods
+ */
+
+ private void setFields(EditConfigurationVTwo editConfiguration, VitroRequest vreq, String predicateUri) {
+ Map fields = new HashMap();
+ //Multiple fields
+ getActivityLabelField(editConfiguration, vreq, fields);
+ getRoleActivityTypeField(editConfiguration, vreq, fields);
+ getRoleActivityField(editConfiguration, vreq, fields);
+ getRoleLabelField(editConfiguration, vreq, fields);
+ getStartField(editConfiguration, vreq, fields);
+ getEndField(editConfiguration, vreq, fields);
+
+ editConfiguration.setFields(fields);
+ }
+
+
+ //Label of "right side" of role, i.e. label for role roleIn Activity
+ private void getActivityLabelField(EditConfigurationVTwo editConfiguration,
+ VitroRequest vreq, Map fields) {
+ String fieldName = "activityLabel";
+ //get range data type uri and range language
+ String stringDatatypeUri = XSD.xstring.toString();
+
+ FieldVTwo field = new FieldVTwo();
+ field.setName(fieldName);
+ field.setNewResource(false);
+ //queryForExisting is not being used anywhere in Field
+
+
+ List validators = new ArrayList();
+ //If add mode or repair, etc. need to add label required validator
+ if(isAddMode(vreq) || isRepairMode(vreq)) {
+ validators.add("nonempty");
+ }
+ validators.add("datatype:" + stringDatatypeUri);
+ field.setValidators(validators);
+
+ //subjectUri and subjectClassUri are not being used in Field
+
+ field.setOptionsType("UNDEFINED");
+ //why isn't predicate uri set for data properties?
+ field.setPredicateUri(null);
+ field.setObjectClassUri(null);
+ field.setRangeDatatypeUri(stringDatatypeUri);
+
+
+ field.setLiteralOptions(new ArrayList>());
+
+ //set assertions
+ List assertions = new ArrayList();
+ assertions.add(getN3ForActivityLabel());
+ field.setAssertions(assertions);
+ fields.put(field.getName(), field);
+ }
+
+ //type of "right side" of role, i.e. type of activity from role roleIn activity
+ private void getRoleActivityTypeField(
+ EditConfigurationVTwo editConfiguration, VitroRequest vreq,
+ Map fields) {
+ String fieldName = "roleActivityType";
+ //get range data type uri and range language
+
+ FieldVTwo field = new FieldVTwo();
+ field.setName(fieldName);
+ field.setNewResource(true);
+ //queryForExisting is not being used anywhere in Field
+
+
+ List validators = new ArrayList();
+ if(isAddMode(vreq) || isRepairMode(vreq)) {
+ validators.add("nonempty");
+ }
+ field.setValidators(validators);
+
+ //subjectUri and subjectClassUri are not being used in Field
+ //TODO: Check if this is correct
+ field.setOptionsType(getRoleActivityTypeOptionsType(vreq).toString());
+ //why isn't predicate uri set for data properties?
+ field.setPredicateUri(null);
+ field.setObjectClassUri(getRoleActivityTypeObjectClassUri(vreq));
+ field.setRangeDatatypeUri(null);
+
+
+ HashMap literalOptionsMap = getRoleActivityTypeLiteralOptions(vreq);
+ List> fieldLiteralOptions = new ArrayList>();
+ Set optionUris = literalOptionsMap.keySet();
+ for(String optionUri: optionUris) {
+ List uriLabelArray = new ArrayList();
+ uriLabelArray.add(optionUri);
+ uriLabelArray.add(literalOptionsMap.get(optionUri));
+ fieldLiteralOptions.add(uriLabelArray);
+ }
+ field.setLiteralOptions(fieldLiteralOptions);
+
+ //set assertions
+ List assertions = new ArrayList();
+ assertions.add(getN3ForActivityType());
+ field.setAssertions(assertions);
+ fields.put(field.getName(), field);
+
+ }
+
+ //Assuming URI for activity for role?
+ private void getRoleActivityField(EditConfigurationVTwo editConfiguration,
+ VitroRequest vreq, Map fields) {
+ String fieldName = "roleActivity";
+ //get range data type uri and range language
+
+ FieldVTwo field = new FieldVTwo();
+ field.setName(fieldName);
+ field.setNewResource(true);
+
+ List validators = new ArrayList();
+ field.setValidators(validators);
+
+ //subjectUri and subjectClassUri are not being used in Field
+
+ field.setOptionsType("UNDEFINED");
+ //why isn't predicate uri set for data properties?
+ field.setPredicateUri(null);
+ field.setObjectClassUri(null);
+ field.setRangeDatatypeUri(null);
+ //empty
+ field.setLiteralOptions(new ArrayList>());
+
+ //set assertions
+ List assertions = new ArrayList();
+ //N3ForRoleToActivity
+ String n3ForRoleToActivity = "@prefix core: <" + getVivoCoreNamespace() + "> ." +
+ "?role <" + getRoleToActivityPredicate(vreq) + "> ?roleActivity ." +
+ "?roleActivity <" + getActivityToRolePredicate(vreq) + "> ?role .";
+ assertions.add(n3ForRoleToActivity);
+ field.setAssertions(assertions);
+ fields.put(field.getName(), field);
+
+ }
+
+ private void getRoleLabelField(EditConfigurationVTwo editConfiguration,
+ VitroRequest vreq, Map fields) {
+ String fieldName = "roleLabel";
+ String stringDatatypeUri = XSD.xstring.toString();
+
+
+ FieldVTwo field = new FieldVTwo();
+ field.setName(fieldName);
+ field.setNewResource(false);
+
+ List validators = new ArrayList();
+ validators.add("datatype:" + stringDatatypeUri);
+ if(isShowRoleLabelField(vreq)) {
+ validators.add("nonempty");
+ }
+ field.setValidators(validators);
+
+ //subjectUri and subjectClassUri are not being used in Field
+
+ field.setOptionsType("UNDEFINED");
+ //why isn't predicate uri set for data properties?
+ field.setPredicateUri(null);
+ field.setObjectClassUri(null);
+ field.setRangeDatatypeUri(stringDatatypeUri);
+ //empty
+ field.setLiteralOptions(new ArrayList>());
+
+ //set assertions
+ List assertions = new ArrayList();
+ assertions.add(getN3RoleLabelAssertion());
+ field.setAssertions(assertions);
+ fields.put(field.getName(), field);
+
+ }
+
+
+
+ private void getStartField(EditConfigurationVTwo editConfiguration,
+ VitroRequest vreq, Map fields) {
+ String fieldName = "startField";
+
+ FieldVTwo field = new FieldVTwo();
+ field.setName(fieldName);
+ field.setNewResource(false);
+
+ List validators = new ArrayList();
+ field.setValidators(validators);
+
+ //subjectUri and subjectClassUri are not being used in Field
+
+ field.setOptionsType("UNDEFINED");
+ //why isn't predicate uri set for data properties?
+ field.setPredicateUri(null);
+ field.setObjectClassUri(null);
+ field.setRangeDatatypeUri(null);
+ //empty
+ field.setLiteralOptions(new ArrayList>());
+
+ //set assertions
+ List assertions = new ArrayList();
+ assertions.addAll(getN3ForStart());
+ field.setAssertions(assertions);
+
+ //This logic was originally after edit configuration object created from json in original jsp
+ field.setEditElement(
+ new DateTimeWithPrecisionVTwo(field,
+ VitroVocabulary.Precision.YEAR.uri(),
+ VitroVocabulary.Precision.NONE.uri()));
+
+ fields.put(field.getName(), field);
+
+ }
+
+ private void getEndField(EditConfigurationVTwo editConfiguration,
+ VitroRequest vreq, Map fields) {
+ String fieldName = "endField";
+
+ FieldVTwo field = new FieldVTwo();
+ field.setName(fieldName);
+ field.setNewResource(false);
+
+ List validators = new ArrayList();
+ field.setValidators(validators);
+
+ //subjectUri and subjectClassUri are not being used in Field
+
+ field.setOptionsType("UNDEFINED");
+ //why isn't predicate uri set for data properties?
+ field.setPredicateUri(null);
+ field.setObjectClassUri(null);
+ field.setRangeDatatypeUri(null);
+ //empty
+ field.setLiteralOptions(new ArrayList>());
+
+ //set assertions
+ List assertions = new ArrayList();
+ assertions.addAll(getN3ForEnd());
+ field.setAssertions(assertions);
+ //Set edit element
+ field.setEditElement(
+ new DateTimeWithPrecisionVTwo(field,
+ VitroVocabulary.Precision.YEAR.uri(),
+ VitroVocabulary.Precision.NONE.uri()));
+
+ fields.put(field.getName(), field);
+
+ }
+
+ /**
+ * Prepare edit configuration for update
+ * @param vreq
+ * @param session
+ * @param editConfiguration
+ */
+
+ private void prepareForUpdate(VitroRequest vreq, HttpSession session, EditConfigurationVTwo editConfiguration) {
+ //Here, retrieve model from
+ Model model = (Model) session.getServletContext().getAttribute("jenaOntModel");
+ //Object property by definition
+ String objectUri = EditConfigurationUtils.getObjectUri(vreq);
+ if(objectUri != null) {
+ //update existing object
+ editConfiguration.prepareForObjPropUpdate(model);
+ } else {
+ //new object to be created
+ editConfiguration.prepareForNonUpdate( model );
+ }
+ }
+
+
+
+
+ /**
+ * Methods that are REQUIRED to be implemented in subclasses
+ **/
+ //role type will always be set based on particular form
+ abstract public String getRoleType(VitroRequest vreq);
+ //In the case of literal options, subclass generator will set the options to be returned
+ abstract protected HashMap getRoleActivityTypeLiteralOptions(VitroRequest vreq);
+ //Each subclass generator will return its own type of option here:
+ //whether literal hardcoded, based on class group, or subclasses of a specific class
+ //The latter two will apparently lend some kind of uri to objectClassUri ?
+ abstract public RoleActivityOptionTypes getRoleActivityTypeOptionsType(VitroRequest vreq);
+ //This too will depend on the specific subclass of generator
+ abstract public String getRoleActivityTypeObjectClassUri(VitroRequest vreq);
+
+ /**
+ * Methods with default values that may be overwritten when required by a subclass
+ * Both Default value and method that can be overwritten are included below
+ **/
+
+ public boolean isShowRoleLabelField(VitroRequest vreq) {
+ return true;
+ }
+
+ public String getActivityToRolePredicate(VitroRequest vreq) {
+ return getDefaultActivityToRolePredicate();
+ }
+
+ //This has a default value, but note that even that will not be used
+ //in the update with realized in or contributes to
+ //Overridden when need be in subclassed generator
+ public String getRoleToActivityPredicate(VitroRequest vreq) {
+ return getDefaultRoleToActivityPredicate();
+ }
+
+ //Some values will have a default value
+ //activityToRolePredicate
+ public String getDefaultActivityToRolePredicate() {
+ return "http://vivoweb.org/ontology/core#relatedRole";
+ }
+
+ //roleToActivityPredicate
+ public String getDefaultRoleToActivityPredicate() {
+ return "http://vivoweb.org/ontology/core#roleIn";
+
+ }
+
+ /**
+ * Methods that check edit mode
+ */
+
+ //Get edit mode
+ private EditMode getEditMode(VitroRequest vreq) {
+ String roleToActivityPredicate = getRoleToActivityPredicate(vreq);
+ EditMode mode = FrontEndEditingUtils.getEditMode(vreq, roleToActivityPredicate);
+ return mode;
+ //(mode == EditMode.ADD || mode == EditMode.REPAIR) ? "\"nonempty\"
+ }
+ private boolean isAddMode(VitroRequest vreq) {
+ EditMode mode = getEditMode(vreq);
+ return (mode == EditMode.ADD);
+ }
+
+ private boolean isEditMode(VitroRequest vreq) {
+ EditMode mode = getEditMode(vreq);
+ return (mode == EditMode.EDIT);
+ }
+
+ private boolean isRepairMode(VitroRequest vreq) {
+ EditMode mode = getEditMode(vreq);
+ return (mode == EditMode.REPAIR);
+ }
+
+
+ /**
+ * Methods to return URIS for various predicates
+ **/
+ public String getVivoCoreNamespace() {
+ return "http://vivoweb.org/ontology/core#";
+ }
+
+ public String getRoleToIntervalURI() {
+ return getVivoCoreNamespace() + "dateTimeInterval";
+ }
+
+ public String getIntervalTypeURI() {
+ return getVivoCoreNamespace() + "DateTimeInterval";
+ }
+
+ public String getIntervalToStartURI() {
+ return getVivoCoreNamespace() + "start";
+ }
+
+ public String getIntervalToEndURI() {
+ return getVivoCoreNamespace() + "end";
+ }
+
+ public String getStartYearPredURI() {
+ return getVivoCoreNamespace() + "startYear";
+ }
+
+ public String getEndYearPredURI() {
+ return getVivoCoreNamespace() + "endYear";
+ }
+
+ public String getDateTimeValueTypeURI() {
+ return getVivoCoreNamespace() + "DateTimeValue";
+ }
+
+ public String getDateTimePrecisionURI() {
+ return getVivoCoreNamespace() + "dateTimePrecision";
+ }
+
+ public String getDateTimeValueURI() {
+ return getVivoCoreNamespace() + "dateTime";
+ }
+
+ //Form specific data
+ public void addFormSpecificData(EditConfigurationVTwo editConfiguration, VitroRequest vreq) {
+ HashMap formSpecificData = new HashMap();
+ formSpecificData.put("editMode", getEditMode(vreq).name());
+ //Fields that will need select lists generated
+ //Store field names
+ List objectSelect = new ArrayList();
+ objectSelect.add("roleActivityType");
+ //TODO: Check if this is the proper way to do this?
+ formSpecificData.put("objectSelect", objectSelect);
+ //Put in the fact that we require field
+ editConfiguration.setFormSpecificData(formSpecificData);
+ }
+
+}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java
index 6ef2ddb61..85657e77b 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java
@@ -141,7 +141,10 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet {
editConfGeneratorName = DEFAULT_DELETE_FORM;
}
// *** handle the case where the form is specified as a request parameter ***
- else if( predicateUri == null && ( formParam != null && !formParam.isEmpty()) ){
+ //TODO: Substitute the original line in again which checks for null predicate, currently overriding
+ //in order to test
+ //else if( predicateUri == null && ( formParam != null && !formParam.isEmpty()) ){
+ else if( 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
@@ -212,7 +215,7 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet {
String subjectUri = EditConfigurationUtils.getSubjectUri(vreq);
String predicateUri = EditConfigurationUtils.getPredicateUri(vreq);
String formParam = getFormParam(vreq);
-
+ //if no form parameter, then predicate uri and subject uri must both be populated
if (formParam == null || "".equals(formParam)) {
if ((predicateUri == null || predicateUri.trim().length() == 0)) {
return true;
@@ -225,7 +228,11 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet {
//Check predicate - if not vitro label and neither data prop nor object prop return error
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
- if(!EditConfigurationUtils.isObjectProperty(predicateUri, vreq)
+ //TODO: Check if any error conditions are not met here
+ //At this point, if there is a form paramter, we don't require a predicate uri
+ if(formParam == null
+ && predicateUri != null
+ && !EditConfigurationUtils.isObjectProperty(predicateUri, vreq)
&& !isVitroLabel(predicateUri)
&& !EditConfigurationUtils.isDataProperty(predicateUri, vreq))
{
@@ -255,7 +262,7 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet {
//should return null
private String getFormParam(VitroRequest vreq) {
- String formParam = (String) vreq.getAttribute("editForm");
+ String formParam = (String) vreq.getParameter("editForm");
return formParam;
}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java
index 2487fb4d3..3eea60a28 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java
@@ -7,9 +7,13 @@ 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.EditConfiguration;
+import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.FieldVTwo;
+import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditElementVTwo;
+
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.utils.FrontEndEditingUtils;
+import edu.cornell.mannlib.vitro.webapp.utils.FrontEndEditingUtils.EditMode;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel;
import java.io.UnsupportedEncodingException;
@@ -22,6 +26,7 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
+import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
@@ -64,29 +69,57 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel {
public String getSubmitToUrl(){
return getUrl( editConfig.getSubmitToUrl() );
}
- //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
+
+ /*
+ * Used to calculate/retrieve/extract additional form-specific data
+ * Such as options for a drop-down etc.
+ */
+
private void retrieveEditData() {
//Get vitro request attributes for
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();
- }*/
-
+ //Get the form specific data
+ HashMap formSpecificData = editConfig.getFormSpecificData();
+ pageData.putAll(formSpecificData);
+ populateDropdowns();
+ //populate html with edit element where appropriate
+ populateGeneratedHtml();
}
+ //Based on certain pre-set fields/variables, look for what
+ //drop-downs need to be populated
+ private void populateDropdowns() {
+ if(EditConfigurationUtils.isObjectProperty(editConfig.getPredicateUri(), vreq)) {
+ setRangeOptions();
+ }
+ if(pageData.containsKey("objectSelect")) {
+ List fieldNames = (List)pageData.get("objectSelect");
+ for(String field:fieldNames) {
+ WebappDaoFactory wdf = vreq.getWebappDaoFactory();
+ Map optionsMap = SelectListGeneratorVTwo.getOptions(editConfig, field , wdf);
+ pageData.put(field, optionsMap);
+ }
+ }
+
+ }
+
+ //TODO: Check if this should return a list instead
+ //Also check if better manipulated/handled within the freemarker form itself
+ private String getSelectedValue(String field) {
+ String selectedValue = null;
+ Map> urisInScope = editConfig.getUrisInScope();
+ if(urisInScope.containsKey(field)) {
+ List values = urisInScope.get(field);
+ //Unsure how to deal with multi-select drop-downs
+ //TODO: Handle multiple select dropdowns
+ selectedValue = StringUtils.join(values, ",");
+ }
+ return selectedValue;
+ }
+
private boolean isRangeOptionsExist() {
boolean rangeOptionsExist = (pageData.get("rangeOptionsExist") != null && (Boolean) pageData.get("rangeOptionsExist") == true);
return rangeOptionsExist;
@@ -189,9 +222,10 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel {
ObjectProperty prop = EditConfigurationUtils.getObjectProperty(vreq);
if( prop.getSelectFromExisting() ){
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
-
-
- Map rangeOptions = SelectListGeneratorVTwo.getOptions(editConfig, "objectVar" , wdf);
+ //TODO: Change this to varname for object from object property?
+ String fieldName = editConfig.getVarNameForObject();
+ //TODO: Check if this still works?
+ Map rangeOptions = SelectListGeneratorVTwo.getOptions(editConfig, fieldName , wdf);
if( rangeOptions != null && rangeOptions.size() > 0 ) {
pageData.put("rangeOptionsExist", true);
pageData.put("rangeOptions", rangeOptions);
@@ -243,6 +277,7 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel {
return literalValues;
}
+
//Check if possible to send in particular parameter
public String dataLiteralValueFor(String dataLiteralName) {
List literalValues = getLiteralStringValue(dataLiteralName);
@@ -567,4 +602,40 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel {
return vitroNsProp;
}
+ //Additional data to be returned
+ public HashMap getPageData() {
+ return pageData;
+ }
+
+ //Literals in scope and uris in scope are the values
+ //that currently exist for any of the fields/values
+
+ //Get literals in scope returned as string values
+ public Map> getExistingLiteralValues() {
+ return EditConfigurationUtils.getExistingLiteralValues(vreq, editConfig);
+ }
+
+ public Map> getExistingUriValues() {
+ return editConfig.getUrisInScope();
+ }
+
+ //Get editElements with html
+ public void populateGeneratedHtml() {
+ Map generatedHtml = new HashMap();
+ Map fieldMap = editConfig.getFields();
+ //Check if any of the fields have edit elements and should be generated
+ Set keySet = fieldMap.keySet();
+ for(String key: keySet) {
+ FieldVTwo field = fieldMap.get(key);
+ EditElementVTwo editElement = field.getEditElement();
+ String fieldName = field.getName();
+ if(editElement != null) {
+ generatedHtml.put(fieldName, EditConfigurationUtils.generateHTMLForElement(vreq, fieldName, editConfig));
+ }
+ }
+
+ //Put in pageData
+ pageData.put("htmlForElements", generatedHtml);
+ }
+
}
diff --git a/webapp/web/templates/freemarker/edit/forms/addClinicalRoleToPerson.ftl b/webapp/web/templates/freemarker/edit/forms/addClinicalRoleToPerson.ftl
new file mode 100644
index 000000000..4cfc12bd8
--- /dev/null
+++ b/webapp/web/templates/freemarker/edit/forms/addClinicalRoleToPerson.ftl
@@ -0,0 +1,7 @@
+<#--Assign property-specific variables here-->
+<#assign roleDescriptor = "clinical activity" />
+<#assign typeSelectorLabel = "clinical activity type" />
+
+<#--Can Also set buttonText for a given form->
+<#--Each of the two stage forms will include the form below-->
+<#include "addRoleToPersonTwoStage.ftl">
\ No newline at end of file
diff --git a/webapp/web/templates/freemarker/edit/forms/addRoleToPersonTwoStage.ftl b/webapp/web/templates/freemarker/edit/forms/addRoleToPersonTwoStage.ftl
new file mode 100644
index 000000000..b18c81263
--- /dev/null
+++ b/webapp/web/templates/freemarker/edit/forms/addRoleToPersonTwoStage.ftl
@@ -0,0 +1,192 @@
+<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
+
+<#--Retrieve certain edit configuration information-->
+<#assign editMode = editConfiguration.pageData.editMode />
+<#assign literalValues = editConfiguration.existingLiteralValues />
+<#assign uriValues = editConfiguration.existingUriValues />
+<#assign htmlForElements = editConfiguration.pageData.htmlForElements />
+
+Edit Mode is ${editMode}
+<#--Freemarker variables with default values that can be overridden by specific forms-->
+
+
+<#--buttonText, typeSelectorLabel, numDateFields, showRoleLabelField, roleExamples-->
+<#if !buttonText?has_content>
+ <#assign buttonText = roleDescriptor />
+#if>
+<#if !typeSelectorLabel?has_content>
+ <#assign typeSelectorLabel = roleDescriptor />
+#if>
+<#if !numDateFields?has_content>
+ <#assign numDateFields = 2 />
+#if>
+<#if !showRoleLabelField?has_content>
+ <#assign showRoleLabelField = true />
+#if>
+<#if !roleExamples?has_content>
+ <#assign roleExamples = "" />
+#if>
+
+<#--Setting values for titleVerb, submitButonText, and disabled Value-->
+<#if editConfiguration.objectUri?has_content>
+ <#assign titleVerb = "Edit"/>
+ <#assign submitButtonText>Edit ${buttonText}#assign>
+ <#if editMode = "repair">
+ <#assign disabledVal = ""/>
+ <#else>
+ <#assign disabledVal = "disabled"/>
+ #if>
+<#else>
+ <#assign titleVerb = "Create"/>
+ <#assign submitButtonText>${buttonText}#assign>
+ <#assign disabledVal = ""/>
+ <#--The original jsp sets editMode to add, why?-->
+#if>
+
+<#--Get existing value for specific data literals and uris-->
+
+
+<#--Get selected activity type value if it exists, this is alternative to below-->
+<#assign activityTypeValue = ""/>
+<#if uriValues?keys?seq_contains("activityType") && uriValues.activityType?size > 0>
+ <#assign activityTypeValue = uriValues.activityType[0] />
+#if>
+
+ <#--Get activity label value-->
+<#assign activityLabelValue = "" />
+<#if literalValues?keys?seq_contains("activityLabel") && literalValues.activityLabel?size > 0>
+ <#assign activityLabelValue = literalValues.activityLabel[0] />
+#if>
+
+<#--Get role label-->
+<#assign roleLabel = "" />
+<#if literalValues?keys?seq_contains("roleLabel") && literalValues.roleLabel?size > 0 >
+ <#assign roleLabel = literalValues.roleLabel[0] />
+#if>
+
+
+ActivityLabel:${activityLabelValue}
+Activity type: ${activityTypeValue}
+
+
${titleVerb} ${roleDescriptor} entry for ${editConfiguration.subjectName}
+
+<#--Display error messages if any-->
+<#if errorNameFieldIsEmpty??>
+ <#assign errorMessage = "Enter a name for the ." />
+#if>
+
+<#if errorRoleFieldIsEmpty??>
+ <#assign errorMessage = "Specify a role for this ." />
+#if>
+
+<#if errorMessage?has_content>
+
+
+
${errorMessage}
+
+#if>
+
+
+
+
+
+
+
* required fields
+
+
+<#--Specifying form-specific script and adding stylesheets and scripts-->
+
+
+
+${stylesheets.add('')}
+${stylesheets.add('')}
+${stylesheets.add('')}
+
+${scripts.add('')}
+${scripts.add('')}
+${scripts.add('')}
+
+
+
\ No newline at end of file