This is an automated email from the ASF dual-hosted git repository.
andy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/jena.git
The following commit(s) were added to refs/heads/main by this push:
new 700089c935 GH-2657: fix several defects in profiles support (RL, QL):
- OntDisjoint.Classes should only contain subClassExpressions - subject of
hasKey axiom should be subClassExpression
700089c935 is described below
commit 700089c935e97de359363db94d28d44d308e78ac
Author: sszuev <[email protected]>
AuthorDate: Thu Aug 29 22:23:09 2024 +0300
GH-2657: fix several defects in profiles support (RL, QL):
- OntDisjoint.Classes should only contain subClassExpressions
- subject of hasKey axiom should be subClassExpression
---
.../jena/ontapi/common/OntPersonalities.java | 4 +-
.../apache/jena/ontapi/impl/OntGraphModelImpl.java | 3 +-
.../ontapi/impl/factories/OWL2ObjectFactories.java | 2 +
.../jena/ontapi/impl/factories/OntDisjoints.java | 34 ++++++++++
.../jena/ontapi/impl/objects/OntClassImpl.java | 13 +++-
.../jena/ontapi/impl/objects/OntDisjointImpl.java | 29 +++++++++
.../org/apache/jena/ontapi/model/OntClass.java | 4 +-
.../org/apache/jena/ontapi/model/OntDisjoint.java | 3 +-
.../apache/jena/ontapi/OntModelOWL2ELSpecTest.java | 29 +++++++--
.../apache/jena/ontapi/OntModelOWL2QLSpecTest.java | 15 +++++
.../apache/jena/ontapi/OntModelOWL2RLSpecTest.java | 75 ++++++++++++++++++++++
11 files changed, 198 insertions(+), 13 deletions(-)
diff --git
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/common/OntPersonalities.java
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/common/OntPersonalities.java
index e6a42bd100..d175c1f949 100644
---
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/common/OntPersonalities.java
+++
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/common/OntPersonalities.java
@@ -371,7 +371,7 @@ public class OntPersonalities {
.add(OntDataRange.class, OWL2ObjectFactories.QL_ANY_DATARANGE)
// disjoint anonymous collections:
- .add(OntDisjoint.Classes.class,
OWL2ObjectFactories.CLASSES_DISJOINT)
+ .add(OntDisjoint.Classes.class,
OWL2ObjectFactories.QL_CLASSES_DISJOINT)
.add(OntDisjoint.Individuals.class,
OWL2ObjectFactories.DIFFERENT_INDIVIDUALS_DISJOINT)
.add(OntDisjoint.ObjectProperties.class,
OWL2ObjectFactories.OBJECT_PROPERTIES_DISJOINT)
.add(OntDisjoint.DataProperties.class,
OWL2ObjectFactories.DATA_PROPERTIES_DISJOINT)
@@ -446,7 +446,7 @@ public class OntPersonalities {
.add(OntNegativeAssertion.class,
OWL2ObjectFactories.ANY_NEGATIVE_PROPERTY_ASSERTION)
// disjoint anonymous collections:
- .add(OntDisjoint.Classes.class,
OWL2ObjectFactories.CLASSES_DISJOINT)
+ .add(OntDisjoint.Classes.class,
OWL2ObjectFactories.RL_CLASSES_DISJOINT)
.add(OntDisjoint.Individuals.class,
OWL2ObjectFactories.DIFFERENT_INDIVIDUALS_DISJOINT)
.add(OntDisjoint.ObjectProperties.class,
OWL2ObjectFactories.OBJECT_PROPERTIES_DISJOINT)
.add(OntDisjoint.DataProperties.class,
OWL2ObjectFactories.DATA_PROPERTIES_DISJOINT)
diff --git
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/OntGraphModelImpl.java
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/OntGraphModelImpl.java
index 3b4ab2b5de..8228f6e1d9 100644
---
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/OntGraphModelImpl.java
+++
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/OntGraphModelImpl.java
@@ -966,7 +966,8 @@ public class OntGraphModelImpl extends ModelCom implements
OntModel, OntEnhGraph
@Override
public OntDisjoint.Classes createDisjointClasses(Collection<OntClass>
classes) {
checkType(OntDisjoint.Classes.class);
- return OntDisjointImpl.createDisjointClasses(this, classes.stream());
+ checkType(OntClass.IntersectionOf.class);
+ return checkCreate(model ->
OntDisjointImpl.createDisjointClasses(this, classes.stream()),
OntDisjoint.Classes.class);
}
@Override
diff --git
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/factories/OWL2ObjectFactories.java
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/factories/OWL2ObjectFactories.java
index ed9d34dccc..16b248a8bc 100644
---
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/factories/OWL2ObjectFactories.java
+++
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/factories/OWL2ObjectFactories.java
@@ -795,6 +795,8 @@ public final class OWL2ObjectFactories {
true,
OWL2.members
);
+ public static final EnhNodeFactory QL_CLASSES_DISJOINT =
OntDisjoints.createQLRLOntDisjointFactory();
+ public static final EnhNodeFactory RL_CLASSES_DISJOINT =
OntDisjoints.createQLRLOntDisjointFactory();
public static final Function<OntConfig, EnhNodeFactory>
DIFFERENT_INDIVIDUALS_DISJOINT =
OntDisjoints::createDifferentIndividualsFactory;
public static final EnhNodeFactory OBJECT_PROPERTIES_DISJOINT =
OntDisjoints.createFactory(
diff --git
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/factories/OntDisjoints.java
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/factories/OntDisjoints.java
index 795edccb01..1f34d0d83d 100644
---
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/factories/OntDisjoints.java
+++
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/factories/OntDisjoints.java
@@ -32,6 +32,7 @@ import org.apache.jena.ontapi.common.OntConfig;
import org.apache.jena.ontapi.common.OntEnhGraph;
import org.apache.jena.ontapi.common.OntEnhNodeFactories;
import org.apache.jena.ontapi.impl.objects.OntDisjointImpl;
+import org.apache.jena.ontapi.model.OntClass;
import org.apache.jena.ontapi.model.OntIndividual;
import org.apache.jena.ontapi.utils.Iterators;
import org.apache.jena.rdf.model.Property;
@@ -84,6 +85,39 @@ final class OntDisjoints {
.and(getHasMembersOfFilter(view, allowEmptyList, predicates)));
}
+ public static EnhNodeFactory createQLRLOntDisjointFactory() {
+ EnhNodeProducer maker = new EnhNodeProducer.WithType(
+ OntDisjointImpl.QLRLClassesImpl.class,
+ OWL2.AllDisjointClasses,
+ OntDisjointImpl.QLRLClassesImpl::new
+ );
+ EnhNodeFinder finder = new
EnhNodeFinder.ByType(OWL2.AllDisjointClasses);
+ EnhNodeFilter filter = EnhNodeFilter.ANON.and(new
EnhNodeFilter.HasType(OWL2.AllDisjointClasses)).and((n, g) -> {
+ ExtendedIterator<Triple> res = g.asGraph().find(n,
OWL2.members.asNode(), Node.ANY);
+ try {
+ while (res.hasNext()) {
+ Node listNode = res.next().getObject();
+ if (!STDObjectFactories.RDF_LIST.canWrap(listNode, g)) {
+ return false;
+ }
+ RDFList list = (RDFList)
STDObjectFactories.RDF_LIST.wrap(listNode, g);
+ if (Iterators.hasAtLeast(
+ list.iterator()
+ .mapWith(it ->
+
OntEnhGraph.asPersonalityModel(g).findNodeAs(it.asNode(), OntClass.class)
+ )
+ .filterKeep(it -> it != null &&
it.canAsDisjointClass()), 2)) {
+ return true;
+ }
+ }
+ } finally {
+ res.close();
+ }
+ return false;
+ });
+ return OntEnhNodeFactories.createCommon(maker, finder, filter);
+ }
+
private static EnhNodeFilter getHasPredicatesFilter(Property...
predicates) {
if (predicates.length == 0) {
throw new IllegalArgumentException();
diff --git
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntClassImpl.java
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntClassImpl.java
index 5d5680a64b..7bd3b28932 100644
---
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntClassImpl.java
+++
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntClassImpl.java
@@ -198,6 +198,9 @@ public abstract class OntClassImpl extends OntObjectImpl
implements OntClass {
OntClass clazz,
Stream<? extends
OntRelationalProperty> collection) {
OntGraphModelImpl.checkFeature(m,
OntModelControls.USE_OWL2_CLASS_HAS_KEY_FEATURE, "owl:hasKey");
+ OntJenaException.checkSupported(clazz.canAsSubClass(),
+ "Class " + OntEnhNodeFactories.viewAsString(clazz.getClass())
+ " cannot have keys. " +
+ "Profile: " + m.getOntPersonality().getName());
return m.createOntList(clazz, OWL2.hasKey, OntRelationalProperty.class,
collection.distinct().map(OntRelationalProperty.class::cast).iterator());
}
@@ -206,6 +209,9 @@ public abstract class OntClassImpl extends OntObjectImpl
implements OntClass {
if (!OntGraphModelImpl.configValue(m,
OntModelControls.USE_OWL2_CLASS_HAS_KEY_FEATURE)) {
return Stream.empty();
}
+ if (!clazz.canAsSubClass()) {
+ return Stream.empty();
+ }
return OntListImpl.stream(m, clazz, OWL2.hasKey,
OntRelationalProperty.class);
}
@@ -213,7 +219,12 @@ public abstract class OntClassImpl extends OntObjectImpl
implements OntClass {
OntClass clazz,
RDFNode rdfList) throws
OntJenaException.IllegalArgument {
OntGraphModelImpl.checkFeature(m,
OntModelControls.USE_OWL2_CLASS_HAS_KEY_FEATURE, "owl:hasKey");
- m.deleteOntList(clazz, OWL2.hasKey,
clazz.findHasKey(rdfList).orElse(null));
+ if (rdfList == null) {
+ clazz.hasKeys().toList().forEach(it -> m.deleteOntList(clazz,
OWL2.hasKey, it));
+ } else {
+ m.deleteOntList(clazz, OWL2.hasKey, clazz.findHasKey(rdfList)
+ .orElseThrow(() -> new
OntJenaException.IllegalArgument("can't find list " + rdfList)));
+ }
}
public static Stream<OntClass> disjointClasses(OntGraphModelImpl m,
OntClass clazz) {
diff --git
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntDisjointImpl.java
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntDisjointImpl.java
index 9fa01762a1..4e88d8ab26 100644
---
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntDisjointImpl.java
+++
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntDisjointImpl.java
@@ -156,6 +156,35 @@ public abstract class OntDisjointImpl<O extends OntObject>
extends OntObjectImpl
}
}
+ /**
+ * {@code DisjointClasses := 'DisjointClasses' '(' axiomAnnotations
subClassExpression subClassExpression { subClassExpression } ')'}
+ */
+ public static class QLRLClassesImpl extends OntDisjointImpl<OntClass>
implements Classes {
+ public QLRLClassesImpl(Node n, EnhGraph m) {
+ super(n, m);
+ }
+
+ @Override
+ public Class<? extends OntObject> objectType() {
+ return Classes.class;
+ }
+
+ @Override
+ protected Class<OntClass> getComponentType() {
+ return OntClass.class;
+ }
+
+ @Override
+ protected Resource getResourceType() {
+ return OWL2.AllDisjointClasses;
+ }
+
+ @Override
+ public Stream<OntClass> members() {
+ return
getList().members().filter(OntClass::canAsDisjointClass).map(OntClass::asDisjointClass);
+ }
+ }
+
public static class IndividualsImpl extends OntDisjointImpl<OntIndividual>
implements Individuals {
private final boolean useMembers;
private final boolean useDistinctMembers;
diff --git
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntClass.java
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntClass.java
index 940a73790c..0f86f17057 100644
--- a/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntClass.java
+++ b/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntClass.java
@@ -258,9 +258,9 @@ public interface OntClass extends OntObject,
AsNamed<OntClass.Named>, HasDisjoin
/**
* Deletes the given {@code HasKey} list including its annotations.
*
- * @param list {@link Resource} can be {@link OntList} or {@link RDFList}
+ * @param list {@link Resource} can be {@link OntList} or {@link RDFList};
+ * if {@code null} the method will remove all hasKey's
* @return <b>this</b> instance to allow cascading calls
- * @throws OntJenaException if the list is not found
*/
OntClass removeHasKey(Resource list);
diff --git
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntDisjoint.java
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntDisjoint.java
index 584f22a93d..c937764e8a 100644
--- a/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntDisjoint.java
+++ b/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntDisjoint.java
@@ -36,7 +36,8 @@ public interface OntDisjoint<O extends OntObject> extends
OntObject, HasRDFNodeL
/**
* Lists all pair-wise disjoint members holding by this {@link OntDisjoint
Ontology Disjoint} resource.
- * In general, this method is equivalent to the expression {@code
this.getList().members()}.
+ * Note that the returned values are not necessarily the same as {@link
OntList#members()} output:
+ * some profiles (e.g., OWL2 QL) impose some restrictions.
*
* @return Stream (<b>not distinct</b>) of {@link OntObject}s
*/
diff --git
a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelOWL2ELSpecTest.java
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelOWL2ELSpecTest.java
index 99e845d39e..31ae4c96d8 100644
---
a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelOWL2ELSpecTest.java
+++
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelOWL2ELSpecTest.java
@@ -212,9 +212,9 @@ public class OntModelOWL2ELSpecTest {
Resource c0 = m.createResource("C", OWL2.Class);
Resource i1 = m.createResource("i1", c0);
Resource i2 = m.createResource("i2", c0);
- Resource c1 = m.createResource().addProperty(RDF.type,
OWL2.Class).addProperty(OWL2.oneOf, m.createList());
- Resource c2 = m.createResource().addProperty(RDF.type,
OWL2.Class).addProperty(OWL2.oneOf, m.createList(i1));
- Resource c3 = m.createResource().addProperty(RDF.type,
OWL2.Class).addProperty(OWL2.oneOf, m.createList(i1, i2));
+ m.createResource().addProperty(RDF.type,
OWL2.Class).addProperty(OWL2.oneOf, m.createList());
+ m.createResource().addProperty(RDF.type,
OWL2.Class).addProperty(OWL2.oneOf, m.createList(i1));
+ m.createResource().addProperty(RDF.type,
OWL2.Class).addProperty(OWL2.oneOf, m.createList(i1, i2));
OntModel om = OntModelFactory.createModel(m.getGraph(), spec.inst);
OntIndividual oi1 = Objects.requireNonNull(om.getIndividual("i1"));
@@ -237,9 +237,9 @@ public class OntModelOWL2ELSpecTest {
Model m = ModelFactory.createDefaultModel();
Literal v1 = m.createTypedLiteral(42);
Literal v2 = m.createTypedLiteral("42");
- Resource c1 = m.createResource().addProperty(RDF.type,
RDFS.Datatype).addProperty(OWL2.oneOf, m.createList());
- Resource c2 = m.createResource().addProperty(RDF.type,
RDFS.Datatype).addProperty(OWL2.oneOf, m.createList(v1));
- Resource c3 = m.createResource().addProperty(RDF.type,
RDFS.Datatype).addProperty(OWL2.oneOf, m.createList(v1, v2));
+ m.createResource().addProperty(RDF.type,
RDFS.Datatype).addProperty(OWL2.oneOf, m.createList());
+ m.createResource().addProperty(RDF.type,
RDFS.Datatype).addProperty(OWL2.oneOf, m.createList(v1));
+ m.createResource().addProperty(RDF.type,
RDFS.Datatype).addProperty(OWL2.oneOf, m.createList(v1, v2));
OntModel om = OntModelFactory.createModel(m.getGraph(), spec.inst);
OntDataRange.OneOf oc2 =
om.ontObjects(OntDataRange.OneOf.class).findFirst().orElseThrow(AssertionError::new);
@@ -284,4 +284,21 @@ public class OntModelOWL2ELSpecTest {
"wrong result for " + it)
);
}
+
+ @ParameterizedTest
+ @EnumSource(names = {
+ "OWL2_EL_MEM",
+ "OWL2_EL_MEM_RDFS_INF",
+ "OWL2_EL_MEM_TRANS_INF",
+ })
+ public void testHasKey(TestSpec spec) {
+ OntModel m = OntModelFactory.createModel(spec.inst);
+ OntClass a = m.createOntClass("a");
+ OntDataProperty p1 = m.createDataProperty("p1");
+ OntDataProperty p2 = m.createDataProperty("p2");
+ a.addHasKey(p1, p2);
+ Assertions.assertEquals(1L, a.hasKeys().count());
+ a.removeHasKey(null);
+ Assertions.assertEquals(0L, a.hasKeys().count());
+ }
}
diff --git
a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelOWL2QLSpecTest.java
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelOWL2QLSpecTest.java
index 3e0235e5a2..fd6b35ca67 100644
---
a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelOWL2QLSpecTest.java
+++
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelOWL2QLSpecTest.java
@@ -414,4 +414,19 @@ public class OntModelOWL2QLSpecTest {
Assertions.assertThrows(OntJenaException.Unsupported.class,
mc7::asDisjointClass);
Assertions.assertThrows(OntJenaException.Unsupported.class,
mc7::asEquivalentClass);
}
+
+ @ParameterizedTest
+ @EnumSource(names = {
+ "OWL2_QL_MEM",
+ "OWL2_QL_MEM_RDFS_INF",
+ "OWL2_QL_MEM_TRANS_INF",
+ })
+ public void testHasKey(TestSpec spec) {
+ OntModel m = OntModelFactory.createModel(spec.inst);
+ OntClass a = m.createOntClass("a");
+ OntDataProperty p1 = m.createDataProperty("p1");
+ OntDataProperty p2 = m.createDataProperty("p2");
+ Assertions.assertThrows(OntJenaException.Unsupported.class, () ->
a.addHasKey(p1, p2));
+ Assertions.assertThrows(OntJenaException.Unsupported.class, () ->
a.removeHasKey(m.createList()));
+ }
}
diff --git
a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelOWL2RLSpecTest.java
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelOWL2RLSpecTest.java
index 879fb1ac91..1e9ee1de77 100644
---
a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelOWL2RLSpecTest.java
+++
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelOWL2RLSpecTest.java
@@ -21,9 +21,12 @@ package org.apache.jena.ontapi;
import org.apache.jena.ontapi.model.OntClass;
import org.apache.jena.ontapi.model.OntDataProperty;
import org.apache.jena.ontapi.model.OntDataRange;
+import org.apache.jena.ontapi.model.OntDisjoint;
+import org.apache.jena.ontapi.model.OntList;
import org.apache.jena.ontapi.model.OntModel;
import org.apache.jena.ontapi.model.OntObject;
import org.apache.jena.ontapi.model.OntObjectProperty;
+import org.apache.jena.ontapi.model.OntRelationalProperty;
import org.apache.jena.ontapi.testutils.RDFIOTestUtils;
import org.apache.jena.rdf.model.RDFNode;
import org.apache.jena.rdf.model.Statement;
@@ -558,4 +561,76 @@ public class OntModelOWL2RLSpecTest {
Assertions.assertNull(m.getOWLTopObjectProperty());
Assertions.assertNull(m.getOWLTopDataProperty());
}
+
+ @ParameterizedTest
+ @EnumSource(names = {
+ "OWL2_RL_MEM",
+ "OWL2_RL_MEM_RDFS_INF",
+ "OWL2_RL_MEM_TRANS_INF",
+ })
+ public void testOntDisjointClasses(TestSpec spec) {
+ OntModel data = OntModelFactory.createModel();
+ data.createDisjointClasses(
+ data.createOntClass("A"),
data.createObjectComplementOf(data.createOntClass("B"))
+ );
+ data.createDisjointClasses(
+ data.createOntClass("C")
+ );
+ data.createDisjointClasses(
+ data.createDataAllValuesFrom(data.createDataProperty("p1"),
data.getDatatype(XSD.xstring)), // super
+ data.createOntClass("D"),
+
data.createObjectSomeValuesFrom(data.createObjectProperty("p2"),
data.createOntClass("E")),
+ data.createObjectComplementOf(data.createOntClass("F")) //
super
+ );
+
+ OntModel m = OntModelFactory.createModel(data.getGraph(), spec.inst);
+
+ List<OntDisjoint.Classes> disjoints1 =
m.ontObjects(OntDisjoint.Classes.class).toList();
+ Assertions.assertEquals(1, disjoints1.size());
+ List<OntClass> members = disjoints1.get(0).members().toList();
+ Assertions.assertEquals(2, members.size());
+ Assertions.assertTrue(members.stream().anyMatch(it ->
it.canAs(OntClass.Named.class)));
+ Assertions.assertTrue(members.stream().anyMatch(it ->
it.canAs(OntClass.ObjectSomeValuesFrom.class)));
+
+ Assertions.assertThrows(OntJenaException.Unsupported.class, () ->
+ m.createDisjointClasses(
+ m.createDataAllValuesFrom(m.createDataProperty("p1"),
m.getDatatype(XSD.xstring)), // super
+ m.createOntClass("D"),
+ m.createObjectComplementOf(m.createOntClass("F")) //
super
+ )
+ );
+ Assertions.assertThrows(OntJenaException.Unsupported.class, () ->
+ m.createDisjointClasses(m.createOntClass("G"))
+ );
+ m.createDisjointClasses(m.createOntClass("G"), m.createOntClass("H"));
+ List<OntDisjoint.Classes> disjoints2 =
m.ontObjects(OntDisjoint.Classes.class).toList();
+ Assertions.assertEquals(2, disjoints2.size());
+ }
+
+ @ParameterizedTest
+ @EnumSource(names = {
+ "OWL2_RL_MEM",
+ "OWL2_RL_MEM_RDFS_INF",
+ "OWL2_RL_MEM_TRANS_INF",
+ })
+ public void testHasKey(TestSpec spec) {
+ OntModel data = OntModelFactory.createModel();
+ OntClass c11 =
data.createOntClass("A").addHasKey(data.createObjectProperty("p1"));
+ OntClass c12 =
data.createObjectMaxCardinality(data.createObjectProperty("p2"), 1,
data.createOntClass("B"));
+
+ OntModel m = OntModelFactory.createModel(data.getGraph(), spec.inst);
+ OntClass c21 = c11.inModel(m).as(OntClass.class);
+ OntClass c22 = c12.inModel(m).as(OntClass.class);
+ List<OntList<OntRelationalProperty>> hasKey1 = c21.hasKeys().toList();
+ Assertions.assertEquals(1, hasKey1.size());
+ List<OntList<OntRelationalProperty>> hasKey2 = c22.hasKeys().toList();
+ Assertions.assertEquals(0, hasKey2.size());
+
+ Assertions.assertThrows(OntJenaException.Unsupported.class, () ->
+ c22.createHasKey(List.of(m.createObjectProperty("p1")),
List.of())
+ );
+ c21.createHasKey(List.of(m.createObjectProperty("p3")),
List.of(m.createDataProperty("p4")));
+ List<OntList<OntRelationalProperty>> hasKey3 = c21.hasKeys().toList();
+ Assertions.assertEquals(2, hasKey3.size());
+ }
}