Repository: apache/jena (java)

Issue:
ontapi: do not allow OntDisjoints with less than 2 members
### Version

5.1.0

### Feature

Currently it is possible to create\list `OntDisjoint`s with one or no members.
I think it would be more correct not to allow such constructs for EL/QL/RL profiles (not sure about DL). It is already done for QL\RL `OntDisjoint.Classes` .

### Are you interested in contributing a solution yourself?

Yes

Pull request description:
GH-2673: [ontapi] OntDisjoints - require more than one member (for EL QL, RL)

GitHub issue resolved #2673

Pull request Description:

Now OntDisjoints does not allow less than two members for EL, QL, RL profiles, DL profile unchanged

----

 - [x] Tests are included.
 - [ ] Documentation change and updates are provided for the [Apache Jena website](https://github.com/apache/jena-site/)
 - [x] Commits have been squashed to remove intermediate development commit messages.
 - [x] Key commit messages start with the issue number (GH-xxxx)

By submitting this pull request, I acknowledge that I am making a contribution to the Apache Software Foundation under the terms and conditions of the [Contributor's Agreement](https://www.apache.org/licenses/contributor-agreements.html).

----

See the [Apache Jena "Contributing" guide](https://github.com/apache/jena/blob/main/CONTRIBUTING.md).


Patch:
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/protobuf/wire/PB_RDF.java b/jena-arq/src/main/java/org/apache/jena/riot/protobuf/wire/PB_RDF.java
index 820c94ab66..98c53c547c 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/protobuf/wire/PB_RDF.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/protobuf/wire/PB_RDF.java
@@ -17,8 +17,9 @@
  */
 
 // Generated by the protocol buffer compiler.  DO NOT EDIT!
+// NO CHECKED-IN PROTOBUF GENCODE
 // source: binary-rdf.proto
-// Protobuf Java Version: 4.26.0
+// Protobuf Java Version: 4.28.0
 
 package org.apache.jena.riot.protobuf.wire;
 
@@ -29,7 +30,7 @@ public final class PB_RDF {
     com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
       com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
       /* major= */ 4,
-      /* minor= */ 26,
+      /* minor= */ 28,
       /* patch= */ 0,
       /* suffix= */ "",
       PB_RDF.class.getName());
@@ -71,7 +72,7 @@ public final class PB_RDF {
       com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
         com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
         /* major= */ 4,
-        /* minor= */ 26,
+        /* minor= */ 28,
         /* patch= */ 0,
         /* suffix= */ "",
         RDF_IRI.class.getName());
@@ -597,7 +598,7 @@ public final class PB_RDF {
       com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
         com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
         /* major= */ 4,
-        /* minor= */ 26,
+        /* minor= */ 28,
         /* patch= */ 0,
         /* suffix= */ "",
         RDF_PrefixName.class.getName());
@@ -1255,7 +1256,7 @@ public final class PB_RDF {
       com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
         com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
         /* major= */ 4,
-        /* minor= */ 26,
+        /* minor= */ 28,
         /* patch= */ 0,
         /* suffix= */ "",
         RDF_BNode.class.getName());
@@ -1855,7 +1856,7 @@ public final class PB_RDF {
       com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
         com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
         /* major= */ 4,
-        /* minor= */ 26,
+        /* minor= */ 28,
         /* patch= */ 0,
         /* suffix= */ "",
         RDF_Literal.class.getName());
@@ -3086,7 +3087,7 @@ public final class PB_RDF {
       com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
         com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
         /* major= */ 4,
-        /* minor= */ 26,
+        /* minor= */ 28,
         /* patch= */ 0,
         /* suffix= */ "",
         RDF_Decimal.class.getName());
@@ -3593,7 +3594,7 @@ public final class PB_RDF {
       com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
         com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
         /* major= */ 4,
-        /* minor= */ 26,
+        /* minor= */ 28,
         /* patch= */ 0,
         /* suffix= */ "",
         RDF_Var.class.getName());
@@ -4091,7 +4092,7 @@ public final class PB_RDF {
       com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
         com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
         /* major= */ 4,
-        /* minor= */ 26,
+        /* minor= */ 28,
         /* patch= */ 0,
         /* suffix= */ "",
         RDF_ANY.class.getName());
@@ -4446,7 +4447,7 @@ public final class PB_RDF {
       com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
         com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
         /* major= */ 4,
-        /* minor= */ 26,
+        /* minor= */ 28,
         /* patch= */ 0,
         /* suffix= */ "",
         RDF_UNDEF.class.getName());
@@ -4801,7 +4802,7 @@ public final class PB_RDF {
       com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
         com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
         /* major= */ 4,
-        /* minor= */ 26,
+        /* minor= */ 28,
         /* patch= */ 0,
         /* suffix= */ "",
         RDF_REPEAT.class.getName());
@@ -5338,7 +5339,7 @@ public final class PB_RDF {
       com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
         com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
         /* major= */ 4,
-        /* minor= */ 26,
+        /* minor= */ 28,
         /* patch= */ 0,
         /* suffix= */ "",
         RDF_Term.class.getName());
@@ -8109,7 +8110,7 @@ public final class PB_RDF {
       com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
         com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
         /* major= */ 4,
-        /* minor= */ 26,
+        /* minor= */ 28,
         /* patch= */ 0,
         /* suffix= */ "",
         RDF_Triple.class.getName());
@@ -9094,7 +9095,7 @@ public final class PB_RDF {
       com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
         com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
         /* major= */ 4,
-        /* minor= */ 26,
+        /* minor= */ 28,
         /* patch= */ 0,
         /* suffix= */ "",
         RDF_Quad.class.getName());
@@ -10232,7 +10233,7 @@ public final class PB_RDF {
       com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
         com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
         /* major= */ 4,
-        /* minor= */ 26,
+        /* minor= */ 28,
         /* patch= */ 0,
         /* suffix= */ "",
         RDF_PrefixDecl.class.getName());
@@ -10936,7 +10937,7 @@ public final class PB_RDF {
       com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
         com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
         /* major= */ 4,
-        /* minor= */ 26,
+        /* minor= */ 28,
         /* patch= */ 0,
         /* suffix= */ "",
         RDF_StreamRow.class.getName());
@@ -12233,7 +12234,7 @@ public final class PB_RDF {
       com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
         com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
         /* major= */ 4,
-        /* minor= */ 26,
+        /* minor= */ 28,
         /* patch= */ 0,
         /* suffix= */ "",
         RDF_Stream.class.getName());
@@ -12973,7 +12974,7 @@ public final class PB_RDF {
       com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
         com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
         /* major= */ 4,
-        /* minor= */ 26,
+        /* minor= */ 28,
         /* patch= */ 0,
         /* suffix= */ "",
         RDF_VarTuple.class.getName());
@@ -13713,7 +13714,7 @@ public final class PB_RDF {
       com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
         com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
         /* major= */ 4,
-        /* minor= */ 26,
+        /* minor= */ 28,
         /* patch= */ 0,
         /* suffix= */ "",
         RDF_DataTuple.class.getName());
@@ -14453,7 +14454,7 @@ public final class PB_RDF {
       com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
         com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
         /* major= */ 4,
-        /* minor= */ 26,
+        /* minor= */ 28,
         /* patch= */ 0,
         /* suffix= */ "",
         RDF_Graph.class.getName());
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 59ca66d6ad..23abfbfbf8 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
@@ -311,8 +311,8 @@ public class OntPersonalities {
             .add(OntNegativeAssertion.class, OWL2ObjectFactories.ANY_NEGATIVE_PROPERTY_ASSERTION)
 
             // disjoint anonymous collections:
-            .add(OntDisjoint.Classes.class, OWL2ObjectFactories.CLASSES_DISJOINT)
-            .add(OntDisjoint.Individuals.class, OWL2ObjectFactories.DIFFERENT_INDIVIDUALS_DISJOINT)
+            .add(OntDisjoint.Classes.class, OWL2ObjectFactories.EL_CLASSES_DISJOINT)
+            .add(OntDisjoint.Individuals.class, OWL2ObjectFactories.EL_QL_RL_DIFFERENT_INDIVIDUALS_DISJOINT)
             .add(OntDisjoint.class, OWL2ObjectFactories.EL_ANY_DISJOINT);
 
     /**
@@ -370,10 +370,10 @@ public class OntPersonalities {
             .add(OntDataRange.class, OWL2ObjectFactories.QL_ANY_DATARANGE)
 
             // disjoint anonymous collections:
-            .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)
+            .add(OntDisjoint.Classes.class, OWL2ObjectFactories.QL_RL_CLASSES_DISJOINT)
+            .add(OntDisjoint.Individuals.class, OWL2ObjectFactories.EL_QL_RL_DIFFERENT_INDIVIDUALS_DISJOINT)
+            .add(OntDisjoint.ObjectProperties.class, OWL2ObjectFactories.QL_RL_OBJECT_PROPERTIES_DISJOINT)
+            .add(OntDisjoint.DataProperties.class, OWL2ObjectFactories.QL_RL_DATA_PROPERTIES_DISJOINT)
             .add(OntDisjoint.Properties.class, OWL2ObjectFactories.ANY_PROPERTIES_DISJOINT)
             .add(OntDisjoint.class, OWL2ObjectFactories.ANY_DISJOINT);
 
@@ -445,10 +445,10 @@ public class OntPersonalities {
             .add(OntNegativeAssertion.class, OWL2ObjectFactories.ANY_NEGATIVE_PROPERTY_ASSERTION)
 
             // disjoint anonymous collections:
-            .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)
+            .add(OntDisjoint.Classes.class, OWL2ObjectFactories.QL_RL_CLASSES_DISJOINT)
+            .add(OntDisjoint.Individuals.class, OWL2ObjectFactories.EL_QL_RL_DIFFERENT_INDIVIDUALS_DISJOINT)
+            .add(OntDisjoint.ObjectProperties.class, OWL2ObjectFactories.QL_RL_OBJECT_PROPERTIES_DISJOINT)
+            .add(OntDisjoint.DataProperties.class, OWL2ObjectFactories.QL_RL_DATA_PROPERTIES_DISJOINT)
             .add(OntDisjoint.Properties.class, OWL2ObjectFactories.ANY_PROPERTIES_DISJOINT)
             .add(OntDisjoint.class, OWL2ObjectFactories.ANY_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 59da29167c..588fa3e26b 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
@@ -967,25 +967,33 @@ public class OntGraphModelImpl extends ModelCom implements OntModel, OntEnhGraph
     public OntDisjoint.Classes createDisjointClasses(Collection<OntClass> classes) {
         checkType(OntDisjoint.Classes.class);
         checkType(OntClass.IntersectionOf.class);
-        return checkCreate(model -> OntDisjointImpl.createDisjointClasses(this, classes.stream()), OntDisjoint.Classes.class);
+        return checkCreate(model ->
+                OntDisjointImpl.createDisjointClasses(model, classes.stream()), OntDisjoint.Classes.class
+        );
     }
 
     @Override
     public OntDisjoint.Individuals createDifferentIndividuals(Collection<OntIndividual> individuals) {
         checkType(OntDisjoint.Individuals.class);
-        return OntDisjointImpl.createDifferentIndividuals(this, individuals.stream());
+        return checkCreate(model ->
+                OntDisjointImpl.createDifferentIndividuals(model, individuals.stream()), OntDisjoint.Individuals.class
+        );
     }
 
     @Override
     public OntDisjoint.ObjectProperties createDisjointObjectProperties(Collection<OntObjectProperty> properties) {
         checkType(OntDisjoint.ObjectProperties.class);
-        return OntDisjointImpl.createDisjointObjectProperties(this, properties.stream());
+        return checkCreate(model ->
+                OntDisjointImpl.createDisjointObjectProperties(model, properties.stream()), OntDisjoint.ObjectProperties.class
+        );
     }
 
     @Override
     public OntDisjoint.DataProperties createDisjointDataProperties(Collection<OntDataProperty> properties) {
         checkType(OntDisjoint.DataProperties.class);
-        return OntDisjointImpl.createDisjointDataProperties(this, properties.stream());
+        return checkCreate(model ->
+                OntDisjointImpl.createDisjointDataProperties(model, properties.stream()), OntDisjoint.DataProperties.class
+        );
     }
 
     @Override
diff --git a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/factories/OWL1ObjectFactories.java b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/factories/OWL1ObjectFactories.java
index 39d874cf9c..eed8fdf522 100644
--- a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/factories/OWL1ObjectFactories.java
+++ b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/factories/OWL1ObjectFactories.java
@@ -369,7 +369,7 @@ public class OWL1ObjectFactories {
     );
 
     public static final Function<OntConfig, EnhNodeFactory> DIFFERENT_INDIVIDUALS_DISJOINT =
-            OntDisjoints::createDifferentIndividualsFactory;
+            OntDisjoints::createDLFullDifferentIndividualsFactory;
     public static final Function<OntConfig, EnhNodeFactory> ANY_DISJOINT = DIFFERENT_INDIVIDUALS_DISJOINT;
 
     private static boolean isNamedIndividual(Node n, EnhGraph eg) {
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 150b9f09bb..d79b8ea209 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
@@ -27,7 +27,6 @@ import org.apache.jena.ontapi.common.OntPersonality;
 import org.apache.jena.ontapi.impl.objects.OntAnnotationImpl;
 import org.apache.jena.ontapi.impl.objects.OntClassImpl;
 import org.apache.jena.ontapi.impl.objects.OntDataRangeImpl;
-import org.apache.jena.ontapi.impl.objects.OntDisjointImpl;
 import org.apache.jena.ontapi.impl.objects.OntFacetRestrictionImpl;
 import org.apache.jena.ontapi.impl.objects.OntIDImpl;
 import org.apache.jena.ontapi.impl.objects.OntIndividualImpl;
@@ -35,13 +34,11 @@ import org.apache.jena.ontapi.impl.objects.OntNegativePropertyAssertionImpl;
 import org.apache.jena.ontapi.impl.objects.OntObjectImpl;
 import org.apache.jena.ontapi.impl.objects.OntSimpleClassImpl;
 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.OntFacetRestriction;
 import org.apache.jena.ontapi.model.OntIndividual;
 import org.apache.jena.ontapi.model.OntNegativeAssertion;
-import org.apache.jena.ontapi.model.OntObjectProperty;
 import org.apache.jena.rdf.model.RDFList;
 import org.apache.jena.vocabulary.OWL2;
 import org.apache.jena.vocabulary.RDF;
@@ -788,34 +785,18 @@ public final class OWL2ObjectFactories {
             OntFacetRestriction.LangRange.class
     );
 
-    public static final EnhNodeFactory CLASSES_DISJOINT = OntDisjoints.createFactory(
-            OntDisjointImpl.ClassesImpl.class,
-            OntDisjointImpl.ClassesImpl::new,
-            OWL2.AllDisjointClasses,
-            OntClass.class,
-            true,
-            OWL2.members
-    );
-    public static final EnhNodeFactory QL_CLASSES_DISJOINT = OntDisjoints.createQLRLOntDisjointFactory();
-    public static final EnhNodeFactory RL_CLASSES_DISJOINT = OntDisjoints.createQLRLOntDisjointFactory();
+    public static final EnhNodeFactory CLASSES_DISJOINT = OntDisjoints.createDisjointClassesFactory(0);
+    public static final EnhNodeFactory EL_CLASSES_DISJOINT = OntDisjoints.createDisjointClassesFactory(2);
+    public static final EnhNodeFactory QL_RL_CLASSES_DISJOINT = OntDisjoints.createQLRLDisjointClassesFactory();
     public static final Function<OntConfig, EnhNodeFactory> DIFFERENT_INDIVIDUALS_DISJOINT =
-            OntDisjoints::createDifferentIndividualsFactory;
-    public static final EnhNodeFactory OBJECT_PROPERTIES_DISJOINT = OntDisjoints.createFactory(
-            OntDisjointImpl.ObjectPropertiesImpl.class,
-            OntDisjointImpl.ObjectPropertiesImpl::new,
-            OWL2.AllDisjointProperties,
-            OntObjectProperty.class,
-            false,
-            OWL2.members
-    );
-    public static final EnhNodeFactory DATA_PROPERTIES_DISJOINT = OntDisjoints.createFactory(
-            OntDisjointImpl.DataPropertiesImpl.class,
-            OntDisjointImpl.DataPropertiesImpl::new,
-            OWL2.AllDisjointProperties,
-            OntDataProperty.class,
-            false,
-            OWL2.members
-    );
+            OntDisjoints::createDLFullDifferentIndividualsFactory;
+    public static final EnhNodeFactory EL_QL_RL_DIFFERENT_INDIVIDUALS_DISJOINT =
+            OntDisjoints.createELQLRLDifferentIndividualsFactory();
+    public static final EnhNodeFactory OBJECT_PROPERTIES_DISJOINT = OntDisjoints.createDisjointObjectPropertiesFactory(0);
+    public static final EnhNodeFactory QL_RL_OBJECT_PROPERTIES_DISJOINT = OntDisjoints.createDisjointObjectPropertiesFactory(2);
+    public static final EnhNodeFactory DATA_PROPERTIES_DISJOINT = OntDisjoints.createDisjointDataPropertiesFactory(0);
+    public static final EnhNodeFactory QL_RL_DATA_PROPERTIES_DISJOINT = OntDisjoints.createDisjointDataPropertiesFactory(2);
+
     public static final EnhNodeFactory ANY_PROPERTIES_DISJOINT = OntEnhNodeFactories.createFrom(
             OntDisjoints.PROPERTIES_FINDER,
             OntDisjoint.ObjectProperties.class,
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 1f34d0d83d..8b6561a3be 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
@@ -20,7 +20,6 @@ package org.apache.jena.ontapi.impl.factories;
 
 import org.apache.jena.enhanced.EnhGraph;
 import org.apache.jena.enhanced.EnhNode;
-import org.apache.jena.graph.Graph;
 import org.apache.jena.graph.Node;
 import org.apache.jena.graph.Triple;
 import org.apache.jena.ontapi.OntModelControls;
@@ -33,7 +32,9 @@ 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.OntDataProperty;
 import org.apache.jena.ontapi.model.OntIndividual;
+import org.apache.jena.ontapi.model.OntObjectProperty;
 import org.apache.jena.ontapi.utils.Iterators;
 import org.apache.jena.rdf.model.Property;
 import org.apache.jena.rdf.model.RDFList;
@@ -43,13 +44,14 @@ import org.apache.jena.util.iterator.ExtendedIterator;
 import org.apache.jena.vocabulary.OWL2;
 
 import java.util.function.BiFunction;
+import java.util.function.Predicate;
 
 final class OntDisjoints {
     public static final EnhNodeFinder PROPERTIES_FINDER = new EnhNodeFinder.ByType(OWL2.AllDisjointProperties);
     public static final EnhNodeFinder DISJOINT_FINDER = OntEnhNodeFactories.createFinder(OWL2.AllDisjointClasses,
             OWL2.AllDifferent, OWL2.AllDisjointProperties);
 
-    public static EnhNodeFactory createDifferentIndividualsFactory(OntConfig config) {
+    public static EnhNodeFactory createDLFullDifferentIndividualsFactory(OntConfig config) {
         boolean useDistinctMembers = config.getBoolean(OntModelControls.USE_OWL1_DISTINCT_MEMBERS_PREDICATE_FEATURE);
         boolean compatible = config.getBoolean(OntModelControls.USE_OWL2_DEPRECATED_VOCABULARY_FEATURE);
         Property[] predicates;
@@ -65,48 +67,106 @@ final class OntDisjoints {
                 (n, g) -> new OntDisjointImpl.IndividualsImpl(n, g, !compatible, useDistinctMembers),
                 OWL2.AllDifferent,
                 OntIndividual.class,
-                true,
+                it -> true,
+                0,
                 predicates
         );
     }
 
-    public static EnhNodeFactory createFactory(
-            Class<? extends OntDisjointImpl<?>> impl,
-            BiFunction<Node, EnhGraph, EnhNode> producer,
-            Resource type,
-            Class<? extends RDFNode> view,
-            boolean allowEmptyList,
-            Property... predicates) {
-        EnhNodeProducer maker = new EnhNodeProducer.WithType(impl, type, producer);
-        EnhNodeFinder finder = new EnhNodeFinder.ByType(type);
-        EnhNodeFilter filter = EnhNodeFilter.ANON.and(new EnhNodeFilter.HasType(type));
-        return OntEnhNodeFactories.createCommon(maker, finder, filter
-                .and(getHasPredicatesFilter(predicates))
-                .and(getHasMembersOfFilter(view, allowEmptyList, predicates)));
+    public static EnhNodeFactory createELQLRLDifferentIndividualsFactory() {
+        return createFactory(
+                OntDisjointImpl.IndividualsImpl.class,
+                (n, g) -> new OntDisjointImpl.IndividualsImpl(n, g, true, false),
+                OWL2.AllDifferent,
+                OntIndividual.class,
+                it -> true,
+                2,
+                OWL2.members
+        );
+    }
+
+    public static EnhNodeFactory createDisjointObjectPropertiesFactory(int atLeastN) {
+        return createFactory(
+                OntDisjointImpl.ObjectPropertiesImpl.class,
+                OntDisjointImpl.ObjectPropertiesImpl::new,
+                OWL2.AllDisjointProperties,
+                OntObjectProperty.class,
+                it -> true,
+                atLeastN,
+                OWL2.members
+        );
+    }
+
+    public static EnhNodeFactory createDisjointDataPropertiesFactory(int atLeastN) {
+        return createFactory(
+                OntDisjointImpl.DataPropertiesImpl.class,
+                OntDisjointImpl.DataPropertiesImpl::new,
+                OWL2.AllDisjointProperties,
+                OntDataProperty.class,
+                it -> true,
+                atLeastN,
+                OWL2.members
+        );
+    }
+
+    public static EnhNodeFactory createDisjointClassesFactory(int atLeastN) {
+        return createFactory(
+                OntDisjointImpl.QLRLClassesImpl.class,
+                OntDisjointImpl.QLRLClassesImpl::new,
+                OWL2.AllDisjointClasses,
+                OntClass.class,
+                it -> true,
+                atLeastN,
+                OWL2.members
+        );
     }
 
-    public static EnhNodeFactory createQLRLOntDisjointFactory() {
-        EnhNodeProducer maker = new EnhNodeProducer.WithType(
+    public static EnhNodeFactory createQLRLDisjointClassesFactory() {
+        return createFactory(
                 OntDisjointImpl.QLRLClassesImpl.class,
+                OntDisjointImpl.QLRLClassesImpl::new,
                 OWL2.AllDisjointClasses,
-                OntDisjointImpl.QLRLClassesImpl::new
+                OntClass.class,
+                OntClass::canAsDisjointClass,
+                2,
+                OWL2.members
         );
-        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);
+    }
+
+    private static <X extends RDFNode> EnhNodeFactory createFactory(
+            Class<? extends OntDisjointImpl<?>> impl,
+            BiFunction<Node, EnhGraph, EnhNode> producer,
+            Resource rdfType,
+            Class<X> memberType,
+            Predicate<X> testMember,
+            int atLeastN,
+            Property... membersPredicates
+    ) {
+        EnhNodeProducer maker = new EnhNodeProducer.WithType(impl, rdfType, producer);
+        EnhNodeFinder finder = new EnhNodeFinder.ByType(rdfType);
+        EnhNodeFilter filter = EnhNodeFilter.ANON.and(new EnhNodeFilter.HasType(rdfType)).and((n, g) -> {
+            ExtendedIterator<Triple> res;
+            if (membersPredicates.length == 1) {
+                res = g.asGraph().find(n, membersPredicates[0].asNode(), Node.ANY);
+            } else {
+                res = Iterators.flatMap(Iterators.of(membersPredicates), it -> g.asGraph().find(n, it.asNode(), Node.ANY));
+            }
             try {
                 while (res.hasNext()) {
                     Node listNode = res.next().getObject();
                     if (!STDObjectFactories.RDF_LIST.canWrap(listNode, g)) {
                         return false;
                     }
+                    if (atLeastN == 0) {
+                        return true;
+                    }
                     RDFList list = (RDFList) STDObjectFactories.RDF_LIST.wrap(listNode, g);
                     if (Iterators.hasAtLeast(
                             list.iterator()
                                     .mapWith(it ->
-                                            OntEnhGraph.asPersonalityModel(g).findNodeAs(it.asNode(), OntClass.class)
+                                            OntEnhGraph.asPersonalityModel(g).findNodeAs(it.asNode(), memberType)
                                     )
-                                    .filterKeep(it -> it != null && it.canAsDisjointClass()), 2)) {
+                                    .filterKeep(it -> it != null && testMember.test(it)), atLeastN)) {
                         return true;
                     }
                 }
@@ -117,46 +177,4 @@ final class OntDisjoints {
         });
         return OntEnhNodeFactories.createCommon(maker, finder, filter);
     }
-
-    private static EnhNodeFilter getHasPredicatesFilter(Property... predicates) {
-        if (predicates.length == 0) {
-            throw new IllegalArgumentException();
-        }
-        EnhNodeFilter res = new EnhNodeFilter.HasPredicate(predicates[0]);
-        for (int i = 1; i < predicates.length; i++) {
-            res = res.or(new EnhNodeFilter.HasPredicate(predicates[i]));
-        }
-        return res;
-    }
-
-    private static EnhNodeFilter getHasMembersOfFilter(Class<? extends RDFNode> view,
-                                                       boolean allowEmptyList,
-                                                       Property... predicates) {
-        return (node, eg) -> {
-            ExtendedIterator<Node> res = listRoots(node, eg.asGraph(), predicates);
-            try {
-                while (res.hasNext()) {
-                    if (testList(res.next(), eg, view, allowEmptyList)) return true;
-                }
-            } finally {
-                res.close();
-            }
-            return false;
-        };
-    }
-
-    private static ExtendedIterator<Node> listRoots(Node node, Graph graph, Property... predicates) {
-        return Iterators.flatMap(Iterators.of(predicates),
-                p -> graph.find(node, p.asNode(), Node.ANY).mapWith(Triple::getObject));
-    }
-
-    private static boolean testList(Node node, EnhGraph graph, Class<? extends RDFNode> view, boolean allowEmptyList) {
-        if (!STDObjectFactories.RDF_LIST.canWrap(node, graph)) {
-            return false;
-        }
-        if (view == null) return true;
-        RDFList list = (RDFList) STDObjectFactories.RDF_LIST.wrap(node, graph);
-        return (list.isEmpty() && allowEmptyList) ||
-                Iterators.anyMatch(list.iterator().mapWith(RDFNode::asNode), n -> OntEnhGraph.canAs(view, n, graph));
-    }
 }
diff --git a/pom.xml b/pom.xml
index 18dc837fb8..07bcc31543 100644
--- a/pom.xml
+++ b/pom.xml
@@ -60,14 +60,14 @@
 
     <!-- Logging -->
     <ver.slf4j>2.0.16</ver.slf4j>
-    <ver.log4j2>2.23.1</ver.log4j2>
+    <ver.log4j2>2.24.0</ver.log4j2>
 
     <!-- JSON-LD 1.1 -->
     <ver.titanium-json-ld>1.4.1</ver.titanium-json-ld>
     <ver.jakarta.json>2.0.1</ver.jakarta.json>
 
     <!-- These two must be in-step -->
-    <ver.jetty>12.0.12</ver.jetty>
+    <ver.jetty>12.0.13</ver.jetty>
     <ver.jakarta-servlet>6.1.0</ver.jakarta-servlet>
 
     <ver.shiro>2.0.1</ver.shiro>


Test patch:
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 08b56e2b49..d7edeaa0a4 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
@@ -22,6 +22,7 @@ import org.apache.jena.ontapi.model.OntAnnotationProperty;
 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.OntEntity;
 import org.apache.jena.ontapi.model.OntIndividual;
 import org.apache.jena.ontapi.model.OntModel;
@@ -48,6 +49,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -304,4 +306,68 @@ public class OntModelOWL2ELSpecTest {
         a.removeHasKey(null);
         Assertions.assertEquals(0L, a.hasKeys().count());
     }
+
+    @ParameterizedTest
+    @EnumSource(names = {
+            "OWL2_EL_MEM",
+            "OWL2_EL_MEM_RDFS_INF",
+            "OWL2_EL_MEM_TRANS_INF",
+    })
+    public void testDifferentIndividuals(TestSpec spec) {
+        OntModel data = OntModelFactory.createModel();
+        data.createDifferentIndividuals(data.createIndividual("a"));
+        data.createDifferentIndividuals();
+        data.createDifferentIndividuals(data.createIndividual("b"), data.createIndividual("c"));
+
+        OntModel m = OntModelFactory.createModel(data.getGraph(), spec.inst);
+
+        List<OntDisjoint.Individuals> res1 = m.ontObjects(OntDisjoint.Individuals.class).toList();
+        Assertions.assertEquals(1, res1.size());
+        Assertions.assertEquals(
+                Set.of("b", "c"),
+                res1.get(0).members().map(Resource::getURI).collect(Collectors.toSet())
+        );
+
+        Assertions.assertThrows(
+                OntJenaException.Unsupported.class,
+                () -> m.createDifferentIndividuals(m.createIndividual("d"))
+        );
+
+        m.createDifferentIndividuals(m.createIndividual("e"), m.createIndividual("f"), m.createIndividual("g"));
+
+        List<OntDisjoint.Individuals> res2 = m.ontObjects(OntDisjoint.Individuals.class).toList();
+        Assertions.assertEquals(2, res2.size());
+    }
+
+    @ParameterizedTest
+    @EnumSource(names = {
+            "OWL2_EL_MEM",
+            "OWL2_EL_MEM_RDFS_INF",
+            "OWL2_EL_MEM_TRANS_INF",
+    })
+    public void testDisjointClasses(TestSpec spec) {
+        OntModel data = OntModelFactory.createModel();
+        data.createDisjointClasses(data.createOntClass("a"));
+        data.createDisjointClasses();
+        data.createDisjointClasses(data.createOntClass("b"), data.createOntClass("c"));
+
+        OntModel m = OntModelFactory.createModel(data.getGraph(), spec.inst);
+
+        List<OntDisjoint.Classes> res1 = m.ontObjects(OntDisjoint.Classes.class).toList();
+        Assertions.assertEquals(1, res1.size());
+        Assertions.assertEquals(
+                Set.of("b", "c"),
+                res1.get(0).members().map(Resource::getURI).collect(Collectors.toSet())
+        );
+
+        Assertions.assertThrows(
+                OntJenaException.Unsupported.class,
+                () -> m.createDisjointClasses(m.createOntClass("d"))
+        );
+
+        m.createDisjointClasses(m.createOntClass("e"), m.createOntClass("f"), m.createOntClass("g"));
+
+        List<OntDisjoint.Classes> res2 = m.ontObjects(OntDisjoint.Classes.class).toList();
+        Assertions.assertEquals(2, res2.size());
+    }
 }
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 fd6b35ca67..5001096a61 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
@@ -20,12 +20,14 @@ 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.OntDisjoint;
 import org.apache.jena.ontapi.model.OntIndividual;
 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.testutils.RDFIOTestUtils;
 import org.apache.jena.rdf.model.RDFNode;
+import org.apache.jena.rdf.model.Resource;
 import org.apache.jena.rdf.model.Statement;
 import org.apache.jena.riot.Lang;
 import org.apache.jena.vocabulary.OWL2;
@@ -303,7 +305,7 @@ public class OntModelOWL2QLSpecTest {
             "OWL2_QL_MEM_TRANS_INF",
             "OWL2_QL_MEM_RULES_INF",
     })
-    public void testDisjoints(TestSpec spec) {
+    public void testDisjointClasses(TestSpec spec) {
         OntModel m = OntModelFactory.createModel(spec.inst);
         OntObjectProperty op = m.createObjectProperty("p");
         OntDataProperty dp = m.createDataProperty("d");
@@ -429,4 +431,36 @@ public class OntModelOWL2QLSpecTest {
         Assertions.assertThrows(OntJenaException.Unsupported.class, () -> a.addHasKey(p1, p2));
         Assertions.assertThrows(OntJenaException.Unsupported.class, () -> a.removeHasKey(m.createList()));
     }
+
+    @ParameterizedTest
+    @EnumSource(names = {
+            "OWL2_QL_MEM",
+            "OWL2_QL_MEM_RDFS_INF",
+            "OWL2_QL_MEM_TRANS_INF",
+    })
+    public void testDisjointDataProperties(TestSpec spec) {
+        OntModel data = OntModelFactory.createModel();
+        data.createDisjointDataProperties(data.createDataProperty("a"));
+        data.createDisjointDataProperties();
+        data.createDisjointDataProperties(data.createDataProperty("b"), data.createDataProperty("c"));
+
+        OntModel m = OntModelFactory.createModel(data.getGraph(), spec.inst);
+
+        List<OntDisjoint.DataProperties> res1 = m.ontObjects(OntDisjoint.DataProperties.class).toList();
+        Assertions.assertEquals(1, res1.size());
+        Assertions.assertEquals(
+                Set.of("b", "c"),
+                res1.get(0).members().map(Resource::getURI).collect(Collectors.toSet())
+        );
+
+        Assertions.assertThrows(
+                OntJenaException.Unsupported.class,
+                () -> m.createDisjointDataProperties(m.createDataProperty("d"))
+        );
+
+        m.createDisjointDataProperties(m.createDataProperty("e"), m.createDataProperty("f"), m.createDataProperty("g"));
+
+        List<OntDisjoint.DataProperties> res2 = m.ontObjects(OntDisjoint.DataProperties.class).toList();
+        Assertions.assertEquals(2, res2.size());
+    }
 }
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 1e9ee1de77..04ff59dcdb 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
@@ -29,6 +29,7 @@ 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.Resource;
 import org.apache.jena.rdf.model.Statement;
 import org.apache.jena.riot.Lang;
 import org.apache.jena.vocabulary.OWL2;
@@ -633,4 +634,38 @@ public class OntModelOWL2RLSpecTest {
         List<OntList<OntRelationalProperty>> hasKey3 = c21.hasKeys().toList();
         Assertions.assertEquals(2, hasKey3.size());
     }
+
+    @ParameterizedTest
+    @EnumSource(names = {
+            "OWL2_RL_MEM",
+            "OWL2_RL_MEM_RDFS_INF",
+            "OWL2_RL_MEM_TRANS_INF",
+    })
+    public void testDisjointObjectProperties(TestSpec spec) {
+        OntModel data = OntModelFactory.createModel();
+        data.createDisjointObjectProperties(data.createObjectProperty("a"));
+        data.createDisjointObjectProperties();
+        data.createDisjointObjectProperties(data.createObjectProperty("b"), data.createObjectProperty("c"));
+
+        OntModel m = OntModelFactory.createModel(data.getGraph(), spec.inst);
+
+        List<OntDisjoint.ObjectProperties> res1 = m.ontObjects(OntDisjoint.ObjectProperties.class).toList();
+        Assertions.assertEquals(1, res1.size());
+        Assertions.assertEquals(
+                Set.of("b", "c"),
+                res1.get(0).members().map(Resource::getURI).collect(Collectors.toSet())
+        );
+
+        Assertions.assertThrows(
+                OntJenaException.Unsupported.class,
+                () -> m.createDisjointObjectProperties(m.createObjectProperty("d"))
+        );
+
+        m.createDisjointObjectProperties(
+                m.createObjectProperty("e"), m.createObjectProperty("f"), m.createObjectProperty("g")
+        );
+
+        List<OntDisjoint.ObjectProperties> res2 = m.ontObjects(OntDisjoint.ObjectProperties.class).toList();
+        Assertions.assertEquals(2, res2.size());
+    }
 }