Merge branch 'develop' of https://github.com/vivo-project/VIVO into develop

This commit is contained in:
hudajkhan 2013-10-02 14:58:19 -04:00
commit 0896b37c3c
18 changed files with 2147 additions and 31 deletions

View file

@ -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
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.

View file

@ -65,12 +65,19 @@
</query-select>
<query-construct>
PREFIX core: &lt;http://vivoweb.org/ontology/core#&gt;
PREFIX bibo: &lt;http://purl.org/ontology/bibo/&gt;
PREFIX vitro: &lt;http://vitro.mannlib.cornell.edu/ns/vitro/0.7#&gt;
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: &lt;http://xmlns.com/foaf/0.1/&gt;
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: &lt;http://purl.org/ontology/bibo/&gt;
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 .

View file

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<!-- See guidelines in vitro/doc/list_view_configuration_guidelines.txt -->
<list-view-config>
<query-select>
PREFIX rdfs: &lt;http://www.w3.org/2000/01/rdf-schema#&gt;
PREFIX core: &lt;http://vivoweb.org/ontology/core#&gt;
PREFIX afn: &lt;http://jena.hpl.hp.com/ARQ/function#&gt;
PREFIX bibo: &lt;http://purl.org/ontology/bibo/&gt;
PREFIX vitro: &lt;http://vitro.mannlib.cornell.edu/ns/vitro/0.7#&gt;
PREFIX foaf: &lt;http://xmlns.com/foaf/0.1/&gt;
SELECT DISTINCT ?subclass
?editorship
?infoResource ?infoResourceName
?dateTime
WHERE {
?subject ?property ?editorship .
?editorship core:relates ?infoResource .
?infoResource a &lt;http://purl.obolibrary.org/obo/IAO_0000030&gt; .
?infoResource rdfs:label ?infoResourceName .
OPTIONAL { ?infoResource vitro:mostSpecificType ?subclass }
OPTIONAL { ?infoResource core:dateTimeValue ?dateTimeValue .
?dateTimeValue core:dateTime ?dateTime
}
<critical-data-required>
FILTER ( bound(?infoResource) )
</critical-data-required>
} ORDER BY ?subclass DESC(?dateTime) ?infoResourceName
</query-select>
<query-construct>
PREFIX core: &lt;http://vivoweb.org/ontology/core#&gt;
PREFIX bibo: &lt;http://purl.org/ontology/bibo/&gt;
PREFIX vitro: &lt;http://vitro.mannlib.cornell.edu/ns/vitro/0.7#&gt;
CONSTRUCT {
?subject ?property ?editorship .
?editorship a core:Editorship .
?editorship core:relates ?infoResource .
?infoResource a &lt;http://purl.obolibrary.org/obo/IAO_0000030&gt; .
?infoResource vitro:mostSpecificType ?subclass
} WHERE {
?subject ?property ?editorship .
?editorship a core:Editorship .
?editorship core:relates ?infoResource .
?infoResource a &lt;http://purl.obolibrary.org/obo/IAO_0000030&gt; .
?infoResource vitro:mostSpecificType ?subclass
}
</query-construct>
<query-construct>
PREFIX core: &lt;http://vivoweb.org/ontology/core#&gt;
PREFIX rdfs: &lt;http://www.w3.org/2000/01/rdf-schema#&gt;
PREFIX bibo: &lt;http://purl.org/ontology/bibo/&gt;
CONSTRUCT {
?subject ?property ?editorship .
?editorship core:relates ?infoResource .
?infoResource a &lt;http://purl.obolibrary.org/obo/IAO_0000030&gt; .
?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 &lt;http://purl.obolibrary.org/obo/IAO_0000030&gt;
} UNION {
?subject ?property ?editorship .
?editorship a core:Editorship .
?editorship core:relates ?infoResource .
?infoResource a &lt;http://purl.obolibrary.org/obo/IAO_0000030&gt; .
?infoResource rdfs:label ?infoResourceName
}
}
</query-construct>
<query-construct>
PREFIX core: &lt;http://vivoweb.org/ontology/core#&gt;
PREFIX rdfs: &lt;http://www.w3.org/2000/01/rdf-schema#&gt;
PREFIX bibo: &lt;http://purl.org/ontology/bibo/&gt;
CONSTRUCT {
?subject ?property ?editorship .
?editorship a core:Editorship .
?editorship core:relates ?infoResource .
?infoResource a &lt;http://purl.obolibrary.org/obo/IAO_0000030&gt; .
?infoResource core:dateTimeValue ?dateTimeValue .
?dateTimeValue core:dateTime ?dateTime
} WHERE {
?subject ?property ?editorship .
?editorship a core:Editorship .
?editorship core:relates ?infoResource .
?infoResource a &lt;http://purl.obolibrary.org/obo/IAO_0000030&gt; .
?infoResource core:dateTimeValue ?dateTimeValue .
?dateTimeValue core:dateTime ?dateTime
}
</query-construct>
<template>propStatement-editorship.ftl</template>
</list-view-config>

View file

@ -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: &lt;http://xmlns.com/foaf/0.1/&gt;
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 .

View file

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<!-- See guidelines in vitro/doc/list_view_configuration_guidelines.txt -->
<list-view-config>
<query-select>
PREFIX rdfs: &lt;http://www.w3.org/2000/01/rdf-schema#&gt;
PREFIX core: &lt;http://vivoweb.org/ontology/core#&gt;
PREFIX afn: &lt;http://jena.hpl.hp.com/ARQ/function#&gt;
PREFIX foaf: &lt;http://xmlns.com/foaf/0.1/&gt;
PREFIX vitro: &lt;http://vitro.mannlib.cornell.edu/ns/vitro/0.7#&gt;
SELECT DISTINCT <collated> ?subclass </collated>
?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
<collated>
OPTIONAL { ?person vitro:mostSpecificType ?subclass .
?subclass rdfs:subClassOf foaf:Person
}
</collated>
}
<critical-data-required>
FILTER ( bound(?person) )
</critical-data-required>
} ORDER BY <collated> ?subclass </collated> ?rank ?personName
</query-select>
<query-construct>
PREFIX rdfs: &lt;http://www.w3.org/2000/01/rdf-schema#&gt;
PREFIX foaf: &lt;http://xmlns.com/foaf/0.1/&gt;
CONSTRUCT {
?subclass rdfs:subClassOf foaf:Person
} WHERE {
?subclass rdfs:subClassOf foaf:Person
}
</query-construct>
<query-construct>
PREFIX core: &lt;http://vivoweb.org/ontology/core#&gt;
PREFIX rdfs: &lt;http://www.w3.org/2000/01/rdf-schema#&gt;
PREFIX vitro: &lt;http://vitro.mannlib.cornell.edu/ns/vitro/0.7#&gt;
PREFIX foaf: &lt;http://xmlns.com/foaf/0.1/&gt;
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
}
}
</query-construct>
<template>propStatement-informationResourceInEditorship.ftl</template>
</list-view-config>

View file

@ -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>
<a href="${profileUrl(statement.uri("infoResource"))}" title="${i18n().resource_name}">${statement.infoResourceName}</a>.&nbsp;
<#else>
<a href="${profileUrl(statement.uri("infoResource"))}" title="${i18n().resource_name}">${statement.infoResourceName}</a>
</#if>
<#else>
<#-- This shouldn't happen, but we must provide for it -->
<a href="${profileUrl(statement.uri("editorship"))}" title="${i18n().missing_info_resource}">${i18n().missing_info_resource}</a>
</#if>
</#local>
${resourceTitle} <@dt.yearSpan "${statement.dateTime!}" />
</#macro>

View file

@ -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??>
<a href="${profileUrl(statement.uri("person"))}" title="${i18n().editor_name}">${statement.personName}</a>
<#else>
<#-- This shouldn't happen, but we must provide for it -->
<a href="${profileUrl(statement.uri("editorship"))}" title="${i18n().missing_editor}">${i18n().missing_editor}</a>
</#if>
</#macro>

View file

@ -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}',

View file

@ -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/>
</#if>
<#--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'"/>
</#if>
<#assign title="<em>${editConfiguration.subjectName}</em>" />
<#assign requiredHint="<span class='requiredHint'> *</span>" />
<#assign initialHint="<span class='hint'>(${i18n().initial_okay})</span>" />
<@lvf.unsupportedBrowser urls.base/>
<h2>${title}</h2>
<#if submissionErrors?has_content>
<section id="error-alert" role="alert" class="validationError">
<img src="${urls.images}/iconAlert.png" width="24" height="24" alert="${i18n().error_alert_icon}" />
<p>
<#--below shows examples of both printing out all error messages and checking the error message for a specific field-->
<#list submissionErrors?keys as errorFieldName>
${submissionErrors[errorFieldName]} <br/>
</#list>
</p>
</section>
</#if>
<h3>${i18n().manage_editors}</h3>
<ul id="editorships" ${ulClass}>
<script type="text/javascript">
var editorshipData = [];
</script>
<#assign editorHref="/individual?uri=" />
<#--This should be a list of java objects where URI and name can be retrieved-->
<#list existingEditorInfo as editorship>
<#assign editorUri = editorship.editorUri/>
<#assign editorName = editorship.editorName/>
<li class="editorship">
<#-- span.editor will be used in the next phase, when we display a message that the editor has been
removed. That text will replace the a.editorName, which will be removed. -->
<span class="editor">
<#-- This span is here to assign a width to. We can't assign directly to the a.editorName,
for the case when it's followed by an em tag - we want the width to apply to the whole thing. -->
<span class="editorNameWrapper">
<#if (editorUri?length > 0)>
<span class="editorName">${editorName}</span>
<#else>
<span class="editorName">${editorship.editorshipName}</span><em> (${i18n().no_linked_editor})</em>
</#if>
</span>
<a href="${urls.base}/edit/primitiveDelete" class="remove" title="${i18n().remove_editor_link}">${i18n().remove_capitalized}</a>
</span>
</li>
<script type="text/javascript">
editorshipData.push({
"editorshipUri": "${editorship.editorshipUri}",
"editorUri": "${editorUri}",
"editorName": "${editorName}"
});
</script>
</#list>
</ul>
<br />
<section id="showAddForm" role="region">
<input type="hidden" name = "editKey" value="${editKey}" />
<input type="submit" id="showAddFormButton" value="${i18n().add_editor}" role="button" />
<span class="or"> ${i18n().or} </span>
<a id="returnLink" class="cancel" href="${cancelUrl}&url=/individual" title="${i18n().cancel_title}">${i18n().return_to_publication}</a>
<img id="indicatorOne" class="indicator hidden" alt="${i18n().processing_indicator}" src="${urls.base}/images/indicatorWhite.gif" />
</section>
<form id="addEditorForm" action ="${submitUrl}" class="customForm noIE67">
<h3>${i18n().add_an_editor}</h3>
<section id="personFields" role="personContainer">
<#--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-->
<p class="inline">
<label for="lastName">${i18n().last_name} <span class='requiredHint'> *</span></label>
<input class="acSelector" size="35" type="text" id="lastName" name="lastName" value="${lastNameValue}" role="input" />
</p>
<p class="inline">
<label for="firstName">${i18n().first_name} ${requiredHint} ${initialHint}</label>
<input size="20" type="text" id="firstName" name="firstName" value="${firstNameValue}" role="input" />
</p>
<p class="inline">
<label for="middleName">${i18n().middle_name} <span class='hint'>(${i18n().initial_okay})</span></label>
<input size="20" type="text" id="middleName" name="middleName" value="${middleNameValue}" role="input" />
</p>
<div id="selectedEditor" class="acSelection">
<p class="inline">
<label>${i18n().selected_editor}:&nbsp;</label>
<span class="acSelectionInfo" id="selectedEditorName"></span>
<a href="${urls.base}/individual?uri=" id="personLink" class="verifyMatch" title="${i18n().verify_match_capitalized}">(${i18n().verify_match_capitalized})</a>
<input type="hidden" id="personUri" name="personUri" value="" role="input" /> <!-- Field value populated by JavaScript -->
</p>
</div>
</section>
<input type="hidden" id="label" name="label" value="" role="input" /> <!-- Field value populated by JavaScript -->
<input type="hidden" name="rank" id="rank" value="${newRank}" role="input" />
<p class="submit">
<input type="hidden" name = "editKey" value="${editKey}" role="input" />
<input type="submit" id="submit" value="${i18n().add_editor}" role="button" role="input" />
<span class="or"> ${i18n().or} </span>
<a id="returnLink" class="cancel" href="${cancelUrl}" title="${i18n().cancel_title}">${i18n().cancel_link}</a>
<img id="indicatorTwo" alt="${i18n().processing_indicator}" class="indicator hidden" src="${urls.base}/images/indicatorWhite.gif" />
</p>
<p id="requiredLegend" class="requiredHint">* ${i18n().required_fields}</p>
</form>
<script type="text/javascript">
var customFormData = {
rankPredicate: '${rankPredicate}',
acUrl: '${urls.base}/autocomplete?type=',
tokenize: '&tokenize=true',
personUrl: 'http://xmlns.com/foaf/0.1/Person',
reorderUrl: '${urls.base}/edit/reorder'
};
var i18nStrings = {
editorNameWrapperTitle: '${i18n().drag_drop_reorder_editors}',
reorderEditorsAlert: '${i18n().reordering_editors_failed}',
removeEditorshipMessage: '${i18n().confirm_editor_removal}',
removeEditorshipAlert: '${i18n().error_processing_editor_request}',
editorTypeText: '${i18n().editor_capitalized}',
helpTextSelect: '${i18n().select_an_existing}',
helptextAdd: '${i18n().or_add_new_one}'
};
</script>
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/js/jquery-ui/css/smoothness/jquery-ui-1.8.9.custom.css" />',
'<link rel="stylesheet" href="${urls.base}/templates/freemarker/edit/forms/css/customForm.css" />',
'<link rel="stylesheet" href="${urls.base}/templates/freemarker/edit/forms/css/autocomplete.css" />',
'<link rel="stylesheet" href="${urls.base}/templates/freemarker/edit/forms/css/addEditorsToInformationResource.css" />')}
${scripts.add('<script type="text/javascript" src="${urls.base}/js/jquery-ui/js/jquery-ui-1.8.9.custom.min.js"></script>')}
${scripts.add('<script type="text/javascript" src="${urls.base}/js/customFormUtils.js"></script>')}
${scripts.add('<script type="text/javascript" src="${urls.base}/js/browserUtils.js"></script>')}
${scripts.add('<script type="text/javascript" src="${urls.base}/templates/freemarker/edit/forms/js/addEditorsToInformationResource.js"></script>')}

View file

@ -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"] />
</#if>
<#--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>
<#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=""/>
</#if>
<#assign requiredHint = "<span class='requiredHint'> *</span>" />
<#assign yearHint = "<span class='hint'>(${i18n().year_hint_format})</span>" />
<h2>${titleVerb}&nbsp;${i18n().educational_training_for} ${editConfiguration.subjectName}</h2>
<#--Display error messages if any-->
<#if submissionErrors?has_content>
<#if orgLabelDisplayValue?has_content >
<#assign orgLabelValue = orgLabelDisplayValue />
</#if>
<section id="error-alert" role="alert">
<img src="${urls.images}/iconAlert.png" width="24" height="24" alert="${i18n().error_alert_icon}" />
<p>
<#--below shows examples of both printing out all error messages and checking the error message for a specific field-->
<#--Checking if Org Type field is empty-->
<#if lvf.submissionErrorExists(editSubmission, "documentType")>
${i18n().select_document_type}
</#if>
<#--Checking if Org Name field is empty-->
<#if lvf.submissionErrorExists(editSubmission, "documentLabel")>
${i18n().select_a_document_name}
</#if>
</p>
</section>
</#if>
<@lvf.unsupportedBrowser urls.base />
<section id="addEditorshipToPerson" role="region">
<form id="addEditorshipToPerson" class="customForm noIE67" action="${submitUrl}" role="add/edit editorship">
<p class="inline">
<label for="orgType">${i18n().document_type_capitalized} ${requiredHint}</label>
<#assign docTypeOpts = editConfiguration.pageData.documentType />
<select id="typeSelector" name="documentType" acGroupName="document">
<option value="" selected="selected">${i18n().select_one}</option>
<#list docTypeOpts?keys as key>
<#if documentTypeValue = key>
<option value="${key}" selected >${docTypeOpts[key]}</option>
<#else>
<option value="${key}">${docTypeOpts[key]}</option>
</#if>
</#list>
</select>
</p>
<p>
<label for="relatedIndLabel">${i18n().document_name_capitalized} ${requiredHint}</label>
<input class="acSelector" size="50" type="text" id="relatedIndLabel" name="documentLabel" acGroupName="document" value="${documentLabelValue}" />
<input class="display" type="hidden" id="documentDisplay" acGroupName="document" name="documentLabelDisplay" value="${documentLabelDisplayValue}">
</p>
<div class="acSelection" acGroupName="document">
<p class="inline">
<label>${i18n().selected_document}:</label>
<span class="acSelectionInfo"></span>
<a href="" class="verifyMatch" title="${i18n().verify_match_capitalized}">(${i18n().verify_match_capitalized}</a> ${i18n().or}
<a href="#" class="changeSelection" id="changeSelection">${i18n().change_selection})</a>
</p>
<input class="acUriReceiver" type="hidden" id="documentUri" name="existingDocument" value="${existingDocumentValue}" ${flagClearLabelForExisting}="true" />
</div>
<#--End draw elements-->
<input type="hidden" id="editKey" name="editKey" value="${editKey}"/>
<p class="submit">
<input type="submit" id="submit" value="${submitButtonText}"/><span class="or"> ${i18n().or} </span>
<a class="cancel" href="${cancelUrl}" title="${i18n().cancel_title}">${i18n().cancel_link}</a>
</p>
<p id="requiredLegend" class="requiredHint">* ${i18n().required_fields}</p>
</form>
<script type="text/javascript">
var customFormData = {
acUrl: '${urls.base}/autocomplete?tokenize=true&stem=true',
editMode: '${editMode}',
acTypes: {document: 'http://purl.org/ontology/bibo/Document'},
defaultTypeName: 'document',
baseHref: '${urls.base}/individual?uri=',
blankSentinel: '${blankSentinel}',
flagClearLabelForExisting: '${flagClearLabelForExisting}',
subjectName: '${editConfiguration.subjectName}'
};
var i18nStrings = {
selectAnExisting: '${i18n().select_an_existing}',
orCreateNewOne: '${i18n().or_create_new_one}',
selectedString: '${i18n().selected}'
};
</script>
</section>
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/js/jquery-ui/css/smoothness/jquery-ui-1.8.9.custom.css" />')}
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/templates/freemarker/edit/forms/css/customForm.css" />')}
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/templates/freemarker/edit/forms/css/customFormWithAutocomplete.css" />')}
${scripts.add('<script type="text/javascript" src="${urls.base}/js/jquery-ui/js/jquery-ui-1.8.9.custom.min.js"></script>',
'<script type="text/javascript" src="${urls.base}/js/customFormUtils.js"></script>',
'<script type="text/javascript" src="${urls.base}/js/extensions/String.js"></script>',
'<script type="text/javascript" src="${urls.base}/js/browserUtils.js"></script>',
'<script type="text/javascript" src="${urls.base}/js/jquery_plugins/jquery.bgiframe.pack.js"></script>',
'<script type="text/javascript" src="${urls.base}/templates/freemarker/edit/forms/js/customFormWithAutocomplete.js"></script>')}

View file

@ -106,7 +106,10 @@ Set this flag on the input acUriReceiver where you would like this behavior to o
</#if>
</#if>
</#list>
<#--Checking if Name field is empty-->
<#--Checking if Type, Name and Role fields are empty-->
<#if lvf.submissionErrorExists(editSubmission, "roleActivityType")>
${i18n().please_select_type}<br />
</#if>
<#if lvf.submissionErrorExists(editSubmission, "activityLabel")>
${i18n().select_or_enter_name}<br />
</#if>

View file

@ -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();
});

View file

@ -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() {

View file

@ -328,7 +328,6 @@ local:advisorRoleConfig a :ObjectPropertyDisplayConfig ;
vitro:customEntryFormAnnot "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.PersonHasAdvisingRelationshipGenerator"^^<http://www.w3.org/2001/XMLSchema#string> ;
:propertyGroup <http://vivoweb.org/ontology#vitroPropertyGroupteaching> .
local:informationResourceInAuthorshipContext a :ConfigContext ;
:hasConfiguration local:informationResourceInAuthorshipConfig ;
:configContextFor <http://vivoweb.org/ontology/core#relatedBy> ;
@ -344,7 +343,23 @@ local:informationResourceInAuthorshipConfig a :ObjectPropertyDisplayConfig ;
vitro:customEntryFormAnnot "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.AddAuthorsToInformationResourceGenerator"^^<http://www.w3.org/2001/XMLSchema#string> ;
:propertyGroup <http://vivoweb.org/ontology#vitroPropertyGroupoverview> .
local:informationResourceInEditorshipContext a :ConfigContext ;
:hasConfiguration local:informationResourceInEditorshipConfig ;
:configContextFor <http://vivoweb.org/ontology/core#relatedBy> ;
:qualifiedByDomain <http://purl.obolibrary.org/obo/IAO_0000030> ;
:qualifiedBy <http://vivoweb.org/ontology/core#Editorship> .
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"^^<http://www.w3.org/2001/XMLSchema#string> ;
:propertyGroup <http://vivoweb.org/ontology#vitroPropertyGroupbibobscure> .
### vcard properties ###
local:mailingAddressContext a :ConfigContext ;
:hasConfiguration local:mailingAddressConfig ;
:configContextFor <http://purl.obolibrary.org/obo/ARG_2000028> ;
@ -435,6 +450,21 @@ local:fullNameConfig a :ObjectPropertyDisplayConfig ;
vitro:customEntryFormAnnot "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.AddFullNameToPersonGenerator"^^<http://www.w3.org/2001/XMLSchema#string> ;
:propertyGroup <http://vivoweb.org/ontology#vitroPropertyGroupaddress> .
local:editorOfContext a :ConfigContext ;
:hasConfiguration local:editorOfConfig ;
:configContextFor <http://vivoweb.org/ontology/core#relatedBy> ;
:qualifiedByDomain <http://xmlns.com/foaf/0.1/Person> ;
:qualifiedBy <http://vivoweb.org/ontology/core#Editorship> .
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"^^<http://www.w3.org/2001/XMLSchema#string> ;
:propertyGroup <http://vivoweb.org/ontology#vitroPropertyGroupbibliographic> .
### properties using default editing form ##
local:eventWithinContext a :ConfigContext ;
@ -479,16 +509,17 @@ local:inEventSeriesConfig a :ObjectPropertyDisplayConfig ;
vitro:prohibitedFromUpdateBelowRoleLevelAnnot role:public ;
:propertyGroup <http://vivoweb.org/ontology#vitroPropertyGroupoverview> .
local:awardAssignedByContext a :ConfigContext ;
:hasConfiguration local:awardAssignedByConfig ;
:configContextFor <http://vivoweb.org/ontology/core#assignedBy> ;
local:awardReceiptsContext a :ConfigContext ;
:hasConfiguration local:awardReceiptsConfig ;
:configContextFor <http://vivoweb.org/ontology/core#relatedBy> ;
:qualifiedByDomain <http://vivoweb.org/ontology/core#Award> ;
:qualifiedBy <http://vivoweb.org/ontology/core#Award> .
:qualifiedBy <http://vivoweb.org/ontology/core#AwardReceipt> .
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 <http://vivoweb.org/ontology#vitroPropertyGroupoverview> .
:propertyGroup <http://vivoweb.org/ontology#vitroPropertyGroupother> .

View file

@ -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<String, String> validate(EditConfigurationVTwo editConfig,
MultiValueEditSubmission editSub) {
Map<String,List<String>> urisFromForm = editSub.getUrisFromForm();
Map<String,List<Literal>> literalsFromForm = editSub.getLiteralsFromForm();
Map<String,String> errors = new HashMap<String,String>();
List<String> 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<Literal> 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<Literal> 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<String> 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;
}
}

View file

@ -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<String> generateN3Optional() {
return list(
getN3NewPersonFirstName() ,
getN3NewPersonMiddleName(),
getN3NewPersonLastName(),
getN3NewPerson(),
getN3EditorshipRank(),
getN3ForExistingPerson());
}
private String getN3NewPersonFirstName() {
return getN3PrefixString() +
"@prefix vcard: <http://www.w3.org/2006/vcard/ns#> . \n" +
"?newPerson <http://purl.obolibrary.org/obo/ARG_2000028> ?vcardPerson . \n" +
"?vcardPerson <http://purl.obolibrary.org/obo/ARG_2000029> ?newPerson . \n" +
"?vcardPerson a <http://www.w3.org/2006/vcard/ns#Individual> . \n" +
"?vcardPerson vcard:hasName ?vcardName . \n" +
"?vcardName a <http://www.w3.org/2006/vcard/ns#Name> . \n" +
"?vcardName vcard:givenName ?firstName .";
}
private String getN3NewPersonMiddleName() {
return getN3PrefixString() +
"@prefix vcard: <http://www.w3.org/2006/vcard/ns#> . \n" +
"?newPerson <http://purl.obolibrary.org/obo/ARG_2000028> ?vcardPerson . \n" +
"?vcardPerson <http://purl.obolibrary.org/obo/ARG_2000029> ?newPerson . \n" +
"?vcardPerson a <http://www.w3.org/2006/vcard/ns#Individual> . \n" +
"?vcardPerson vcard:hasName ?vcardName . \n" +
"?vcardName a <http://www.w3.org/2006/vcard/ns#Name> . \n" +
"?vcardName vcard:middleName ?middleName .";
}
private String getN3NewPersonLastName() {
return getN3PrefixString() +
"@prefix vcard: <http://www.w3.org/2006/vcard/ns#> . \n" +
"?newPerson <http://purl.obolibrary.org/obo/ARG_2000028> ?vcardPerson . \n" +
"?vcardPerson <http://purl.obolibrary.org/obo/ARG_2000029> ?newPerson . \n" +
"?vcardPerson a <http://www.w3.org/2006/vcard/ns#Individual> . \n" +
"?vcardPerson vcard:hasName ?vcardName . \n" +
"?vcardName a <http://www.w3.org/2006/vcard/ns#Name> . \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<String, String> generateNewResources(VitroRequest vreq) {
HashMap<String, String> newResources = new HashMap<String, String>();
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<String, List<String>> urisInScope = new HashMap<String, List<String>>();
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<String> urisOnForm = new ArrayList<String>();
//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<String> 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<String, String> map = new HashMap<String, String>();
editConfiguration.setSparqlForExistingUris(new HashMap<String, String>());
editConfiguration.setSparqlForExistingLiterals(new HashMap<String, String>());
editConfiguration.setSparqlForAdditionalUrisInScope(new HashMap<String, String>());
editConfiguration.setSparqlForAdditionalLiteralsInScope(new HashMap<String, String>());
}
/**
*
* 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<String, Object> formSpecificData = new HashMap<String, Object>();
//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: <http://vivoweb.org/ontology/core#> \n"
+ "PREFIX afn: <http://jena.hpl.hp.com/ARQ/function#> \n"
+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n"
+ "PREFIX foaf: <http://xmlns.com/foaf/0.1/> \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<EditorshipInfo> getExistingEditorships(String subjectUri, VitroRequest vreq) {
String queryStr = QueryUtils.subUriForQueryVar(this.getEditorshipsQuery(), "subject", subjectUri);
log.debug("Query string is: " + queryStr);
List<Map<String, String>> editorships = new ArrayList<Map<String, String>>();
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: <http://vivoweb.org/ontology/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<EditorshipInfo> getEditorshipInfo(
List<Map<String, String>> editorships) {
List<EditorshipInfo> info = new ArrayList<EditorshipInfo>();
String editorshipUri = "";
String editorshipName = "";
String editorUri = "";
String editorName = "";
for ( Map<String, String> editorship : editorships ) {
for (Entry<String, String> 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;
}
}

View file

@ -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: <http://purl.org/ontology/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: <http://purl.org/ontology/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: <http://purl.org/ontology/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<String, Object> formSpecificData = new HashMap<String, Object>();
formSpecificData.put("editMode", getEditMode(vreq).name().toLowerCase());
editConfiguration.setFormSpecificData(formSpecificData);
}
public EditMode getEditMode(VitroRequest vreq) {
List<String> predicates = new ArrayList<String>();
predicates.add("http://vivoweb.org/ontology/core#relates");
return EditModeUtils.getEditMode(vreq, predicates);
}
private List<List<String>> getDocumentTypeLiteralOptions() {
List<List<String>> literalOptions = new ArrayList<List<String>>();
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;
}
}

View file

@ -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
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.