diff --git a/languages/example/themes/wilma/i18n/all_es.properties b/languages/example/themes/wilma/i18n/all_es.properties index 2a89246e..1753870f 100644 --- a/languages/example/themes/wilma/i18n/all_es.properties +++ b/languages/example/themes/wilma/i18n/all_es.properties @@ -669,7 +669,7 @@ vis_tools_note_four = Los modelos se actualizan cada vez que se reinicia el serv drag_drop_reorder_authors = Arrastrar y soltar para cambiar el orden de los autores reordering_authors_failed = Reordenación de los autores no. confirm_author_removal = ¿Está seguro que desea eliminar este autor: -error_processing_aithor_request = Solicitud de procesamiento Error: el autor no se elimina +error_processing_author_request = Solicitud de procesamiento Error: el autor no se elimina author_capitalized = Autor or_add_new_one = o añadir uno nuevo. @@ -824,4 +824,21 @@ first_name = Primer nombre last_name = Apellido title_not_found = Título que no se encuentra. speeches_capitalized = Discursos -theses_capitalized = Tesis \ No newline at end of file +theses_capitalized = Tesis +select_document_type = Por favor seleccione un valor en el campo Tipo de Documento. +select_a_document_name = Por favor, introduzca o seleccione un valor en el campo Nombre de Documento. +document_type_capitalized = Tipo de Documento +document_name_capitalized = Nombre de Documento +selected_document = Documento seleccionada +editor_name = nombre de editor +missing_editor = falta editor +drag_drop_reorder_editors = Arrastrar y soltar para cambiar el orden de los editores +reordering_editors_failed = Reordenación de los editores no. +confirm_editor_removal = ¿Está seguro que desea eliminar este editor: +error_processing_editor_request = olicitud de procesamiento error: el editor no se elimina +manage_editors = Manejar Editores +no_linked_author = ningún editor vinculados +remove_editor_link = desconecte la conexión de editor +add_an_editor = Agregar uno Editor +add_editor = Agregar Editor +please_select_type = Por favor Seleccione un tipo de la lista desplegable. \ No newline at end of file diff --git a/productMods/config/listViewConfig-authorInAuthorship.xml b/productMods/config/listViewConfig-authorInAuthorship.xml index b63ab0a8..2d328285 100644 --- a/productMods/config/listViewConfig-authorInAuthorship.xml +++ b/productMods/config/listViewConfig-authorInAuthorship.xml @@ -65,12 +65,19 @@ + PREFIX core: <http://vivoweb.org/ontology/core#> PREFIX bibo: <http://purl.org/ontology/bibo/> PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> CONSTRUCT { + ?subject ?property ?authorship . + ?authorship a core:Authorship . + ?authorship core:relates ?infoResource . ?infoResource a bibo:Document . ?infoResource vitro:mostSpecificType ?subclass } WHERE { + ?subject ?property ?authorship . + ?authorship a core:Authorship . + ?authorship core:relates ?infoResource . ?infoResource a bibo:Document . ?infoResource vitro:mostSpecificType ?subclass } @@ -90,25 +97,35 @@ ?publishedIn rdfs:label ?journal } WHERE { { - ?subject ?property ?authorship + ?subject ?property ?authorship . + ?authorship a core:Authorship } UNION { ?subject ?property ?authorship . + ?authorship a core:Authorship . ?authorship ?authorshipProperty ?authorshipValue } UNION { ?subject ?property ?authorship . - ?authorship core:linkedInformationResource ?infoResource + ?authorship a core:Authorship . + ?authorship core:relates ?infoResource . + ?infoResource a bibo:Document } UNION { ?subject ?property ?authorship . - ?authorship core:linkedInformationResource ?infoResource . + ?authorship a core:Authorship . + ?authorship core:relates ?infoResource . + ?infoResource a bibo:Document . ?infoResource rdfs:label ?infoResourceName } UNION { ?subject ?property ?authorship . - ?authorship core:linkedInformationResource ?infoResource . + ?authorship a core:Authorship . + ?authorship core:relates ?infoResource . + ?infoResource a bibo:Document . ?infoResource core:hasPublicationVenue ?publishedIn } UNION { ?subject ?property ?authorship . - ?authorship core:linkedInformationResource ?infoResource . + ?authorship a core:Authorship . + ?authorship core:relates ?infoResource . + ?infoResource a bibo:Document . ?infoResource core:hasPublicationVenue ?publishedIn . ?publishedIn rdfs:label ?journal } @@ -123,8 +140,10 @@ PREFIX foaf: <http://xmlns.com/foaf/0.1/> CONSTRUCT { ?subject ?property ?authorship . + ?authorship a core:Authorship . ?authorship ?authorshipProperty ?authorshipValue . - ?authorship core:linkedInformationResource ?infoResource . + ?authorship core:relates ?infoResource . + ?infoResource a bibo:Document . ?infoResource ?infoResourceProperty ?infoResourceValue . ?infoResource bibo:reproducedIn ?appearsInObj . ?infoResource core:publisher ?publisherObj . @@ -139,38 +158,51 @@ ?partOfObj rdfs:label ?partOf } WHERE { { - ?subject ?property ?authorship + ?subject ?property ?authorship . + ?authorship a core:Authorship } UNION { ?subject ?property ?authorship . + ?authorship a core:Authorship . ?authorship ?authorshipProperty ?authorshipValue } UNION { ?subject ?property ?authorship . - ?authorship core:relates ?infoResource + ?authorship a core:Authorship . + ?authorship core:relates ?infoResource . + ?infoResource a bibo:Document . } UNION { ?subject ?property ?authorship . + ?authorship a core:Authorship . ?authorship core:relates ?infoResource . ?infoResource a bibo:Document . ?infoResource ?infoResourceProperty ?infoResourceValue } UNION { ?subject ?property ?authorship . + ?authorship a core:Authorship . ?authorship core:relates ?infoResource . + ?infoResource a bibo:Document . ?infoResource bibo:reproducedIn ?appearsInObj . ?appearsInObj rdfs:label ?appearsIn } UNION { ?subject ?property ?authorship . + ?authorship a core:Authorship . ?authorship core:relates ?infoResource . + ?infoResource a bibo:Document . ?infoResource core:publisher ?publisherObj . ?publisherObj rdfs:label ?publisher } UNION { ?subject ?property ?authorship . + ?authorship a core:Authorship . ?authorship core:relates ?infoResource . + ?infoResource a bibo:Document . ?infoResource core:relatedBy ?editorship . ?editorship core:relates ?editorObj . ?editorObj rdfs:label ?editor } UNION { ?subject ?property ?authorship . + ?authorship a core:Authorship . ?authorship core:relates ?infoResource . + ?infoResource a bibo:Document . ?infoResource core:partOf ?partOfObj . ?partOfObj rdfs:label ?partOf } @@ -183,12 +215,14 @@ PREFIX bibo: <http://purl.org/ontology/bibo/> CONSTRUCT { ?subject ?property ?authorship . + ?authorship a core:Authorship . ?authorship core:relates ?infoResource . ?infoResource a bibo:Document . ?infoResource core:dateTimeValue ?dateTimeValue . ?dateTimeValue core:dateTime ?dateTime } WHERE { ?subject ?property ?authorship . + ?authorship a core:Authorship . ?authorship core:relates ?infoResource . ?infoResource a bibo:Document . ?infoResource core:dateTimeValue ?dateTimeValue . diff --git a/productMods/config/listViewConfig-editorship.xml b/productMods/config/listViewConfig-editorship.xml new file mode 100644 index 00000000..35491465 --- /dev/null +++ b/productMods/config/listViewConfig-editorship.xml @@ -0,0 +1,106 @@ + + + + + + + + PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> + PREFIX core: <http://vivoweb.org/ontology/core#> + PREFIX afn: <http://jena.hpl.hp.com/ARQ/function#> + PREFIX bibo: <http://purl.org/ontology/bibo/> + PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> + PREFIX foaf: <http://xmlns.com/foaf/0.1/> + + SELECT DISTINCT ?subclass + ?editorship + ?infoResource ?infoResourceName + ?dateTime + WHERE { + ?subject ?property ?editorship . + ?editorship core:relates ?infoResource . + ?infoResource a <http://purl.obolibrary.org/obo/IAO_0000030> . + ?infoResource rdfs:label ?infoResourceName . + + OPTIONAL { ?infoResource vitro:mostSpecificType ?subclass } + OPTIONAL { ?infoResource core:dateTimeValue ?dateTimeValue . + ?dateTimeValue core:dateTime ?dateTime + } + + + FILTER ( bound(?infoResource) ) + + } ORDER BY ?subclass DESC(?dateTime) ?infoResourceName + + + + PREFIX core: <http://vivoweb.org/ontology/core#> + PREFIX bibo: <http://purl.org/ontology/bibo/> + PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> + CONSTRUCT { + ?subject ?property ?editorship . + ?editorship a core:Editorship . + ?editorship core:relates ?infoResource . + ?infoResource a <http://purl.obolibrary.org/obo/IAO_0000030> . + ?infoResource vitro:mostSpecificType ?subclass + } WHERE { + ?subject ?property ?editorship . + ?editorship a core:Editorship . + ?editorship core:relates ?infoResource . + ?infoResource a <http://purl.obolibrary.org/obo/IAO_0000030> . + ?infoResource vitro:mostSpecificType ?subclass + } + + + + PREFIX core: <http://vivoweb.org/ontology/core#> + PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> + PREFIX bibo: <http://purl.org/ontology/bibo/> + CONSTRUCT { + ?subject ?property ?editorship . + ?editorship core:relates ?infoResource . + ?infoResource a <http://purl.obolibrary.org/obo/IAO_0000030> . + ?infoResource rdfs:label ?infoResourceName + } WHERE { + { + ?subject ?property ?editorship . + ?editorship a core:Editorship + } + UNION { + ?subject ?property ?editorship . + ?editorship a core:Editorship . + ?editorship core:relates ?infoResource . + ?infoResource a <http://purl.obolibrary.org/obo/IAO_0000030> + } UNION { + ?subject ?property ?editorship . + ?editorship a core:Editorship . + ?editorship core:relates ?infoResource . + ?infoResource a <http://purl.obolibrary.org/obo/IAO_0000030> . + ?infoResource rdfs:label ?infoResourceName + } + } + + + + PREFIX core: <http://vivoweb.org/ontology/core#> + PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> + PREFIX bibo: <http://purl.org/ontology/bibo/> + CONSTRUCT { + ?subject ?property ?editorship . + ?editorship a core:Editorship . + ?editorship core:relates ?infoResource . + ?infoResource a <http://purl.obolibrary.org/obo/IAO_0000030> . + ?infoResource core:dateTimeValue ?dateTimeValue . + ?dateTimeValue core:dateTime ?dateTime + } WHERE { + ?subject ?property ?editorship . + ?editorship a core:Editorship . + ?editorship core:relates ?infoResource . + ?infoResource a <http://purl.obolibrary.org/obo/IAO_0000030> . + ?infoResource core:dateTimeValue ?dateTimeValue . + ?dateTimeValue core:dateTime ?dateTime + } + + + + diff --git a/productMods/config/listViewConfig-informationResourceInAuthorship.xml b/productMods/config/listViewConfig-informationResourceInAuthorship.xml index 43d2c320..343609b0 100644 --- a/productMods/config/listViewConfig-informationResourceInAuthorship.xml +++ b/productMods/config/listViewConfig-informationResourceInAuthorship.xml @@ -16,7 +16,6 @@ ?person ?personName WHERE { ?subject ?property ?authorship . - ?authorship a core:Authorship OPTIONAL { ?authorship core:rank ?rank } OPTIONAL { ?authorship core:relates ?person . ?person a foaf:Person . @@ -50,6 +49,7 @@ PREFIX foaf: <http://xmlns.com/foaf/0.1/> CONSTRUCT { ?subject ?property ?authorship . + ?authorship a core:Authorship . ?authorship ?authorshipProperty ?authorshipValue . ?authorship core:relates ?person . ?person a foaf:Person . @@ -57,17 +57,21 @@ ?person vitro:mostSpecificType ?subclass } WHERE { { - ?subject ?property ?authorship + ?subject ?property ?authorship . + ?authorship a core:Authorship } UNION { ?subject ?property ?authorship . + ?authorship a core:Authorship . ?authorship ?authorshipProperty ?authorshipValue } UNION { ?subject ?property ?authorship . + ?authorship a core:Authorship . ?authorship core:relates ?person . ?person a foaf:Person . ?person rdfs:label ?personName } UNION { ?subject ?property ?authorship . + ?authorship a core:Authorship . ?authorship core:relates ?person . ?person a foaf:Person . ?person rdfs:label ?personName . diff --git a/productMods/config/listViewConfig-informationResourceInEditorship.xml b/productMods/config/listViewConfig-informationResourceInEditorship.xml new file mode 100644 index 00000000..7bd6b34f --- /dev/null +++ b/productMods/config/listViewConfig-informationResourceInEditorship.xml @@ -0,0 +1,84 @@ + + + + + + + + PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> + PREFIX core: <http://vivoweb.org/ontology/core#> + PREFIX afn: <http://jena.hpl.hp.com/ARQ/function#> + PREFIX foaf: <http://xmlns.com/foaf/0.1/> + PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> + + SELECT DISTINCT ?subclass + ?editorship + ?person ?personName + WHERE { + ?subject ?property ?editorship . + OPTIONAL { ?editorship core:rank ?rank } + OPTIONAL { ?editorship core:relates ?person . + ?person a foaf:Person . + ?person rdfs:label ?personName + + OPTIONAL { ?person vitro:mostSpecificType ?subclass . + ?subclass rdfs:subClassOf foaf:Person + } + + } + + FILTER ( bound(?person) ) + + } ORDER BY ?subclass ?rank ?personName + + + + PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> + PREFIX foaf: <http://xmlns.com/foaf/0.1/> + CONSTRUCT { + ?subclass rdfs:subClassOf foaf:Person + } WHERE { + ?subclass rdfs:subClassOf foaf:Person + } + + + + PREFIX core: <http://vivoweb.org/ontology/core#> + PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> + PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> + PREFIX foaf: <http://xmlns.com/foaf/0.1/> + CONSTRUCT { + ?subject ?property ?editorship . + ?editorship a core:Editorship . + ?editorship ?editorshipProperty ?editorshipValue . + ?editorship core:relates ?person . + ?person a foaf:Person . + ?person rdfs:label ?personName . + ?person vitro:mostSpecificType ?subclass + } WHERE { + { + ?subject ?property ?editorship . + ?editorship a core:Editorship + } UNION { + ?subject ?property ?editorship . + ?editorship a core:Editorship . + ?editorship ?editorshipProperty ?editorshipValue + } UNION { + ?subject ?property ?editorship . + ?editorship a core:Editorship . + ?editorship core:relates ?person . + ?person a foaf:Person . + ?person rdfs:label ?personName + } UNION { + ?subject ?property ?editorship . + ?editorship a core:Editorship . + ?editorship core:relates ?person . + ?person a foaf:Person . + ?person rdfs:label ?personName . + ?person vitro:mostSpecificType ?subclass + } + } + + + + diff --git a/productMods/templates/freemarker/body/partials/individual/propStatement-editorship.ftl b/productMods/templates/freemarker/body/partials/individual/propStatement-editorship.ftl new file mode 100644 index 00000000..2f2f4bda --- /dev/null +++ b/productMods/templates/freemarker/body/partials/individual/propStatement-editorship.ftl @@ -0,0 +1,31 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +<#-- Custom object property statement view for http://vivoweb.org/ontology/core#authorInEditorship. + + This template must be self-contained and not rely on other variables set for the individual page, because it + is also used to generate the property statement during a deletion. + --> + +<#import "lib-sequence.ftl" as s> +<#import "lib-datetime.ftl" as dt> + +<@showEditorship statement /> + +<#-- Use a macro to keep variable assignments local; otherwise the values carry over to the + next statement --> +<#macro showEditorship statement> + <#local resourceTitle> + <#if statement.infoResource??> + <#if citationDetails?has_content> + ${statement.infoResourceName}.  + <#else> + ${statement.infoResourceName} + + <#else> + <#-- This shouldn't happen, but we must provide for it --> + ${i18n().missing_info_resource} + + + + ${resourceTitle} <@dt.yearSpan "${statement.dateTime!}" /> + diff --git a/productMods/templates/freemarker/body/partials/individual/propStatement-informationResourceInEditorship.ftl b/productMods/templates/freemarker/body/partials/individual/propStatement-informationResourceInEditorship.ftl new file mode 100644 index 00000000..3d6c16e3 --- /dev/null +++ b/productMods/templates/freemarker/body/partials/individual/propStatement-informationResourceInEditorship.ftl @@ -0,0 +1,21 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +<#-- Custom object property statement view for http://vivoweb.org/ontology/core#informationResourceInAuthorship. + + This template must be self-contained and not rely on other variables set for the individual page, because it + is also used to generate the property statement during a deletion. + --> + +<#import "lib-sequence.ftl" as s> +<@showEditorship statement /> + +<#-- Use a macro to keep variable assignments local; otherwise the values carry over to the + next statement --> +<#macro showEditorship statement> + <#if statement.person??> + ${statement.personName} + <#else> + <#-- This shouldn't happen, but we must provide for it --> + ${i18n().missing_editor} + + \ No newline at end of file diff --git a/productMods/templates/freemarker/edit/forms/addAuthorsToInformationResource.ftl b/productMods/templates/freemarker/edit/forms/addAuthorsToInformationResource.ftl index af1d23e8..1b9af363 100644 --- a/productMods/templates/freemarker/edit/forms/addAuthorsToInformationResource.ftl +++ b/productMods/templates/freemarker/edit/forms/addAuthorsToInformationResource.ftl @@ -188,7 +188,7 @@ var i18nStrings = { authorNameWrapperTitle: '${i18n().drag_drop_reorder_authors}', reorderAuthorsAlert: '${i18n().reordering_authors_failed}', removeAuthorshipMessage: '${i18n().confirm_author_removal}', - removeAuthorshipAlert: '${i18n().error_processing_aithor_request}', + removeAuthorshipAlert: '${i18n().error_processing_author_request}', authorTypeText: '${i18n().author_capitalized}', organizationTypeText: '${i18n().organization_capitalized}', helpTextSelect: '${i18n().select_an_existing}', diff --git a/productMods/templates/freemarker/edit/forms/addEditorsToInformationResource.ftl b/productMods/templates/freemarker/edit/forms/addEditorsToInformationResource.ftl new file mode 100644 index 00000000..2c40d649 --- /dev/null +++ b/productMods/templates/freemarker/edit/forms/addEditorsToInformationResource.ftl @@ -0,0 +1,178 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +<#-- Custom form for adding editors to information resources --> + +<#import "lib-vivo-form.ftl" as lvf> + +<#--Retrieve certain page specific information information--> +<#assign newRank = editConfiguration.pageData.newRank /> +<#assign existingEditorInfo = editConfiguration.pageData.existingEditorInfo /> +<#assign rankPredicate = editConfiguration.pageData.rankPredicate /> + +<#--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/> + + +<#--Submission values for these fields may be returned if user did not fill out fields for new person--> +<#assign lastNameValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "lastName") /> +<#assign firstNameValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "firstName") /> +<#assign middleNameValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "middleName") /> + +<#--UL class based on size of existing editors--> +<#assign ulClass = ""/> +<#if (existingEditorInfo?size > 0)> + <#assign ulClass = "class='dd'"/> + + +<#assign title="${editConfiguration.subjectName}" /> +<#assign requiredHint=" *" /> +<#assign initialHint="(${i18n().initial_okay})" /> + +<@lvf.unsupportedBrowser urls.base/> + +

${title}

+ +<#if submissionErrors?has_content> + + + +

${i18n().manage_editors}

+ + +
+
+ + + + ${i18n().or} + ${i18n().return_to_publication} + +
+ +
+

${i18n().add_an_editor}

+ +
+ <#--These wrapper paragraph elements are important because javascript hides parent of these fields, since last name + should be visible even when first name/middle name are not, the parents should be separate for each field--> +

+ + +

+ +

+ + +

+ +

+ + +

+ +
+

+ + + (${i18n().verify_match_capitalized}) + +

+
+
+ + + + + + +

+ + + + ${i18n().or} + + ${i18n().cancel_link} + +

+ +

* ${i18n().required_fields}

+
+ + + +${stylesheets.add('', + '', + '', + '')} + + +${scripts.add('')} +${scripts.add('')} +${scripts.add('')} +${scripts.add('')} \ No newline at end of file diff --git a/productMods/templates/freemarker/edit/forms/addEditorshipToPerson.ftl b/productMods/templates/freemarker/edit/forms/addEditorshipToPerson.ftl new file mode 100644 index 00000000..8d6deae8 --- /dev/null +++ b/productMods/templates/freemarker/edit/forms/addEditorshipToPerson.ftl @@ -0,0 +1,160 @@ +<#-- $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> + +<#assign subjectName=""/> +<#assign orgLabel="mysteryOrgLabel"/> + +<#--Retrieve certain edit configuration information--> +<#assign editMode = editConfiguration.pageData.editMode /> +<#assign htmlForElements = editConfiguration.pageData.htmlForElements /> + +<#--The blank sentinel indicates what value should be put in a URI when no autocomplete result has been selected. +If the blank value is non-null or non-empty, n3 editing for an existing object will remove the original relationship +if nothing is selected for that object--> +<#assign blankSentinel = "" /> +<#if editConfigurationConstants?has_content && editConfigurationConstants?keys?seq_contains("BLANK_SENTINEL")> + <#assign blankSentinel = editConfigurationConstants["BLANK_SENTINEL"] /> + + +<#--This flag is for clearing the label field on submission for an existing object being selected from autocomplete. +Set this flag on the input acUriReceiver where you would like this behavior to occur. --> +<#assign flagClearLabelForExisting = "flagClearLabelForExisting" /> + +<#--Retrieve variables needed--> +<#assign documentTypeValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "documentType")/> +<#assign documentLabelValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "documentLabel") /> +<#assign documentLabelDisplayValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "documentLabelDisplay") /> +<#assign existingDocumentValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "existingDocument") /> + +<#--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" || editMode == "repair"> + <#assign titleVerb="${i18n().edit_capitalized}"> + <#assign submitButtonText="${i18n().save_changes}"> + <#assign disabledVal="disabled"> +<#else> + <#assign titleVerb="${i18n().create_capitalized}"> + <#assign submitButtonText="${i18n().create_entry}"> + <#assign disabledVal=""/> + + +<#assign requiredHint = " *" /> +<#assign yearHint = "(${i18n().year_hint_format})" /> + + +

${titleVerb} ${i18n().educational_training_for} ${editConfiguration.subjectName}

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

+ + <#assign docTypeOpts = editConfiguration.pageData.documentType /> + +

+ +

+ + + +

+ +
+

+ + + (${i18n().verify_match_capitalized} ${i18n().or} + ${i18n().change_selection}) +

+ +
+ + + <#--End draw elements--> + +

+ ${i18n().or} + ${i18n().cancel_link} +

+ +

* ${i18n().required_fields}

+ +
+ + + + +
+ +${stylesheets.add('')} +${stylesheets.add('')} +${stylesheets.add('')} + + +${scripts.add('', + '', + '', + '', + '', + '')} + + diff --git a/productMods/templates/freemarker/edit/forms/addRoleToPersonTwoStage.ftl b/productMods/templates/freemarker/edit/forms/addRoleToPersonTwoStage.ftl index f5a4c7b3..b8e5981f 100644 --- a/productMods/templates/freemarker/edit/forms/addRoleToPersonTwoStage.ftl +++ b/productMods/templates/freemarker/edit/forms/addRoleToPersonTwoStage.ftl @@ -106,7 +106,10 @@ Set this flag on the input acUriReceiver where you would like this behavior to o - <#--Checking if Name field is empty--> + <#--Checking if Type, Name and Role fields are empty--> + <#if lvf.submissionErrorExists(editSubmission, "roleActivityType")> + ${i18n().please_select_type}
+ <#if lvf.submissionErrorExists(editSubmission, "activityLabel")> ${i18n().select_or_enter_name}
diff --git a/productMods/templates/freemarker/edit/forms/js/addEditorsToInformationResource.js b/productMods/templates/freemarker/edit/forms/js/addEditorsToInformationResource.js new file mode 100644 index 00000000..dc9187fe --- /dev/null +++ b/productMods/templates/freemarker/edit/forms/js/addEditorsToInformationResource.js @@ -0,0 +1,703 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +var addEditorForm = { + + /* *** Initial page setup *** */ + + onLoad: function() { + + if (this.disableFormInUnsupportedBrowsers()) { + return; + } + this.mixIn(); + this.initObjects(); + this.initPage(); + }, + + disableFormInUnsupportedBrowsers: function() { + var disableWrapper = $('#ie67DisableWrapper'); + + // Check for unsupported browsers only if the element exists on the page + if (disableWrapper.length) { + if (vitro.browserUtils.isIELessThan8()) { + disableWrapper.show(); + $('.noIE67').hide(); + return true; + } + } + return false; + }, + + mixIn: function() { + // Mix in the custom form utility methods + $.extend(this, vitro.customFormUtils); + + // Get the custom form data from the page + $.extend(this, customFormData); + + // Get the i18n variables from the page + $.extend(this, i18nStrings); + }, + + // On page load, create references for easy access to form elements. + // NB These must be assigned after the elements have been loaded onto the page. + initObjects: function() { + + this.form = $('#addEditorForm'); + this.showFormButtonWrapper = $('#showAddForm'); + this.showFormButton = $('#showAddFormButton'); + this.removeEditorshipLinks = $('a.remove'); + //this.undoLinks = $('a.undo'); + this.submit = this.form.find(':submit'); + this.cancel = this.form.find('.cancel'); + this.acSelector = this.form.find('.acSelector'); + this.labelField = $('#label'); + this.firstNameField = $('#firstName'); + this.middleNameField = $('#middleName'); + this.lastNameField = $('#lastName'); + this.lastNameLabel = $('label[for=lastName]'); + this.personUriField = $('#personUri'); + this.firstNameWrapper = this.firstNameField.parent(); + this.middleNameWrapper = this.middleNameField.parent(); + this.lastNameWrapper = this.lastNameField.parent(); + this.selectedEditor = $('#selectedEditor'); + this.selectedEditorName = $('#selectedEditorName'); + this.acHelpTextClass = 'acSelectorWithHelpText'; + this.verifyMatch = this.form.find('.verifyMatch'); + this.personSection = $('section#personFields'); + this.personLink = $('a#personLink'); + this.returnLink = $('a#returnLink'); + }, + + // Initial page setup. Called only at page load. + initPage: function() { + + this.initEditorshipData(); + + // Show elements hidden by CSS for the non-JavaScript-enabled version. + // NB The non-JavaScript version of this form is currently not functional. + this.removeEditorshipLinks.show(); + + //this.undoLinks.hide(); + + this.bindEventListeners(); + + this.initAutocomplete(); + + this.initElementData(); + + this.initEditorDD(); + + if (this.findValidationErrors()) { + this.initFormAfterInvalidSubmission(); + } else { + this.initEditorListOnlyView(); + } + }, + + + /* *** Set up the various page views *** */ + + // This initialization is done only on page load, not when returning to editor list only view + // after hitting 'cancel.' + initEditorListOnlyView: function() { + + if ($('.editorship').length) { // make sure we have at least one editor + // Reorder editors on page load so that previously unranked editors get a rank. Otherwise, + // when we add a new editor, it will get put ahead of any previously unranked editors, instead + // of at the end of the list. (It is also helpful to normalize the data before we get started.) + this.reorderEditors(); + } + this.showEditorListOnlyView(); + }, + + // This view shows the list of existing editors and hides the form. + // There is a button to show the form. We do this on page load, and after + // hitting 'cancel' from full view. + showEditorListOnlyView: function() { + this.hideForm(); + this.showFormButtonWrapper.show(); + }, + + // View of form after returning from an invalid submission. On this form, + // validation errors entail that we were entering a new person, so we show + // all the fields straightaway. + initFormAfterInvalidSubmission: function() { + this.initForm(); + this.showFieldsForNewPerson(); + }, + + // Initial view of add editor form. We get here by clicking the show form button, + // or by cancelling out of an autocomplete selection. + initFormView: function() { + + this.initForm(); + + // There's a conflict bewteen the last name fields .blur event and the cancel + // button's click. So display the middle and first names along with the last name tlw72 + //this.hideFieldsForNewPerson(); + + // This shouldn't be needed, because calling this.hideFormFields(this.lastNameWrapper) + // from showSelectedEditor should do it. However, it doesn't work from there, + // or in the cancel action, or if referring to this.lastNameField. None of those work, + // however. + $('#lastName').val(''); + // Set the initial autocomplete help text in the acSelector field. + this.addAcHelpText(this.acSelector); + + return false; + + }, + + // Form initialization common to both a 'clean' form view and when + // returning from an invalid submission. + initForm: function() { + + // Hide the button that shows the form + this.showFormButtonWrapper.hide(); + + this.hideSelectedPerson(); + + this.cancel.unbind('click'); + this.cancel.bind('click', function() { + addEditorForm.showEditorListOnlyView(); + addEditorForm.setEditorType("person"); + return false; + }); + + // Reset the last name field. It had been hidden if we selected an editor from + // the autocomplete field. + this.lastNameWrapper.show(); + this.showFieldsForNewPerson(); + + // Show the form + this.form.show(); + //this.lastNameField.focus(); + }, + + hideSelectedPerson: function() { + this.selectedEditor.hide(); + this.selectedEditorName.html(''); + this.personUriField.val(''); + }, + + showFieldsForNewPerson: function() { + this.firstNameWrapper.show(); + this.middleNameWrapper.show(); + }, + + hideFieldsForNewPerson: function() { + this.hideFields(this.firstNameWrapper); + this.hideFields(this.middleNameWrapper); + }, + + /* *** Ajax initializations *** */ + + /* Autocomplete */ + initAutocomplete: function() { + + // Make cache a property of this so we can access it after removing + // an editor. + this.acCache = {}; + this.setAcFilter(); + var $acField = this.lastNameField; + var urlString = addEditorForm.acUrl + addEditorForm.personUrl + addEditorForm.tokenize; + var authType = "person"; + + $acField.autocomplete({ + minLength: 2, + source: function(request, response) { + if (request.term in addEditorForm.acCache) { + // console.log('found term in cache'); + response(addEditorForm.acCache[request.term]); + return; + } + // console.log('not getting term from cache'); + + // If the url query params are too long, we could do a post + // here instead of a get. Add the exclude uris to the data + // rather than to the url. + $.ajax({ + url: urlString, + dataType: 'json', + data: { + term: request.term + }, + complete: function(xhr, status) { + // Not sure why, but we need an explicit json parse here. jQuery + // should parse the response text and return a json object. + var results = jQuery.parseJSON(xhr.responseText), + filteredResults = addEditorForm.filterAcResults(results); + addEditorForm.acCache[request.term] = filteredResults; + response(filteredResults); + } + + }); + }, + // Select event not triggered in IE6/7 when selecting with enter key rather + // than mouse. Thus form is disabled in these browsers. + // jQuery UI bug: when scrolling through the ac suggestions with up/down arrow + // keys, the input element gets filled with the highlighted text, even though no + // select event has been triggered. To trigger a select, the user must hit enter + // or click on the selection with the mouse. This appears to confuse some users. + select: function(event, ui) { + addEditorForm.showSelectedEditor(ui,authType); + } + }); + + }, + + initElementData: function() { + this.verifyMatch.data('baseHref', this.verifyMatch.attr('href')); + }, + + setAcFilter: function() { + this.acFilter = []; + + $('.editorship').each(function() { + var uri = $(this).data('editorUri'); + addEditorForm.acFilter.push(uri); + }); + }, + + removeEditorFromAcFilter: function(editor) { + var index = $.inArray(editor, this.acFilter); + if (index > -1) { // this should always be true + this.acFilter.splice(index, 1); + } + }, + + filterAcResults: function(results) { + var filteredResults = []; + if (!this.acFilter.length) { + return results; + } + $.each(results, function() { + if ($.inArray(this.uri, addEditorForm.acFilter) == -1) { + // console.log("adding " + this.label + " to filtered results"); + filteredResults.push(this); + } + else { + // console.log("filtering out " + this.label); + } + }); + return filteredResults; + }, + + // After removing an editorship, selectively clear matching autocomplete + // cache entries, else the associated editor will not be included in + // subsequent autocomplete suggestions. + clearAcCacheEntries: function(name) { + name = name.toLowerCase(); + $.each(this.acCache, function(key, value) { + if (name.indexOf(key) == 0) { + delete addEditorForm.acCache[key]; + } + }); + }, + + // Action taken after selecting an editor from the autocomplete list + showSelectedEditor: function(ui,authType) { + + if ( authType == "person" ) { + this.personUriField.val(ui.item.uri); + this.selectedEditor.show(); + + // Transfer the name from the autocomplete to the selected editor + // name display, and hide the last name field. + this.selectedEditorName.html(ui.item.label); + // NB For some reason this doesn't delete the value from the last name + // field when the form is redisplayed. Thus it's done explicitly in initFormView. + this.hideFields(this.lastNameWrapper); + // These get displayed if the selection was made through an enter keystroke, + // since the keydown event on the last name field is also triggered (and + // executes first). So re-hide them here. + this.hideFieldsForNewPerson(); + this.personLink.attr('href', this.verifyMatch.data('baseHref') + ui.item.uri); + } + + // Cancel restores initial form view + this.cancel.unbind('click'); + this.cancel.bind('click', function() { + addEditorForm.initFormView(); + addEditorForm.setEditorType(authType); + return false; + }); + }, + + /* Drag-and-drop */ + initEditorDD: function() { + + var editorshipList = $('#editorships'), + editorships = editorshipList.children('li'); + + if (editorships.length < 2) { + return; + } + + $('.editorNameWrapper').each(function() { + $(this).attr('title', addEditorForm.editorNameWrapperTitle); + }); + + editorshipList.sortable({ + cursor: 'move', + update: function(event, ui) { + addEditorForm.reorderEditors(event, ui); + } + }); + }, + + // Reorder editors. Called on page load and after editor drag-and-drop and remove. + // Event and ui parameters are defined only in the case of drag-and-drop. + reorderEditors: function(event, ui) { + var editorships = $('li.editorship').map(function(index, el) { + return $(this).data('editorshipUri'); + }).get(); + + $.ajax({ + url: addEditorForm.reorderUrl, + data: { + predicate: addEditorForm.rankPredicate, + individuals: editorships + }, + traditional: true, // serialize the array of individuals for the server + dataType: 'json', + type: 'POST', + success: function(data, status, request) { + var pos; + $('.editorship').each(function(index){ + pos = index + 1; + // Set the new position for this element. The only function of this value + // is so we can reset an element to its original position in case reordering fails. + addEditorForm.setPosition(this, pos); + }); + // Set the form rank field value. + $('#rank').val(pos + 1); + }, + error: function(request, status, error) { + // ui is undefined on page load and after an editorship removal. + if (ui) { + // Put the moved item back to its original position. + // Seems we need to do this by hand. Can't see any way to do it with jQuery UI. ?? + var pos = addEditorForm.getPosition(ui.item), + nextpos = pos + 1, + editorships = $('#editorships'), + next = addEditorForm.findEditorship('position', nextpos); + + if (next.length) { + ui.item.insertBefore(next); + } + else { + ui.item.appendTo(editorships); + } + + alert(addEditorForm.reorderEditorsAlert); + } + } + }); + }, + + // On page load, associate data with each editorship element. Then we don't + // have to keep retrieving data from or modifying the DOM as we manipulate the + // editorships. + initEditorshipData: function() { + $('.editorship').each(function(index) { + $(this).data(editorshipData[index]); + + // RY We might still need position to put back an element after reordering + // failure. Rank might already have been reset? Check. + // We also may need position to implement undo links: we want the removed editorship + // to show up in the list, but it has no rank. + $(this).data('position', index+1); + }); + }, + + getPosition: function(editorship) { + return $(editorship).data('position'); + }, + + setPosition: function(editorship, pos) { + $(editorship).data('position', pos); + }, + + findEditorship: function(key, value) { + var matchingEditorship = $(); // if we don't find one, return an empty jQuery set + + $('.editorship').each(function() { + var editorship = $(this); + if ( editorship.data(key) === value ) { + matchingEditorship = editorship; + return false; // stop the loop + } + }); + + return matchingEditorship; + }, + + + /* *** Event listeners *** */ + + bindEventListeners: function() { + + this.showFormButton.click(function() { + addEditorForm.initFormView(); + return false; + }); + + this.form.submit(function() { + // NB Important JavaScript scope issue: if we call it this way, this = addEditorForm + // in prepareSubmit. If we do this.form.submit(this.prepareSubmit); then + // this != addEditorForm in prepareSubmit. + $selectedObj = addEditorForm.form.find('input.acSelector'); + addEditorForm.deleteAcHelpText($selectedObj); + addEditorForm.prepareSubmit(); + }); + + this.lastNameField.blur(function() { + // Cases where this event should be ignored: + // 1. personUri field has a value: the autocomplete select event has already fired. + // 2. The last name field is empty (especially since the field has focus when the form is displayed). + // 3. Autocomplete suggestions are showing. + if ( addEditorForm.personUriField.val() || !$(this).val() || $('ul.ui-autocomplete li.ui-menu-item').length ) { + return; + } + addEditorForm.onLastNameChange(); + }); + + this.personLink.click(function() { + window.open($(this).attr('href'), 'verifyMatchWindow', 'width=640,height=640,scrollbars=yes,resizable=yes,status=yes,toolbar=no,menubar=no,location=no'); + return false; + }); + + this.acSelector.focus(function() { + addEditorForm.deleteAcHelpText(this); + }); + + this.acSelector.blur(function() { + addEditorForm.addAcHelpText(this); + }); + + // When hitting enter in last name field, show first and middle name fields. + // NB This event fires when selecting an autocomplete suggestion with the enter + // key. Since it fires first, we undo its effects in the ac select event listener. + this.lastNameField.keydown(function(event) { + if (event.which === 13) { + addEditorForm.onLastNameChange(); + return false; // don't submit form + } + }); + + this.removeEditorshipLinks.click(function() { + addEditorForm.removeEditorship(this); + return false; + }); + + }, + + prepareSubmit: function() { + var firstName, + middleName, + lastName, + name; + + // If selecting an existing person, don't submit name fields + if (this.personUriField.val() != '' ) { + this.firstNameField.attr('disabled', 'disabled'); + this.middleNameField.attr('disabled', 'disabled'); + this.lastNameField.attr('disabled', 'disabled'); + } + else { + firstName = this.firstNameField.val(); + middleName = this.middleNameField.val(); + lastName = this.lastNameField.val(); + + name = lastName; + if (firstName) { + name += ', ' + firstName; + } + if (middleName) { + name += ' ' + middleName; + } + + this.labelField.val(name); + } + + }, + + onLastNameChange: function() { + this.showFieldsForNewPerson(); + this.firstNameField.focus(); + // this.fixNames(); + }, + + removeEditorship: function(link) { + // RY Upgrade this to a modal window + + editorName = $(link).prev().children().text(); + + var removeLast = false, + message = addEditorForm.removeEditorshipMessage + '\n\n' + editorName + ' ?\n\n'; + if (!confirm(message)) { + return false; + } + + if ( addEditorForm.showFormButtonWrapper.is(':visible') ) { + addEditorForm.returnLink.hide(); + $('img#indicatorOne').removeClass('hidden'); + addEditorForm.showFormButton.addClass('disabledSubmit'); + addEditorForm.showFormButton.attr('disabled','disabled'); + } + else { + addEditorForm.cancel.hide(); + $('img#indicatorTwo').removeClass('hidden'); + addEditorForm.submit.addClass('disabledSubmit'); + addEditorForm.submit.attr('disabled','disabled'); + } + + if ($(link)[0] === $('.remove:last')[0]) { + removeLast = true; + } + + $.ajax({ + url: $(link).attr('href'), + type: 'POST', + data: { + deletion: $(link).parents('.editorship').data('editorshipUri') + }, + dataType: 'json', + context: link, // context for callback + complete: function(request, status) { + var editorship, + editorUri; + + if (status === 'success') { + + editorship = $(this).parents('.editorship'); + + // Clear autocomplete cache entries matching this editor's name, else + // autocomplete will be retrieved from the cache, which excludes the removed editor. + addEditorForm.clearAcCacheEntries(editorship.data('editorName')); + + // Remove this editor from the acFilter so it is included in autocomplete + // results again. + addEditorForm.removeEditorFromAcFilter(editorship.data('editorUri')); + + editorship.fadeOut(400, function() { + var numEditors; + + // For undo link: add to a deletedEditorships array + + // Remove from the DOM + $(this).remove(); + + // Actions that depend on the editor having been removed from the DOM: + numEditors = $('.editorship').length; // retrieve the length after removing editorship from the DOM + + // If removed item not last, reorder to remove any gaps + if (numEditors > 0 && ! removeLast) { + addEditorForm.reorderEditors(); + } + + // If fewer than two editors remaining, disable drag-drop + if (numEditors < 2) { + addEditorForm.disableEditorDD(); + } + + if ( $('img#indicatorOne').is(':visible') ) { + $('img#indicatorOne').fadeOut(100, function() { + $(this).addClass('hidden'); + }); + + addEditorForm.returnLink.fadeIn(100, function() { + $(this).show(); + }); + addEditorForm.showFormButton.removeClass('disabledSubmit'); + addEditorForm.showFormButton.attr('disabled',''); + } + else { + $('img#indicatorTwo').fadeOut(100, function() { + $(this).addClass('hidden'); + }); + + addEditorForm.cancel.fadeIn(100, function() { + $(this).show(); + }); + addEditorForm.submit.removeClass('disabledSubmit'); + addEditorForm.submit.attr('disabled',''); + } + }); + + } else { + alert(addEditorForm.removeEditorshipAlert); + + } + } + }); + }, + + // Disable DD and associated cues if only one editor remains + disableEditorDD: function() { + var editorships = $('#editorships'), + editorNameWrapper = $('.editorNameWrapper'); + + editorships.sortable({ disable: true } ); + + // Use class dd rather than jQuery UI's class ui-sortable, so that we can remove + // the class if there's fewer than one editor. We don't want to remove the ui-sortable + // class, in case we want to re-enable DD without a page reload (e.g., if implementing + // adding an editor via Ajax request). + editorships.removeClass('dd'); + + editorNameWrapper.removeAttr('title'); + }, + + // RY To be implemented later. + toggleRemoveLink: function() { + // when clicking remove: remove the editor, and change link text to 'undo' + // when clicking undo: add the editor back, and change link text to 'remove' + }, + + // Set the initial help text in the lastName field and change the class name. + addAcHelpText: function(selectedObj) { + var typeText; + if ( $(selectedObj).attr('id') == "lastName" ) { + typeText = addEditorForm.editorTypeText; + } + + if (!$(selectedObj).val()) { + $(selectedObj).val(addEditorForm.helpTextSelect + " " + typeText + " " + addEditorForm.helpTextAdd) + .addClass(this.acHelpTextClass); + } + }, + + deleteAcHelpText: function(selectedObj) { + if ($(selectedObj).hasClass(this.acHelpTextClass)) { + $(selectedObj).val('') + .removeClass(this.acHelpTextClass); + } + }, + + // we need to set the correct class names for fields like the acSelector, acSelection, etc. + // as well as clear and disable fields, call other functions ... + setEditorType: function(authType) { + if ( authType == "person" ) { + this.personSection.show(); + this.acSelector.addClass("acSelector"); + this.personRadio.attr('checked', true); // needed for reset when cancel button is clicked + this.selectedEditor.addClass("acSelection"); + this.selectedEditorName.addClass("acSelectionInfo"); + this.personLink.addClass("verifyMatch"); + this.acSelector.attr('disabled', ''); + this.firstNameField.attr('disabled', ''); + this.middleNameField.attr('disabled', ''); + this.lastNameField.attr('disabled', ''); + + addEditorForm.addAcHelpText(this.acSelector); + addEditorForm.initAutocomplete(); + } + } +}; + +$(document).ready(function() { + addEditorForm.onLoad(); +}); diff --git a/productMods/templates/freemarker/edit/forms/js/awardReceiptUtils.js b/productMods/templates/freemarker/edit/forms/js/awardReceiptUtils.js index 6a5ed540..8f10a968 100644 --- a/productMods/templates/freemarker/edit/forms/js/awardReceiptUtils.js +++ b/productMods/templates/freemarker/edit/forms/js/awardReceiptUtils.js @@ -92,13 +92,8 @@ var awardReceiptUtils = { buildAwardReceiptLabel: function() { var rdfsLabel = ""; var $acSelection = $("div.acSelection[acGroupName='award']") - if ( this.editMode == "edit" ) { - if ( $acSelection.find("span.acSelectionInfo").text().length > 0 ) { - rdfsLabel = $("span.acSelectionInfo").text(); - } - else { - rdfsLabel = this.award.val(); - } + if ( $acSelection.find("span.acSelectionInfo").text().length > 0 ) { + rdfsLabel = $("span.acSelectionInfo").text(); } else { rdfsLabel = this.award.val(); @@ -110,6 +105,7 @@ var awardReceiptUtils = { rdfsLabel += " (" + this.subjectName + ")"; } this.recLabel.val(rdfsLabel); + alert(this.recLabel.val()); }, setYearAwardedValue: function() { diff --git a/rdf/display/everytime/PropertyConfig.n3 b/rdf/display/everytime/PropertyConfig.n3 index 26d55afc..80fa8df4 100644 --- a/rdf/display/everytime/PropertyConfig.n3 +++ b/rdf/display/everytime/PropertyConfig.n3 @@ -328,7 +328,6 @@ local:advisorRoleConfig a :ObjectPropertyDisplayConfig ; vitro:customEntryFormAnnot "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.PersonHasAdvisingRelationshipGenerator"^^ ; :propertyGroup . - local:informationResourceInAuthorshipContext a :ConfigContext ; :hasConfiguration local:informationResourceInAuthorshipConfig ; :configContextFor ; @@ -344,7 +343,23 @@ local:informationResourceInAuthorshipConfig a :ObjectPropertyDisplayConfig ; vitro:customEntryFormAnnot "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.AddAuthorsToInformationResourceGenerator"^^ ; :propertyGroup . +local:informationResourceInEditorshipContext a :ConfigContext ; + :hasConfiguration local:informationResourceInEditorshipConfig ; + :configContextFor ; + :qualifiedByDomain ; + :qualifiedBy . + +local:informationResourceInEditorshipConfig a :ObjectPropertyDisplayConfig ; + :listViewConfigFile "listViewConfig-informationResourceInEditorship.xml"^^xsd:string ; + :displayName "editors" ; + vitro:displayRankAnnot 10; + vitro:hiddenFromDisplayBelowRoleLevelAnnot role:public ; + vitro:prohibitedFromUpdateBelowRoleLevelAnnot role:public ; + vitro:customEntryFormAnnot "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.AddEditorsToInformationResourceGenerator"^^ ; + :propertyGroup . + ### vcard properties ### + local:mailingAddressContext a :ConfigContext ; :hasConfiguration local:mailingAddressConfig ; :configContextFor ; @@ -435,6 +450,21 @@ local:fullNameConfig a :ObjectPropertyDisplayConfig ; vitro:customEntryFormAnnot "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.AddFullNameToPersonGenerator"^^ ; :propertyGroup . +local:editorOfContext a :ConfigContext ; + :hasConfiguration local:editorOfConfig ; + :configContextFor ; + :qualifiedByDomain ; + :qualifiedBy . + +local:editorOfConfig a :ObjectPropertyDisplayConfig ; + :listViewConfigFile "listViewConfig-editorship.xml"^^xsd:string ; + :displayName "editor of" ; + vitro:displayRankAnnot 20; + vitro:hiddenFromDisplayBelowRoleLevelAnnot role:public ; + vitro:prohibitedFromUpdateBelowRoleLevelAnnot role:public ; + vitro:customEntryFormAnnot "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.AddEditorshipToPersonGenerator"^^ ; + :propertyGroup . + ### properties using default editing form ## local:eventWithinContext a :ConfigContext ; @@ -479,16 +509,17 @@ local:inEventSeriesConfig a :ObjectPropertyDisplayConfig ; vitro:prohibitedFromUpdateBelowRoleLevelAnnot role:public ; :propertyGroup . -local:awardAssignedByContext a :ConfigContext ; - :hasConfiguration local:awardAssignedByConfig ; - :configContextFor ; +local:awardReceiptsContext a :ConfigContext ; + :hasConfiguration local:awardReceiptsConfig ; + :configContextFor ; :qualifiedByDomain ; - :qualifiedBy . + :qualifiedBy . -local:awardAssignedByConfig a :ObjectPropertyDisplayConfig ; +local:awardReceiptsConfig a :ObjectPropertyDisplayConfig ; :listViewConfigFile "listViewConfig-default.xml"^^xsd:string ; - :displayName "award conferred by" ; + :displayName "receipts" ; vitro:displayRankAnnot 3; vitro:hiddenFromDisplayBelowRoleLevelAnnot role:public ; vitro:prohibitedFromUpdateBelowRoleLevelAnnot role:public ; - :propertyGroup . + :propertyGroup . + diff --git a/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/PublicationHasEditorValidator.java b/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/PublicationHasEditorValidator.java new file mode 100644 index 00000000..fafc1def --- /dev/null +++ b/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/PublicationHasEditorValidator.java @@ -0,0 +1,100 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.edit.n3editing; + +import java.lang.String; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang.StringUtils; + +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 PublicationHasEditorValidator implements N3ValidatorVTwo { + + private static String MISSING_FIRST_NAME_ERROR = "Must specify the editor's first name."; + private static String MISSING_LAST_NAME_ERROR = "Must specify the editor's last name."; + private static String MALFORMED_LAST_NAME_ERROR = "Last name 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 personUri = urisFromForm.get("personUri"); + + if (allListElementsEmpty(personUri)) { + personUri = null; + } + // If there's a personUri, then we're done. The firstName and lastName fields are + // disabled and so don't get submitted. + if (personUri != 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/AddEditorsToInformationResourceGenerator.java b/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/AddEditorsToInformationResourceGenerator.java new file mode 100644 index 00000000..030bc915 --- /dev/null +++ b/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/AddEditorsToInformationResourceGenerator.java @@ -0,0 +1,464 @@ +/* $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.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.servlet.http.HttpSession; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.query.QuerySolution; +import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.rdf.model.RDFNode; +import com.hp.hpl.jena.rdf.model.Literal; +import com.hp.hpl.jena.vocabulary.RDFS; +import com.hp.hpl.jena.vocabulary.XSD; + +import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyComparator; +import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.beans.Individual; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.jena.QueryUtils; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.PublicationHasEditorValidator; +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.edit.n3editing.VTwo.EditConfigurationVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators.AntiXssValidation; + +/** + * This is a slightly unusual generator that is used by Manage Editors on + * information resources. + * + * It is intended to always be an add, and never an update. + */ +public class AddEditorsToInformationResourceGenerator extends VivoBaseGenerator implements EditConfigurationGenerator { + public static Log log = LogFactory.getLog(AddEditorsToInformationResourceGenerator.class); + + @Override + public EditConfigurationVTwo getEditConfiguration(VitroRequest vreq, + HttpSession session) { + EditConfigurationVTwo editConfiguration = new EditConfigurationVTwo(); + initBasics(editConfiguration, vreq); + initPropertyParameters(vreq, session, editConfiguration); + + //Overriding URL to return to + setUrlToReturnTo(editConfiguration, vreq); + + //set variable names + editConfiguration.setVarNameForSubject("infoResource"); + editConfiguration.setVarNameForPredicate("predicate"); + editConfiguration.setVarNameForObject("editorshipUri"); + + // Required N3 + editConfiguration.setN3Required( list( getN3NewEditorship() ) ); + + // Optional N3 + editConfiguration.setN3Optional( generateN3Optional()); + + editConfiguration.addNewResource("editorshipUri", DEFAULT_NS_TOKEN); + editConfiguration.addNewResource("newPerson", DEFAULT_NS_TOKEN); + editConfiguration.addNewResource("vcardPerson", DEFAULT_NS_TOKEN); + editConfiguration.addNewResource("vcardName", DEFAULT_NS_TOKEN); + + //In scope + setUrisAndLiteralsInScope(editConfiguration, vreq); + + //on Form + setUrisAndLiteralsOnForm(editConfiguration, vreq); + + //Sparql queries + setSparqlQueries(editConfiguration, vreq); + + //set fields + setFields(editConfiguration, vreq, EditConfigurationUtils.getPredicateUri(vreq)); + + //template file + editConfiguration.setTemplate("addEditorsToInformationResource.ftl"); + //add validators + editConfiguration.addValidator(new PublicationHasEditorValidator()); + + //Adding additional data, specifically edit mode + addFormSpecificData(editConfiguration, vreq); + + editConfiguration.addValidator(new AntiXssValidation()); + + //NOITCE this generator does not run prepare() since it + //is never an update and has no SPARQL for existing + + return editConfiguration; + } + + private void setUrlToReturnTo(EditConfigurationVTwo editConfiguration, VitroRequest vreq) { + editConfiguration.setUrlPatternToReturnTo(EditConfigurationUtils.getFormUrlWithoutContext(vreq)); + } + + /***N3 strings both required and optional***/ + + public String getN3PrefixString() { + return "@prefix core: <" + vivoCore + "> .\n" + + "@prefix foaf: <" + foaf + "> . \n" ; + } + + private String getN3NewEditorship() { + return getN3PrefixString() + + "?editorshipUri a core:Editorship ;\n" + + " core:relates ?infoResource .\n" + + "?infoResource core:relatedBy ?editorshipUri ."; + } + + private String getN3EditorshipRank() { + return getN3PrefixString() + + "?editorshipUri core:editorRank ?rank ."; + } + + //first name, middle name, last name, and new perseon for new editor being created, and n3 for existing person + //if existing person selected as editor + public List generateN3Optional() { + return list( + getN3NewPersonFirstName() , + getN3NewPersonMiddleName(), + getN3NewPersonLastName(), + getN3NewPerson(), + getN3EditorshipRank(), + getN3ForExistingPerson()); + } + + + private String getN3NewPersonFirstName() { + return getN3PrefixString() + + "@prefix vcard: . \n" + + "?newPerson ?vcardPerson . \n" + + "?vcardPerson ?newPerson . \n" + + "?vcardPerson a . \n" + + "?vcardPerson vcard:hasName ?vcardName . \n" + + "?vcardName a . \n" + + "?vcardName vcard:givenName ?firstName ."; + } + + private String getN3NewPersonMiddleName() { + return getN3PrefixString() + + "@prefix vcard: . \n" + + "?newPerson ?vcardPerson . \n" + + "?vcardPerson ?newPerson . \n" + + "?vcardPerson a . \n" + + "?vcardPerson vcard:hasName ?vcardName . \n" + + "?vcardName a . \n" + + "?vcardName vcard:middleName ?middleName ."; + } + + private String getN3NewPersonLastName() { + return getN3PrefixString() + + "@prefix vcard: . \n" + + "?newPerson ?vcardPerson . \n" + + "?vcardPerson ?newPerson . \n" + + "?vcardPerson a . \n" + + "?vcardPerson vcard:hasName ?vcardName . \n" + + "?vcardName a . \n" + + "?vcardName vcard:familyName ?lastName ."; + } + + private String getN3NewPerson() { + return getN3PrefixString() + + "?newPerson a foaf:Person ;\n" + + "<" + RDFS.label.getURI() + "> ?label .\n" + + "?editorshipUri core:relates ?newPerson .\n" + + "?newPerson core:relatedBy ?editorshipUri . "; + } + + private String getN3ForExistingPerson() { + return getN3PrefixString() + + "?editorshipUri core:relates ?personUri .\n" + + "?personUri core:relatedBy ?editorshipUri ."; + } + + /** Get new resources */ + //A new editorship uri will always be created when an editor is added + //A new person may be added if a person not in the system will be added as editor + private Map generateNewResources(VitroRequest vreq) { + + + HashMap newResources = new HashMap(); + newResources.put("editorshipUri", DEFAULT_NS_TOKEN); + newResources.put("newPerson", DEFAULT_NS_TOKEN); + newResources.put("vcardPerson", DEFAULT_NS_TOKEN); + newResources.put("vcardName", DEFAULT_NS_TOKEN); + return newResources; + } + + /** Set URIS and Literals In Scope and on form and supporting methods */ + private void setUrisAndLiteralsInScope(EditConfigurationVTwo editConfiguration, VitroRequest vreq) { + //Uris in scope always contain subject and predicate + HashMap> urisInScope = new HashMap>(); + urisInScope.put(editConfiguration.getVarNameForSubject(), + Arrays.asList(new String[]{editConfiguration.getSubjectUri()})); + urisInScope.put(editConfiguration.getVarNameForPredicate(), + Arrays.asList(new String[]{editConfiguration.getPredicateUri()})); + editConfiguration.setUrisInScope(urisInScope); + //no literals in scope + } + + public void setUrisAndLiteralsOnForm(EditConfigurationVTwo editConfiguration, VitroRequest vreq) { + List urisOnForm = new ArrayList(); + //If an existing person is being used as an editor, need to get the person uri + urisOnForm.add("personUri"); + editConfiguration.setUrisOnform(urisOnForm); + + //for person who is not in system, need to add first name, last name and middle name + //Also need to store editorship rank and label of editor + List literalsOnForm = list("firstName", + "middleName", + "lastName", + "rank", + "label"); + editConfiguration.setLiteralsOnForm(literalsOnForm); + } + + /** Set SPARQL Queries and supporting methods. */ + private void setSparqlQueries(EditConfigurationVTwo editConfiguration, VitroRequest vreq) { + //Sparql queries are all empty for existing values + //This form is different from the others that it gets multiple editors on the same page + //and that information will be queried and stored in the additional form specific data + HashMap map = new HashMap(); + editConfiguration.setSparqlForExistingUris(new HashMap()); + editConfiguration.setSparqlForExistingLiterals(new HashMap()); + editConfiguration.setSparqlForAdditionalUrisInScope(new HashMap()); + editConfiguration.setSparqlForAdditionalLiteralsInScope(new HashMap()); + } + + /** + * + * Set Fields and supporting methods + */ + + public void setFields(EditConfigurationVTwo editConfiguration, VitroRequest vreq, String predicateUri) { + setLabelField(editConfiguration); + setFirstNameField(editConfiguration); + setMiddleNameField(editConfiguration); + setLastNameField(editConfiguration); + setRankField(editConfiguration); + setPersonUriField(editConfiguration); + } + + private void setLabelField(EditConfigurationVTwo editConfiguration) { + editConfiguration.addField(new FieldVTwo(). + setName("label"). + setValidators(list("datatype:" + XSD.xstring.toString())). + setRangeDatatypeUri(XSD.xstring.toString()) + ); + } + + + private void setFirstNameField(EditConfigurationVTwo editConfiguration) { + editConfiguration.addField(new FieldVTwo(). + setName("firstName"). + setValidators(list("datatype:" + XSD.xstring.toString())). + setRangeDatatypeUri(XSD.xstring.toString()) + ); + } + + + private void setMiddleNameField(EditConfigurationVTwo editConfiguration) { + editConfiguration.addField(new FieldVTwo(). + setName("middleName"). + setValidators(list("datatype:" + XSD.xstring.toString())). + setRangeDatatypeUri(XSD.xstring.toString()) + ); + } + + private void setLastNameField(EditConfigurationVTwo editConfiguration) { + editConfiguration.addField(new FieldVTwo(). + setName("lastName"). + setValidators(list("datatype:" + XSD.xstring.toString())). + setRangeDatatypeUri(XSD.xstring.toString()) + ); + } + + private void setRankField(EditConfigurationVTwo editConfiguration) { + editConfiguration.addField(new FieldVTwo(). + setName("rank"). + setValidators(list("nonempty")). + setRangeDatatypeUri(XSD.xint.toString()) + ); + } + + + private void setPersonUriField(EditConfigurationVTwo editConfiguration) { + editConfiguration.addField(new FieldVTwo(). + setName("personUri") + //.setObjectClassUri(personClass) + ); + } + + //Form specific data + public void addFormSpecificData(EditConfigurationVTwo editConfiguration, VitroRequest vreq) { + HashMap formSpecificData = new HashMap(); + //Get the existing editorships + formSpecificData.put("existingEditorInfo", getExistingEditorships(editConfiguration.getSubjectUri(), vreq)); + formSpecificData.put("newRank", getMaxRank(editConfiguration.getSubjectUri(), vreq) + 1); + formSpecificData.put("rankPredicate", "http://vivoweb.org/ontology/core#rank"); + editConfiguration.setFormSpecificData(formSpecificData); + } + + private static String EDITORSHIPS_QUERY = "" + + "PREFIX core: \n" + + "PREFIX afn: \n" + + "PREFIX rdfs: \n" + + "PREFIX foaf: \n" + + "SELECT ?editorshipURI (afn:localname(?editorshipURI) AS ?editorshipName) ?editorURI ?editorName ?rank \n" + + "WHERE { \n" + + "?subject core:relatedBy ?editorshipURI . \n" + + "?editorshipURI a core:Editorship . \n" + + "?editorshipURI core:relates ?editorURI . \n" + + "?editorURI a foaf:Person . \n" + + "OPTIONAL { ?editorURI rdfs:label ?editorName } \n" + + "OPTIONAL { ?editorshipURI core:rank ?rank } \n" + + "} ORDER BY ?rank"; + + + private List getExistingEditorships(String subjectUri, VitroRequest vreq) { + + String queryStr = QueryUtils.subUriForQueryVar(this.getEditorshipsQuery(), "subject", subjectUri); + log.debug("Query string is: " + queryStr); + List> editorships = new ArrayList>(); + try { + ResultSet results = QueryUtils.getQueryResults(queryStr, vreq); + while (results.hasNext()) { + QuerySolution soln = results.nextSolution(); + RDFNode node = soln.get("editorshipURI"); + if (node.isURIResource()) { + editorships.add(QueryUtils.querySolutionToStringValueMap(soln)); + } + } + } catch (Exception e) { + log.error(e, e); + } + log.debug("editorships = " + editorships); + return getEditorshipInfo(editorships); + } + + private static String MAX_RANK_QUERY = "" + + "PREFIX core: \n" + + "SELECT DISTINCT ?rank WHERE { \n" + + " ?subject core:relatedBy ?editorship . \n" + + " ?editorship a core:Editorship . \n" + + " ?editorship core:rank ?rank .\n" + + "} ORDER BY DESC(?rank) LIMIT 1"; + + private int getMaxRank(String subjectUri, VitroRequest vreq) { + + int maxRank = 0; // default value + String queryStr = QueryUtils.subUriForQueryVar(this.getMaxRankQueryStr(), "subject", subjectUri); + log.debug("maxRank query string is: " + queryStr); + try { + ResultSet results = QueryUtils.getQueryResults(queryStr, vreq); + if (results != null && results.hasNext()) { // there is at most one result + QuerySolution soln = results.next(); + RDFNode node = soln.get("rank"); + if (node != null && node.isLiteral()) { + // node.asLiteral().getInt() won't return an xsd:string that + // can be parsed as an int. + int rank = Integer.parseInt(node.asLiteral().getLexicalForm()); + if (rank > maxRank) { + log.debug("setting maxRank to " + rank); + maxRank = rank; + } + } + } + } catch (NumberFormatException e) { + log.error("Invalid rank returned from query: not an integer value."); + } catch (Exception e) { + log.error(e, e); + } + log.debug("maxRank is: " + maxRank); + return maxRank; + } + + private List getEditorshipInfo( + List> editorships) { + List info = new ArrayList(); + String editorshipUri = ""; + String editorshipName = ""; + String editorUri = ""; + String editorName = ""; + + for ( Map editorship : editorships ) { + for (Entry entry : editorship.entrySet() ) { + if ( entry.getKey().equals("editorshipURI") ) { + editorshipUri = entry.getValue(); + } + else if ( entry.getKey().equals("editorshipName") ) { + editorshipName = entry.getValue(); + } + else if ( entry.getKey().equals("editorURI") ) { + editorUri = entry.getValue(); + } + else if ( entry.getKey().equals("editorName") ) { + editorName = entry.getValue(); + } + } + + EditorshipInfo aaInfo = new EditorshipInfo(editorshipUri, editorshipName, editorUri, editorName); + info.add(aaInfo); + } + log.debug("info = " + info); + return info; + } + + //This is the information about editors the form will require + public class EditorshipInfo { + //This is the editorship node information + private String editorshipUri; + private String editorshipName; + //Editor information for editorship node + private String editorUri; + private String editorName; + + public EditorshipInfo(String inputEditorshipUri, + String inputEditorshipName, + String inputEditorUri, + String inputEditorName) { + editorshipUri = inputEditorshipUri; + editorshipName = inputEditorshipName; + editorUri = inputEditorUri; + editorName = inputEditorName; + + } + + //Getters - specifically required for Freemarker template's access to POJO + public String getEditorshipUri() { + return editorshipUri; + } + + public String getEditorshipName() { + return editorshipName; + } + + public String getEditorUri() { + return editorUri; + } + + public String getEditorName() { + return editorName; + } + } + + static final String DEFAULT_NS_TOKEN=null; //null forces the default NS + + protected String getMaxRankQueryStr() { + return MAX_RANK_QUERY; + } + + protected String getEditorshipsQuery() { + return EDITORSHIPS_QUERY; + } + +} diff --git a/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/AddEditorshipToPersonGenerator.java b/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/AddEditorshipToPersonGenerator.java new file mode 100644 index 00000000..b3093c85 --- /dev/null +++ b/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/AddEditorshipToPersonGenerator.java @@ -0,0 +1,167 @@ +/* $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.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.PersonHasAdviseesValidator; +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.EditConfigurationUtils; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.ChildVClassesWithParent; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.ConstantFieldOptions; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.IndividualsViaVClassOptions; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators.AntiXssValidation; +import edu.cornell.mannlib.vitro.webapp.utils.FrontEndEditingUtils.EditMode; +import edu.cornell.mannlib.vitro.webapp.utils.generators.EditModeUtils; + +public class AddEditorshipToPersonGenerator extends VivoBaseGenerator implements + EditConfigurationGenerator { + + public AddEditorshipToPersonGenerator() {} + + @Override + public EditConfigurationVTwo getEditConfiguration(VitroRequest vreq, + HttpSession session) throws Exception { + + EditConfigurationVTwo conf = new EditConfigurationVTwo(); + + initBasics(conf, vreq); + initPropertyParameters(vreq, session, conf); + initObjectPropForm(conf, vreq); + + conf.setTemplate("addEditorshipToPerson.ftl"); + + conf.setVarNameForSubject("person"); + conf.setVarNameForPredicate("predicate"); + conf.setVarNameForObject("editorship"); + + conf.setN3Required( Arrays.asList( n3ForNewEditorship ) ); + conf.setN3Optional( Arrays.asList( n3ForNewDocumentAssertion, + n3ForExistingDocumentAssertion ) ); + + conf.addNewResource("editorship", DEFAULT_NS_FOR_NEW_RESOURCE); + conf.addNewResource("newDocument", DEFAULT_NS_FOR_NEW_RESOURCE); + + conf.setUrisOnform(Arrays.asList("existingDocument", "documentType")); + conf.setLiteralsOnForm(Arrays.asList("documentLabel", "documentLabelDisplay" )); + + conf.addSparqlForExistingLiteral("documentLabel", documentLabelQuery); + + conf.addSparqlForExistingUris("documentType", documentTypeQuery); + conf.addSparqlForExistingUris("existingDocument", existingDocumentQuery); + + conf.addField( new FieldVTwo(). + setName("documentType"). + setValidators( list("nonempty") ). + setOptions( new ConstantFieldOptions("documentType", getDocumentTypeLiteralOptions() )) + ); + + conf.addField( new FieldVTwo(). + setName("documentLabel"). + setRangeDatatypeUri(XSD.xstring.toString() ). + setValidators( list("datatype:" + XSD.xstring.toString()) ) + ); + + conf.addValidator(new AntiXssValidation()); + addFormSpecificData(conf, vreq); + + prepare(vreq, conf); + return conf; + } + + /* N3 assertions */ + + final static String n3ForNewEditorship = + "@prefix vivo: <" + vivoCore + "> . \n" + + "?person ?predicate ?editorship . \n" + + "?editorship a vivo:Editorship . \n" + + "?editorship vivo:relates ?person . " ; + + final static String n3ForNewDocumentAssertion = + "@prefix vivo: <" + vivoCore + "> . \n" + + "?editorship vivo:relates ?newDocument . \n" + + "?newDocument vivo:editedBy ?editorship . \n" + + "?newDocument a ?documentType . \n" + + "?newDocument <" + label + "> ?documentLabel. " ; + + final static String n3ForExistingDocumentAssertion = + "@prefix vivo: <" + vivoCore + "> . \n" + + "?editorship vivo:relates ?existingDocument . \n" + + "?existingDocument vivo:editedBy ?editorship . \n" + + "?existingDocument a ?documentType . " ; + + /* Queries for editing an existing entry */ + + final static String documentTypeQuery = + "PREFIX vitro: <" + VitroVocabulary.vitroURI + "> \n" + + "PREFIX vivo: <" + vivoCore + "> . \n" + + "PREFIX bibo: . \n" + + "SELECT ?documentType WHERE { \n" + + " ?editorship vivo:relates ?existingDocument . \n" + + " ?existingDocument a bibo:Document . \n" + + " ?existingDocument vitro:mostSpecificType ?documentType . \n" + + "}"; + + final static String documentLabelQuery = + "PREFIX vitro: <" + VitroVocabulary.vitroURI + "> \n" + + "PREFIX vivo: <" + vivoCore + "> . \n" + + "PREFIX bibo: . \n" + + "SELECT ?documentLabel WHERE { \n" + + " ?editorship vivo:relates ?existingDocument . \n" + + " ?existingDocument a bibo:Document . \n" + + " ?existingDocument <" + label + "> ?documentLabel . \n" + + "}"; + + final static String existingDocumentQuery = + "PREFIX vitro: <" + VitroVocabulary.vitroURI + "> \n" + + "PREFIX vivo: <" + vivoCore + "> . \n" + + "PREFIX bibo: . \n" + + "SELECT existingDocument WHERE { \n" + + " ?editorship vivo:relates ?existingDocument . \n" + + " ?existingDocument a bibo:Document . \n" + + "}"; + + //Adding form specific data such as edit mode + public void addFormSpecificData(EditConfigurationVTwo editConfiguration, VitroRequest vreq) { + HashMap formSpecificData = new HashMap(); + formSpecificData.put("editMode", getEditMode(vreq).name().toLowerCase()); + editConfiguration.setFormSpecificData(formSpecificData); + } + + public EditMode getEditMode(VitroRequest vreq) { + List predicates = new ArrayList(); + predicates.add("http://vivoweb.org/ontology/core#relates"); + return EditModeUtils.getEditMode(vreq, predicates); + } + + private List> getDocumentTypeLiteralOptions() { + List> literalOptions = new ArrayList>(); + literalOptions.add(list("http://purl.org/ontology/bibo/Book", "Book")); + literalOptions.add(list("http://purl.org/ontology/bibo/Chapter", "Chapter")); + literalOptions.add(list("http://purl.org/ontology/bibo/Collection", "Collection")); + literalOptions.add(list("http://purl.org/ontology/bibo/EditedBook", "Edited Book")); + literalOptions.add(list("http://purl.org/ontology/bibo/Film", "Film")); + literalOptions.add(list("http://purl.org/ontology/bibo/Magazine", "Magazine")); + literalOptions.add(list("http://vivoweb.org/ontology/core#Newsletter", "Newsletter")); + literalOptions.add(list("http://purl.org/ontology/bibo/Newspaper", "Newspaper")); + literalOptions.add(list("http://vivoweb.org/ontology/core#NewsRelease", "News Release")); + literalOptions.add(list("http://purl.org/ontology/bibo/Periodical", "Periodical")); + literalOptions.add(list("http://purl.org/ontology/bibo/Report", "Report")); + literalOptions.add(list("http://vivoweb.org/ontology/core#Video", "Video")); + literalOptions.add(list("http://purl.org/ontology/bibo/Webpage", "Webpage")); + literalOptions.add(list("http://purl.org/ontology/bibo/Website", "Website")); + return literalOptions; + } + +} \ No newline at end of file diff --git a/themes/wilma/i18n/all.properties b/themes/wilma/i18n/all.properties index 2d8e3f55..21575109 100644 --- a/themes/wilma/i18n/all.properties +++ b/themes/wilma/i18n/all.properties @@ -683,7 +683,7 @@ vis_tools_note_four = The models are refreshed each time the server restarts. S drag_drop_reorder_authors = Drag and drop to reorder authors reordering_authors_failed = Reordering of authors failed. confirm_author_removal = Are you sure you want to remove this author: -error_processing_aithor_request = Error processing request: author not removed +error_processing_author_request = Error processing request: author not removed author_capitalized = Author or_add_new_one = or add a new one. @@ -842,4 +842,21 @@ first_name = First name last_name = Last name title_not_found = Title not found. speeches_capitalized = Speeches -theses_capitalized = Theses \ No newline at end of file +theses_capitalized = Theses +select_document_type = Please select a value in the Document Type field. +select_a_document_name = Please enter or select a value in the Document Name field. +document_type_capitalized = Document Type +document_name_capitalized = Document Name +selected_document = Selected Document +editor_name = editor name +missing_editor = missing editor +drag_drop_reorder_editors = Drag and drop to reorder editors +reordering_editors_failed = Reordering of editors failed. +confirm_editor_removal = Are you sure you want to remove this editor: +error_processing_editor_request = Error processing request: editor not removed +manage_editors = Manage Editors +no_linked_author = no linked editor +remove_editor_link = remove editor link +add_an_editor = Add an Editor +add_editor = Add Editor +please_select_type = Please select a type from the drop-down list. \ No newline at end of file