diff --git a/productMods/config/listViewConfig-issuedCredential.xml b/productMods/config/listViewConfig-issuedCredential.xml
new file mode 100644
index 00000000..44246d90
--- /dev/null
+++ b/productMods/config/listViewConfig-issuedCredential.xml
@@ -0,0 +1,139 @@
+
+
+
+
+
+
+
+ PREFIX foaf: <http://xmlns.com/foaf/0.1/>
+ PREFIX afn: <http://jena.hpl.hp.com/ARQ/function#>
+ PREFIX bibo: <http://purl.org/ontology/bibo/>
+ PREFIX core: <http://vivoweb.org/ontology/core#>
+ PREFIX owl: <http://www.w3.org/2002/07/owl#>
+ PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
+ PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#>
+
+ SELECT DISTINCT ?issuedCredential
+ ?credential
+ ?credentialLabel
+ ?dateTimeStart
+ ?dateTimeEnd
+ ?dateTime
+
+ WHERE {
+ ?subject ?property ?issuedCredential .
+ ?issuedCredential a core:IssuedCredential .
+ OPTIONAL { ?issuedCredential core:relates ?credential .
+ ?credential a core:Credential .
+ ?credential core:relatedBy ?issuedCredential
+ OPTIONAL { ?credential rdfs:label ?credentialLabel }
+ }
+ OPTIONAL { ?issuedCredential core:dateTimeInterval ?dateTimeInterval
+ OPTIONAL { ?dateTimeInterval core:start ?dateTimeStartValue .
+ ?dateTimeStartValue core:dateTime ?dateTimeStart
+ }
+ }
+ OPTIONAL { ?issuedCredential core:dateTimeInterval ?dateTimeInterval
+ OPTIONAL { ?dateTimeInterval core:end ?dateTimeEndValue .
+ ?dateTimeEndValue core:dateTime ?dateTimeEnd
+ }
+ }
+ OPTIONAL { ?issuedCredential core:dateTimeValue ?dateTimeValue
+ OPTIONAL { ?dateTimeValue core:dateTime ?dateTime }
+ }
+ } ORDER BY DESC(?dateTime) DESC(?dateTimeEnd)
+
+
+
+ PREFIX bibo: <http://purl.org/ontology/bibo/>
+ PREFIX core: <http://vivoweb.org/ontology/core#>
+ PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
+ PREFIX foaf: <http://xmlns.com/foaf/0.1/>
+
+ CONSTRUCT {
+ ?subject ?property ?issuedCredential .
+ ?issuedCredential a core:IssuedCredential .
+ ?issuedCredential core:relates ?credential .
+ ?credential a core:Credential .
+ ?credential core:relatedBy ?issuedCredential .
+ ?credential rdfs:label ?credentialLabel .
+ } WHERE {
+ {
+ ?subject ?property ?issuedCredential .
+ ?issuedCredential a core:IssuedCredential .
+ } UNION {
+ ?subject ?property ?issuedCredential .
+ ?issuedCredential a core:IssuedCredential .
+ ?issuedCredential core:relates ?credential .
+ ?credential a core:Credential .
+ ?credential core:relatedBy ?issuedCredential
+ } UNION {
+ ?subject ?property ?issuedCredential .
+ ?issuedCredential a core:IssuedCredential .
+ ?issuedCredential core:relates ?credential .
+ ?credential a core:Credential .
+ ?credential core:relatedBy ?issuedCredential .
+ ?credential rdfs:label ?credentialLabel
+ } UNION {
+ ?subject ?property ?issuedCredential .
+ ?issuedCredential a core:IssuedCredential .
+ ?issuedCredential core:relates ?credential .
+ ?credential a core:Credential .
+ ?credential core:relatedBy ?issuedCredential .
+ ?credential rdfs:label ?credentialLabel .
+ }
+ }
+
+
+
+ PREFIX core: <http://vivoweb.org/ontology/core#>
+ CONSTRUCT {
+ ?subject ?property ?issuedCredential .
+ ?issuedCredential a core:IssuedCredential .
+ ?issuedCredential core:dateTimeInterval ?dateTimeInterval .
+ ?dateTimeInterval core:start ?dateTimeStartValue .
+ ?dateTimeStartValue core:dateTime ?dateTimeStart
+ } WHERE {
+ ?subject ?property ?issuedCredential .
+ ?issuedCredential a core:IssuedCredential .
+ ?issuedCredential core:dateTimeInterval ?dateTimeInterval .
+ ?dateTimeInterval core:start ?dateTimeStartValue .
+ ?dateTimeStartValue core:dateTime ?dateTimeStart
+ }
+
+
+
+ PREFIX core: <http://vivoweb.org/ontology/core#>
+ CONSTRUCT {
+ ?subject ?property ?issuedCredential .
+ ?issuedCredential a core:IssuedCredential .
+ ?issuedCredential core:dateTimeInterval ?dateTimeInterval .
+ ?dateTimeInterval core:end ?dateTimeEndValue .
+ ?dateTimeEndValue core:dateTime ?dateTimeEnd
+ } WHERE {
+ ?subject ?property ?issuedCredential .
+ ?issuedCredential a core:IssuedCredential .
+ ?issuedCredential core:dateTimeInterval ?dateTimeInterval .
+ ?dateTimeInterval core:end ?dateTimeEndValue .
+ ?dateTimeEndValue core:dateTime ?dateTimeEnd
+ }
+
+
+
+ PREFIX core: <http://vivoweb.org/ontology/core#>
+ PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
+ CONSTRUCT {
+ ?subject ?property ?issuedCredential .
+ ?issuedCredential a core:IssuedCredential .
+ ?issuedCredential core:dateTimeValue ?dateTimeValue .
+ ?dateTimeValue core:dateTime ?dateTime
+ } WHERE {
+ ?subject ?property ?issuedCredential .
+ ?issuedCredential a core:IssuedCredential .
+ ?issuedCredential core:dateTimeValue ?dateTimeValue .
+ ?dateTimeValue core:dateTime ?dateTime
+ }
+
+
+ propStatement-issuedCredential.ftl
+
diff --git a/productMods/templates/freemarker/body/partials/individual/propStatement-issuedCredential.ftl b/productMods/templates/freemarker/body/partials/individual/propStatement-issuedCredential.ftl
new file mode 100644
index 00000000..555ebda8
--- /dev/null
+++ b/productMods/templates/freemarker/body/partials/individual/propStatement-issuedCredential.ftl
@@ -0,0 +1,35 @@
+<#-- $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#credentialOrHonor.
+
+ 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>
+<@showCredential statement />
+
+<#-- Use a macro to keep variable assignments local; otherwise the values carry over to the
+ next statement -->
+<#macro showCredential statement>
+
+ <#local linkedIndividual>
+ <#if statement.credential??>
+ ${statement.credentialLabel!statement.localName!}
+ <#else>
+ ${statement.issuedCredential!}
+ #if>
+ #local>
+
+ <#local dateTimeVal>
+ <#if statement.dateTime??>
+ <@dt.yearSpan statement.dateTime! />
+ <#else>
+ <@dt.yearIntervalSpan "${statement.dateTimeStart!}" "${statement.dateTimeEnd!}" />
+ #if>
+ #local>
+
+
+ <@s.join [ linkedIndividual, dateTimeVal! ] />
+
+ #macro>
diff --git a/productMods/templates/freemarker/edit/forms/js/issuedCredentialUtils.js b/productMods/templates/freemarker/edit/forms/js/issuedCredentialUtils.js
new file mode 100644
index 00000000..285ab333
--- /dev/null
+++ b/productMods/templates/freemarker/edit/forms/js/issuedCredentialUtils.js
@@ -0,0 +1,45 @@
+/* $This file is distributed under the terms of the license in /doc/license.txt$ */
+
+
+var issuedCredentialUtils = {
+
+ onLoad: function() {
+ this.initObjectReferences();
+ this.bindEventListeners();
+ $.extend(this, credentials);
+
+ // copy the year awarded to the displayed input element for edit mode
+ if ( this.yearCredentialed.val().length > 0 ) {
+ this.displayedYear.val(this.yearCredentialed.val());
+ }
+ },
+
+ initObjectReferences: function() {
+
+ this.form = $('#personHasIssuedCredential');
+ this.yearCredentialed = $('#yearCredentialed-year');
+ this.displayedYear = $('#yearCredentialedDisplay');
+ this.typeSelector = $('#typeSelector');
+ this.issuedType = $('#issuedCredentialType');
+
+ },
+
+ bindEventListeners: function() {
+ this.idCache = {};
+
+ this.form.submit(function() {
+ issuedCredentialUtils.setIssuedCredentialType($(issuedCredentialUtils.typeSelector).find(":selected").text());
+ issuedCredentialUtils.setYearCredentialedValue();
+ });
+
+ },
+
+ setYearCredentialedValue: function() {
+ this.yearCredentialed.val(this.displayedYear.val());
+ },
+
+ setIssuedCredentialType: function(val) {
+ this.issuedType.val(credentials[val]);
+ }
+
+}
\ No newline at end of file
diff --git a/productMods/templates/freemarker/edit/forms/personHasIssuedCredential.ftl b/productMods/templates/freemarker/edit/forms/personHasIssuedCredential.ftl
new file mode 100644
index 00000000..d542fd2d
--- /dev/null
+++ b/productMods/templates/freemarker/edit/forms/personHasIssuedCredential.ftl
@@ -0,0 +1,229 @@
+<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
+
+<#-- this is in request.subject.name -->
+
+<#-- leaving this edit/add mode code in for reference in case we decide we need it -->
+
+<#import "lib-vivo-form.ftl" as lvf>
+
+<#--Retrieve certain edit configuration information-->
+<#if editConfiguration.objectUri?has_content>
+ <#assign editMode = "edit">
+<#else>
+ <#assign editMode = "add">
+#if>
+
+<#--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" />
+
+<#assign htmlForElements = editConfiguration.pageData.htmlForElements />
+
+<#--Retrieve variables needed-->
+<#assign credentialTypeValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "credentialType")/>
+<#assign credentialValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "existingCredential") />
+<#assign credentialLabelValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "credentialLabel") />
+<#assign yearCredentialedDisplayValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "yearCredentialedDisplay") />
+<#assign credentialLabelDisplayValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "credentialLabelDisplay") />
+<#assign issuedCredentialTypeValue = lvf.getFormFieldValue(editSubmission, editConfiguration, "issuedCredentialType")/>
+
+<#--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">
+ <#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 = " *" />
+<#assign yearHint = "(${i18n().year_hint_format})" />
+
+
${titleVerb} ${i18n().credentials} ${editConfiguration.subjectName}
+
+<#--Display error messages if any-->
+<#if submissionErrors?has_content>
+ <#if credentialLabelDisplayValue?has_content >
+ <#assign credentialLabelValue = credentialLabelDisplayValue />
+ #if>
+
+
+
+
+ <#--Checking if any required fields are empty-->
+ <#if lvf.submissionErrorExists(editSubmission, "credentialLabel")>
+ ${i18n().select_credential_or_enter_name}
+ #if>
+ <#list submissionErrors?keys as errorFieldName>
+ <#if errorFieldName == "startField">
+ <#if submissionErrors[errorFieldName]?contains("before")>
+ ${i18n().start_year_must_precede_end}
+ <#else>
+ ${submissionErrors[errorFieldName]}
+ #if>
+
+ <#elseif errorFieldName == "endField">
+ <#if submissionErrors[errorFieldName]?contains("after")>
+ ${i18n().end_year_must_be_later}
+ <#else>
+ ${submissionErrors[errorFieldName]}
+ #if>
+ #if>
+ #list>
+
+
+#if>
+
+<@lvf.unsupportedBrowser urls.base />
+
+
+
+
+<#assign credentials = editConfiguration.pageData.credentialTypeMap />
+
+
+
+
+
+
+
+
+
+${stylesheets.add('')}
+${stylesheets.add('')}
+${stylesheets.add('')}
+
+${scripts.add('',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '')}
+
+
+
diff --git a/rdf/display/everytime/PropertyConfig.n3 b/rdf/display/everytime/PropertyConfig.n3
index d46ff45d..22793314 100644
--- a/rdf/display/everytime/PropertyConfig.n3
+++ b/rdf/display/everytime/PropertyConfig.n3
@@ -394,6 +394,21 @@ local:editorOfConfig a :ObjectPropertyDisplayConfig ;
vitro:customEntryFormAnnot "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.AddEditorshipToPersonGenerator"^^ ;
:propertyGroup .
+local:issuedCredentialContext a :ConfigContext ;
+ :hasConfiguration local:issuedCredentialConfig ;
+ :configContextFor ;
+ :qualifiedByDomain ;
+ :qualifiedBy .
+
+local:issuedCredentialConfig a :ObjectPropertyDisplayConfig ;
+ :listViewConfigFile "listViewConfig-issuedCredential.xml"^^xsd:string ;
+ :displayName "credentials" ;
+ vitro:displayRankAnnot 5;
+ vitro:hiddenFromDisplayBelowRoleLevelAnnot role:public ;
+ vitro:prohibitedFromUpdateBelowRoleLevelAnnot role:public ;
+ vitro:customEntryFormAnnot "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.PersonHasIssuedCredentialGenerator"^^ ;
+ :propertyGroup .
+
### vcard properties ###
local:mailingAddressContext a :ConfigContext ;
diff --git a/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/PersonHasIssuedCredentialGenerator.java b/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/PersonHasIssuedCredentialGenerator.java
new file mode 100644
index 00000000..594f5d4e
--- /dev/null
+++ b/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/PersonHasIssuedCredentialGenerator.java
@@ -0,0 +1,338 @@
+/* $This file is distributed under the terms of the license in /doc/license.txt$ */
+
+package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+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.AutocompleteRequiredInputValidator;
+import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.DateTimeIntervalValidationVTwo;
+import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.DateTimeWithPrecisionVTwo;
+import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
+import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.ChildVClassesWithParent;
+import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.ConstantFieldOptions;
+import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldOptions;
+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;
+
+public class PersonHasIssuedCredentialGenerator extends VivoBaseGenerator implements
+ EditConfigurationGenerator {
+
+ final static String issuedCredentialTypeClass = vivoCore + "IssuedCredential";
+ final static String credentialTypeClass = vivoCore + "Credential";
+ final static String yearCredentialedPred = vivoCore + "dateTimeValue";
+ final static String issuedCredentialToInterval = vivoCore + "dateTimeInterval";
+ final static String intervalType = vivoCore + "DateTimeInterval";
+ final static String intervalToStart = vivoCore + "start";
+ final static String intervalToEnd = vivoCore + "end";
+ final static String dateTimeValueType = vivoCore + "DateTimeValue";
+ final static String dateTimeValue = vivoCore + "dateTime";
+ final static String dateTimePrecision = vivoCore + "dateTimePrecision";
+
+ public PersonHasIssuedCredentialGenerator() {}
+
+ @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("personHasIssuedCredential.ftl");
+
+ conf.setVarNameForSubject("person");
+ conf.setVarNameForPredicate("predicate");
+ conf.setVarNameForObject("issuedCredential");
+
+ conf.setN3Required( Arrays.asList( n3ForNewIssuedCredential, n3ForICTypeAssertion) );
+ conf.setN3Optional( Arrays.asList( n3ForNewCredentialAssertion,
+ n3ForExistingCredentialAssertion,
+ n3ForYearCredentialed,
+ n3ForStart,
+ n3ForEnd ) );
+
+ conf.addNewResource("credential", DEFAULT_NS_FOR_NEW_RESOURCE);
+ conf.addNewResource("issuedCredential", DEFAULT_NS_FOR_NEW_RESOURCE);
+ conf.addNewResource("yearCredentialedNode", DEFAULT_NS_FOR_NEW_RESOURCE);
+ conf.addNewResource("intervalNode", DEFAULT_NS_FOR_NEW_RESOURCE);
+ conf.addNewResource("startNode", DEFAULT_NS_FOR_NEW_RESOURCE);
+ conf.addNewResource("endNode", DEFAULT_NS_FOR_NEW_RESOURCE);
+
+ //uris in scope: none
+ //literals in scope: none
+
+ conf.setUrisOnform(Arrays.asList("existingCredential", "issuedCredentialType", "credentialType"));
+ conf.setLiteralsOnForm(Arrays.asList("yearCredentialedDisplay","credentialLabel", "credentialLabelDisplay" ));
+
+ conf.addSparqlForExistingLiteral("credentialLabel", credentialLabelQuery);
+ conf.addSparqlForExistingLiteral("yearCredentialed-value", existingYearCredentialedQuery);
+ conf.addSparqlForExistingLiteral("startField-value", existingStartDateQuery);
+ conf.addSparqlForExistingLiteral("endField-value", existingEndDateQuery);
+
+ conf.addSparqlForExistingUris("existingCredential", existingCredentialQuery);
+ conf.addSparqlForExistingUris("credentialType", existingCredentialTypeQuery);
+ conf.addSparqlForExistingUris("issuedCredentialType", issuedCredentialTypeQuery);
+ conf.addSparqlForExistingUris("yearCredentialedNode",existingYearCredentialedNodeQuery);
+ conf.addSparqlForExistingUris("intervalNode",existingIntervalNodeQuery);
+ conf.addSparqlForExistingUris("startNode", existingStartNodeQuery);
+ conf.addSparqlForExistingUris("endNode", existingEndNodeQuery);
+ conf.addSparqlForExistingUris("yearCredentialed-precision", existingYearCredentialedPrecisionQuery);
+ conf.addSparqlForExistingUris("startField-precision", existingStartPrecisionQuery);
+ conf.addSparqlForExistingUris("endField-precision", existingEndPrecisionQuery);
+
+ conf.addField( new FieldVTwo().
+ setName("issuedCredentialType").
+ setRangeDatatypeUri(XSD.xstring.toString() ).
+ setValidators( list("datatype:" + XSD.xstring.toString()))
+ );
+
+ conf.addField( new FieldVTwo().
+ setName("credentialType").
+ setOptions(getCredentialTypeFieldOptions(vreq)));
+
+ conf.addField( new FieldVTwo(). // options will be added in browser by auto complete JS
+ setName("existingCredential")
+ );
+
+ conf.addField( new FieldVTwo().
+ setName("credentialLabel").
+ setRangeDatatypeUri(XSD.xstring.toString() ).
+ setValidators( list("datatype:" + XSD.xstring.toString()) )
+ );
+
+ conf.addField( new FieldVTwo().
+ setName("yearCredentialedDisplay").
+ setRangeDatatypeUri(XSD.xstring.toString() ).
+ setValidators( list("datatype:" + XSD.xstring.toString()))
+ );
+
+ conf.addField( new FieldVTwo().
+ setName("orgLabelDisplay").
+ setRangeDatatypeUri(XSD.xstring.toString() ).
+ setValidators( list("datatype:" + XSD.xstring.toString()))
+ );
+
+ conf.addField( new FieldVTwo().
+ setName("credentialLabelDisplay").
+ setRangeDatatypeUri(XSD.xstring.toString() ).
+ setValidators( list("datatype:" + XSD.xstring.toString()))
+ );
+
+ conf.addField( new FieldVTwo().setName("yearCredentialed").
+ setEditElement(
+ new DateTimeWithPrecisionVTwo(null,
+ VitroVocabulary.Precision.YEAR.uri(),
+ VitroVocabulary.Precision.NONE.uri())
+ )
+ );
+
+ conf.addField( new FieldVTwo().setName("startField").
+ setEditElement(
+ new DateTimeWithPrecisionVTwo(null,
+ VitroVocabulary.Precision.YEAR.uri(),
+ VitroVocabulary.Precision.NONE.uri())
+ )
+ );
+
+ conf.addField( new FieldVTwo().setName("endField").
+ setEditElement(
+ new DateTimeWithPrecisionVTwo(null,
+ VitroVocabulary.Precision.YEAR.uri(),
+ VitroVocabulary.Precision.NONE.uri())
+ )
+ );
+
+ conf.addValidator(new DateTimeIntervalValidationVTwo("startField","endField"));
+ conf.addValidator(new AntiXssValidation());
+ conf.addValidator(new AutocompleteRequiredInputValidator("existingCredential", "credentialLabel"));
+
+ addFormSpecificData(conf, vreq);
+ prepare(vreq, conf);
+ return conf;
+ }
+
+ /* N3 assertions */
+
+ final static String n3ForNewIssuedCredential =
+ "@prefix vivo: <" + vivoCore + "> . \n\n" +
+ "?person vivo:relatedBy ?issuedCredential . \n" +
+ "?issuedCredential a <" + issuedCredentialTypeClass + "> . \n" +
+ "?issuedCredential vivo:relates ?person . " ;
+
+ final static String n3ForICTypeAssertion =
+ "?issuedCredential a ?issuedCredentialType .";
+
+ final static String n3ForNewCredentialAssertion =
+ "@prefix vivo: <" + vivoCore + "> . \n\n" +
+ "?issuedCredential vivo:relates ?credential . \n" +
+ "?credential a <" + credentialTypeClass + "> . \n" +
+ "?credential vivo:relatedBy ?issuedCredential . \n" +
+ "?credential a ?credentialType . \n" +
+ "?credential <"+ label + "> ?credentialLabel .";
+
+ final static String n3ForExistingCredentialAssertion =
+ "@prefix vivo: <" + vivoCore + "> . \n\n" +
+ "?issuedCredential vivo:relates ?existingCredential . \n" +
+ "?existingCredential a <" + credentialTypeClass + "> . \n" +
+ "?credential a ?credentialType . \n" +
+ "?existingCredential vivo:relatedBy ?issuedCredential . " ;
+
+ final static String n3ForYearCredentialed =
+ "?issuedCredential <" + yearCredentialedPred + "> ?yearCredentialedNode . \n" +
+ "?yearCredentialedNode a <" + dateTimeValueType + "> . \n" +
+ "?yearCredentialedNode <" + dateTimeValue + "> ?yearCredentialed-value . \n" +
+ "?yearCredentialedNode <" + dateTimePrecision + "> ?yearCredentialed-precision .";
+
+ final static String n3ForStart =
+ "?issuedCredential <" + issuedCredentialToInterval + "> ?intervalNode . \n" +
+ "?intervalNode a <" + intervalType + "> . \n" +
+ "?intervalNode <" + intervalToStart + "> ?startNode . \n" +
+ "?startNode a <" + dateTimeValueType + "> . \n" +
+ "?startNode <" + dateTimeValue + "> ?startField-value . \n" +
+ "?startNode <" + dateTimePrecision + "> ?startField-precision . \n";
+
+ final static String n3ForEnd =
+ "?issuedCredential <" + issuedCredentialToInterval + "> ?intervalNode . \n" +
+ "?intervalNode a <" + intervalType + "> . \n" +
+ "?intervalNode <" + intervalToEnd + "> ?endNode . \n" +
+ "?endNode a <" + dateTimeValueType + "> . \n" +
+ "?endNode <" + dateTimeValue + "> ?endField-value . \n" +
+ "?endNode <" + dateTimePrecision + "> ?endField-precision . \n";
+
+ /* Queries for editing an existing entry */
+
+ final static String existingCredentialQuery =
+ "PREFIX vivo: \n" +
+ "SELECT ?existingCredential WHERE { \n" +
+ " ?issuedCredential vivo:relates ?existingCredential . \n" +
+ " ?existingCredential a vivo:Credential . \n" +
+ "}";
+
+ final static String existingCredentialTypeQuery =
+ "PREFIX vivo: \n" +
+ "PREFIX vitro: <" + VitroVocabulary.vitroURI + "> \n" +
+ "SELECT ?existingCredentialType WHERE { \n" +
+ " ?issuedCredential vivo:relates ?existingCredential . \n" +
+ " ?existingCredential a vivo:Credential . \n" +
+ " ?existingCredential vitro:mostSpecificType ?existingCredentialType . \n" +
+ "}";
+
+ final static String issuedCredentialTypeQuery =
+ "PREFIX vitro: <" + VitroVocabulary.vitroURI + "> \n" +
+ "SELECT ?existingICType WHERE { \n" +
+ " ?issuedCredential vitro:mostSpecificType ?existingICType . \n" +
+ "}";
+
+ final static String credentialLabelQuery =
+ "PREFIX vivo: \n" +
+ "SELECT ?existingCredentialLabel WHERE { \n" +
+ " ?issuedCredential vivo:relates ?existingCredential . \n" +
+ " ?existingCredential a . \n" +
+ " ?existingCredential <" + label + "> ?existingCredentialLabel . \n" +
+ "}";
+
+ final static String existingYearCredentialedQuery =
+ "SELECT ?existingYearCredentialedValue WHERE { \n" +
+ " ?issuedCredential <" + yearCredentialedPred + "> ?yearCredentialedNode . \n" +
+ " ?yearCredentialedNode a <" + dateTimeValueType + "> . \n" +
+ " ?yearCredentialedNode <" + dateTimeValue + "> ?existingYearCredentialedValue }";
+
+ final static String existingYearCredentialedNodeQuery =
+ "SELECT ?existingYearCredentialedNode WHERE { \n" +
+ " ?issuedCredential <" + yearCredentialedPred + "> ?existingYearCredentialedNode . }";
+
+ final static String existingStartDateQuery =
+ "SELECT ?existingStartDate WHERE { \n" +
+ " ?issuedCredential <" + issuedCredentialToInterval + "> ?intervalNode . \n" +
+ " ?intervalNode a <" + intervalType + "> . \n" +
+ " ?intervalNode <" + intervalToStart + "> ?startNode . \n" +
+ " ?startNode a <" + dateTimeValueType +"> . \n" +
+ " ?startNode <" + dateTimeValue + "> ?existingStartDate . }";
+
+ final static String existingEndDateQuery =
+ "SELECT ?existingEndDate WHERE { \n" +
+ " ?issuedCredential <" + issuedCredentialToInterval + "> ?intervalNode . \n" +
+ " ?intervalNode a <" + intervalType + "> . \n " +
+ " ?intervalNode <" + intervalToEnd + "> ?endNode . \n" +
+ " ?endNode a <" + dateTimeValueType + "> . \n" +
+ " ?endNode <" + dateTimeValue + "> ?existingEndDate . }";
+
+ final static String existingIntervalNodeQuery =
+ "SELECT ?existingIntervalNode WHERE { \n" +
+ " ?issuedCredential <" + issuedCredentialToInterval + "> ?existingIntervalNode . \n" +
+ " ?existingIntervalNode a <" + intervalType + "> . }";
+
+ final static String existingStartNodeQuery =
+ "SELECT ?existingStartNode WHERE { \n" +
+ " ?issuedCredential <" + issuedCredentialToInterval + "> ?intervalNode . \n" +
+ " ?intervalNode a <" + intervalType + "> . \n" +
+ " ?intervalNode <" + intervalToStart + "> ?existingStartNode . \n" +
+ " ?existingStartNode a <" + dateTimeValueType + "> . } ";
+
+ final static String existingEndNodeQuery =
+ "SELECT ?existingEndNode WHERE { \n" +
+ " ?issuedCredential <" + issuedCredentialToInterval + "> ?intervalNode . \n" +
+ " ?intervalNode a <" + intervalType + "> . \n" +
+ " ?intervalNode <" + intervalToEnd + "> ?existingEndNode . \n" +
+ " ?existingEndNode a <" + dateTimeValueType + "> } ";
+
+ final static String existingYearCredentialedPrecisionQuery =
+ "SELECT ?existingYearCredentialedPrecision WHERE { \n" +
+ " ?issuedCredential <" + yearCredentialedPred + "> ?yearCredentialed . \n" +
+ " ?yearCredentialed a <" + dateTimeValueType + "> . \n" +
+ " ?yearCredentialed <" + dateTimePrecision + "> ?existingYearCredentialedPrecision . }";
+
+ final static String existingStartPrecisionQuery =
+ "SELECT ?existingStartPrecision WHERE { \n" +
+ " ?issuedCredential <" + issuedCredentialToInterval + "> ?intervalNode . \n" +
+ " ?intervalNode a <" + intervalType + "> . \n" +
+ " ?intervalNode <" + intervalToStart + "> ?startNode . \n" +
+ " ?startNode a <" + dateTimeValueType + "> . \n" +
+ " ?startNode <" + dateTimePrecision + "> ?existingStartPrecision . }";
+
+ final static String existingEndPrecisionQuery =
+ "SELECT ?existingEndPrecision WHERE { \n" +
+ " ?issuedCredential <" + issuedCredentialToInterval + "> ?intervalNode . \n" +
+ " ?intervalNode a <" + intervalType + "> . \n" +
+ " ?intervalNode <" + intervalToEnd + "> ?endNode . \n" +
+ " ?endNode a <" + dateTimeValueType + "> . \n" +
+ " ?endNode <" + dateTimePrecision + "> ?existingEndPrecision . }";
+
+ //Form specific data
+ public void addFormSpecificData(EditConfigurationVTwo editConfiguration, VitroRequest vreq) {
+ HashMap formSpecificData = new HashMap();
+ formSpecificData.put("credentialTypeMap", getCredentialTypeMap());
+ editConfiguration.setFormSpecificData(formSpecificData);
+ }
+
+ // Issued Credentials relate a Credential to a person. The class type of a Credential and its subclasses
+ // are different than -- but correspond to -- the class type of an Issued Credential and its subclasses.
+ // When a user picks a type of credential in the GUI, we need to set the corresponding type for the issued
+ // credential. This map makes that possible. The class name of the credential is on the right, and the URI
+ // of th eissued credential is on the left.
+ private HashMap getCredentialTypeMap() {
+ HashMap credentials = new HashMap();
+ credentials.put("Credential","http://vivoweb.org/ontology/core#IssuedCredential");
+ credentials.put("Certificate","http://vivoweb.org/ontology/core#Certification");
+ credentials.put("License","http://vivoweb.org/ontology/core#Licensure");
+ return credentials;
+ }
+ private FieldOptions getCredentialTypeFieldOptions(VitroRequest vreq) throws Exception {
+ return new ConstantFieldOptions(
+ "http://vivoweb.org/ontology/core#Certificate", "Certificate",
+ "http://vivoweb.org/ontology/core#Credential", "Credential",
+ "http://vivoweb.org/ontology/core#License", "License");
+ }
+
+}