updates for restricting broader/narrower term to adding individuals with most specific type of concept, and updates to isPersonType for new individual form

This commit is contained in:
hudajkhan 2013-10-30 16:29:24 -04:00
parent f614f6cee4
commit f1587409f2
7 changed files with 372 additions and 1 deletions

View file

@ -66,6 +66,9 @@
<div class="column conceptVocabSource">
<#if existingConcept.vocabURI?has_content && existingConcept.vocabLabel?has_content>
${existingConcept.vocabLabel}
<#else>
&nbsp;
<#--We still want the column to be there even if no vocabulary source is present-->
</#if>
</div>
<div class="column conceptRemoval">

View file

@ -0,0 +1,145 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#--Assign variables from editConfig-->
<#assign rangeOptions = editConfiguration.pageData.objectVar />
<#--
<#assign rangeOptionsExist = false />
<#if (rangeOptions?keys?size > 0)>
<#assign rangeOptionsExist = true/>
</#if>
-->
<#assign rangeOptionsExist = true />
<#assign objectTypes = editConfiguration.pageData.objectTypes />
<#assign objectTypesSize = objectTypes?length />
<#assign objectTypesExist = false />
<#assign multipleTypes = false />
<#if (objectTypesSize > 1)>
<#assign objectTypesExist = true />
</#if>
<#if objectTypes?contains(",")>
<#assign multipleTypes = true/>
</#if>
<#assign sparqlForAcFilter = editConfiguration.pageData.sparqlForAcFilter />
<#assign editMode = editConfiguration.pageData.editMode />
<#assign propertyNameForDisplay = "" />
<#if editConfiguration.objectPropertyNameForDisplay?has_content>
<#assign propertyNameForDisplay = editConfiguration.objectPropertyNameForDisplay />
</#if>
<#if editMode = "edit" >
<#assign titleVerb = "${i18n().edit_capitalized}" />
<#assign objectLabel = editConfiguration.pageData.objectLabel />
<#assign selectedObjectUri = editConfiguration.objectUri />
<#assign submitButtonText = "${i18n().save_button}" />
<#else>
<#assign titleVerb = "${i18n().add_capitalized}" >
<#assign objectLabel = "" />
<#assign selectedObjectUri = ""/>
<#assign submitButtonText = "${i18n().create_entry}" />
</#if>
<#if editConfiguration.formTitle?contains("collaborator") >
<#assign formTitle = "${i18n().select_existing_collaborator(editConfiguration.subjectName)}" />
<#else>
<#assign formTitle = editConfiguration.formTitle />
</#if>
<#--In order to fill out the subject-->
<#assign acFilterForIndividuals = "['" + editConfiguration.subjectUri + "']" />
<h2>${formTitle}</h2>
<#if editConfiguration.propertySelectFromExisting = true>
<#if rangeOptionsExist = true >
<form class="customForm" action = "${submitUrl}">
<input type="hidden" name="editKey" id="editKey" value="${editKey}" role="input" />
<#if editConfiguration.propertyPublicDescription?has_content>
<p>${editConfiguration.propertyPublicDescription}</p>
</#if>
<#---This section should become autocomplete instead-->
<p>
<label for="object"> ${propertyNameForDisplay?capitalize} ${i18n().name_capitalized}<span class='requiredHint'> *</span></label>
<input class="acSelector" size="50" type="text" id="object" name="objectLabel" acGroupName="object" value="${objectLabel}" />
</p>
<div class="acSelection" acGroupName="object" >
<p class="inline">
<label>${i18n().selected}:</label>
<span class="acSelectionInfo"></span>
<a href="" class="verifyMatch" title="${i18n().verify_this_match}">(${i18n().verify_this_match}</a> ${i18n().or}
<a href="#" class="changeSelection" id="changeSelection">${i18n().change_selection})</a>
</p>
<input class="acUriReceiver" type="hidden" id="objectVar" name="objectVar" value="${selectedObjectUri}" />
</div>
<#--The above section should be autocomplete-->
<p>
<input type="submit" id="submit" value="${submitButtonText}" role="button" disabled="disabled"/>
<span class="or"> or </span>
<a title="${i18n().cancel_title}" class="cancel" href="${cancelUrl}">${i18n().cancel_link}</a>
</p>
</form>
<#else>
<p> ${i18n().there_are_no_entries_for_selection} </p>
</#if>
</#if>
<p>&nbsp;</p>
<#if editConfiguration.propertyOfferCreateNewOption = true>
<#include "addConceptThroughObjectPropertyCreateNew.ftl">
</#if>
<#if editConfiguration.propertySelectFromExisting = false && editConfiguration.propertyOfferCreateNewOption = false>
<p>${i18n().editing_prohibited} </p>
</#if>
<#if editConfiguration.includeDeletionForm = true>
<#include "defaultDeletePropertyForm.ftl">
</#if>
<#assign sparqlQueryUrl = "${urls.base}/ajax/sparqlQuery" >
<#--Passing in object types only if there are any types returned, otherwise
the parameter should not be passed at all to the solr search.
Also multiple types parameter set to true only if more than one type returned-->
<script type="text/javascript">
var customFormData = {
acUrl: '${urls.base}/autocomplete?tokenize=true',
<#if objectTypesExist = true>
acTypes: {object: '${objectTypes}'},
</#if>
<#if multipleTypes = true>
acMultipleTypes: 'true',
</#if>
editMode: '${editMode}',
typeName:'${propertyNameForDisplay}',
acSelectOnly: 'true',
sparqlForAcFilter: '${sparqlForAcFilter}',
sparqlQueryUrl: '${sparqlQueryUrl}',
acFilterForIndividuals: ${acFilterForIndividuals},
defaultTypeName: '${propertyNameForDisplay}', // used in repair mode to generate button text
baseHref: '${urls.base}/individual?uri='
};
var i18nStrings = {
selectAnExisting: '${i18n().select_an_existing}',
orCreateNewOne: '${i18n().or_create_new_one}',
selectedString: '${i18n().selected}'
};
</script>
<#--
edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.AutocompleteObjectPropertyFormGenerator
edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.AddAttendeeRoleToPersonGenerator
-->
${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/browserUtils.js"></script>',
'<script type="text/javascript" src="${urls.base}/templates/freemarker/edit/forms/js/customFormWithAutocomplete.js"></script>')}

View file

@ -0,0 +1,35 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#--Overriding default form here to allow just concepts to show in the list-->
<#if rangeOptionsExist = true >
<p>${i18n().no_appropriate_entry}:</p>
<#else>
<p>${i18n().create_new_entry}</p>
</#if>
<#if editConfiguration.objectUri?has_content>
<#assign objectUri = editConfiguration.objectUri>
<#else>
<#assign objectUri = ""/>
</#if>
<#assign typesList = editConfiguration.pageData.createNewTypes/>
<form class="editForm" action="${editConfiguration.mainEditUrl}" role="input" />
<input type="hidden" value="${editConfiguration.subjectUri}" name="subjectUri" role="input" />
<input type="hidden" value="${editConfiguration.predicateUri}" name="predicateUri" role="input" />
<input type="hidden" value="${objectUri}" name="objectUri" role="input" />
<input type="hidden" value="create" name="cmd" role="input" />
<select id="typeOfNew" name="typeOfNew" role="selection">
<#assign typeKeys = typesList?keys />
<#list typeKeys as typeKey>
<option value="${typeKey}" role="option"> ${typesList[typeKey]} </option>
</#list>
</select>
<input type="submit" id="offerCreate" class="submit" value="${i18n().add_new_of_type}" role="button" />
<#if rangeOptionsExist = false >
<span class="or"> ${i18n().or} </span>
<a title="${i18n().cancel_title}" class="cancel" href="${cancelUrl}">${i18n().cancel_link}</a>
</#if>
</form>

View file

@ -0,0 +1,49 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#--Assign variables from editConfig-->
<#assign rangeOptions = editConfiguration.pageData.objectVar />
<#assign rangeOptionsExist = false />
<#if (rangeOptions?keys?size > 0)>
<#assign rangeOptionsExist = true/>
</#if>
<h2>${editConfiguration.formTitle}</h2>
<#if editConfiguration.propertySelectFromExisting = true>
<#if rangeOptionsExist = true >
<#assign rangeOptionKeys = rangeOptions?keys />
<form class="editForm" action = "${submitUrl}">
<input type="hidden" name="editKey" id="editKey" value="${editKey}" role="input" />
<#if editConfiguration.propertyPublicDescription?has_content>
<p>${editConfiguration.propertyPublicDescription}</p>
</#if>
<select id="objectVar" name="objectVar" role="select">
<#list rangeOptionKeys as key>
<option value="${key}" <#if editConfiguration.objectUri?has_content && editConfiguration.objectUri = key>selected</#if> role="option">${rangeOptions[key]}</option>
</#list>
</select>
<p>
<input type="submit" id="submit" value="${editConfiguration.submitLabel}" role="button "/>
<span class="or"> ${i18n().or} </span>
<a title="${i18n().cancel_title}" class="cancel" href="${cancelUrl}">${i18n().cancel_link}</a>
</p>
</form>
<#else>
<p> ${i18n().there_are_no_entries_for_selection} </p>
</#if>
</#if>
<#if editConfiguration.propertyOfferCreateNewOption = true>
<#include "addConceptThroughObjectPropertyCreateNew.ftl">
</#if>
<#if editConfiguration.propertySelectFromExisting = false && editConfiguration.propertyOfferCreateNewOption = false>
<p>${i18n().editing_prohibited} </p>
</#if>
<#if editConfiguration.includeDeletionForm = true>
<#include "defaultDeletePropertyForm.ftl">
</#if>

View file

@ -329,6 +329,8 @@ vivo:GovernmentAgency
skos:narrower
rdfs:label "narrower term"@en-US ;
vitro:customEntryFormAnnot
"edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.AddConceptThroughObjectPropertyGenerator"^^xsd:string ;
vitro:displayLimitAnnot
"5"^^xsd:int ;
vitro:displayRankAnnot
@ -4744,6 +4746,8 @@ obo:ERO_0001245
skos:broader
rdfs:label "broader term"@en-US ;
vitro:customEntryFormAnnot
"edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.AddConceptThroughObjectPropertyGenerator"^^xsd:string ;
vitro:displayLimitAnnot
"5"^^xsd:int ;
vitro:displayRankAnnot

View file

@ -0,0 +1,133 @@
/* $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.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
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.ConstantFieldOptions;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.IndividualsViaObjectPropetyOptions;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.IndividualsViaSolrQueryOptions;
/**
* This generator is for the case where a new concept is being added for an object property other than research/subject areas where the
* default object property form generator would work instead of the generator for managing concepts.
* In this case, we don't want the dropdown list for types for "add a new item of this type" to show concept subclasses, so we are overriding
* the fields to just include the Concept class.
*/
public class AddConceptThroughObjectPropertyGenerator extends DefaultObjectPropertyFormGenerator implements EditConfigurationGenerator {
private Log log = LogFactory.getLog(AddConceptThroughObjectPropertyGenerator.class);
@Override
public EditConfigurationVTwo getEditConfiguration(VitroRequest vreq,
HttpSession session) throws Exception {
EditConfigurationVTwo editConfig = super.getEditConfiguration(vreq, session);
//return rangetypes in form specific data
editConfig.addFormSpecificData("createNewTypes", getCreateNewTypesOptions(vreq));
//override templates with ones that will override create new types portion
editConfig.setTemplate(getTemplate(vreq));
return editConfig;
}
private HashMap<String, String> getCreateNewTypesOptions(VitroRequest vreq) {
HashMap<String, String> options = new HashMap<String, String>();
List<VClass> rangeTypes = getRangeTypes(vreq);
for(VClass v: rangeTypes) {
options.put(v.getURI(), v.getName());
}
return options;
}
//We will override range types as well so that autocomplete and other fields dependent on range
//will only consider the main concept type to be the range type
@Override
protected List<VClass> getRangeTypes(VitroRequest vreq) {
// This first part needs a WebappDaoFactory with no filtering/RDFService
// funny business because it needs to be able to retrieve anonymous union
// classes by their "pseudo-bnode URIs".
// Someday we'll need to figure out a different way of doing this.
//WebappDaoFactory ctxDaoFact = ModelAccess.on(
// vreq.getSession().getServletContext()).getWebappDaoFactory();
WebappDaoFactory ctxDaoFact = vreq.getLanguageNeutralWebappDaoFactory();
List<VClass> types = new ArrayList<VClass>();
Individual subject = EditConfigurationUtils.getSubjectIndividual(vreq);
String predicateUri = EditConfigurationUtils.getPredicateUri(vreq);
String rangeUri = EditConfigurationUtils.getRangeUri(vreq);
if (rangeUri != null) {
VClass rangeVClass = ctxDaoFact.getVClassDao().getVClassByURI(rangeUri);
if (!rangeVClass.isUnion()) {
types.add(rangeVClass);
} else {
for (VClass unionComponent : rangeVClass.getUnionComponents()) {
types.add(unionComponent);
}
}
return types;
} else {
//This should never happen
log.warn("Range not found for this property so employing SKOS concept class");
String vclassURI = "http://www.w3.org/2004/02/skos/core#Concept";
VClass rangeVClass = ctxDaoFact.getVClassDao().getVClassByURI(vclassURI);
types.add(rangeVClass);
}
return types;
}
//Should override the method in default object property
private String getTemplate(
VitroRequest vreq) {
String acObjectPropertyTemplate = "addConceptThroughObjectPropertyAutoComplete.ftl";
String objectPropertyTemplate = "addConceptThroughObjectPropertyForm.ftl";
String template = objectPropertyTemplate;
if( doAutoComplete )
template = acObjectPropertyTemplate;
return template;
}
@Override
protected void setFields(EditConfigurationVTwo editConfiguration, VitroRequest vreq, String predicateUri, List<VClass> rangeTypes) throws Exception {
FieldVTwo field = new FieldVTwo();
field.setName("objectVar");
List<String> validators = new ArrayList<String>();
validators.add("nonempty");
field.setValidators(validators);
if( ! doAutoComplete ){
List<String> types = new ArrayList<String>();
for(VClass v: rangeTypes) {
types.add(v.getURI());
}
field.setOptions( new IndividualsViaSolrQueryOptions(
vreq.getSession().getServletContext(),
types.toArray(new String[types.size()])));
}else{
field.setOptions(null);
}
Map<String, FieldVTwo> fields = new HashMap<String, FieldVTwo>();
fields.put(field.getName(), field);
editConfiguration.setFields(fields);
}
}

View file

@ -173,6 +173,8 @@ public class NewIndividualFormGenerator extends BaseEditConfigurationGenerator i
Boolean isPersonType = Boolean.FALSE;
String foafPersonType = getFOAFPersonClassURI();
List<String> superTypes = wdf.getVClassDao().getAllSuperClassURIs(getTypeOfNew(vreq));
//add foaf person type too so that can also get checked
superTypes.add(foafPersonType);
if( superTypes != null ){
for( String typeUri : superTypes){
if( foafPersonType.equals(typeUri)) {