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());
+    }
 }

Reply via email to