diff --git a/productMods/WEB-INF/filegraph/tbox/ConceptSemanticType.owl b/productMods/WEB-INF/filegraph/tbox/ConceptSemanticType.owl deleted file mode 100644 index 04ab3d10..00000000 --- a/productMods/WEB-INF/filegraph/tbox/ConceptSemanticType.owl +++ /dev/null @@ -1,47 +0,0 @@ - - - 0.7 - - - - Semantic Type for given concept, for example UMLS's type returned for concepts - Semantic Type for given concept, for example UMLS's type returned for concepts. - - Concept Semantic Type - - - - - - - - diff --git a/productMods/images/individual/manage-icon.png b/productMods/images/individual/manage-icon.png deleted file mode 100644 index 18ab5756..00000000 Binary files a/productMods/images/individual/manage-icon.png and /dev/null differ diff --git a/productMods/templates/freemarker/body/individual/individual--foaf-person-2column.ftl b/productMods/templates/freemarker/body/individual/individual--foaf-person-2column.ftl index d3a63df8..b50f47af 100644 --- a/productMods/templates/freemarker/body/individual/individual--foaf-person-2column.ftl +++ b/productMods/templates/freemarker/body/individual/individual--foaf-person-2column.ftl @@ -10,6 +10,9 @@ <#if !labelCount??> <#assign labelCount = 0 > +<#if !localesCount??> + <#assign localesCount = 1> + <#assign qrCodeIcon = "qr-code-icon.png"> <#assign visRequestingTemplate = "foaf-person-2column">
@@ -40,7 +43,7 @@ <#else>

style="float:left;border-right:1px solid #A6B1B0;"> <#-- Label --> - <@p.label individual editable labelCount/> + <@p.label individual editable labelCount localesCount/>

<#-- Display preferredTitle if it exists; otherwise mostSpecificTypes --> <#assign title = propertyGroups.pullProperty("${core}preferredTitle")!> diff --git a/productMods/templates/freemarker/body/individual/individual--foaf-person-quickview.ftl b/productMods/templates/freemarker/body/individual/individual--foaf-person-quickview.ftl index 810250b5..006f1f8e 100644 --- a/productMods/templates/freemarker/body/individual/individual--foaf-person-quickview.ftl +++ b/productMods/templates/freemarker/body/individual/individual--foaf-person-quickview.ftl @@ -12,6 +12,9 @@ <#if !labelCount??> <#assign labelCount = 0 > +<#if !localesCount??> + <#assign localesCount = 1> + <#assign qrCodeIcon = "qr-code-icon.png"> <#assign individualImage> <@p.image individual=individual @@ -52,7 +55,7 @@
${individualImage}

style="float:left;border-right:1px solid #A6B1B0;"> <#-- Label --> - <@p.label individual editable labelCount/> + <@p.label individual editable labelCount localesCount/>

<#-- Display preferredTitle if it exists; otherwise mostSpecificTypes --> <#assign title = propertyGroups.pullProperty("${core}preferredTitle")!> diff --git a/productMods/templates/freemarker/body/individual/manageLabelsForIndividualTerms.ftl b/productMods/templates/freemarker/body/individual/manageLabelsForIndividualTerms.ftl new file mode 100644 index 00000000..cca1dcb6 --- /dev/null +++ b/productMods/templates/freemarker/body/individual/manageLabelsForIndividualTerms.ftl @@ -0,0 +1,4 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +<#--Some values for labels etc. may be different between vitro and other systems --> +<#assign returnText = "${i18n().return_to_profile}" /> \ No newline at end of file diff --git a/productMods/templates/freemarker/edit/forms/addAssociatedConcept.ftl b/productMods/templates/freemarker/edit/forms/addAssociatedConcept.ftl index f08e0f35..bacdf43f 100644 --- a/productMods/templates/freemarker/edit/forms/addAssociatedConcept.ftl +++ b/productMods/templates/freemarker/edit/forms/addAssociatedConcept.ftl @@ -51,6 +51,9 @@ <#if existingConcept.vocabURI?has_content && existingConcept.vocabLabel?has_content> (${existingConcept.vocabLabel}) + <#if existingConcept.conceptSemanticTypeLabel?has_content> + ${existingConcept.conceptSemanticTypeLabel} +  ${i18n().remove_capitalized} diff --git a/rdf/abox/filegraph/vocabularySource.n3 b/rdf/abox/filegraph/vocabularySource.n3 index 97690dd7..a111d896 100644 --- a/rdf/abox/filegraph/vocabularySource.n3 +++ b/rdf/abox/filegraph/vocabularySource.n3 @@ -1,3 +1,6 @@ . . - . \ No newline at end of file + . + "UMLS"^^ . + "AGROVOC"^^ . + "GEMET"^^ . \ No newline at end of file diff --git a/rdf/abox/firsttime/vocabularySource-labels.n3 b/rdf/abox/firsttime/vocabularySource-labels.n3 deleted file mode 100644 index a0a7966e..00000000 --- a/rdf/abox/firsttime/vocabularySource-labels.n3 +++ /dev/null @@ -1,3 +0,0 @@ - "UMLS"^^ . - "AGROVOC"^^ . - "GEMET"^^ . \ No newline at end of file diff --git a/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/AddAssociatedConceptGenerator.java b/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/AddAssociatedConceptGenerator.java index 9b9ce7f5..23f4e1bf 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/AddAssociatedConceptGenerator.java +++ b/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/AddAssociatedConceptGenerator.java @@ -396,37 +396,38 @@ public class AddAssociatedConceptGenerator extends VivoBaseGenerator implements } + //To determine whether or not a concept is a user generated or one from an external vocab source. + //we cannot rely on whether or not it is a skos concept because incorporating UMLS semantic network classes as + //SKOS concept subclasses means that even concepts from an external vocab source might be considered SKOS concepts + //Instead, we will simply determine whether a concept is defined by an external vocabulary source and use that + //as the primary indicator of whether a concept is from an external vocabulary source or a user generated concept private List getAssociatedConceptInfo( List concepts, VitroRequest vreq) { List info = new ArrayList(); for ( Individual conceptIndividual : concepts ) { - boolean isSKOSConcept = false; + boolean userGenerated = true; + //Note that this isn't technically String conceptUri = conceptIndividual.getURI(); String conceptLabel = conceptIndividual.getName(); - //Check if SKOS Concept type - List osl = conceptIndividual.getObjectPropertyStatements(RDF.type.getURI()); - for(ObjectPropertyStatement os: osl) { - if(os.getObjectURI().equals(SKOSConceptType)) { - isSKOSConcept = true; - break; - } - } + //Check if defined by an external vocabulary source + List vocabList = conceptIndividual.getObjectPropertyStatements(RDFS.isDefinedBy.getURI()); + String vocabSource = null; + String vocabLabel = null; + if(vocabList != null && vocabList.size() > 0) { + userGenerated = false; + vocabSource = vocabList.get(0).getObjectURI(); + Individual sourceIndividual = EditConfigurationUtils.getIndividual(vreq, vocabSource); + //Assuming name will get label + vocabLabel = sourceIndividual.getName(); + } + - if(isSKOSConcept) { + + if(userGenerated) { //if the concept in question is skos - which would imply a user generated concept info.add(new AssociatedConceptInfo(conceptLabel, conceptUri, null, null, SKOSConceptType, null, null)); } else { - //Get the vocab source and vocab label - List vocabList = conceptIndividual.getObjectPropertyStatements(RDFS.isDefinedBy.getURI()); - String vocabSource = null; - String vocabLabel = null; - if(vocabList != null && vocabList.size() > 0) { - vocabSource = vocabList.get(0).getObjectURI(); - Individual sourceIndividual = EditConfigurationUtils.getIndividual(vreq, vocabSource); - //Assuming name will get label - vocabLabel = sourceIndividual.getName(); - } String conceptSemanticTypeURI = null; String conceptSemanticTypeLabel = null; //Can a concept have multiple semantic types? Currently we are only returning the first one @@ -438,7 +439,6 @@ public class AddAssociatedConceptGenerator extends VivoBaseGenerator implements if(typeAndLabel.containsKey("semanticTypeLabel")) { conceptSemanticTypeLabel = typeAndLabel.get("semanticTypeLabel"); } - //Assuming this is from an external vocabulary source info.add(new AssociatedConceptInfo(conceptLabel, conceptUri, vocabSource, vocabLabel, null, conceptSemanticTypeURI, conceptSemanticTypeLabel)); diff --git a/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/AddAssociatedConceptsPreprocessor.java b/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/AddAssociatedConceptsPreprocessor.java index b4429094..1b81dbf1 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/AddAssociatedConceptsPreprocessor.java +++ b/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/AddAssociatedConceptsPreprocessor.java @@ -84,6 +84,8 @@ public class AddAssociatedConceptsPreprocessor extends //This will put the URI value in scope for the first semantic type label //and generate the rest if need be processConceptSemanticValues(); + //Also need to see if any broader or narrower uris for the concepts that already exist in the system + //and set up the appropriate relationships between this concept and the broader/narrower uri if (numberConcepts > 1) { processConceptNodes(numberConcepts); } diff --git a/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/ConceptSemanticTypesPreprocessor.java b/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/ConceptSemanticTypesPreprocessor.java new file mode 100644 index 00000000..b95733b4 --- /dev/null +++ b/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/ConceptSemanticTypesPreprocessor.java @@ -0,0 +1,125 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.query.Dataset; +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.query.QueryExecution; +import com.hp.hpl.jena.query.QueryExecutionFactory; +import com.hp.hpl.jena.query.QueryFactory; +import com.hp.hpl.jena.query.QuerySolutionMap; +import com.hp.hpl.jena.query.Syntax; +import com.hp.hpl.jena.rdf.model.Literal; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.rdf.model.Property; +import com.hp.hpl.jena.rdf.model.ResIterator; +import com.hp.hpl.jena.rdf.model.Resource; +import com.hp.hpl.jena.rdf.model.ResourceFactory; +import com.hp.hpl.jena.rdf.model.Statement; +import com.hp.hpl.jena.shared.Lock; +import com.hp.hpl.jena.vocabulary.RDF; +import com.hp.hpl.jena.vocabulary.RDFS; + +import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.jena.DatasetWrapper; +import edu.cornell.mannlib.vitro.webapp.dao.jena.DatasetWrapperFactory; + +//We are representing semantic types from the UMLS Semantic Network as OWL Classes +//and this preprocessor will add the appropriate class information to the TBox + +public class ConceptSemanticTypesPreprocessor implements ModelChangePreprocessor { + + private static String VIVOCore = "http://vivoweb.org/ontology/core#"; + private static String SKOSConceptType = "http://www.w3.org/2004/02/skos/core#Concept"; + private Log log = LogFactory.getLog(ConceptSemanticTypesPreprocessor.class); + + private OntModel toUpdateModel = null; + + //Custom constructor + public ConceptSemanticTypesPreprocessor(OntModel updateModel) { + this.toUpdateModel = updateModel; + } + + @Override + public void preprocess(Model retractionsModel, Model additionsModel, + HttpServletRequest request) { + //Run a construct query against the additions model + String prefixes = "PREFIX rdfs:<" + RDFS.getURI() + "> " + + "PREFIX owl: " + + "PREFIX rdf:<" + RDF.getURI() + ">" + + "PREFIX skos:"; + String constructQuery = prefixes + " CONSTRUCT { " + + "?semanticType rdf:type owl:Class. " + + "?semanticType rdfs:subClassOf skos:Concept . " + + "?semanticType rdfs:label ?label. " + + "} WHERE { " + + "?concept rdf:type ?semanticType. " + + "?semanticType rdfs:label ?label . " + + "?semanticType rdfs:subClassOf skos:Concept . " + + "}"; + + //Execute construct query + Model constructedModel = ModelFactory.createDefaultModel(); + + + log.debug("CONSTRUCT query string " + constructQuery); + + Query query = null; + try { + query = QueryFactory.create(constructQuery, Syntax.syntaxARQ); + } catch(Throwable th){ + log.error("Could not create CONSTRUCT SPARQL query for query " + + "string. " + th.getMessage()); + log.error(constructQuery); + return; + } + + + + additionsModel.getLock().enterCriticalSection(Lock.READ); + QueryExecution qe = null; + try { + qe = QueryExecutionFactory.create( + query, additionsModel); + qe.execConstruct(constructedModel); + } catch (Exception e) { + log.error("Error getting constructed model for query string " + constructQuery); + } finally { + if (qe != null) { + qe.close(); + } + additionsModel.getLock().leaveCriticalSection(); + } + + //Add constructed model to the designated update model + toUpdateModel.enterCriticalSection(Lock.WRITE); + try { + toUpdateModel.add(constructedModel); + } catch (Exception e) { + log.error("Error adding statements to update model for " + constructQuery); + } finally { + toUpdateModel.leaveCriticalSection(); + } + + //Take this constructed model and remove from the additions model + additionsModel.enterCriticalSection(Lock.WRITE); + try { + additionsModel.remove(constructedModel.listStatements().toList()); + } catch (Exception e) { + log.error("Error removing statements from additions model for " + constructQuery); + } finally { + additionsModel.leaveCriticalSection(); + } + + } + + + +} diff --git a/themes/wilma/i18n/all.properties b/themes/wilma/i18n/all.properties index 38583523..a0f2585f 100644 --- a/themes/wilma/i18n/all.properties +++ b/themes/wilma/i18n/all.properties @@ -280,7 +280,6 @@ change_selection = change selection # custom form templates ( /templates/freemarker/edit/forms ) # manage_concepts = Manage Concepts -remove_capitalized = Remove no_concepts_specified = There are currently no concepts specified. return_to_profile = Return to Profile Page external_vocabulary_services = External Vocabulary Services diff --git a/themes/wilma/templates/individual--foaf-person.ftl b/themes/wilma/templates/individual--foaf-person.ftl index 6e2161fb..761333be 100644 --- a/themes/wilma/templates/individual--foaf-person.ftl +++ b/themes/wilma/templates/individual--foaf-person.ftl @@ -11,6 +11,9 @@ <#if !labelCount??> <#assign labelCount = 0 > +<#if !localesCount??> + <#assign localesCount = 1> + <#assign visRequestingTemplate = "foaf-person-wilma">
@@ -55,7 +58,7 @@ <#else>

<#-- Label --> - <@p.label individual editable labelCount/> + <@p.label individual editable labelCount localesCount/> <#-- Display preferredTitle if it exists; otherwise mostSpecificTypes --> <#assign title = propertyGroups.pullProperty("${core}preferredTitle")!>