Skip to content

Commit

Permalink
Find external property assertions for individuals from ontology.
Browse files Browse the repository at this point in the history
The xslt parser cannot extract metadata from other ontologies. This
adds a parser to process the external properties and if a match
is found then the appropiate property is added (dp,op,ni). If no
match is found then add in the documentation an "ep" property
which indicates that the property is found in an external
ontology.
  • Loading branch information
Victor Chavez committed Jan 2, 2024
1 parent c8c5dfa commit 9b607aa
Show file tree
Hide file tree
Showing 9 changed files with 201 additions and 8 deletions.
6 changes: 5 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@
<version>3.9.0</version>
</dependency>


<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.17.2</version>
</dependency>
<dependency>
<groupId>com.github.VisualDataWeb</groupId>
<artifactId>OWL2VOWL</artifactId>
Expand Down
17 changes: 12 additions & 5 deletions src/main/java/widoco/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import widoco.entities.Agent;
import widoco.entities.Ontology;
import widoco.ExternalPropertyParser;

/**
*
Expand Down Expand Up @@ -337,6 +338,7 @@ public class Constants {
public static final String LANG_CLASSES = "classes";
public static final String LANG_OBJ_PROP = "objProp";
public static final String LANG_DATA_PROP = "dataProp";
public static final String LANG_EXT_PROP = "extProp";
public static final String LANG_ANN_PROP = "annProp";
public static final String LANG_NAMED_INDIV = "namedIndiv";
public static final String LANG_TABLE_OF_CONTENTS = "tableOfContents";
Expand Down Expand Up @@ -1500,25 +1502,30 @@ public static String getLegend(
+ " <span class=\"backlink\"> " + lang.getProperty(Constants.LANG_BACK)
+ " <a href=\"#toc\">ToC</a></span></h2>\n"
+ "<div class=\"entity\">\n"
+ (includesClass ?
+ (includesClass || ExternalPropertyParser.hasClasses()?
"<sup class=\"type-c\" title=\""
+ lang.getProperty(Constants.LANG_CLASSES)
+ "\">c</sup>: " + lang.getProperty(Constants.LANG_CLASSES) + " <br/>\n"
: "")
+ (includesProperty ?
+ (includesProperty || ExternalPropertyParser.hasObjProps()?
"<sup class=\"type-op\" title=\""
+ lang.getProperty(Constants.LANG_OBJ_PROP) + "\">op</sup>: "
+ lang.getProperty(Constants.LANG_OBJ_PROP) + " <br/>\n"
: "")
+ (includesDatatypeProperty ?
+ (includesDatatypeProperty || ExternalPropertyParser.hasDataProps()?
"<sup class=\"type-dp\" title=\""
+ lang.getProperty(Constants.LANG_DATA_PROP) + "\">dp</sup>: "
+ lang.getProperty(Constants.LANG_DATA_PROP) + " <br/>\n"
: "")
+ (includesNamedIndividual ?
+ (includesNamedIndividual || ExternalPropertyParser.hasNamedIndiv() ?
"<sup class=\"type-ni\" title=\""
+ lang.getProperty(Constants.LANG_NAMED_INDIV) + "\">ni</sup>: "
+ lang.getProperty(Constants.LANG_NAMED_INDIV) + "\n"
+ lang.getProperty(Constants.LANG_NAMED_INDIV) + " <br/>\n"
: "")
+ (ExternalPropertyParser.hasExternalProps() ?
"<sup class=\"type-ep\" title=\""
+ lang.getProperty(Constants.LANG_EXT_PROP) + "\">ep</sup>: "
+ lang.getProperty(Constants.LANG_EXT_PROP) + "\n"
: "")
+ "</div>\n" + "</div>"
+ "\n";
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/widoco/CreateResources.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public static void generateDocumentation(String outFolder, Configuration c, File
logger.info("- ontology IRI: " + c.getOntologyURI());
lodeContent = LODEGeneration.getLODEhtml(c, lodeResources);
LODEParser lode = new LODEParser(lodeContent, c, languageFile);

if (c.isCreateHTACCESS()) {
File fOut = new File(folderOut);
if (!fOut.exists()) {
Expand Down
167 changes: 167 additions & 0 deletions src/main/java/widoco/ExternalPropertyParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package widoco;

import org.semanticweb.owlapi.model.*;
import org.semanticweb.owlapi.model.parameters.Imports;

import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class ExternalPropertyParser {
private enum PropertyType {
OBJECT_PROPERTY,
DATA_PROPERTY,
NAMED_INDIVIDUAL,
CLASS,
ANNOTATION_PROPERTY,
EXTERNAL_PROPERTY,
}

private static boolean uses_ep = false;
private static boolean uses_op = false;
private static boolean uses_ap = false;
private static boolean uses_dp = false;
private static boolean uses_ni = false;
private static boolean uses_c = false;

private static final Logger logger = LoggerFactory.getLogger(ExternalPropertyParser.class);

public static boolean hasExternalProps(){
return uses_ep;
}

public static boolean hasClasses(){
return uses_c;
}

public static boolean hasObjProps(){
return uses_op;
}

public static boolean hasAnnotProps(){
return uses_ap;
}

public static boolean hasDataProps(){
return uses_dp;
}

public static boolean hasNamedIndiv(){
return uses_ni;
}

/**
* Parse html content with external property tags, i.e., the sup tag
* with class type-ep and attempt to find the type of property type
* within the ontology.
* The main purpose of this utility is to add metadata from the ontology
* to the named individual assertions since the xslt transform cannot
* look for external properties outisde of the xml rdf serialization of the
* ontology.
* @param htmlContent Html content where the external properties are located.
* Typically this is the named individuals section
* @param ontology The ontology that will be used to look for the IRIS of
* the external properties.
* @return
*/
public static String parse(String htmlContent, OWLOntology ontology) {
Document document = Jsoup.parseBodyFragment(htmlContent, "UTF-8");
// Find all <a> tags with <sup> tags having class "type-ep"
Elements links = document.select("a + sup.type-ep");
// Modify the <sup> tag based on the property type
for (Element link : links) {
String href = link.previousElementSibling().attr("href");
PropertyType type = getPropertyType(ontology, href);
String class_name;
String text;
String title;
if (type == PropertyType.OBJECT_PROPERTY) {
class_name = "type-op";
text="op";
title = "object property";
if (!uses_op) {
uses_op = true;
}
} else if(type == PropertyType.DATA_PROPERTY) {
class_name = "type-dp";
text="dp";
title = "data property";
if (!uses_dp) {
uses_dp = true;
}
} else if (type == PropertyType.NAMED_INDIVIDUAL) {
class_name = "type-ni";
text="ni";
title = "named individual";
if (!uses_ni) {
uses_ni = true;
}
} else if (type == PropertyType.CLASS) {
class_name = "type-c";
text="c";
title = "class";
if (!uses_c) {
uses_c = true;
}
} else if (type == PropertyType.ANNOTATION_PROPERTY) {
class_name = "type-ap";
text="ap";
title = "annotation property";
if (!uses_ap) {
uses_ap = true;
}
} else {
class_name = "type-ep";
text ="ep";
title ="external property";
if (!uses_ep) {
uses_ep = true;
}
}
link.text(text);
link.attr("class",class_name);
link.attr("title",title);
}
return document.body().html();
}

private static PropertyType getPropertyType(OWLOntology ontology, String propertyIRI) {
IRI propertyIRIObject = IRI.create(propertyIRI);
Set<OWLObjectProperty> objectProperties = ontology.getObjectPropertiesInSignature(Imports.INCLUDED);
for (OWLObjectProperty objectProperty : objectProperties) {
if (objectProperty.getIRI().equals(propertyIRIObject)) {
return PropertyType.OBJECT_PROPERTY;
}
}
Set<OWLDataProperty> dataProperties = ontology.getDataPropertiesInSignature(Imports.INCLUDED);
for (OWLDataProperty dataProperty : dataProperties) {
if (dataProperty.getIRI().equals(propertyIRIObject)) {
return PropertyType.DATA_PROPERTY;
}
}
Set<OWLNamedIndividual> individuals = ontology.getIndividualsInSignature(Imports.INCLUDED);
for (OWLNamedIndividual individual : individuals) {
if (individual.getIRI().equals(propertyIRIObject)) {
return PropertyType.NAMED_INDIVIDUAL;
}
}
Set<OWLClass> classes = ontology.getClassesInSignature(Imports.INCLUDED);
for (OWLClass owl_class : classes) {
if (owl_class.getIRI().equals(propertyIRIObject)) {
return PropertyType.CLASS;
}
}
Set<OWLAnnotationProperty> annotationProperties = ontology.getAnnotationPropertiesInSignature(Imports.INCLUDED);
for (OWLAnnotationProperty annotationProperty : annotationProperties) {
if (annotationProperty.getIRI().equals(propertyIRIObject)) {
return PropertyType.ANNOTATION_PROPERTY;
}
}
return PropertyType.EXTERNAL_PROPERTY;
}

}
8 changes: 8 additions & 0 deletions src/main/java/widoco/LODEParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import widoco.ExternalPropertyParser;

/**
* Class made for parsing and manipulating LODE's html. This class contains most
* of the TemplateGeneratorOLD class
Expand Down Expand Up @@ -190,20 +192,23 @@ private void parse(String content, Properties langFile) {
classes = classes.replace("<h2>" + langFile.getProperty(Constants.LANG_CLASSES) + "</h2>",
"<h3 id=\"classes-headline\" class=\"list\">" + langFile.getProperty(Constants.LANG_CLASSES)
+ "</h3>");
classes = ExternalPropertyParser.parse(classes, c.getMainOntology().getOWLAPIModel());
break;
case "objectproperties":
propertyList = getTermList(html.item(i));
properties = (nodeToString(html.item(i)));
properties = properties.replace("<h2>" + langFile.getProperty(Constants.LANG_OBJ_PROP) + "</h2>",
"<h3 id=\"properties\" class=\"list\">" + langFile.getProperty(Constants.LANG_OBJ_PROP)
+ "</h3>");
properties = ExternalPropertyParser.parse(properties, c.getMainOntology().getOWLAPIModel());
break;
case "dataproperties":
dataPropList = (getTermList(html.item(i)));
dataProp = (nodeToString(html.item(i)));
dataProp = dataProp.replace("<h2>" + langFile.getProperty(Constants.LANG_DATA_PROP) + "</h2>",
"<h3 id=\"dataproperties-headline\" class=\"list\">"
+ langFile.getProperty(Constants.LANG_DATA_PROP) + "</h3>");
dataProp = ExternalPropertyParser.parse(dataProp, c.getMainOntology().getOWLAPIModel());
break;
case "annotationproperties":
annotationPropList = (getTermList(html.item(i)));
Expand All @@ -212,6 +217,7 @@ private void parse(String content, Properties langFile) {
"<h2>" + langFile.getProperty(Constants.LANG_ANN_PROP) + "</h2>",
"<h3 id=\"annotationproperties\" class=\"list\">"
+ langFile.getProperty(Constants.LANG_ANN_PROP) + "</h3>");
annotationProp = ExternalPropertyParser.parse(annotationProp, c.getMainOntology().getOWLAPIModel());
break;
case "namedindividuals":
namedIndividualList = (getTermList(html.item(i)));
Expand All @@ -220,6 +226,7 @@ private void parse(String content, Properties langFile) {
"<h2>" + langFile.getProperty(Constants.LANG_NAMED_INDIV) + "</h2>",
"<h3 id=\"namedindividuals\" class=\"list\">"
+ langFile.getProperty(Constants.LANG_NAMED_INDIV) + "</h3>");
namedIndividuals = ExternalPropertyParser.parse(namedIndividuals, c.getMainOntology().getOWLAPIModel());
break;
/*missing: rules!*/
case "rules":
Expand All @@ -245,6 +252,7 @@ private void parse(String content, Properties langFile) {
swrlrules = (nodeToString(html.item(i)));
swrlrules = swrlrules.replace("<h2>SWRL rules</h2>",
"<h3 id=\"swrlrules\" class=\"list\">SWRL rules</h3>");
swrlrules = ExternalPropertyParser.parse(swrlrules, c.getMainOntology().getOWLAPIModel());
break;
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/main/resources/lode/extraction.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -1173,8 +1173,12 @@ http://www.oxygenxml.com/ns/doc/xsl ">
<xsl:template name="get.individual.assertions">
<xsl:variable name="assertions">
<assertions>
<xsl:variable name="ns_rdfs" select="'http://www.w3.org/2000/01/rdf-schema#'"/>
<xsl:variable name="ns_dc" select="'http://purl.org/dc/elements/1.1/'"/>
<xsl:for-each select="element()">
<xsl:if test="name() != 'rdf:type'">
<xsl:if test="(name() != 'rdf:type')
and string(namespace-uri()) != $ns_rdfs
and string(namespace-uri()) != $ns_dc">
<xsl:variable name="currentURI" select="concat(namespace-uri(.),local-name(.))" as="xs:string"/>
<assertion rdf:about="{$currentURI}">
<xsl:choose>
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/widoco/de.properties
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ crossRefPlaceHolder=Dieser Abschnitt enth&auml;lt Details f&uuml;r jede Klasse u
classes=Klassen
objProp=Object Properties
dataProp=Data Properties
extProp=External Properties
annProp=Annotation Properties
namedIndiv=Named Individuals
referencesTitle=Referenzen
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/widoco/en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ crossRefPlaceHolder=This section provides details for each class and property de
classes=Classes
objProp=Object Properties
dataProp=Data Properties
extProp=External Properties
annProp=Annotation Properties
namedIndiv=Named Individuals
referencesTitle=References
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/widoco/es.properties
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ crossRefPlaceHolder=Esta secci&oacute;n introduce m&aacute;s detalles sobre cada
classes=Clases
objProp=Propiedades de objeto
dataProp=Propiedades de datos
extProp=Propiedades externas
annProp=Propiedades usadas para anotaci&oacute;n
namedIndiv=Individuos
referencesTitle=Referencias
Expand Down

0 comments on commit 9b607aa

Please sign in to comment.