From 696320cd9bc2af0e321caef5ca5412ef970b0ad0 Mon Sep 17 00:00:00 2001 From: tworrall Date: Fri, 24 Feb 2012 17:25:55 +0000 Subject: [PATCH] Js and ftl changes to support multiple autocomplete fields in custom forms. New custom forms for advisees and awards, NIHVIVO-488, 489, 534, 540. Also NIHVIVO-2596 and 1922 included. --- .../edit/forms/addGrantRoleToPerson.ftl | 21 +- .../edit/forms/addPublicationToPerson.ftl | 26 +- .../edit/forms/addRoleToPersonTwoStage.ftl | 61 +-- .../edit/forms/addUserDefinedConcept.ftl | 15 +- .../edit/forms/autoCompleteObjectPropForm.ftl | 48 +-- .../forms/css/customFormWithAutocomplete.css | 3 + .../forms/js/advisingRelationshipUtils.js | 69 ++++ .../edit/forms/js/awardReceiptUtils.js | 47 +++ .../forms/js/customFormWithAutocomplete.js | 379 +++++++++--------- .../forms/organizationHasPositionHistory.ftl | 23 +- .../forms/personHasAdvisingRelationship.ftl | 212 ++++++++++ .../edit/forms/personHasAwardOrHonor.ftl | 181 +++++++++ .../forms/personHasEducationalTraining.ftl | 56 +-- .../edit/forms/personHasPositionHistory.ftl | 30 +- .../freemarker/lib/lib-vivo-form.ftl | 4 +- .../n3editing/PersonHasAdviseesValidator.java | 95 +++++ ...ersonHasAdvisingRelationshipGenerator.java | 367 +++++++++++++++++ .../PersonHasAwardOrHonorGenerator.java | 332 +++++++++++++++ 18 files changed, 1645 insertions(+), 324 deletions(-) create mode 100644 productMods/templates/freemarker/edit/forms/js/advisingRelationshipUtils.js create mode 100644 productMods/templates/freemarker/edit/forms/js/awardReceiptUtils.js create mode 100644 productMods/templates/freemarker/edit/forms/personHasAdvisingRelationship.ftl create mode 100644 productMods/templates/freemarker/edit/forms/personHasAwardOrHonor.ftl create mode 100644 src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/PersonHasAdviseesValidator.java create mode 100644 src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/PersonHasAdvisingRelationshipGenerator.java create mode 100644 src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/PersonHasAwardOrHonorGenerator.java diff --git a/productMods/templates/freemarker/edit/forms/addGrantRoleToPerson.ftl b/productMods/templates/freemarker/edit/forms/addGrantRoleToPerson.ftl index 5587565c..dd34288d 100644 --- a/productMods/templates/freemarker/edit/forms/addGrantRoleToPerson.ftl +++ b/productMods/templates/freemarker/edit/forms/addGrantRoleToPerson.ftl @@ -23,17 +23,16 @@ <#assign submitButtonLabel = "Investigator" /> <#if editConfiguration.predicateUri?ends_with("hasPrincipalInvestigatorRole") > <#assign formHeading = "principal investigator entry for "/> - <#assign submitButtonLabel = "Principal Investigator" /> <#elseif editConfiguration.predicateUri?ends_with("hasCo-PrincipalInvestigatorRole") > <#assign formHeading = "co-principal investigator entry for "/> - <#assign submitButtonLabel = "Co-Principal Investigator" /> <#if editMode = "add"> <#assign formHeading> Create ${formHeading} + <#assign submitButtonLabel>Create Entry <#else> <#assign formHeading> Edit ${formHeading} - <#assign submitButtonLabel> Edit ${submitButtonLabel} + <#assign submitButtonLabel>Save Changes @@ -100,15 +99,11 @@

- - + +

- <#if editMode = "edit"> - - - - <@lvf.acSelection urls.base "grant" "grant" existingGrantValue "Selected Grant"/> + <@lvf.acSelection urls.base "grant" "grant" "grant" existingGrantValue "Selected Grant"/>

Years of Participation in Grant

<#if htmlForElements?keys?seq_contains("startField")> @@ -139,10 +134,10 @@ var customFormData = { sparqlForAcFilter: '${sparqlForAcFilter}', sparqlQueryUrl: '${urls.base}${sparqlQueryUrl}', acUrl: '${urls.base}${acUrl}', - acType: 'http://vivoweb.org/ontology/core#Grant', + acTypes: {grant: 'http://vivoweb.org/ontology/core#Grant'}, editMode: '${editMode}', - submitButtonTextType: 'compound', - typeName: 'Grant' + typeName: 'Grant', + baseHref: '${urls.base}/individual?uri=' }; ${stylesheets.add('')} diff --git a/productMods/templates/freemarker/edit/forms/addPublicationToPerson.ftl b/productMods/templates/freemarker/edit/forms/addPublicationToPerson.ftl index d02340e7..ca01b8a3 100644 --- a/productMods/templates/freemarker/edit/forms/addPublicationToPerson.ftl +++ b/productMods/templates/freemarker/edit/forms/addPublicationToPerson.ftl @@ -6,6 +6,8 @@ <#--Retrieve certain edit configuration information--> <#assign editMode = editConfiguration.pageData.editMode /> + + <#assign sparqlForAcFilter = editConfiguration.pageData.sparqlForAcFilter /> <#--assign htmlForElements = editConfiguration.pageData.htmlForElements ! {}/--> @@ -20,13 +22,15 @@ <#--In case of submission error, may already have publication type or title - although latter not likely, but storing values to be on safe side--> <#assign publicationTypeValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "pubType") /> <#assign titleValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "title") /> +<#assign pubUriValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "pubUri") /> + <#if editMode == "edit"> <#assign titleVerb="Edit"> - <#assign submitButtonText="Edit Publication"> + <#assign submitButtonText="Save Changes"> <#assign disabledVal="disabled"> <#else> <#assign titleVerb="Create"> - <#assign submitButtonText="Publication"> + <#assign submitButtonText="Create Entry"> <#assign disabledVal=""/> @@ -60,8 +64,8 @@ <#--TODO: Check if possible to have existing publication options here in order to select--> -

- <#list pubTypeLiteralOptions?keys as key> @@ -71,17 +75,17 @@

- 0)>disabled="${disabledVal}" value="" /> +

-
+

- (Verify this match) + (Verify this match or + change selection)

- +
@@ -101,9 +105,9 @@ sparqlForAcFilter: '${sparqlForAcFilter}', sparqlQueryUrl: '${sparqlQueryUrl}', acUrl: '${urls.base}/autocomplete?tokenize=true', - submitButtonTextType: 'simple', editMode: '${editMode}', - defaultTypeName: 'publication' // used in repair mode to generate button text + defaultTypeName: 'publication', // used in repair mode to generate button text + baseHref: '${urls.base}/individual?uri=' }; diff --git a/productMods/templates/freemarker/edit/forms/addRoleToPersonTwoStage.ftl b/productMods/templates/freemarker/edit/forms/addRoleToPersonTwoStage.ftl index ada5a3ba..cf78dd45 100644 --- a/productMods/templates/freemarker/edit/forms/addRoleToPersonTwoStage.ftl +++ b/productMods/templates/freemarker/edit/forms/addRoleToPersonTwoStage.ftl @@ -14,10 +14,8 @@ <#--Freemarker variables with default values that can be overridden by specific forms--> -<#--buttonText, typeSelectorLabel, numDateFields, roleExamples--> -<#if !buttonText?has_content> - <#assign buttonText = roleDescriptor /> - +<#-- typeSelectorLabel, numDateFields, roleExamples--> + <#if !typeSelectorLabel?has_content> <#assign typeSelectorLabel = roleDescriptor /> @@ -32,7 +30,7 @@ <#--Setting values for titleVerb, submitButonText, and disabled Value--> <#if editConfiguration.objectUri?has_content> <#assign titleVerb = "Edit"/> - <#assign submitButtonText>Edit ${buttonText?capitalize} + <#assign submitButtonText>Save Changes <#if editMode = "repair"> <#assign disabledVal = ""/> <#else> @@ -40,7 +38,7 @@ <#else> <#assign titleVerb = "Create"/> - <#assign submitButtonText>${buttonText?capitalize} + <#assign submitButtonText>Create Entry <#assign disabledVal = ""/> <#assign editMode = "add" /> @@ -110,45 +108,48 @@ -

- + + + <#else> + +

- - - disabled=${disabledVal} - - /> + +

- +<#-- <#if editMode = "edit"> - <@lvf.acSelection urls.base "roleActivity" "roleActivityUri" existingRoleActivityValue /> +--> + <@lvf.acSelection urls.base "roleActivity" "roleActivityUri" "activity" existingRoleActivityValue /> <#if showRoleLabelField = true>

@@ -189,8 +190,8 @@ var customFormData = { acUrl: '${urls.base}/autocomplete?tokenize=true', editMode: '${editMode}', - submitButtonTextType: 'compound', - defaultTypeName: 'activity' // used in repair mode, to generate button text and org name field label + defaultTypeName: 'activity', // used in repair mode, to generate button text and org name field label + baseHref: '${urls.base}/individual?uri=' }; diff --git a/productMods/templates/freemarker/edit/forms/addUserDefinedConcept.ftl b/productMods/templates/freemarker/edit/forms/addUserDefinedConcept.ftl index 9324313f..acdca2b3 100644 --- a/productMods/templates/freemarker/edit/forms/addUserDefinedConcept.ftl +++ b/productMods/templates/freemarker/edit/forms/addUserDefinedConcept.ftl @@ -16,14 +16,15 @@ <#--Autocomplete for looking up existing skos concepts -->

- +

-
+ @@ -34,7 +35,7 @@

- or Return to Manage Concepts + or Return to Manage Concepts

* required fields

@@ -48,11 +49,11 @@ sparqlForAcFilter: '${sparqlForAcFilter}', sparqlQueryUrl: '${sparqlQueryUrl}', acUrl: '${urls.base}/autocomplete?tokenize=true', - acType: 'http://www.w3.org/2004/02/skos/core#Concept', - submitButtonTextType: 'simple', + acTypes: {concept: 'http://www.w3.org/2004/02/skos/core#Concept'}, editMode: 'add', typeName: 'Concept', - defaultTypeName: 'concept' // used in repair mode to generate button text + defaultTypeName: 'concept', // used in repair mode to generate button text + baseHref: '${urls.base}/individual?uri=' }; diff --git a/productMods/templates/freemarker/edit/forms/autoCompleteObjectPropForm.ftl b/productMods/templates/freemarker/edit/forms/autoCompleteObjectPropForm.ftl index 48277cf4..23a232d2 100644 --- a/productMods/templates/freemarker/edit/forms/autoCompleteObjectPropForm.ftl +++ b/productMods/templates/freemarker/edit/forms/autoCompleteObjectPropForm.ftl @@ -26,10 +26,12 @@ <#assign titleVerb = "Edit" /> <#assign objectLabel = editConfiguration.pageData.objectLabel /> <#assign selectedObjectUri = editConfiguration.objectUri /> + <#assign submitButtonText = "Save Change" /> <#else> <#assign titleVerb = "Add" > <#assign objectLabel = "" /> - <#assign selectedObjectUri = ""/> + <#assign selectedObjectUri = ""/> + <#assign submitButtonText = "Create Entry" /> <#if editConfiguration.formTitle?contains("collaborator") > @@ -52,27 +54,24 @@ <#---This section should become autocomplete instead-->

- - -

+ + +

-
-

- - - (Verify this match) - (Change selection) -

-
+
+

+ + + (Verify this match or + change selection) +

+ +
- <#--The above section should be autocomplete--> -

- + or Cancel @@ -106,22 +105,25 @@ Also multiple types parameter set to true only if more than one type returned--> var customFormData = { acUrl: '${urls.base}/autocomplete?tokenize=true', <#if objectTypesExist = true> - acType: '${objectTypes}', + acTypes: {object: '${objectTypes}'}, <#if multipleTypes = true> - acMultipleTypes: 'true', + acMultipleTypes: 'true', - submitButtonTextType: 'simple', editMode: '${editMode}', typeName:'${propertyNameForDisplay}', - supportEdit: 'true', + acSelectOnly: 'true', sparqlForAcFilter: '${sparqlForAcFilter}', sparqlQueryUrl: '${sparqlQueryUrl}', acFilterForIndividuals: ${acFilterForIndividuals}, - defaultTypeName: '${propertyNameForDisplay}' // used in repair mode to generate button text + defaultTypeName: '${propertyNameForDisplay}', // used in repair mode to generate button text + baseHref: '${urls.base}/individual?uri=' }; - +<#-- + edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.AutocompleteObjectPropertyFormGenerator + edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.AddAttendeeRoleToPersonGenerator +--> ${stylesheets.add('')} ${stylesheets.add('')} diff --git a/productMods/templates/freemarker/edit/forms/css/customFormWithAutocomplete.css b/productMods/templates/freemarker/edit/forms/css/customFormWithAutocomplete.css index 7c66f21b..742fb8a7 100644 --- a/productMods/templates/freemarker/edit/forms/css/customFormWithAutocomplete.css +++ b/productMods/templates/freemarker/edit/forms/css/customFormWithAutocomplete.css @@ -31,3 +31,6 @@ form.customForm h4 { .disabledSubmit { cursor: default ! important; } +span.readOnly { + color: #000; +} diff --git a/productMods/templates/freemarker/edit/forms/js/advisingRelationshipUtils.js b/productMods/templates/freemarker/edit/forms/js/advisingRelationshipUtils.js new file mode 100644 index 00000000..1ac33f34 --- /dev/null +++ b/productMods/templates/freemarker/edit/forms/js/advisingRelationshipUtils.js @@ -0,0 +1,69 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +var advisingRelUtils = { + + onLoad: function(subject) { + if ( subject ) { subjName = subject; } + + this.initObjectReferences(); + this.bindEventListeners(); + }, + + initObjectReferences: function() { + + this.form = $('#personHasAdvisingRelationship'); + this.label = $('#advisingRelLabel'); + this.advisee = $('#advisee'); + this.subjArea = $('#SubjectArea'); + this.firstName = $('#firstName'); + this.lastName = $('#lastName'); + this.adviseeUri = $('#adviseeUri'); + + }, + + bindEventListeners: function() { + this.idCache = {}; + + this.form.submit(function() { + advisingRelUtils.resolveAdviseeNames(); + advisingRelUtils.buildAdvisingRelLabel(); + }); + }, + + resolveAdviseeNames: function() { + var firstName, + lastName, + name; + + // If selecting an existing person, don't submit name fields + if (this.adviseeUri.val() != '') { + this.firstName.attr('disabled', 'disabled'); + this.lastName.attr('disabled', 'disabled'); + } + else { + firstName = this.firstName.val(); + lastName = this.advisee.val(); + + name = lastName; + if (firstName) { + name += ', ' + firstName; + } + this.advisee.val(name); + this.lastName.val(lastName); + + } + + }, + buildAdvisingRelLabel: function() { + if ( this.advisee.val().substring(0, 18) != "Select an existing") { + this.label.val(subjName + " advising " + this.advisee.val()); + } + else if ( this.subjArea.val().substring(0, 18) != "Select an existing" ) { + this.label.val(subjName + " advising in " + this.subjArea.val()); + } + else { + this.label.val(subjName + " advising relationship"); + } + } + +} diff --git a/productMods/templates/freemarker/edit/forms/js/awardReceiptUtils.js b/productMods/templates/freemarker/edit/forms/js/awardReceiptUtils.js new file mode 100644 index 00000000..64720c1a --- /dev/null +++ b/productMods/templates/freemarker/edit/forms/js/awardReceiptUtils.js @@ -0,0 +1,47 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + + +var awardReceiptUtils = { + + onLoad: function(mode) { + this.initObjectReferences(); + this.bindEventListeners(); + // in edit mode, copy the year awarded to the displayed input element + if ( mode == "edit" ) { + this.displayedYear.val(this.yearAwarded.val()); + } + }, + + initObjectReferences: function() { + + this.form = $('#personHasAwardOrHonor'); + this.recLabel = $('#awardReceiptLabel'); + this.award = $('#award'); + this.yearAwarded = $('#yearAwarded-year'); + this.displayedYear = $('#yearAwardedDisplay'); + + }, + + bindEventListeners: function() { + this.idCache = {}; + + this.form.submit(function() { + awardReceiptUtils.setYearAwardedLabel(); + awardReceiptUtils.buildAwardReceiptLabel(); + }); + + }, + + buildAwardReceiptLabel: function() { + var rdfsLabel = this.award.val(); + if ( this.yearAwarded.val().length ) { + rdfsLabel += " (" + this.yearAwarded.val() + ")"; + } + this.recLabel.val(rdfsLabel); + }, + + setYearAwardedLabel: function() { + this.yearAwarded.val(this.displayedYear.val()); + } + +} \ No newline at end of file diff --git a/productMods/templates/freemarker/edit/forms/js/customFormWithAutocomplete.js b/productMods/templates/freemarker/edit/forms/js/customFormWithAutocomplete.js index a025e838..9b84c994 100644 --- a/productMods/templates/freemarker/edit/forms/js/customFormWithAutocomplete.js +++ b/productMods/templates/freemarker/edit/forms/js/customFormWithAutocomplete.js @@ -44,21 +44,45 @@ var customForm = { this.fullViewOnly = $('.fullViewOnly'); this.button = $('#submit'); this.requiredLegend = $('#requiredLegend'); - this.typeSelector = this.form.find('#typeSelector'); - - // These are classed rather than id'd in case we want more than one autocomplete on a form. - // At that point we'll use ids to match them up with one another. - this.acSelector = this.form.find('.acSelector'); - this.acSelection = this.form.find('.acSelection'); - this.acSelectionInfo = this.form.find('.acSelectionInfo'); - this.acUriReceiver = this.form.find('.acUriReceiver'); - //this.acLabelReceiver = this.form.find('.acLabelReceiver'); - this.verifyMatch = this.form.find('.verifyMatch'); - this.acSelectorWrapper = this.acSelector.parent(); - + this.typeSelector = this.form.find('select#typeSelector'); + this.typeSelectorInput = this.form.find('input#typeSelectorInput'); + this.typeSelectorSpan = this.form.find('span#typeSelectorSpan'); this.or = $('span.or'); this.cancel = this.form.find('.cancel'); - this.acHelpTextClass = 'acSelectorWithHelpText'; + this.acHelpTextClass = 'acSelectorWithHelpText'; + // this.verifyMatch is referenced in bindEventListeners to size and open + // the verify popup window. Although there could be multiple verifyMatch objects + // selecting one and binding the event works for all of them + this.verifyMatch = this.form.find('.verifyMatch'); + + // find all the acSelector input elements + this.acSelectors = [] ; + + this.form.find('.acSelector').each(function() { + customForm.acSelectors.push($(this)); + }); + + // find all the acSelection div elements + this.acSelections = new Object(); + + this.form.find('.acSelection').each(function() { + var groupName = $(this).attr('acGroupName'); + customForm.acSelections[groupName] = $(this); + }); + + // 2-stage forms with only one ac field will not have the acTypes defined + // so create an object for when the user selects a type via the typeSelector + if ( this.acTypes == undefined || this.acTypes == null ) { + this.acTypes = new Object(); + } + + // forms with multi ac fields will have this defined in customFormData + // this is helpful when the type to display is not a single word, like "Subject Area" + this.hasMultipleTypeNames = false; + if ( this.multipleTypeNames != undefined || this.multipleTypeNames != null ) { + this.hasMultipleTypeNames = true; + } + }, // Set up the form on page load @@ -78,18 +102,12 @@ var customForm = { } } - //Handles special case such as autocomplete which allows for editing with autocomplete - //By default set to false - if(!this.supportEdit) { - this.supportEdit = false; - } else { - this.supportEdit = true; - } - this.bindEventListeners(); - this.initAutocomplete(); - + $.each(this.acSelectors, function() { + customForm.initAutocomplete($(this)); + }); + this.initElementData(); this.initFormView(); @@ -99,17 +117,18 @@ var customForm = { initFormView: function() { var typeVal = this.typeSelector.val(); - + // Put this case first, because in edit mode with // validation errors we just want initFormFullView. - if ((!this.supportEdit) && (this.editMode == 'edit' || this.editMode == 'repair')) { +// if ((!this.supportEdit) && (this.editMode == 'edit' || this.editMode == 'repair')) { + if (this.editMode == 'edit' || this.editMode == 'repair') { + this.initFormWithValidationErrors(); this.initFormFullView(); } else if (this.findValidationErrors()) { this.initFormWithValidationErrors(); - } else if(this.supportEdit) { - this.initFormWithSupportEdit(); } + // If type is already selected when the page loads (Firefox retains value // on a refresh), go directly to full view. Otherwise user has to reselect // twice to get to full view. @@ -126,24 +145,25 @@ var customForm = { this.setType(); // empty any previous values (perhaps not needed) this.hideFields(this.fullViewOnly); this.button.hide(); - this.requiredLegend.hide(); this.or.hide(); + this.requiredLegend.hide(); this.cancel.unbind('click'); }, initFormFullView: function() { - this.setType(); + this.setType(); this.fullViewOnly.show(); this.or.show(); this.requiredLegend.show(); this.button.show(); - this.setButtonText('new'); this.setLabels(); - // Set the initial autocomplete help text in the acSelector field. - this.addAcHelpText(); + // Set the initial autocomplete help text in the acSelector fields. + $.each(this.acSelectors, function() { + customForm.addAcHelpText($(this)); + }); this.cancel.unbind('click'); if (this.formSteps > 1) { @@ -157,36 +177,29 @@ var customForm = { // autocomplete type can be determined. If a type selection has been made, // unhide the acSelector field. } else if (this.typeSelector.length) { - this.typeSelector.val() ? this.acSelectorWrapper.show() : this.hideFields(this.acSelectorWrapper); + this.typeSelector.val() ? this.fullViewOnly.show() : this.hideFields(this.fullViewOnly); + } + if ( this.acSelectOnly ) { + this.disableSubmit(); } - }, initFormWithValidationErrors: function() { - var uri = this.acUriReceiver.val(), - label = this.acSelector.val(); - // Call initFormFullView first, because showAutocompleteSelection needs // acType, which is set in initFormFullView. this.initFormFullView(); - - if (uri) { - this.showAutocompleteSelection(label, uri); - } - + + $.each(this.acSelectors, function() { + var $acSelection = customForm.acSelections[$(this).attr('acGroupName')]; + var uri = $acSelection.find('input.acUriReceiver').val(), + label = $(this).val(); + if (uri) { + customForm.showAutocompleteSelection(label, uri, $(this)); + } + }); + }, - initFormWithSupportEdit: function() { - if(this.editMode == 'edit') { - this.initFormWithValidationErrors(); - //Hide verify match when edit mode - this.verifyMatch.hide(); - } else { - this.initFormFullView(); - } - //Disable submit button until selection made - this.disableSubmit(); // tlw - }, - + // Bind event listeners that persist over the life of the page. Event listeners // that depend on the view should be initialized in the view setup method. bindEventListeners: function() { @@ -195,7 +208,12 @@ var customForm = { var typeVal = $(this).val(); // If an autocomplete selection has been made, undo it. - customForm.undoAutocompleteSelection(); + // NEED TO LINK THE TYPE SELECTOR TO THE ACSELECTOR IT'S ASSOCIATED WITH + // BECAUSE THERE COULD BE MORE THAN ON AC FIELD. ASSOCIATION IS MADE BY + // SHARING THE SAME ID -- "typeSelector" -- AMONG THE SELECT AND THE INPUT + // AND THE AC SELECTION DIV + // DO WE NEED AN IF STATEMENT AROUND THIS **** + customForm.undoAutocompleteSelection($(this)); // Reinitialize view. If no type selection in a two-step form, go back to type view; // otherwise, reinitialize full view. @@ -204,8 +222,6 @@ var customForm = { } else { customForm.initFormFullView(); - // TW Setting focus here was clearing autocomplete help text, so commented it out - // customForm.acSelector.focus(); } }); @@ -214,33 +230,30 @@ var customForm = { return false; }); - this.acSelector.focus(function() { - customForm.deleteAcHelpText(); - }); - - this.acSelector.blur(function() { - customForm.addAcHelpText(); - }); + // loop through all the acSelectors + $.each(this.acSelectors, function() { + $(this).focus(function() { + customForm.deleteAcHelpText($(this)); + }); + $(this).blur(function() { + customForm.addAcHelpText($(this)); + }); + }); this.form.submit(function() { customForm.deleteAcHelpText(); }); - }, - initAutocomplete: function() { + initAutocomplete: function(selectedObj) { - if (this.editMode === 'edit' && !this.supportEdit) { - return; - } - this.getAcFilter(); //If specific individuals are to be filtered out, add them here //to the filtering list this.getAcFilterForIndividuals(); this.acCache = {}; - - this.acSelector.autocomplete({ + + $(selectedObj).autocomplete({ minLength: 3, source: function(request, response) { if (request.term in customForm.acCache) { @@ -249,13 +262,12 @@ var customForm = { return; } // console.log('not getting term from cache'); - $.ajax({ url: customForm.acUrl, dataType: 'json', data: { term: request.term, - type: customForm.acType, + type: customForm.acTypes[$(selectedObj).attr('acGroupName')], multipleTypes:(customForm.acMultipleTypes == undefined || customForm.acMultipleTypes == null)? null: customForm.acMultipleTypes }, complete: function(xhr, status) { @@ -268,7 +280,7 @@ var customForm = { }); }, select: function(event, ui) { - customForm.showAutocompleteSelection(ui.item.label, ui.item.uri); + customForm.showAutocompleteSelection(ui.item.label, ui.item.uri, $(selectedObj)); } }); }, @@ -288,8 +300,7 @@ var customForm = { }); this.button.data('baseText', this.button.val()); - - this.verifyMatch.data('baseHref', this.verifyMatch.attr('href')); + }, //get autocomplete filter with sparql query getAcFilter: function() { @@ -369,88 +380,102 @@ var customForm = { this.acCache = {}; }, - showAutocompleteSelection: function(label, uri) { + showAutocompleteSelection: function(label, uri, selectedObj) { + // hide the acSelector field and set it's value to the selected ac item + this.hideFields($(selectedObj).parent()); + $(selectedObj).val(label); - this.hideFields(this.acSelectorWrapper); - - // If form has a type selector, add type name to label. If form has no type selector, - // type name is coded into the html. + var $acDiv = this.acSelections[$(selectedObj).attr('acGroupName')]; + + // If the form has a type selector, add type name to label in add mode. In edit mode, use typeSelectorSpan + // html. The second case is an "else if" and not an else because the template may not be passing the label + // to the acSelection macro or it may not be using the macro at all and the label is hard-coded in the html. if (this.typeSelector.length) { - this.acSelection.find('label').html('Selected ' + this.typeName + ':'); + $acDiv.find('label').html('Selected ' + this.typeName + ':'); } - - this.acSelection.show(); + else if ( this.typeSelectorSpan.html() ) { + $acDiv.find('label').html('Selected ' + this.typeSelectorSpan.html() + ':'); + } + + $acDiv.show(); + $acDiv.find("input").val(uri); + $acDiv.find("span").html(label); + $acDiv.find("a.verifyMatch").attr('href', this.baseHref + uri); - this.acUriReceiver.val(uri); - this.acSelector.val(label); - this.acSelectionInfo.html(label); - this.verifyMatch.attr('href', this.verifyMatch.data('baseHref') + uri); - //Verify match is hidden in edit mode and support edit so unhide it - if(this.editMode == 'edit' && this.supportEdit) { - this.verifyMatch.show(); - } - if(this.supportEdit) { - //On initialization in this mode, submit button is disabled - this.enableSubmit(); // tlw - } - this.setButtonText('existing'); - - this.cancel.unbind('click'); - this.cancel.click(function() { - customForm.undoAutocompleteSelection(); - customForm.initFormFullView(); - return false; + $changeLink = $acDiv.find('a.changeSelection'); + $changeLink.unbind('click'); + $changeLink.click(function() { + customForm.undoAutocompleteSelection($acDiv); }); + + if ( this.acSelectOnly ) { + //On initialization in this mode, submit button is disabled + this.enableSubmit(); + } + }, - // Cancel action after making an autocomplete selection: undo autocomplete - // selection (from showAutocomplete) before returning to full view. - undoAutocompleteSelection: function() { - + undoAutocompleteSelection: function(selectedObj) { // The test is not just for efficiency: undoAutocompleteSelection empties the acSelector value, // which we don't want to do if user has manually entered a value, since he may intend to // change the type but keep the value. If no new value has been selected, form initialization // below will correctly empty the value anyway. - if (!this.acSelection.is(':hidden')) { - this.acSelectorWrapper.show(); - this.hideFields(this.acSelection); - this.acSelector.val(''); - this.acUriReceiver.val(''); - this.acSelectionInfo.html(''); - this.verifyMatch.attr('href', this.verifyMatch.data('baseHref')); - - if (this.formSteps > 1) { - this.acSelection.find('label').html('Selected '); - } + + // Check to see if the parameter is the typeSelector. If it is, we need to get the acSelection div + // that is associated with it. + var $acSelectionObj = null; + if ( $(selectedObj).attr('id') == "typeSelector" ) { + $acSelectionObj = customForm.acSelections[$(selectedObj).attr('acGroupName')]; + } + else { + $acSelectionObj = $(selectedObj); + } + if ( !$acSelectionObj.is(':hidden') ) { + var $acSelector = null; + $.each(this.acSelectors, function() { + if ( $(this).attr('acGroupName') == $acSelectionObj.attr('acGroupName') ) { + $acSelector = $(this); + } + }); + $acSelector.parent("p").show(); + this.hideFields($acSelectionObj); + $acSelectionObj.find("input.acUriReceiver").val(''); + $acSelectionObj.find("span").text(''); + $acSelectionObj.find("a.verifyMatch").attr('href', this.baseHref); + $acSelector.val(''); + customForm.addAcHelpText($acSelector); //Resetting so disable submit button again for object property autocomplete - if(this.supportEdit) { + if ( this.acSelectOnly ) { this.disableSubmit(); } - - } + } }, // Set type uri for autocomplete, and type name for labels and button text. // Note: we still need this in edit mode, to set the text values. setType: function() { - var selectedType; // If there's no type selector, these values have been specified in customFormData, // and will not change over the life of the form. if (!this.typeSelector.length) { + if ( this.editMode == 'edit' && (this.typeSelectorSpan.html() != null && this.typeSelectorInput.val() != null) ) { + this.typeName = this.typeSelectorSpan.html(); + this.acTypes[this.typeSelectorInput.attr('acGroupName')] = this.typeSelectorInput.val(); + } return; } - selectedType = this.typeSelector.find(':selected'); - if (selectedType.length) { - this.acType = selectedType.val(); + selectedType = this.typeSelector.find(':selected'); + var acTypeKey = this.typeSelector.attr('acGroupName'); + if (selectedType.val().length) { + this.acTypes[acTypeKey] = selectedType.val(); this.typeName = selectedType.html(); } // reset to empty values; may not need else { - this.acType = ''; + delete this.acTypes[acTypeKey]; this.typeName = ''; } }, @@ -467,80 +492,58 @@ var customForm = { }, - // Set button text based on both type selection and whether it's an autocomplete selection - // or a new related individual. Called when setting up full view of form, and after - // an autocomplete selection. - setButtonText: function(newOrExisting) { - var typeText, - buttonText, - baseButtonText = this.button.data('baseText'); - - // Edit mode button doesn't change, so it's specified in the jsp - if (this.editMode === 'edit') { - return; - } - - //if support select editing, keep button label same - if(this.supportEdit) { - return; - } - - typeText = this.getTypeNameForLabels(); - - // Creating new related individual - if (newOrExisting === 'new') { - if (this.submitButtonTextType == 'compound') { // use == to tolerate nulls - // e.g., 'Create Grant & Principal Investigator' - buttonText = 'Create ' + typeText + ' & ' + baseButtonText; - } else { - // In repair mode, baseButtonText is "Edit X". Keep that for this case. - // In add mode, baseButtonText is "X", so we get, e.g., "Create Publication" - buttonText = this.editMode == 'repair' ? baseButtonText : 'Create ' + baseButtonText; - } - } - // Using existing related individual - else { - // In repair mode, baseButtonText is "Edit X". Keep that for this case. - buttonText = this.editMode == 'repair' ? baseButtonText : 'Add ' + baseButtonText; - } - - this.button.val(buttonText); - }, - - getTypeNameForLabels: function() { + getTypeNameForLabels: function(selectedObj) { // If this.acType is empty, we are either in a one-step form with no type yet selected, // or in repair mode in a two-step form with no type selected. Use the default type // name specified in the form data. - return this.acType ? this.typeName : this.capitalize(this.defaultTypeName); + if ( selectedObj && this.hasMultipleTypeNames ) { + var name = customForm.multipleTypeNames[$(selectedObj).attr('id')]; + return this.capitalize(name); + } + else { + return this.acTypes ? this.typeName : this.capitalize(this.defaultTypeName); + } }, // Set the initial help text that appears in the autocomplete field and change the class name - addAcHelpText: function() { + addAcHelpText: function(selectedObj) { var typeText; - - // First case applies on page load; second case applies when the type gets changed. - if (!this.acSelector.val() || this.acSelector.hasClass(this.acHelpTextClass)) { - typeText = this.getTypeNameForLabels(); + // First case applies on page load; second case applies when the type gets changed. With multiple + // ac fields there are cases where we also have to check if the help text is already there + if (!$(selectedObj).val() || $(selectedObj).hasClass(this.acHelpTextClass) || $(selectedObj).val().substring(0, 18) == "Select an existing" ) { + typeText = this.getTypeNameForLabels($(selectedObj)); var helpText = "Select an existing " + typeText + " or create a new one."; //Different for object property autocomplete - if(this.supportEdit) { + if ( this.acSelectOnly ) { helpText = "Select an existing " + typeText; } - this.acSelector.val(helpText) - .addClass(this.acHelpTextClass); - } - }, + $(selectedObj).val(helpText) + .addClass(this.acHelpTextClass); + } + }, - deleteAcHelpText: function() { - if (this.acSelector.hasClass(this.acHelpTextClass)) { - this.acSelector.val('') - .removeClass(this.acHelpTextClass); - } - }, - disableSubmit: function() { + + deleteAcHelpText: function(selectedObj) { + // on submit, no selectedObj gets passed, so we need to check for this + if ( selectedObj ) { + if ($(selectedObj).hasClass(this.acHelpTextClass)) { + $(selectedObj).val('') + .removeClass(this.acHelpTextClass); + } + } + else { + $.each(this.acSelectors, function() { + if ($(this).hasClass(customForm.acHelpTextClass)) { + $(this).val('') + .removeClass(customForm.acHelpTextClass); + } + }); + } + }, + disableSubmit: function() { //Disable submit button until selection made this.button.attr('disabled', 'disabled'); - this.button.addClass('disabledSubmit'); // tlw + this.button.addClass('disabledSubmit'); }, enableSubmit:function() { this.button.removeAttr('disabled'); @@ -549,6 +552,6 @@ var customForm = { }; -$(document).ready(function() { +$(document).ready(function() { customForm.onLoad(); }); diff --git a/productMods/templates/freemarker/edit/forms/organizationHasPositionHistory.ftl b/productMods/templates/freemarker/edit/forms/organizationHasPositionHistory.ftl index 161c67ae..5245f0f3 100644 --- a/productMods/templates/freemarker/edit/forms/organizationHasPositionHistory.ftl +++ b/productMods/templates/freemarker/edit/forms/organizationHasPositionHistory.ftl @@ -12,11 +12,11 @@ <#if editMode == "edit"> <#assign titleVerb="Edit"> - <#assign submitButtonText="Edit Position"> + <#assign submitButtonText="Save Changes"> <#assign disabledVal="disabled"> <#else> <#assign titleVerb="Create"> - <#assign submitButtonText="Position"> + <#assign submitButtonText="Create Entry"> <#assign disabledVal=""/> @@ -94,19 +94,15 @@

- <#if editMode == "edit"> - - - <#else> - - +

-
+ @@ -139,10 +135,11 @@ diff --git a/productMods/templates/freemarker/edit/forms/personHasAdvisingRelationship.ftl b/productMods/templates/freemarker/edit/forms/personHasAdvisingRelationship.ftl new file mode 100644 index 00000000..29b34a79 --- /dev/null +++ b/productMods/templates/freemarker/edit/forms/personHasAdvisingRelationship.ftl @@ -0,0 +1,212 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +<#-- this is in request.subject.name --> + +<#-- leaving this edit/add mode code in for reference in case we decide we need it --> + +<#import "lib-vivo-form.ftl" as lvf> + +<#--Retrieve certain edit configuration information--> +<#if editConfiguration.objectUri?has_content> + <#assign editMode = "edit"> +<#else> + <#assign editMode = "add"> + + +<#assign htmlForElements = editConfiguration.pageData.htmlForElements /> + +<#--Retrieve variables needed--> +<#assign adviseeValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "advisee") /> +<#assign adviseeLabelValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "adviseeLabel") /> +<#assign firstNameValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "firstName") /> +<#assign lastNameValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "lastName") /> +<#assign advisingRelTypeValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "advisingRelType") /> +<#assign advisingRelLabelValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "advisingRelLabel") /> +<#assign subjAreaValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "subjArea") /> +<#assign subjAreaLabelValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "subjAreaLabel") /> +<#assign degreeValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "degree") /> +<#assign acFilterForIndividuals = "['" + editConfiguration.subjectUri + "']" /> +<#assign sparqlForAcFilter = editConfiguration.pageData.sparqlForAcFilter /> + +<#--If edit submission exists, then retrieve validation errors if they exist--> +<#if editSubmission?has_content && editSubmission.submissionExists = true && editSubmission.validationErrors?has_content> + <#assign submissionErrors = editSubmission.validationErrors/> + + +<#if editMode == "edit"> + <#assign titleVerb="Edit"> + <#assign submitButtonText="Save Changes"> + <#assign disabledVal="disabled"> +<#else> + <#assign titleVerb="Create"> + <#assign submitButtonText="Create Entry"> + <#assign disabledVal=""/> + + +<#assign requiredHint = " *" /> +<#assign yearHint = "(YYYY)" /> + +

${titleVerb} advising relationship entry for ${editConfiguration.subjectName}

+ +<#--Display error messages if any--> +<#if submissionErrors?has_content> + + + +<@lvf.unsupportedBrowser urls.base /> + +
+ + +

+ + <#assign advisingRelTypeOpts = editConfiguration.pageData.advisingRelType /> + <#if editMode == "edit"> + <#list advisingRelTypeOpts?keys as key> + <#if advisingRelTypeValue = key > + ${advisingRelTypeOpts[key]} + + + + <#else> + + +

+

+ + +
+ +

+ +
+

+ + + (Verify this match or + change selection) +

+ +
+ +

+ + +

+
+

+ + + (Verify this match or + change selection) +

+ +
+ +

+ + + <#assign degreeOpts = editConfiguration.pageData.degree /> + +

+ +

+

Years of Participation

+

+ <#--Need to draw edit elements for dates here--> + <#assign htmlForElements = editConfiguration.pageData.htmlForElements /> + <#if htmlForElements?keys?seq_contains("startField")> + + ${htmlForElements["startField"]} ${yearHint} + +
+ <#if htmlForElements?keys?seq_contains("endField")> + + ${htmlForElements["endField"]} ${yearHint} + + <#--End draw elements--> + + + +

+ or + Cancel +

+ +

* required fields

+ + + +
+ +<#assign sparqlQueryUrl = "${urls.base}/ajax/sparqlQuery" > + + + + +${stylesheets.add('')} +${stylesheets.add('')} +${stylesheets.add('')} + +${scripts.add('', + '', + '', + '', + '', + '', + '')} + + diff --git a/productMods/templates/freemarker/edit/forms/personHasAwardOrHonor.ftl b/productMods/templates/freemarker/edit/forms/personHasAwardOrHonor.ftl new file mode 100644 index 00000000..95c58aa1 --- /dev/null +++ b/productMods/templates/freemarker/edit/forms/personHasAwardOrHonor.ftl @@ -0,0 +1,181 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +<#-- this is in request.subject.name --> + +<#-- leaving this edit/add mode code in for reference in case we decide we need it --> + +<#import "lib-vivo-form.ftl" as lvf> + +<#--Retrieve certain edit configuration information--> +<#if editConfiguration.objectUri?has_content> + <#assign editMode = "edit"> +<#else> + <#assign editMode = "add"> + + +<#assign htmlForElements = editConfiguration.pageData.htmlForElements /> + +<#--Retrieve variables needed--> +<#assign awardValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "award") /> +<#assign awardLabelValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "awardLabel") /> +<#assign awardReceiptLabelValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "awardReceiptLabel") /> +<#assign orgValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "org") /> +<#assign orgLabelValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "orgLabel") /> +<#assign descriptionValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "description") /> +<#assign yearAwardedValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "yearAwarded") /> + +<#--If edit submission exists, then retrieve validation errors if they exist--> +<#if editSubmission?has_content && editSubmission.submissionExists = true && editSubmission.validationErrors?has_content> + <#assign submissionErrors = editSubmission.validationErrors/> + + +<#if editMode == "edit"> + <#assign titleVerb="Edit"> + <#assign submitButtonText="Save Changes"> + <#assign disabledVal="disabled"> +<#else> + <#assign titleVerb="Create"> + <#assign submitButtonText="Create Entry"> + <#assign disabledVal=""/> + + +<#assign requiredHint = " *" /> +<#assign yearHint = "(YYYY)" /> + +

${titleVerb} award or honor for ${editConfiguration.subjectName}

+ +<#--Display error messages if any--> +<#if submissionErrors?has_content> + + + +<@lvf.unsupportedBrowser urls.base /> + +
+ +
+

+ + +

+ +
+

+ + + (Verify this match or + change selection) +

+ +
+

+ + +

+
+

+ + + (Verify this match or + change selection) +

+ +
+ +

+ + +

+ +

+ + ${yearHint} +

+ +

+

Years Inclusive  (e.g., for multi-year awards)

+

+ <#--Need to draw edit elements for dates here--> + <#assign htmlForElements = editConfiguration.pageData.htmlForElements /> + <#if htmlForElements?keys?seq_contains("startField")> + + ${htmlForElements["startField"]} ${yearHint} + +
+ <#if htmlForElements?keys?seq_contains("endField")> + + ${htmlForElements["endField"]} ${yearHint} + + <#--End draw elements--> + + + + +

+ or + Cancel +

+ +

* required fields

+ +
+ +
+ + + + + + + +${stylesheets.add('')} +${stylesheets.add('')} +${stylesheets.add('')} + +${scripts.add('', + '', + '', + '', + '', + '', + '')} + + + diff --git a/productMods/templates/freemarker/edit/forms/personHasEducationalTraining.ftl b/productMods/templates/freemarker/edit/forms/personHasEducationalTraining.ftl index cfddbef1..63ea38f1 100644 --- a/productMods/templates/freemarker/edit/forms/personHasEducationalTraining.ftl +++ b/productMods/templates/freemarker/edit/forms/personHasEducationalTraining.ftl @@ -31,11 +31,11 @@ <#if editMode == "edit"> <#assign titleVerb="Edit"> - <#assign submitButtonText="Edit Educational Training"> + <#assign submitButtonText="Save Changes"> <#assign disabledVal="disabled"> <#else> <#assign titleVerb="Create"> - <#assign submitButtonText="Educational Training"> + <#assign submitButtonText="Create Entry"> <#assign disabledVal=""/> @@ -75,6 +75,11 @@ <#if lvf.submissionErrorExists(editSubmission, "orgLabel")> Please enter or select a value in the Name field. + <#--Checking if Training Type field is empty--> + <#if lvf.submissionErrorExists(editSubmission, "trainingType")> + Please select a value in the Type of Educational Training field.
+ +

@@ -90,32 +95,35 @@

<#assign orgTypeOpts = editConfiguration.pageData.orgType /> - + <#if editMode == "edit"> + <#list orgTypeOpts?keys as key> + <#if orgTypeValue = key > + ${orgTypeOpts[key]} + + + + <#else> + +

- 0)>disabled="${disabledVal}" /> +

- - <#--Store values in hidden fields--> - <#if editMode="edit"> - - - - - <@lvf.acSelection urls.base "org" "org" existingOrgValue/> + + <@lvf.acSelection urls.base "org" "org" "org" existingOrgValue/> <#assign trainingTypeOpts = editConfiguration.pageData.trainingType /> @@ -127,7 +135,7 @@

- +

@@ -183,8 +191,8 @@ var customFormData = { acUrl: '${urls.base}/autocomplete?tokenize=true&stem=true', editMode: '${editMode}', - submitButtonTextType: 'compound', - defaultTypeName: 'organization' + defaultTypeName: 'organization', + baseHref: '${urls.base}/individual?uri=' }; diff --git a/productMods/templates/freemarker/edit/forms/personHasPositionHistory.ftl b/productMods/templates/freemarker/edit/forms/personHasPositionHistory.ftl index cab88b0b..bf30f51b 100644 --- a/productMods/templates/freemarker/edit/forms/personHasPositionHistory.ftl +++ b/productMods/templates/freemarker/edit/forms/personHasPositionHistory.ftl @@ -23,11 +23,11 @@ <#assign disabledVal = ""/> <#if editMode == "edit"> <#assign formAction="Edit"> - <#assign submitButtonText="Edit Position"> + <#assign submitButtonText="Save Changes"> <#assign disabledVal="disabled"> <#else> <#assign formAction="Create"> - <#assign submitButtonText="Position"> + <#assign submitButtonText="Create Entry"> <#assign disabledVal=""> @@ -83,27 +83,31 @@

- + <#assign orgTypeOpts = editConfiguration.pageData.orgType /> - + + + <#else> + +

- 0)>disabled="${disabledVal}" > +

- <#if editMode = "edit"> - - - - <@lvf.acSelection urls.base "org" "org" existingOrgValue/> - + <@lvf.acSelection urls.base "org" "org" "org" existingOrgValue /> @@ -150,8 +154,8 @@ var customFormData = { acUrl: '${urls.base}/autocomplete?tokenize=true', editMode: '${editMode}', - submitButtonTextType: 'compound', - defaultTypeName: 'organization' // used in repair mode, to generate button text and org name field label + defaultTypeName: 'organization', // used in repair mode, to generate button text and org name field label + baseHref: '${urls.base}/individual?uri=' }; diff --git a/productMods/templates/freemarker/lib/lib-vivo-form.ftl b/productMods/templates/freemarker/lib/lib-vivo-form.ftl index cdbe29ce..ea900a5b 100644 --- a/productMods/templates/freemarker/lib/lib-vivo-form.ftl +++ b/productMods/templates/freemarker/lib/lib-vivo-form.ftl @@ -15,8 +15,8 @@ <#-- After selecting an individual via autocomplete, display highlighted and with verify link --> -<#macro acSelection urlsBase inputName inputId inputValue labelValue=""> -
+<#macro acSelection urlsBase inputName inputId acGroupName inputValue labelValue=""> +

diff --git a/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/PersonHasAdviseesValidator.java b/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/PersonHasAdviseesValidator.java new file mode 100644 index 00000000..31ebd2f1 --- /dev/null +++ b/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/PersonHasAdviseesValidator.java @@ -0,0 +1,95 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.edit.n3editing; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.hp.hpl.jena.rdf.model.Literal; + +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.N3ValidatorVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.MultiValueEditSubmission; + +public class PersonHasAdviseesValidator implements N3ValidatorVTwo { + + private static String MISSING_FIRST_NAME_ERROR = "You must enter a value in the First Name field."; + private static String MISSING_LAST_NAME_ERROR = "You must enter a value in the Last Name field."; + private static String MALFORMED_LAST_NAME_ERROR = "The last name field may not contain a comma. Please enter first name in First Name field."; +; + @Override + public Map validate(EditConfigurationVTwo editConfig, + MultiValueEditSubmission editSub) { + Map> urisFromForm = editSub.getUrisFromForm(); + Map> literalsFromForm = editSub.getLiteralsFromForm(); + + Map errors = new HashMap(); + + List adviseeUri = urisFromForm.get("advisee"); + if (allListElementsEmpty(adviseeUri)) { + adviseeUri = null; + } + // If there's an adviseeUri, then we're done. The firstName and lastName fields are + // disabled and so don't get submitted. + if (adviseeUri != null) { + return null; + } + + //Expecting only one first name in this case + //To Do: update logic if multiple first names considered + Literal firstName = null; + List firstNameList = literalsFromForm.get("firstName"); + if(firstNameList != null && firstNameList.size() > 0) { + firstName = firstNameList.get(0); + } + if( firstName != null && + firstName.getLexicalForm() != null && + "".equals(firstName.getLexicalForm()) ) + firstName = null; + + + List lastNameList = literalsFromForm.get("lastName"); + Literal lastName = null; + if(lastNameList != null && lastNameList.size() > 0) { + lastName = lastNameList.get(0); + } + String lastNameValue = ""; + if (lastName != null) { + lastNameValue = lastName.getLexicalForm(); + if( "".equals(lastNameValue) ) { + lastName = null; + } + } + + if (lastName == null) { + errors.put("lastName", MISSING_LAST_NAME_ERROR); + // Don't reject space in the last name: de Vries, etc. + } else if (lastNameValue.contains(",")) { + errors.put("lastName", MALFORMED_LAST_NAME_ERROR); + } + + if (firstName == null) { + errors.put("firstName", MISSING_FIRST_NAME_ERROR); + } + + return errors.size() != 0 ? errors : null; + } + + private boolean allListElementsEmpty(List checkList) { + if(checkList == null) + return true; + if(checkList.isEmpty()) { + return true; + } + boolean allEmpty = true; + for(String s: checkList) { + if(s.length() != 0){ + allEmpty = false; + break; + } + } + return allEmpty; + } + +} diff --git a/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/PersonHasAdvisingRelationshipGenerator.java b/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/PersonHasAdvisingRelationshipGenerator.java new file mode 100644 index 00000000..56d8c20e --- /dev/null +++ b/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/PersonHasAdvisingRelationshipGenerator.java @@ -0,0 +1,367 @@ +/* $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.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +import javax.servlet.http.HttpSession; + +import com.hp.hpl.jena.vocabulary.RDFS; +import com.hp.hpl.jena.vocabulary.XSD; + +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.DateTimeIntervalValidationVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.DateTimeWithPrecisionVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.FieldVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators.AntiXssValidation; +import edu.cornell.mannlib.vitro.webapp.utils.FrontEndEditingUtils; +import edu.cornell.mannlib.vitro.webapp.utils.FrontEndEditingUtils.EditMode; +import edu.cornell.mannlib.vitro.webapp.utils.generators.EditModeUtils; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.PersonHasAdviseesValidator; + +public class PersonHasAdvisingRelationshipGenerator extends VivoBaseGenerator implements + EditConfigurationGenerator { + + final static String advisingRelClass = vivoCore + "AdvisingRelationship"; + final static String subjAreaClass = "http://www.w3.org/2004/02/skos/core#Concept"; + final static String degreeClass = vivoCore+"AcademicDegree"; + final static String adviseeClass = foaf + "Person"; + final static String advisorInPred = vivoCore + "advisorIn"; + final static String adviseeInPred = vivoCore + "adviseeIn"; + final static String advisorPred = vivoCore + "advisor"; + final static String adviseePred = vivoCore + "advisee" ; + final static String subjAreaPred = vivoCore + "hasSubjectArea" ; + final static String degreePred = vivoCore + "degreeCandidacy" ; + final static String advisingRelToInterval = vivoCore + "dateTimeInterval"; + final static String intervalType = vivoCore + "DateTimeInterval"; + final static String intervalToStart = vivoCore + "start"; + final static String intervalToEnd = vivoCore + "end"; + final static String dateTimeValueType = vivoCore + "DateTimeValue"; + final static String dateTimeValue = vivoCore + "dateTime"; + final static String dateTimePrecision = vivoCore + "dateTimePrecision"; + + public PersonHasAdvisingRelationshipGenerator() {} + + @Override + public EditConfigurationVTwo getEditConfiguration(VitroRequest vreq, + HttpSession session) { + + EditConfigurationVTwo conf = new EditConfigurationVTwo(); + + initBasics(conf, vreq); + initPropertyParameters(vreq, session, conf); + initObjectPropForm(conf, vreq); + + conf.setTemplate("personHasAdvisingRelationship.ftl"); + + conf.setVarNameForSubject("person"); + conf.setVarNameForPredicate("predicate"); + conf.setVarNameForObject("advisingRelationship"); + + conf.setN3Required( Arrays.asList( n3ForNewAdvisingRelationship, + advisingRelLabelAssertion, + advisingRelTypeAssertion ) ); + conf.setN3Optional( Arrays.asList( n3ForAdviseeAssertion, + adviseeLabelAssertion, + degreeAssertion, + firstNameAssertion, + lastNameAssertion, + n3ForSubjAreaAssertion, + subjAreaLabelAssertion, + n3ForStart, + n3ForEnd ) ); + + conf.addNewResource("advisingRelationship", DEFAULT_NS_FOR_NEW_RESOURCE); + conf.addNewResource("advisee", DEFAULT_NS_FOR_NEW_RESOURCE); + conf.addNewResource("subjArea", DEFAULT_NS_FOR_NEW_RESOURCE); + conf.addNewResource("intervalNode", DEFAULT_NS_FOR_NEW_RESOURCE); + conf.addNewResource("startNode", DEFAULT_NS_FOR_NEW_RESOURCE); + conf.addNewResource("endNode", DEFAULT_NS_FOR_NEW_RESOURCE); + + //uris in scope: none + //literals in scope: none + + conf.setUrisOnform(Arrays.asList("advisingRelType", "subjArea", "degree", "advisee")); + conf.setLiteralsOnForm(Arrays.asList("advisingRelLabel", "subjAreaLabel", "adviseeLabel", "firstName", "lastName" )); + + conf.addSparqlForExistingLiteral("advisingRelLabel", advisingRelLabelQuery); + conf.addSparqlForExistingLiteral("adviseeLabel", adviseeLabelQuery); +// may not need these two because in edit mode the display will be an acSelection div +// conf.addSparqlForExistingLiteral("firstName", firstNameQuery); +// conf.addSparqlForExistingLiteral("lastName", lastNameQuery); + conf.addSparqlForExistingLiteral("subjAreaLabel", subjAreaLabelQuery); + conf.addSparqlForExistingLiteral("startField-value", existingStartDateQuery); + conf.addSparqlForExistingLiteral("endField-value", existingEndDateQuery); + + conf.addSparqlForExistingUris("advisingRelType", advisingRelTypeQuery); + conf.addSparqlForExistingUris("subjArea", subjAreaQuery); + conf.addSparqlForExistingUris("advisee", adviseeQuery); + conf.addSparqlForExistingUris("degree", degreeQuery); + conf.addSparqlForExistingUris("intervalNode",existingIntervalNodeQuery); + conf.addSparqlForExistingUris("startNode", existingStartNodeQuery); + conf.addSparqlForExistingUris("endNode", existingEndNodeQuery); + conf.addSparqlForExistingUris("startField-precision", existingStartPrecisionQuery); + conf.addSparqlForExistingUris("endField-precision", existingEndPrecisionQuery); + + conf.addField( new FieldVTwo(). + setName("advisingRelType"). + setOptionsType(FieldVTwo.OptionsType.CHILD_VCLASSES_WITH_PARENT). + setObjectClassUri(advisingRelClass). + setValidators( list("nonempty") ) + ); + + conf.addField( new FieldVTwo(). + setName("advisingRelLabel"). + setRangeDatatypeUri(XSD.xstring.toString() ). + setValidators( list("datatype:" + XSD.xstring.toString()) ) + ); + + conf.addField( new FieldVTwo(). + setName("firstName"). + setRangeDatatypeUri(XSD.xstring.toString() ). + setValidators( list("datatype:" + XSD.xstring.toString()) ) + ); + + conf.addField( new FieldVTwo(). + setName("lastName"). + setRangeDatatypeUri(XSD.xstring.toString() ). + setValidators( list("datatype:" + XSD.xstring.toString()) ) + ); + + conf.addField( new FieldVTwo(). + setName("subjArea"). + setOptionsType(FieldVTwo.OptionsType.INDIVIDUALS_VIA_VCLASS). + setObjectClassUri( subjAreaClass ) + ); + + conf.addField( new FieldVTwo(). + setName("subjAreaLabel"). + setRangeDatatypeUri(XSD.xstring.toString() ). + setValidators( list("datatype:" + XSD.xstring.toString()) ) + ); + + conf.addField( new FieldVTwo(). + setName("degree"). + setOptionsType( FieldVTwo.OptionsType.INDIVIDUALS_VIA_VCLASS ). + setObjectClassUri( degreeClass ) + ); + + conf.addField( new FieldVTwo(). + setName("advisee"). + setOptionsType(FieldVTwo.OptionsType.INDIVIDUALS_VIA_VCLASS). + setObjectClassUri( adviseeClass ) + ); + + conf.addField( new FieldVTwo(). + setName("adviseeLabel"). + setRangeDatatypeUri(XSD.xstring.toString() ). + setValidators( list("datatype:" + XSD.xstring.toString()) ) + ); + + conf.addField( new FieldVTwo().setName("startField"). + setEditElement( + new DateTimeWithPrecisionVTwo(null, + VitroVocabulary.Precision.YEAR.uri(), + VitroVocabulary.Precision.NONE.uri()) + ) + ); + + conf.addField( new FieldVTwo().setName("endField"). + setEditElement( + new DateTimeWithPrecisionVTwo(null, + VitroVocabulary.Precision.YEAR.uri(), + VitroVocabulary.Precision.NONE.uri()) + ) + ); + + conf.addValidator(new DateTimeIntervalValidationVTwo("startField","endField")); + conf.addValidator(new AntiXssValidation()); + conf.addValidator(new PersonHasAdviseesValidator()); + addFormSpecificData(conf, vreq); + + prepare(vreq, conf); + return conf; + } + + /* N3 assertions */ + + final static String n3ForNewAdvisingRelationship = + "@prefix vivo: <" + vivoCore + "> . \n\n" + + "?person <" + advisorInPred + "> ?advisingRelationship . \n" + + "?advisingRelationship a <" + advisingRelClass + "> . \n" + + "?advisingRelationship <" + advisorPred + "> ?person . \n" ; + + final static String advisingRelLabelAssertion = + "?advisingRelationship <"+ label + "> ?advisingRelLabel ."; + + final static String advisingRelTypeAssertion = + "?advisingRelationship a ?advisingRelType ."; + + final static String n3ForAdviseeAssertion = + "?advisingRelationship <" + adviseePred + "> ?advisee . \n" + + "?advisee <" + adviseeInPred + "> ?advisingRelationship . "; + + final static String adviseeLabelAssertion = + "?advisee <" + label + "> ?adviseeLabel ."; + + final static String firstNameAssertion = + "@prefix foaf: <" + foaf + "> . \n" + + "?advisee foaf:firstName ?firstName ."; + + final static String lastNameAssertion = + "@prefix foaf: <" + foaf + "> . \n" + + "?advisee foaf:lastName ?lastName ."; + + final static String degreeAssertion = + "?advisingRelationship <"+ degreePred +"> ?degree ."; + + final static String n3ForSubjAreaAssertion = + "?advisingRelationship <"+ subjAreaPred +"> ?subjArea .\n" + + "?subjArea a <" + subjAreaClass + "> . "; + + final static String subjAreaLabelAssertion = + "?subjArea <"+ label + "> ?subjAreaLabel . "; + + final static String n3ForStart = + "?advisingRelationship <" + advisingRelToInterval + "> ?intervalNode . \n" + + "?intervalNode a <" + intervalType + "> . \n" + + "?intervalNode <" + intervalToStart + "> ?startNode . \n" + + "?startNode a <" + dateTimeValueType + "> . \n" + + "?startNode <" + dateTimeValue + "> ?startField-value . \n" + + "?startNode <" + dateTimePrecision + "> ?startField-precision . \n"; + + final static String n3ForEnd = + "?advisingRelationship <" + advisingRelToInterval + "> ?intervalNode . \n" + + "?intervalNode a <" + intervalType + "> . \n" + + "?intervalNode <" + intervalToEnd + "> ?endNode . \n" + + "?endNode a <" + dateTimeValueType + "> . \n" + + "?endNode <" + dateTimeValue + "> ?endField-value . \n" + + "?endNode <" + dateTimePrecision + "> ?endField-precision . \n"; + + /* Queries for editing an existing entry */ + + final static String advisingRelTypeQuery = + "PREFIX vitro: <" + VitroVocabulary.vitroURI + "> \n" + + "SELECT ?advisingRelType WHERE { \n" + + " ?advisingRelationship vitro:mostSpecificType ?advisingRelType . \n" + + "}"; + + final static String adviseeQuery = + "SELECT ?existingAdvisee WHERE { \n" + + " ?advisingRelationship <" + adviseePred + "> ?existingAdvisee . \n" + + "}"; + + final static String adviseeLabelQuery = + "SELECT ?existingAdviseeLabel WHERE { \n" + + " ?advisingRelationship <" + adviseePred + "> ?existingAdvisee . \n" + + " ?existingAdvisee <" + label + "> ?existingAdviseeLabel . \n" + + "}"; + +/* May not need these + final static String firstNameQuery = + "prefix foaf: <" + foaf + "> \n" + + "SELECT ?existingFirstName WHERE { \n" + + " ?advisingRelationship <" + adviseePred + "> ?existingAdvisee . \n" + + " ?existingAdvisee foaf:firstName ?existingFirstName . \n" + + "}"; + + final static String lastNameQuery = + "prefix foaf: <" + foaf + "> \n" + + "SELECT ?existingLastName WHERE { \n" + + " ?advisingRelationship <" + adviseePred + "> ?existingAdvisee . \n" + + " ?existingAdvisee foaf:lastName ?existingLastName . \n" + + "}"; +*/ + final static String subjAreaQuery = + "SELECT ?existingSubjArea WHERE { \n" + + " ?advisingRelationship <" + subjAreaPred + "> ?existingSubjArea . \n" + + "}"; + + final static String subjAreaLabelQuery = + "SELECT ?existingSubjAreaLabel WHERE { \n" + + " ?advisingRelationship <" + subjAreaPred + "> ?existingSubjArea . \n" + + " ?existingSubjArea <" + label + "> ?existingSubjAreaLabel . \n" + + "}"; + + final static String advisingRelLabelQuery = + "SELECT ?existingAdvisingRelLabel WHERE { \n" + + " ?advisingRelationship <" + label + "> ?existingAdvisingRelLabel . \n" + + "}"; + + final static String degreeQuery = + "SELECT ?existingDegree WHERE {\n"+ + " ?advisingRelationship <"+ degreePred +"> ?existingDegree . }"; + + final static String existingStartDateQuery = + "SELECT ?existingDateStart WHERE { \n" + + " ?advisingRelationship <" + advisingRelToInterval + "> ?intervalNode . \n" + + " ?intervalNode a <" + intervalType + "> . \n" + + " ?intervalNode <" + intervalToStart + "> ?startNode . \n" + + " ?startNode a <" + dateTimeValueType +"> . \n" + + " ?startNode <" + dateTimeValue + "> ?existingDateStart . }"; + + final static String existingEndDateQuery = + "SELECT ?existingEndDate WHERE { \n" + + " ?advisingRelationship <" + advisingRelToInterval + "> ?intervalNode . \n" + + " ?intervalNode a <" + intervalType + "> . \n " + + " ?intervalNode <" + intervalToEnd + "> ?endNode . \n" + + " ?endNode a <" + dateTimeValueType + "> . \n" + + " ?endNode <" + dateTimeValue + "> ?existingEndDate . }"; + + final static String existingIntervalNodeQuery = + "SELECT ?existingIntervalNode WHERE { \n" + + " ?advisingRelationship <" + advisingRelToInterval + "> ?existingIntervalNode . \n" + + " ?existingIntervalNode a <" + intervalType + "> . }"; + + final static String existingStartNodeQuery = + "SELECT ?existingStartNode WHERE { \n" + + " ?advisingRelationship <" + advisingRelToInterval + "> ?intervalNode . \n" + + " ?intervalNode a <" + intervalType + "> . \n" + + " ?intervalNode <" + intervalToStart + "> ?existingStartNode . \n" + + " ?existingStartNode a <" + dateTimeValueType + "> .} "; + + final static String existingEndNodeQuery = + "SELECT ?existingEndNode WHERE { \n" + + " ?advisingRelationship <" + advisingRelToInterval + "> ?intervalNode . \n" + + " ?intervalNode a <" + intervalType + "> . \n" + + " ?intervalNode <" + intervalToEnd + "> ?existingEndNode . \n" + + " ?existingEndNode a <" + dateTimeValueType + "> } "; + + final static String existingStartPrecisionQuery = + "SELECT ?existingStartPrecision WHERE { \n" + + " ?advisingRelationship <" + advisingRelToInterval + "> ?intervalNode . \n" + + " ?intervalNode a <" + intervalType + "> . \n" + + " ?intervalNode <" + intervalToStart + "> ?startNode . \n" + + " ?startNode a <" + dateTimeValueType + "> . \n" + + " ?startNode <" + dateTimePrecision + "> ?existingStartPrecision . }"; + + final static String existingEndPrecisionQuery = + "SELECT ?existingEndPrecision WHERE { \n" + + " ?advisingRelationship <" + advisingRelToInterval + "> ?intervalNode . \n" + + " ?intervalNode a <" + intervalType + "> . \n" + + " ?intervalNode <" + intervalToEnd + "> ?endNode . \n" + + " ?endNode a <" + dateTimeValueType + "> . \n" + + " ?endNode <" + dateTimePrecision + "> ?existingEndPrecision . }"; + + public void addFormSpecificData(EditConfigurationVTwo editConfiguration, VitroRequest vreq) { + HashMap formSpecificData = new HashMap(); + formSpecificData.put("sparqlForAcFilter", getSparqlForAcFilter(vreq)); + editConfiguration.setFormSpecificData(formSpecificData); + } + + public String getSparqlForAcFilter(VitroRequest vreq) { + String subject = EditConfigurationUtils.getSubjectUri(vreq); + String predicate = EditConfigurationUtils.getPredicateUri(vreq); + //Get all objects for existing predicate, filters out results from addition and edit + String query = "SELECT ?objectVar WHERE { " + + "<" + subject + "> <" + predicate + "> ?objectVar .} "; + return query; + } + +} diff --git a/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/PersonHasAwardOrHonorGenerator.java b/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/PersonHasAwardOrHonorGenerator.java new file mode 100644 index 00000000..0925cd88 --- /dev/null +++ b/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/PersonHasAwardOrHonorGenerator.java @@ -0,0 +1,332 @@ +/* $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.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +import javax.servlet.http.HttpSession; + +import com.hp.hpl.jena.vocabulary.RDFS; +import com.hp.hpl.jena.vocabulary.XSD; + +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.DateTimeIntervalValidationVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.DateTimeWithPrecisionVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.FieldVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators.AntiXssValidation; +import edu.cornell.mannlib.vitro.webapp.utils.FrontEndEditingUtils; +import edu.cornell.mannlib.vitro.webapp.utils.FrontEndEditingUtils.EditMode; +import edu.cornell.mannlib.vitro.webapp.utils.generators.EditModeUtils; + +public class PersonHasAwardOrHonorGenerator extends VivoBaseGenerator implements + EditConfigurationGenerator { + + final static String awardReceiptClass = vivoCore + "AwardReceipt"; + final static String awardClass = vivoCore + "Award"; + final static String orgClass = "http://xmlns.com/foaf/0.1/Organization"; + final static String awardReceiptPred = vivoCore + "awardOrHonor"; + final static String awardForPred = vivoCore + "awardOrHonorFor"; + final static String receiptPred =vivoCore+"receipt" ; + final static String receiptOfPred =vivoCore+"receiptOf" ; + final static String awardConferredByPred =vivoCore+"awardConferredBy" ; + final static String awardConferredPred =vivoCore+"awardConferred" ; + final static String descriptionPred = vivoCore + "description"; + final static String yearAwardedPred = vivoCore + "dateTimeValue"; + final static String awardReceiptToInterval = vivoCore + "dateTimeInterval"; + final static String intervalType = vivoCore + "DateTimeInterval"; + final static String intervalToStart = vivoCore + "start"; + final static String intervalToEnd = vivoCore + "end"; + final static String dateTimeValueType = vivoCore + "DateTimeValue"; + final static String dateTimeValue = vivoCore + "dateTime"; + final static String dateTimePrecision = vivoCore + "dateTimePrecision"; + + public PersonHasAwardOrHonorGenerator() {} + + @Override + public EditConfigurationVTwo getEditConfiguration(VitroRequest vreq, + HttpSession session) { + + EditConfigurationVTwo conf = new EditConfigurationVTwo(); + + initBasics(conf, vreq); + initPropertyParameters(vreq, session, conf); + initObjectPropForm(conf, vreq); + + conf.setTemplate("personHasAwardOrHonor.ftl"); + + conf.setVarNameForSubject("person"); + conf.setVarNameForPredicate("predicate"); + conf.setVarNameForObject("awardReceipt"); + + conf.setN3Required( Arrays.asList( n3ForNewAwardReceipt, + awardReceiptLabelAssertion ) ); + conf.setN3Optional( Arrays.asList( n3ForReceiptToAward, + n3ForAwardToReceipt, + descriptionAssertion, + n3ForOrgAssertion, + orgLabelAssertion, + awardLabelAssertion, + n3ForYearAwarded, + n3ForStart, + n3ForEnd ) ); + + conf.addNewResource("award", DEFAULT_NS_FOR_NEW_RESOURCE); + conf.addNewResource("awardReceipt", DEFAULT_NS_FOR_NEW_RESOURCE); + conf.addNewResource("org", DEFAULT_NS_FOR_NEW_RESOURCE); + conf.addNewResource("yearAwardedNode", DEFAULT_NS_FOR_NEW_RESOURCE); + conf.addNewResource("intervalNode", DEFAULT_NS_FOR_NEW_RESOURCE); + conf.addNewResource("startNode", DEFAULT_NS_FOR_NEW_RESOURCE); + conf.addNewResource("endNode", DEFAULT_NS_FOR_NEW_RESOURCE); + + //uris in scope: none + //literals in scope: none + + conf.setUrisOnform(Arrays.asList("award", "org")); + conf.setLiteralsOnForm(Arrays.asList("description", "awardReceiptLabel", "awardLabel", "orgLabel" )); + + conf.addSparqlForExistingLiteral("awardReceiptLabel", awardReceiptLabelQuery); + conf.addSparqlForExistingLiteral("awardLabel", awardLabelQuery); + conf.addSparqlForExistingLiteral("orgLabel", orgLabelQuery); + conf.addSparqlForExistingLiteral("description", descriptionQuery); + conf.addSparqlForExistingLiteral("yearAwarded-value", existingYearAwardedQuery); + conf.addSparqlForExistingLiteral("startField-value", existingStartDateQuery); + conf.addSparqlForExistingLiteral("endField-value", existingEndDateQuery); + + conf.addSparqlForExistingUris("award", awardQuery); + conf.addSparqlForExistingUris("org", orgQuery); + conf.addSparqlForExistingUris("yearAwardedNode",existingYearAwardedNodeQuery); + conf.addSparqlForExistingUris("intervalNode",existingIntervalNodeQuery); + conf.addSparqlForExistingUris("startNode", existingStartNodeQuery); + conf.addSparqlForExistingUris("endNode", existingEndNodeQuery); + conf.addSparqlForExistingUris("yearAwarded-precision", existingYearAwardedPrecisionQuery); + conf.addSparqlForExistingUris("startField-precision", existingStartPrecisionQuery); + conf.addSparqlForExistingUris("endField-precision", existingEndPrecisionQuery); + + conf.addField( new FieldVTwo(). + setName("description") + .setRangeDatatypeUri( XSD.xstring.toString() ). + setValidators( list("datatype:" + XSD.xstring.toString()) ) + ); + + conf.addField( new FieldVTwo(). + setName("org"). + setOptionsType(FieldVTwo.OptionsType.INDIVIDUALS_VIA_VCLASS). + setObjectClassUri( orgClass ) + ); + + conf.addField( new FieldVTwo(). + setName("award"). + setOptionsType(FieldVTwo.OptionsType.INDIVIDUALS_VIA_VCLASS). + setObjectClassUri( awardClass ) + ); + + conf.addField( new FieldVTwo(). + setName("awardReceiptLabel"). + setRangeDatatypeUri(XSD.xstring.toString() ). + setValidators( list("datatype:" + XSD.xstring.toString()) ) + ); + + conf.addField( new FieldVTwo(). + setName("orgLabel"). + setRangeDatatypeUri(XSD.xstring.toString() ). + setValidators( list("datatype:" + XSD.xstring.toString()) ) + ); + + conf.addField( new FieldVTwo(). + setName("awardLabel"). + setRangeDatatypeUri(XSD.xstring.toString() ). + setValidators( list("nonempty") ) + ); + + conf.addField( new FieldVTwo().setName("yearAwarded"). + setEditElement( + new DateTimeWithPrecisionVTwo(null, + VitroVocabulary.Precision.YEAR.uri(), + VitroVocabulary.Precision.NONE.uri()) + ) + ); + + conf.addField( new FieldVTwo().setName("startField"). + setEditElement( + new DateTimeWithPrecisionVTwo(null, + VitroVocabulary.Precision.YEAR.uri(), + VitroVocabulary.Precision.NONE.uri()) + ) + ); + + conf.addField( new FieldVTwo().setName("endField"). + setEditElement( + new DateTimeWithPrecisionVTwo(null, + VitroVocabulary.Precision.YEAR.uri(), + VitroVocabulary.Precision.NONE.uri()) + ) + ); + + conf.addValidator(new DateTimeIntervalValidationVTwo("startField","endField")); + conf.addValidator(new AntiXssValidation()); + + prepare(vreq, conf); + return conf; + } + + /* N3 assertions */ + + final static String n3ForNewAwardReceipt = + "@prefix vivo: <" + vivoCore + "> . \n\n" + + "?person <" + awardReceiptPred + "> ?awardReceipt . \n" + + "?awardReceipt a <" + awardReceiptClass + "> . \n" + + "?awardReceipt <" + awardForPred + "> ?person . \n" + + "?awardReceipt <" + receiptOfPred + "> ?award . \n" + + "?award a <" + awardClass + "> . " ; + + final static String awardReceiptLabelAssertion = + "?awardReceipt <"+ label + "> ?awardReceiptLabel ."; + + final static String n3ForReceiptToAward = + "?awardReceipt <" + receiptOfPred + "> ?award ."; + + final static String awardLabelAssertion = + "?award <"+ label + "> ?awardLabel ."; + + final static String n3ForAwardToReceipt = + "?award <" + receiptPred + "> ?awardReceipt ."; + + final static String descriptionAssertion = + "?awardReceipt <"+ descriptionPred +"> ?description ."; + + final static String n3ForOrgAssertion = + "?award <" + awardConferredByPred +"> ?org . \n" + + "?org a <" + orgClass + "> . \n" + + "?org <" + awardConferredPred + "> ?award ."; + + final static String orgLabelAssertion = + "?org <"+ label + "> ?orgLabel ."; + + final static String n3ForYearAwarded = + "?awardReceipt <" + yearAwardedPred + "> ?yearAwardedNode . \n" + + "?yearAwardedNode a <" + dateTimeValueType + "> . \n" + + "?yearAwardedNode <" + dateTimeValue + "> ?yearAwarded-value . \n" + + "?yearAwardedNode <" + dateTimePrecision + "> ?yearAwarded-precision ."; + + final static String n3ForStart = + "?awardReceipt <" + awardReceiptToInterval + "> ?intervalNode . \n" + + "?intervalNode a <" + intervalType + "> . \n" + + "?intervalNode <" + intervalToStart + "> ?startNode . \n" + + "?startNode a <" + dateTimeValueType + "> . \n" + + "?startNode <" + dateTimeValue + "> ?startField-value . \n" + + "?startNode <" + dateTimePrecision + "> ?startField-precision . \n"; + + final static String n3ForEnd = + "?awardReceipt <" + awardReceiptToInterval + "> ?intervalNode . \n" + + "?intervalNode a <" + intervalType + "> . \n" + + "?intervalNode <" + intervalToEnd + "> ?endNode . \n" + + "?endNode a <" + dateTimeValueType + "> . \n" + + "?endNode <" + dateTimeValue + "> ?endField-value . \n" + + "?endNode <" + dateTimePrecision + "> ?endField-precision . \n"; + + /* Queries for editing an existing entry */ + + final static String awardQuery = + "SELECT ?existingAward WHERE { \n" + + " ?awardReceipt <" + receiptOfPred + "> ?existingAward . \n" + + "}"; + + final static String orgQuery = + "SELECT ?existingOrg WHERE { \n" + + " ?award <" + awardConferredByPred + "> ?existingOrg . \n" + + "}"; + + final static String awardReceiptLabelQuery = + "SELECT ?existingAwardReceiptLabel WHERE { \n" + + " ?awardReceipt <" + label + "> ?existingAwardReceiptLabel . \n" + + "}"; + + final static String awardLabelQuery = + "SELECT ?existingAwardLabel WHERE { \n" + + " ?awardReceipt <" + receiptOfPred + "> ?existingAward . \n" + + " ?existingAward <" + label + "> ?existingAwardLabel . \n" + + "}"; + + final static String orgLabelQuery = + "SELECT ?existingOrgLabel WHERE { \n" + + " ?award <" + awardConferredByPred + "> ?existingOrg . \n" + + " ?existingOrg <" + label + "> ?existingOrgLabel . \n" + + "}"; + + final static String descriptionQuery = + "SELECT ?existingDescription WHERE {\n"+ + " ?awardReceipt <"+ descriptionPred +"> ?existingDescription . }"; + + final static String existingYearAwardedQuery = + "SELECT ?existingYearAwardedValue WHERE { \n" + + " ?awardReceipt <" + yearAwardedPred + "> ?yearAwardedNode . \n" + + " ?yearAwardedNode a <" + dateTimeValueType + "> . \n" + + " ?yearAwardedNode <" + dateTimeValue + "> ?existingYearAwardedValue }"; + + final static String existingYearAwardedNodeQuery = + "SELECT ?existingYearAwardedNode WHERE { \n" + + " ?awardReceipt <" + yearAwardedPred + "> ?existingYearAwardedNode . }"; + + final static String existingStartDateQuery = + "SELECT ?existingStartDate WHERE { \n" + + " ?awardReceipt <" + awardReceiptToInterval + "> ?intervalNode . \n" + + " ?intervalNode a <" + intervalType + "> . \n" + + " ?intervalNode <" + intervalToStart + "> ?startNode . \n" + + " ?startNode a <" + dateTimeValueType +"> . \n" + + " ?startNode <" + dateTimeValue + "> ?existingStartDate . }"; + + final static String existingEndDateQuery = + "SELECT ?existingEndDate WHERE { \n" + + " ?awardReceipt <" + awardReceiptToInterval + "> ?intervalNode . \n" + + " ?intervalNode a <" + intervalType + "> . \n " + + " ?intervalNode <" + intervalToEnd + "> ?endNode . \n" + + " ?endNode a <" + dateTimeValueType + "> . \n" + + " ?endNode <" + dateTimeValue + "> ?existingEndDate . }"; + + final static String existingIntervalNodeQuery = + "SELECT ?existingIntervalNode WHERE { \n" + + " ?awardReceipt <" + awardReceiptToInterval + "> ?existingIntervalNode . \n" + + " ?existingIntervalNode a <" + intervalType + "> . }"; + + final static String existingStartNodeQuery = + "SELECT ?existingStartNode WHERE { \n" + + " ?awardReceipt <" + awardReceiptToInterval + "> ?intervalNode . \n" + + " ?intervalNode a <" + intervalType + "> . \n" + + " ?intervalNode <" + intervalToStart + "> ?existingStartNode . \n" + + " ?existingStartNode a <" + dateTimeValueType + "> . } "; + + final static String existingEndNodeQuery = + "SELECT ?existingEndNode WHERE { \n" + + " ?awardReceipt <" + awardReceiptToInterval + "> ?intervalNode . \n" + + " ?intervalNode a <" + intervalType + "> . \n" + + " ?intervalNode <" + intervalToEnd + "> ?existingEndNode . \n" + + " ?existingEndNode a <" + dateTimeValueType + "> } "; + + final static String existingYearAwardedPrecisionQuery = + "SELECT ?existingYearAwardedPrecision WHERE { \n" + + " ?awardReceipt <" + yearAwardedPred + "> ?yearAwarded . \n" + + " ?yearAwarded a <" + dateTimeValueType + "> . \n" + + " ?yearAwarded <" + dateTimePrecision + "> ?existingYearAwardedPrecision . }"; + + final static String existingStartPrecisionQuery = + "SELECT ?existingStartPrecision WHERE { \n" + + " ?awardReceipt <" + awardReceiptToInterval + "> ?intervalNode . \n" + + " ?intervalNode a <" + intervalType + "> . \n" + + " ?intervalNode <" + intervalToStart + "> ?startNode . \n" + + " ?startNode a <" + dateTimeValueType + "> . \n" + + " ?startNode <" + dateTimePrecision + "> ?existingStartPrecision . }"; + + final static String existingEndPrecisionQuery = + "SELECT ?existingEndPrecision WHERE { \n" + + " ?awardReceipt <" + awardReceiptToInterval + "> ?intervalNode . \n" + + " ?intervalNode a <" + intervalType + "> . \n" + + " ?intervalNode <" + intervalToEnd + "> ?endNode . \n" + + " ?endNode a <" + dateTimeValueType + "> . \n" + + " ?endNode <" + dateTimePrecision + "> ?existingEndPrecision . }"; + +}