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 2646c857e8 GH-2487: add OntClass#canAs*Class methods + fix some 
mistakes
2646c857e8 is described below

commit 2646c857e85120cd705669df0badfcead90a47c0
Author: sszuev <[email protected]>
AuthorDate: Sun Jun 16 13:12:22 2024 +0300

    GH-2487: add OntClass#canAs*Class methods + fix some mistakes
    
    - add `OntClass#canAsSubClass`, `OntClass#canAsSuperClass`, 
`OntClass#canAsAssertionClass`, `OntClass#canAsDisjointClass`, 
`OntClass#canAsEquivalentClass`
    - make `OntClass#as*Class` throw exception if corresponding 
`OntClass#canAs*Class` returns false
    - fix few mistakes
---
 .../org/apache/jena/ontapi/OntJenaException.java   |   5 +-
 .../apache/jena/ontapi/impl/OntGraphModelImpl.java |   2 +-
 .../ontapi/impl/factories/OWL2ObjectFactories.java |   4 +-
 .../jena/ontapi/impl/factories/OntClasses.java     |  50 +--
 .../jena/ontapi/impl/objects/OntClassImpl.java     | 487 +++++++++++++++++----
 .../ontapi/impl/objects/OntIndividualImpl.java     |  15 +-
 .../ontapi/impl/objects/OntSimpleClassImpl.java    |  40 +-
 .../org/apache/jena/ontapi/model/OntClass.java     | 106 ++++-
 .../apache/jena/ontapi/model/OntIndividual.java    |   3 +
 .../jena/ontapi/model/OntObjectProperty.java       |   2 +-
 .../jena/ontapi/model/OntRelationalProperty.java   |   2 +-
 .../apache/jena/ontapi/OntModelOWL2QLSpecTest.java |  76 +++-
 .../apache/jena/ontapi/OntModelOWL2RLSpecTest.java | 172 ++++++++
 .../java/org/apache/jena/ontapi/StreamsTest.java   |   8 +-
 14 files changed, 820 insertions(+), 152 deletions(-)

diff --git 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/OntJenaException.java 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/OntJenaException.java
index 98d6f39ee5..8ef14ff080 100644
--- a/jena-ontapi/src/main/java/org/apache/jena/ontapi/OntJenaException.java
+++ b/jena-ontapi/src/main/java/org/apache/jena/ontapi/OntJenaException.java
@@ -18,7 +18,6 @@
 
 package org.apache.jena.ontapi;
 
-import org.apache.jena.ontapi.common.EnhNodeFactory;
 import org.apache.jena.shared.JenaException;
 
 /**
@@ -134,10 +133,8 @@ public class OntJenaException extends JenaException {
 
     /**
      * Exception that is thrown when an ontology resource is converted to 
another facet,
-     * using {@link org.apache.jena.rdf.model.RDFNode#as as()},
+     * usually using {@link org.apache.jena.rdf.model.RDFNode#as as()},
      * and the requested conversion is not possible.
-     * This is an analogue of {@link 
org.apache.jena.ontology.ConversionException},
-     * and it is used mostly by {@link EnhNodeFactory}.
      */
     public static class Conversion extends OntJenaException {
         public Conversion(String message, Throwable cause) {
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 7cfa1d4d23..75b64b3f01 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
@@ -264,7 +264,7 @@ public class OntGraphModelImpl extends ModelCom implements 
OntModel, OntEnhGraph
             return testIsOWLClass(model, candidate);
         }
         OntClass clazz = model.safeFindNodeAs(candidate, OntClass.class);
-        return clazz != null && clazz.asAssertionClass() != null;
+        return clazz != null && clazz.canAsAssertionClass();
     }
 
     private static <M extends OntModel & OntEnhGraph> boolean testIsOWLClass(M 
model, Node candidate) {
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 f8697bb5cc..ed9d34dccc 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
@@ -176,8 +176,8 @@ public final class OWL2ObjectFactories {
                     OntClass.class,
                     OntClassImpl.ComplementOfImpl::new,
                     config);
-    public static final Function<OntConfig, EnhNodeFactory> 
QL_COMPLEMENT_OF_CLASS = OntClasses::createOWL2RLQLComplementOfFactory;
-    public static final Function<OntConfig, EnhNodeFactory> 
RL_COMPLEMENT_OF_CLASS = OntClasses::createOWL2RLQLComplementOfFactory;
+    public static final Function<OntConfig, EnhNodeFactory> 
QL_COMPLEMENT_OF_CLASS = OntClasses::createOWL2QLComplementOfFactory;
+    public static final Function<OntConfig, EnhNodeFactory> 
RL_COMPLEMENT_OF_CLASS = OntClasses::createOWL2RLComplementOfFactory;
 
     public static final Function<OntConfig, EnhNodeFactory> 
OBJECT_SOME_VALUES_FROM_CLASS =
             config -> OntClasses.createComponentRestrictionFactory(
diff --git 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/factories/OntClasses.java
 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/factories/OntClasses.java
index 94ff04f3ce..5d0e85810b 100644
--- 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/factories/OntClasses.java
+++ 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/factories/OntClasses.java
@@ -265,7 +265,7 @@ final class OntClasses {
                             if (clazz == null) {
                                 continue;
                             }
-                            if (OWL2.Thing.equals(clazz) || clazz.asSubClass() 
!= null) {
+                            if (OWL2.Thing.equals(clazz) || 
clazz.canAsSubClass()) {
                                 return true;
                             }
                         }
@@ -289,7 +289,7 @@ final class OntClasses {
                         while (res.hasNext()) {
                             Node node = res.next().getObject();
                             OntClass clazz = 
OntEnhGraph.asPersonalityModel(g).safeFindNodeAs(node, OntClass.class);
-                            if (clazz != null && clazz.asSuperClass() != null) 
{
+                            if (clazz != null && clazz.canAsSuperClass()) {
                                 return true;
                             }
                         }
@@ -320,7 +320,7 @@ final class OntClasses {
                                             .mapWith(it ->
                                                     
OntEnhGraph.asPersonalityModel(g).safeFindNodeAs(it.asNode(), OntClass.class)
                                             )
-                                            .filterKeep(it -> it != null && 
it.asSuperClass() != null), 2)) {
+                                            .filterKeep(it -> it != null && 
it.canAsSuperClass()), 2)) {
                                 return true;
                             }
                         }
@@ -357,13 +357,13 @@ final class OntClasses {
                                     if (clazz == null) {
                                         continue;
                                     }
-                                    if (clazz.asSubClass() != null) {
+                                    if (clazz.canAsSubClass()) {
                                         numSub++;
                                     }
-                                    if (clazz.asSuperClass() != null) {
+                                    if (clazz.canAsSuperClass()) {
                                         numSup++;
                                     }
-                                    if (clazz.asEquivalentClass() != null) {
+                                    if (clazz.canAsEquivalentClass()) {
                                         numEqv++;
                                     }
                                     if (numSub > 1 || numSup > 1 || numEqv > 
1) {
@@ -382,9 +382,18 @@ final class OntClasses {
         return OntEnhNodeFactories.createCommon(maker, CLASS_FINDER, filter);
     }
 
-    public static EnhNodeFactory createOWL2RLQLComplementOfFactory(OntConfig 
config) {
-        EnhNodeProducer maker = new 
EnhNodeProducer.WithType(OntClassImpl.RLQLComplementOfImpl.class, OWL2.Class,
-                OntClassImpl.RLQLComplementOfImpl::new);
+    public static EnhNodeFactory createOWL2RLComplementOfFactory(OntConfig 
config) {
+        return createOWL2RLQLComplementOfFactory(config, 
OntClassImpl.RLComplementOfImpl.class, OntClassImpl.RLComplementOfImpl::new);
+    }
+
+    public static EnhNodeFactory createOWL2QLComplementOfFactory(OntConfig 
config) {
+        return createOWL2RLQLComplementOfFactory(config, 
OntClassImpl.QLComplementOfImpl.class, OntClassImpl.QLComplementOfImpl::new);
+    }
+
+    private static EnhNodeFactory createOWL2RLQLComplementOfFactory(OntConfig 
config,
+                                                                    Class<? 
extends OntClassImpl> implType,
+                                                                    
BiFunction<Node, EnhGraph, EnhNode> producer) {
+        EnhNodeProducer maker = new EnhNodeProducer.WithType(implType, 
OWL2.Class, producer);
         EnhNodeFilter primary = 
config.getBoolean(OntModelControls.ALLOW_NAMED_CLASS_EXPRESSIONS) ? 
EnhNodeFilter.TRUE : EnhNodeFilter.ANON;
         EnhNodeFilter filter = primary.and(new 
EnhNodeFilter.HasType(OWL2.Class))
                 .and((n, g) -> {
@@ -396,7 +405,7 @@ final class OntClasses {
                             if (clazz == null) {
                                 return false;
                             }
-                            if (clazz.asSubClass() != null) {
+                            if (clazz.canAsSubClass()) {
                                 return true;
                             }
                         }
@@ -427,7 +436,7 @@ final class OntClasses {
                                             .mapWith(it ->
                                                     
OntEnhGraph.asPersonalityModel(g).safeFindNodeAs(it.asNode(), OntClass.class)
                                             )
-                                            .filterKeep(it -> it != null && 
it.asSubClass() != null), 2)) {
+                                            .filterKeep(it -> it != null && 
it.canAsSubClass()), 2)) {
                                 return true;
                             }
                         }
@@ -454,12 +463,10 @@ final class OntClasses {
                                 continue;
                             }
                             if (Iterators.anyMatch(
-                                    g.asGraph().find(n, OWL2.onClass.asNode(), 
Node.ANY)
-                                            .mapWith(it ->
-                                                    
OntEnhGraph.asPersonalityModel(g)
-                                                            
.safeFindNodeAs(it.getObject(), OntClass.class)
-                                                            .asSubClass()
-                                            ), Objects::nonNull)) {
+                                    g.asGraph().find(n, OWL2.onClass.asNode(), 
Node.ANY),
+                                    it -> OntEnhGraph.asPersonalityModel(g)
+                                            .safeFindNodeAs(it.getObject(), 
OntClass.class)
+                                            .canAsSubClass())) {
                                 return true;
                             }
                         }
@@ -648,7 +655,6 @@ final class OntClasses {
         private static final Node ONE_OF = OWL2.oneOf.asNode();
         private static final Node COMPLEMENT_OF = OWL2.complementOf.asNode();
         private static final Node TRUE = 
NodeFactory.createLiteralByValue(Boolean.TRUE, XSDDatatype.XSDboolean);
-        private static final Node SUB_CLASS_OF = RDFS.subClassOf.asNode();
         private static final String NON_NEGATIVE_INTEGER_URI = 
XSD.nonNegativeInteger.getURI();
 
 
@@ -721,14 +727,6 @@ final class OntClasses {
                     .filterKeep(x -> LIST_FACTORY.canWrap(x.getObject(), 
eg))).isPresent();
         }
 
-        @SuppressWarnings("SameParameterValue")
-        private static RDFList getList(Node n, EnhGraph eg, Node p) {
-            return Iterators.findFirst(listObjects(n, eg, p)
-                            .filterKeep(it -> 
LIST_FACTORY.canWrap(it.getObject(), eg))
-                            .mapWith(triple -> new 
RDFListImpl(triple.getObject(), eg)))
-                    .orElse(null);
-        }
-
         @SuppressWarnings("SameParameterValue")
         private static boolean isLiteral(Node n, String dt) {
             return n.isLiteral() && dt.equals(n.getLiteralDatatypeURI());
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 5f801a5adb..5d5680a64b 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
@@ -68,6 +68,7 @@ import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.Function;
+import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -175,7 +176,7 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
 
     public static OntIndividual.Anonymous 
createAnonymousIndividual(OntGraphModelImpl model, OntClass source) {
         OntGraphModelImpl.checkFeature(model, 
OntModelControls.ALLOW_ANONYMOUS_INDIVIDUALS, "anonymous-individuals");
-        OntJenaException.checkSupported(source.asAssertionClass() != null,
+        OntJenaException.checkSupported(source.canAsAssertionClass(),
                 "Class " + OntEnhNodeFactories.viewAsString(source.getClass()) 
+ " cannot have individuals. " +
                         "Profile: " + model.getOntPersonality().getName());
         return model.getNodeAs(model.createResource(source).asNode(), 
OntIndividual.Anonymous.class);
@@ -183,7 +184,7 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
 
     public static OntIndividual.Named createNamedIndividual(OntGraphModelImpl 
model, OntClass source, String uri) {
         OntJenaException.notNull(uri, "Null uri");
-        OntJenaException.checkSupported(source.asAssertionClass() != null,
+        OntJenaException.checkSupported(source.canAsAssertionClass(),
                 "Class " + OntEnhNodeFactories.viewAsString(source.getClass()) 
+ " cannot have individuals. " +
                         "Profile: " + model.getOntPersonality().getName());
         Resource res = model.createResource(uri, source);
@@ -219,7 +220,7 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
         if (!OntGraphModelImpl.configValue(m, 
OntModelControls.USE_OWL_CLASS_DISJOINT_WITH_FEATURE)) {
             return Stream.empty();
         }
-        if (clazz.asDisjointClass() == null) {
+        if (!clazz.canAsDisjointClass()) {
             return Stream.empty();
         }
         return Stream.of(
@@ -231,14 +232,14 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
                 )
                 .flatMap(it -> it)
                 .filter(it -> !it.equals(clazz))
+                .filter(OntClass::canAsDisjointClass)
                 .map(OntClass::asDisjointClass)
-                .filter(Objects::nonNull)
                 .distinct();
     }
 
     public static void addDisjoint(OntGraphModelImpl m, OntClass clazz, 
OntClass other) {
         OntGraphModelImpl.checkFeature(m, 
OntModelControls.USE_OWL_CLASS_DISJOINT_WITH_FEATURE, "owl:disjointWith");
-        OntJenaException.checkSupported(clazz.asDisjointClass() != null && 
other.asDisjointClass() != null,
+        OntJenaException.checkSupported(clazz.canAsDisjointClass() && 
other.canAsDisjointClass(),
                 "Classes " + 
OntEnhNodeFactories.viewAsString(clazz.getClass()) + " and " + 
OntEnhNodeFactories.viewAsString(other.getClass()) +
                         " cannot be disjoint. Profile " + 
m.getOntPersonality().getName()
         );
@@ -252,7 +253,7 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
 
     public static OntStatement addDisjointWithStatement(OntGraphModelImpl m, 
OntClass clazz, OntClass other) {
         OntGraphModelImpl.checkFeature(m, 
OntModelControls.USE_OWL_CLASS_DISJOINT_WITH_FEATURE, "owl:disjointWith");
-        OntJenaException.checkSupported(clazz.asDisjointClass() != null && 
other.asDisjointClass() != null,
+        OntJenaException.checkSupported(clazz.canAsDisjointClass() && 
other.canAsDisjointClass(),
                 "Classes " + 
OntEnhNodeFactories.viewAsString(clazz.getClass()) + " and " + 
OntEnhNodeFactories.viewAsString(other.getClass()) +
                         " cannot be disjoint. Profile " + 
m.getOntPersonality().getName()
         );
@@ -263,7 +264,7 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
         if (!OntGraphModelImpl.configValue(m, 
OntModelControls.USE_OWL_CLASS_EQUIVALENT_FEATURE)) {
             return Stream.empty();
         }
-        if (clazz.asEquivalentClass() == null) {
+        if (!clazz.canAsEquivalentClass()) {
             return Stream.empty();
         }
         return Stream.of(clazz.objects(OWL2.equivalentClass, OntClass.class),
@@ -273,14 +274,14 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
                 )
                 .flatMap(it -> it)
                 .filter(it -> !it.equals(clazz))
+                .filter(OntClass::canAsEquivalentClass)
                 .map(OntClass::asEquivalentClass)
-                .filter(Objects::nonNull)
                 .distinct();
     }
 
     public static OntStatement addEquivalentClass(OntGraphModelImpl m, 
OntClass clazz, OntClass other) {
         OntGraphModelImpl.checkFeature(m, 
OntModelControls.USE_OWL_CLASS_EQUIVALENT_FEATURE, "owl:equivalentClass");
-        OntJenaException.checkSupported(clazz.asEquivalentClass() != null && 
other.asEquivalentClass() != null,
+        OntJenaException.checkSupported(clazz.canAsEquivalentClass() && 
other.canAsEquivalentClass(),
                 "Classes " + 
OntEnhNodeFactories.viewAsString(clazz.getClass()) + " and " + 
OntEnhNodeFactories.viewAsString(other.getClass()) +
                         " cannot be equivalent. Profile " + 
m.getOntPersonality().getName()
         );
@@ -404,7 +405,13 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
         if (!candidate.canAs(OntClass.class)) {
             return false;
         }
+        if (!clazz.canAsDisjointClass()) {
+            return false;
+        }
         OntClass other = candidate.as(OntClass.class);
+        if (!other.canAsDisjointClass()) {
+            return false;
+        }
         try (Stream<OntClass> disjoints = other.disjointClasses()) {
             if (disjoints.anyMatch(clazz::equals)) {
                 return true;
@@ -424,7 +431,7 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
     }
 
     static Stream<OntIndividual> individuals(OntClass clazz, boolean direct) {
-        if (clazz.asAssertionClass() == null) {
+        if (!clazz.canAsAssertionClass()) {
             return Stream.empty();
         }
         if (OntGraphModelImpl.configValue(clazz.getModel(), 
OntModelControls.USE_BUILTIN_HIERARCHY_SUPPORT)) {
@@ -435,7 +442,7 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
     }
 
     public static Stream<OntClass> subClasses(OntClass clazz, boolean direct) {
-        if (clazz.asSuperClass() == null) {
+        if (!clazz.canAsSuperClass()) {
             return Stream.empty();
         }
         if (direct) {
@@ -453,7 +460,7 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
     }
 
     public static Stream<OntClass> superClasses(OntClass clazz, boolean 
direct) {
-        if (clazz.asSubClass() == null) {
+        if (!clazz.canAsSubClass()) {
             return Stream.empty();
         }
         if (direct) {
@@ -475,7 +482,7 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
             // every class is a subclass of itself
             return true;
         }
-        if (clazz.asSubClass() == null || candidateSuper.asSuperClass() == 
null) {
+        if (!clazz.canAsSubClass() || !candidateSuper.canAsSuperClass()) {
             return false;
         }
         if (direct) {
@@ -494,7 +501,7 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
     }
 
     static Stream<OntClass> explicitSuperClasses(Property predicate, OntObject 
clazz) {
-        return clazz.objects(predicate, 
OntClass.class).map(OntClass::asSuperClass).filter(Objects::nonNull);
+        return clazz.objects(predicate, 
OntClass.class).filter(OntClass::canAsSuperClass).map(OntClass::asSuperClass);
     }
 
     static Stream<OntClass> explicitSubClasses(OntClass clazz) {
@@ -502,7 +509,7 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
     }
 
     static Stream<OntClass> explicitSubClasses(Property predicate, OntClass 
clazz) {
-        return subjects(predicate, clazz, 
OntClass.class).map(OntClass::asSubClass).filter(Objects::nonNull);
+        return subjects(predicate, clazz, 
OntClass.class).filter(OntClass::canAsSubClass).map(OntClass::asSubClass);
     }
 
     @Override
@@ -682,27 +689,64 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
 
         @Override
         public OntClass asSubClass() {
-            return OWL2.Thing.equals(getValue()) ? this : null;
+            if (OWL2.Thing.equals(getValue())) {
+                return this;
+            }
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a subclass");
+        }
+
+        @Override
+        public boolean canAsSubClass() {
+            return OWL2.Thing.equals(getValue());
         }
 
         @Override
         public OntClass asSuperClass() {
-            return getValue().isURIResource() ? this : null;
+            if (getValue().isURIResource()) {
+                return this;
+            }
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a superclass");
+        }
+
+        @Override
+        public boolean canAsSuperClass() {
+            return getValue().isURIResource();
         }
 
         @Override
         public OntClass asEquivalentClass() {
-            return asSubClass();
+            if (OWL2.Thing.equals(getValue())) {
+                return this;
+            }
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be an equivalent class");
+        }
+
+        @Override
+        public boolean canAsEquivalentClass() {
+            return OWL2.Thing.equals(getValue());
         }
 
         @Override
         public OntClass asDisjointClass() {
-            return asSubClass();
+            if (OWL2.Thing.equals(getValue())) {
+                return this;
+            }
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a disjoint class");
+        }
+
+        @Override
+        public boolean canAsDisjointClass() {
+            return OWL2.Thing.equals(getValue());
         }
 
         @Override
         public OntClass asAssertionClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a object position of class assertion");
+        }
+
+        @Override
+        public boolean canAsAssertionClass() {
+            return false;
         }
     }
 
@@ -713,7 +757,32 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
 
         @Override
         public OntClass asSuperClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a superclass");
+        }
+
+        @Override
+        public boolean canAsSuperClass() {
+            return false;
+        }
+
+        @Override
+        public OntClass asAssertionClass() {
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a type of individual");
+        }
+
+        @Override
+        public boolean canAsAssertionClass() {
+            return false;
+        }
+
+        @Override
+        public OntClass asEquivalentClass() {
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be an equivalent");
+        }
+
+        @Override
+        public boolean canAsEquivalentClass() {
+            return false;
         }
     }
 
@@ -736,7 +805,12 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
 
         @Override
         public OntClass asAssertionClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a object position of class assertion");
+        }
+
+        @Override
+        public boolean canAsAssertionClass() {
+            return false;
         }
     }
 
@@ -748,12 +822,32 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
 
         @Override
         public OntClass asSuperClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a superclass");
+        }
+
+        @Override
+        public boolean canAsSuperClass() {
+            return false;
+        }
+
+        @Override
+        public OntClass asAssertionClass() {
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a type of individual");
+        }
+
+        @Override
+        public boolean canAsAssertionClass() {
+            return false;
         }
 
         @Override
         public OntClass asEquivalentClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be an equivalent class");
+        }
+
+        @Override
+        public boolean canAsEquivalentClass() {
+            return false;
         }
 
     }
@@ -778,17 +872,32 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
 
         @Override
         public OntClass asSubClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a subclass");
+        }
+
+        @Override
+        public boolean canAsSubClass() {
+            return false;
         }
 
         @Override
         public OntClass asEquivalentClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be an equivalent class");
+        }
+
+        @Override
+        public boolean canAsEquivalentClass() {
+            return false;
         }
 
         @Override
         public OntClass asDisjointClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a disjoint class");
+        }
+
+        @Override
+        public boolean canAsDisjointClass() {
+            return false;
         }
     }
 
@@ -812,17 +921,32 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
 
         @Override
         public OntClass asSubClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a subclass");
+        }
+
+        @Override
+        public boolean canAsSubClass() {
+            return false;
         }
 
         @Override
         public OntClass asEquivalentClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be an equivalent class");
+        }
+
+        @Override
+        public boolean canAsEquivalentClass() {
+            return false;
         }
 
         @Override
         public OntClass asDisjointClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a disjoint class");
+        }
+
+        @Override
+        public boolean canAsDisjointClass() {
+            return false;
         }
     }
 
@@ -869,22 +993,27 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
 
         @Override
         public OntClass asSuperClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a superclass");
+        }
+
+        @Override
+        public boolean canAsSuperClass() {
+            return false;
         }
 
         @Override
         public OntClass asEquivalentClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be an equivalent class");
         }
 
         @Override
-        public OntClass asDisjointClass() {
-            return asSubClass();
+        public boolean canAsEquivalentClass() {
+            return false;
         }
 
         @Override
         public Stream<OntClass> components() {
-            return 
getList().members().map(OntClass::asSubClass).filter(Objects::nonNull);
+            return getList().members().filter(OntClass::canAsSubClass);
         }
     }
 
@@ -906,27 +1035,47 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
 
         @Override
         public OntClass asSubClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a subclass");
+        }
+
+        @Override
+        public boolean canAsSubClass() {
+            return false;
         }
 
         @Override
         public OntClass asAssertionClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a object position of class assertion");
+        }
+
+        @Override
+        public boolean canAsAssertionClass() {
+            return false;
         }
 
         @Override
         public OntClass asEquivalentClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be an equivalent class");
+        }
+
+        @Override
+        public boolean canAsEquivalentClass() {
+            return false;
         }
 
         @Override
         public OntClass asDisjointClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a disjoint class");
+        }
+
+        @Override
+        public boolean canAsDisjointClass() {
+            return false;
         }
 
         @Override
         public Stream<OntClass> components() {
-            return 
getList().members().map(OntClass::asSuperClass).filter(Objects::nonNull);
+            return 
getList().members().filter(OntClass::canAsSuperClass).map(OntClass::asSuperClass);
         }
     }
 
@@ -940,30 +1089,31 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
 
         @Override
         public OntClass asSubClass() {
-            Collection<OntClass> res = collectSubClasses();
-            return res.isEmpty() ? null : new RLIntersectionOfImpl(this.node, 
this.enhGraph) {
-                @Override
-                public Stream<OntClass> components() {
-                    return res.stream();
-                }
-            };
+            return asSubClass(() -> "Specification does not allow this class 
to be a subclass");
+        }
+
+        @Override
+        public boolean canAsSubClass() {
+            return hasMemberSubClasses();
         }
 
         @Override
         public OntClass asSuperClass() {
-            Collection<OntClass> res = collectSuperClasses();
-            return res.isEmpty() ? null : new RLIntersectionOfImpl(this.node, 
this.enhGraph) {
-                @Override
-                public Stream<OntClass> components() {
-                    return res.stream();
-                }
-            };
+            return asSuperClass(() -> "Specification does not allow this class 
to be a superclass");
+        }
+
+        @Override
+        public boolean canAsSuperClass() {
+            return hasMemberSuperClasses();
         }
 
         @Override
         public OntClass asEquivalentClass() {
             Collection<OntClass> res = collectEquivalentClasses();
-            return res.isEmpty() ? null : new RLIntersectionOfImpl(this.node, 
this.enhGraph) {
+            if (res.isEmpty()) {
+                throw new OntJenaException.Unsupported("Specification does not 
allow this class to be an equivalent class");
+            }
+            return new RLIntersectionOfImpl(this.node, this.enhGraph) {
                 @Override
                 public Stream<OntClass> components() {
                     return res.stream();
@@ -971,33 +1121,72 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
             };
         }
 
+        @Override
+        public boolean canAsEquivalentClass() {
+            return hasMemberEquivalentClasses();
+        }
+
         @Override
         public OntClass asAssertionClass() {
-            return asSuperClass();
+            return asSuperClass(() -> "Specification does not allow this class 
to be a type of individual");
+        }
+
+        @Override
+        public boolean canAsAssertionClass() {
+            return hasMemberSuperClasses();
         }
 
         @Override
         public OntClass asDisjointClass() {
-            return asSubClass();
+            return asSubClass(() -> "Specification does not allow this class 
to be a disjoint class");
+        }
+
+        @Override
+        public boolean canAsDisjointClass() {
+            return hasMemberSubClasses();
         }
 
-        private Collection<OntClass> collectSubClasses() {
+        private OntClass asSuperClass(Supplier<String> message) {
+            Collection<OntClass> res = collectMemberSuperClasses();
+            if (res.isEmpty()) {
+                throw new OntJenaException.Unsupported(message.get());
+            }
+            return new RLIntersectionOfImpl(this.node, this.enhGraph) {
+                @Override
+                public Stream<OntClass> components() {
+                    return res.stream();
+                }
+            };
+        }
+
+        private OntClass asSubClass(Supplier<String> message) {
+            Collection<OntClass> res = collectMemberSubClasses();
+            if (res.isEmpty()) {
+                throw new OntJenaException.Unsupported(message.get());
+            }
+            return new RLIntersectionOfImpl(this.node, this.enhGraph) {
+                @Override
+                public Stream<OntClass> components() {
+                    return res.stream();
+                }
+            };
+        }
+
+        private Collection<OntClass> collectMemberSubClasses() {
             Set<OntClass> res = new LinkedHashSet<>();
             getList().members().forEach(it -> {
-                OntClass sub = it.asSubClass();
-                if (sub != null) {
-                    res.add(sub);
+                if (it.canAsSubClass()) {
+                    res.add(it.asSubClass());
                 }
             });
             return res.size() > 1 ? res : List.of();
         }
 
-        private Collection<OntClass> collectSuperClasses() {
+        private Collection<OntClass> collectMemberSuperClasses() {
             Set<OntClass> res = new LinkedHashSet<>();
             getList().members().forEach(it -> {
-                OntClass sub = it.asSuperClass();
-                if (sub != null) {
-                    res.add(sub);
+                if (it.canAsSuperClass()) {
+                    res.add(it.asSuperClass());
                 }
             });
             return res.size() > 1 ? res : List.of();
@@ -1006,13 +1195,30 @@ public abstract class OntClassImpl extends 
OntObjectImpl implements OntClass {
         private Collection<OntClass> collectEquivalentClasses() {
             Set<OntClass> res = new LinkedHashSet<>();
             getList().members().forEach(it -> {
-                OntClass sub = it.asEquivalentClass();
-                if (sub != null) {
-                    res.add(sub);
+                if (it.canAsEquivalentClass()) {
+                    res.add(it.asEquivalentClass());
                 }
             });
             return res.size() > 1 ? res : List.of();
         }
+
+        private boolean hasMemberSubClasses() {
+            try (Stream<OntClass> members = 
getList().members().filter(OntClass::canAsSubClass)) {
+                return Iterators.hasAtLeast(members.iterator(), 2);
+            }
+        }
+
+        private boolean hasMemberSuperClasses() {
+            try (Stream<OntClass> members = 
getList().members().filter(OntClass::canAsSuperClass)) {
+                return Iterators.hasAtLeast(members.iterator(), 2);
+            }
+        }
+
+        private boolean hasMemberEquivalentClasses() {
+            try (Stream<OntClass> members = 
getList().members().filter(OntClass::canAsEquivalentClass)) {
+                return Iterators.hasAtLeast(members.iterator(), 2);
+            }
+        }
     }
 
     public static class IntersectionOfImpl extends CollectionOfImpl<OntClass> 
implements IntersectionOf {
@@ -1033,12 +1239,32 @@ public abstract class OntClassImpl extends 
OntObjectImpl implements OntClass {
 
         @Override
         public OntClass asSuperClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a superclass");
+        }
+
+        @Override
+        public boolean canAsSuperClass() {
+            return false;
+        }
+
+        @Override
+        public OntClass asAssertionClass() {
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a type of individual");
+        }
+
+        @Override
+        public boolean canAsAssertionClass() {
+            return false;
         }
 
         @Override
         public OntClass asEquivalentClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be an equivalent class");
+        }
+
+        @Override
+        public boolean canAsEquivalentClass() {
+            return false;
         }
     }
 
@@ -1085,17 +1311,32 @@ public abstract class OntClassImpl extends 
OntObjectImpl implements OntClass {
 
         @Override
         public OntClass asSubClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a subclass");
+        }
+
+        @Override
+        public boolean canAsSubClass() {
+            return false;
         }
 
         @Override
         public OntClass asEquivalentClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be an equivalent class");
+        }
+
+        @Override
+        public boolean canAsEquivalentClass() {
+            return false;
         }
 
         @Override
         public OntClass asDisjointClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a disjoint class");
+        }
+
+        @Override
+        public boolean canAsDisjointClass() {
+            return false;
         }
     }
 
@@ -1119,17 +1360,32 @@ public abstract class OntClassImpl extends 
OntObjectImpl implements OntClass {
 
         @Override
         public OntClass asSubClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a subclass");
+        }
+
+        @Override
+        public boolean canAsSubClass() {
+            return false;
         }
 
         @Override
         public OntClass asEquivalentClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be an equivalent class");
+        }
+
+        @Override
+        public boolean canAsEquivalentClass() {
+            return false;
         }
 
         @Override
         public OntClass asDisjointClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a disjoint class");
+        }
+
+        @Override
+        public boolean canAsDisjointClass() {
+            return false;
         }
     }
 
@@ -1185,29 +1441,96 @@ public abstract class OntClassImpl extends 
OntObjectImpl implements OntClass {
         }
     }
 
-    public static class RLQLComplementOfImpl extends ComplementOfImpl {
-        public RLQLComplementOfImpl(Node n, EnhGraph m) {
+    public static class QLComplementOfImpl extends ComplementOfImpl {
+        public QLComplementOfImpl(Node n, EnhGraph m) {
+            super(n, m);
+        }
+
+        @Override
+        public OntClass asSubClass() {
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a subclass");
+        }
+
+        @Override
+        public boolean canAsSubClass() {
+            return false;
+        }
+
+        @Override
+        public boolean canAsSuperClass() {
+            return getValue().canAsSubClass();
+        }
+
+        @Override
+        public OntClass asAssertionClass() {
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be an individual type");
+        }
+
+        @Override
+        public boolean canAsAssertionClass() {
+            return false;
+        }
+    }
+
+    public static class RLComplementOfImpl extends ComplementOfImpl {
+        public RLComplementOfImpl(Node n, EnhGraph m) {
             super(n, m);
         }
 
         @Override
         public OntClass asSubClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a subclass");
+        }
+
+        @Override
+        public boolean canAsSubClass() {
+            return false;
+        }
+
+        @Override
+        public OntClass asSuperClass() {
+            if (getValue().canAsSubClass()) {
+                return this;
+            }
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be an super class");
+        }
+
+        @Override
+        public boolean canAsSuperClass() {
+            return getValue().canAsSubClass();
         }
 
         @Override
         public OntClass asAssertionClass() {
-            return null;
+            if (getValue().canAsSubClass()) {
+                return this;
+            }
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be an individual type");
+        }
+
+        @Override
+        public boolean canAsAssertionClass() {
+            return getValue().canAsSubClass();
         }
 
         @Override
         public OntClass asEquivalentClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be an equivalent class");
+        }
+
+        @Override
+        public boolean canAsEquivalentClass() {
+            return false;
         }
 
         @Override
         public OntClass asDisjointClass() {
-            return null;
+            throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a disjoint class");
+        }
+
+        @Override
+        public boolean canAsDisjointClass() {
+            return false;
         }
     }
 
diff --git 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntIndividualImpl.java
 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntIndividualImpl.java
index d13ffce8c0..a177132936 100644
--- 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntIndividualImpl.java
+++ 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntIndividualImpl.java
@@ -38,7 +38,6 @@ import org.apache.jena.vocabulary.OWL2;
 import org.apache.jena.vocabulary.RDF;
 import org.apache.jena.vocabulary.RDFS;
 
-import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -151,7 +150,10 @@ public abstract class OntIndividualImpl extends 
OntObjectImpl implements OntIndi
         if (direct) {
             Property reasonerProperty = 
reasonerProperty(individual.getModel(), RDF.type);
             if (reasonerProperty != null) {
-                return individual.objects(reasonerProperty, 
OntClass.class).map(OntClass::asAssertionClass).filter(Objects::nonNull);
+                return individual
+                        .objects(reasonerProperty, OntClass.class)
+                        .filter(OntClass::canAsAssertionClass)
+                        .map(OntClass::asAssertionClass);
             }
         }
         AtomicBoolean isIndividual = new AtomicBoolean(true);
@@ -160,13 +162,18 @@ public abstract class OntIndividualImpl extends 
OntObjectImpl implements OntIndi
                 direct,
                 OntGraphModelImpl.configValue(individual.getModel(), 
OntModelControls.USE_BUILTIN_HIERARCHY_SUPPORT)
         );
-        return (Stream<OntClass>) res;
+
+        return ((Stream<OntClass>) res)
+                
.filter(OntClass::canAsAssertionClass).map(OntClass::asAssertionClass);
     }
 
     static Stream<OntClass> listClassesFor(OntObject resource, AtomicBoolean 
isFirstLevel) {
         if (isFirstLevel.get()) {
             isFirstLevel.set(false);
-            return resource.objects(RDF.type, 
OntClass.class).map(OntClass::asAssertionClass).filter(Objects::nonNull);
+            return resource
+                    .objects(RDF.type, OntClass.class)
+                    .filter(OntClass::canAsAssertionClass)
+                    .map(OntClass::asAssertionClass);
         }
         return OntClassImpl.explicitSuperClasses(RDFS.subClassOf, resource);
     }
diff --git 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntSimpleClassImpl.java
 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntSimpleClassImpl.java
index 4ea15e4a7d..cef800397b 100644
--- 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntSimpleClassImpl.java
+++ 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntSimpleClassImpl.java
@@ -186,22 +186,54 @@ public class OntSimpleClassImpl extends OntObjectImpl 
implements OntClass {
 
         @Override
         public OntClass asSubClass() {
-            return OWL2.Thing.equals(this) ? null : this;
+            if (OWL2.Thing.equals(this)) {
+                throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a subclass");
+            }
+            return this;
+        }
+
+        @Override
+        public boolean canAsSubClass() {
+            return !OWL2.Thing.equals(this);
         }
 
         @Override
         public OntClass asSuperClass() {
-            return OWL2.Thing.equals(this) ? null : this;
+            if (OWL2.Thing.equals(this)) {
+                throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a superclass");
+            }
+            return this;
+        }
+
+        @Override
+        public boolean canAsSuperClass() {
+            return !OWL2.Thing.equals(this);
         }
 
         @Override
         public OntClass asEquivalentClass() {
-            return OWL2.Thing.equals(this) ? null : this;
+            if (OWL2.Thing.equals(this)) {
+                throw new OntJenaException.Unsupported("Specification does not 
allow this class to be an equivalent class");
+            }
+            return this;
+        }
+
+        @Override
+        public boolean canAsEquivalentClass() {
+            return !OWL2.Thing.equals(this);
         }
 
         @Override
         public OntClass asDisjointClass() {
-            return OWL2.Thing.equals(this) ? null : this;
+            if (OWL2.Thing.equals(this)) {
+                throw new OntJenaException.Unsupported("Specification does not 
allow this class to be a disjoint class");
+            }
+            return this;
+        }
+
+        @Override
+        public boolean canAsDisjointClass() {
+            return !OWL2.Thing.equals(this);
         }
     }
 
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 ecce5daaa6..bbb11b147f 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
@@ -377,15 +377,16 @@ public interface OntClass extends OntObject, 
AsNamed<OntClass.Named>, HasDisjoin
      * @return {@link Optional} wrapping {@link OntClass}
      */
     default Optional<OntClass> subClass() {
-        if (asSuperClass() == null) {
+        if (!canAsSuperClass()) {
             return Optional.empty();
         }
         try (Stream<OntClass> classes = getModel()
                 .statements(null, RDFS.subClassOf, this)
                 .map(OntStatement::getSubject)
                 .filter(it -> it.canAs(OntClass.class))
-                .map(it -> it.as(OntClass.class).asSubClass())
-                .filter(Objects::nonNull)) {
+                .map(it -> it.as(OntClass.class))
+                .filter(OntClass::canAsSubClass)
+                .map(OntClass::asSubClass)) {
             return classes.findFirst();
         }
     }
@@ -412,14 +413,15 @@ public interface OntClass extends OntObject, 
AsNamed<OntClass.Named>, HasDisjoin
      * @return {@link Optional} wrapping {@link OntClass}
      */
     default Optional<OntClass> superClass() {
-        if (asSubClass() == null) {
+        if (!canAsSubClass()) {
             return Optional.empty();
         }
         try (Stream<OntClass> classes = this.statements(RDFS.subClassOf)
                 .map(OntStatement::getSubject)
                 .filter(it -> it.canAs(OntClass.class))
-                .map(it -> it.as(OntClass.class).asSuperClass())
-                .filter(Objects::nonNull)) {
+                .map(it -> it.as(OntClass.class))
+                .filter(OntClass::canAsSuperClass)
+                .map(OntClass::asSuperClass)) {
             return classes.findFirst();
         }
     }
@@ -450,7 +452,7 @@ public interface OntClass extends OntObject, 
AsNamed<OntClass.Named>, HasDisjoin
      */
     default boolean hasSuperClass(OntClass clazz, boolean direct) {
         return equals(clazz) ||
-                (asSubClass() != null && clazz.asSuperClass() != null && 
superClasses(direct).anyMatch(clazz::equals));
+                (canAsSubClass() && clazz.canAsSuperClass() && 
superClasses(direct).anyMatch(clazz::equals));
     }
 
     /**
@@ -529,7 +531,7 @@ public interface OntClass extends OntObject, 
AsNamed<OntClass.Named>, HasDisjoin
      * @see #removeSuperClass(Resource)
      */
     default OntClass addSuperClass(OntClass other) {
-        OntJenaException.checkSupported(this.asSubClass() != null && 
other.asSuperClass() != null);
+        OntJenaException.checkSupported(this.canAsSubClass() && 
other.canAsSuperClass());
         addSubClassOfStatement(other);
         return this;
     }
@@ -543,7 +545,7 @@ public interface OntClass extends OntObject, 
AsNamed<OntClass.Named>, HasDisjoin
      * @see #addSuperClass(OntClass)
      */
     default OntClass addSubClass(OntClass other) {
-        OntJenaException.checkSupported(other.asSubClass() != null && 
this.asSuperClass() != null);
+        OntJenaException.checkSupported(other.canAsSubClass() && 
this.canAsSuperClass());
         other.addSuperClass(this);
         return this;
     }
@@ -558,7 +560,7 @@ public interface OntClass extends OntObject, 
AsNamed<OntClass.Named>, HasDisjoin
      * @see #removeDisjointClass(Resource)
      */
     default OntClass addDisjointClass(OntClass other) {
-        OntJenaException.checkSupported(other.asDisjointClass() != null && 
this.asDisjointClass() != null);
+        OntJenaException.checkSupported(this.canAsDisjointClass() && 
other.canAsDisjointClass());
         addDisjointWithStatement(other);
         return this;
     }
@@ -572,7 +574,7 @@ public interface OntClass extends OntObject, 
AsNamed<OntClass.Named>, HasDisjoin
      * @see #removeDisjointClass(Resource)
      */
     default OntClass addEquivalentClass(OntClass other) {
-        OntJenaException.checkSupported(this.asEquivalentClass() != null && 
other.asEquivalentClass() != null);
+        OntJenaException.checkSupported(this.canAsEquivalentClass() && 
other.canAsEquivalentClass());
         addEquivalentClassStatement(other);
         return this;
     }
@@ -729,70 +731,140 @@ public interface OntClass extends OntObject, 
AsNamed<OntClass.Named>, HasDisjoin
 
     /**
      * Returns the subclass-view of this class
-     * if the specification allows this class to be in subclass position, 
otherwise returns {@code null}.
+     * if the specification allows this class to be in subclass position, 
otherwise throws exception.
      * Some profiles (e.g., OWL2 QL, OWL2 RL)
      * distinguish constructions with respect to their position in the axiom 
statements.
      * Note that the returned class may differ in behavior from this class.
      *
-     * @return {@link OntClass} or {@code null}
+     * @return {@link OntClass}, not {@code null}
+     * @throws OntJenaException.Unsupported if this feature is not supported
+     * @see #canAsSubClass()
      */
     default OntClass asSubClass() {
         return this;
     }
 
+    /**
+     * Answers if this class can be a subclass of another class.
+     * Some profiles (e.g., OWL2 QL, OWL2 RL)
+     * distinguish constructions with respect to their position in the axiom 
statements.
+     *
+     * @return {@code true} if this class can be a subclass
+     * @see #asSubClass()
+     */
+    default boolean canAsSubClass() {
+        return true;
+    }
+
     /**
      * Returns the superclass-view of this class
-     * if the specification allows this class to be in superclass position, 
otherwise returns {@code null}.
+     * if the specification allows this class to be in superclass position, 
otherwise throws exception.
      * Some profiles (e.g., OWL2 QL, OWL2 RL)
      * distinguish constructions with respect to their position in the axiom 
statements.
      * Note that the returned class may differ in behavior from this class.
      *
      * @return {@link OntClass} or {@code null}
+     * @throws OntJenaException.Unsupported if this feature is not supported
+     * @see #canAsSuperClass()
      */
     default OntClass asSuperClass() {
         return this;
     }
 
+    /**
+     * Answers if this class can be a superclass of another class.
+     * Some profiles (e.g., OWL2 QL, OWL2 RL)
+     * distinguish constructions with respect to their position in the axiom 
statements.
+     *
+     * @return {@code true} if this class can be a superclass
+     * @see #asSuperClass()
+     */
+    default boolean canAsSuperClass() {
+        return true;
+    }
+
     /**
      * Returns the assertion-view of this class
-     * if the specification allows this class to make class assertions, 
otherwise returns {@code null}.
+     * if the specification allows this class to make class assertions, 
otherwise throws exception.
      * Some profiles (e.g., OWL2 QL, OWL2 RL)
      * distinguish constructions with respect to their position in the axiom 
statements.
      * Note that the returned class may differ in behavior from this class.
      *
      * @return {@link OntClass} or {@code null}
+     * @throws OntJenaException.Unsupported if this feature is not supported
+     * @see #canAsAssertionClass()
      */
     default OntClass asAssertionClass() {
         return this;
     }
 
+    /**
+     * Answers if this class can be an object in class-assertion statement (a 
type of individual).
+     * Some profiles (e.g., OWL2 QL, OWL2 RL)
+     * distinguish constructions with respect to their position in the axiom 
statements.
+     *
+     * @return {@code true} if this class can be a class-type of an individual
+     * @see #asAssertionClass()
+     */
+    default boolean canAsAssertionClass() {
+        return true;
+    }
+
     /**
      * Returns the equivalent-class-view of this class
      * if the specification allows this class to be in equivalent
-     * position ({@code owl:equivalentClass}), otherwise returns {@code null}.
+     * position ({@code owl:equivalentClass}), otherwise throws exception.
      * Some profiles (e.g., OWL2 QL, OWL2 RL)
      * distinguish constructions with respect to their position in the axiom 
statements.
      * Note that the returned class may differ in behavior from this class.
      *
      * @return {@link OntClass} or {@code null}
+     * @throws OntJenaException.Unsupported if this feature is not supported
+     * @see #canAsEquivalentClass()
      */
     default OntClass asEquivalentClass() {
         return this;
     }
 
+    /**
+     * Answers if this class can be an equivalent of another class.
+     * Some profiles (e.g., OWL2 QL, OWL2 RL)
+     * distinguish constructions with respect to their position in the axiom 
statements.
+     *
+     * @return {@code true} if this class can be equivalent of another class
+     * @see #asEquivalentClass()
+     */
+    default boolean canAsEquivalentClass() {
+        return true;
+    }
+
     /**
      * Returns the disjoint-class-view of this class
      * if the specification allows this to be in disjoint position
-     * ({@code owl:disjointWith}, {@code owl:AllDisjointClasses}), otherwise 
returns {@code null}.
+     * ({@code owl:disjointWith}, {@code owl:AllDisjointClasses}), otherwise 
throws exception.
      * Some profiles (e.g., OWL2 QL, OWL2 RL)
      * distinguish constructions with respect to their position in the axiom 
statements.
      *
      * @return {@link OntClass} or {@code null}
+     * @throws OntJenaException.Unsupported if this feature is not supported
+     * @see #canAsDisjointClass()
      */
     default OntClass asDisjointClass() {
         return this;
     }
 
+    /**
+     * Answers if this class can be disjoint with another class.
+     * Some profiles (e.g., OWL2 QL, OWL2 RL)
+     * distinguish constructions with respect to their position in the axiom 
statements.
+     *
+     * @return {@code true} if this class can be disjoint with another class
+     * @see #asDisjointClass()
+     */
+    default boolean canAsDisjointClass() {
+        return true;
+    }
+
     /*
      * ============================
      * All known Class Expressions:
diff --git 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntIndividual.java 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntIndividual.java
index 8c3c6a75c5..2cb9a63d82 100644
--- a/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntIndividual.java
+++ b/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntIndividual.java
@@ -100,6 +100,9 @@ public interface OntIndividual extends OntObject, 
AsNamed<OntIndividual.Named>,
      */
     default boolean hasOntClass(OntClass clazz, boolean direct) {
         Objects.requireNonNull(clazz);
+        if (!clazz.canAsAssertionClass()) {
+            return false;
+        }
         try (Stream<OntClass> classes = classes(direct)) {
             return classes.anyMatch(clazz::equals);
         }
diff --git 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntObjectProperty.java 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntObjectProperty.java
index 9f59ac64d4..91e10aec7e 100644
--- 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntObjectProperty.java
+++ 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntObjectProperty.java
@@ -133,7 +133,7 @@ public interface OntObjectProperty extends 
OntRelationalProperty, AsNamed<OntObj
      */
     @Override
     default Stream<OntClass> ranges() {
-        return objects(RDFS.range, 
OntClass.class).map(OntClass::asSuperClass).filter(Objects::nonNull);
+        return objects(RDFS.range, 
OntClass.class).filter(OntClass::canAsSuperClass).map(OntClass::asSuperClass);
     }
 
     /**
diff --git 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntRelationalProperty.java
 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntRelationalProperty.java
index d1ad17ed09..2fba8d39d4 100644
--- 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntRelationalProperty.java
+++ 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntRelationalProperty.java
@@ -203,7 +203,7 @@ public interface OntRelationalProperty extends OntProperty {
      */
     @Override
     default Stream<OntClass> domains() {
-        return objects(RDFS.domain, 
OntClass.class).map(OntClass::asSuperClass).filter(Objects::nonNull);
+        return objects(RDFS.domain, 
OntClass.class).filter(OntClass::canAsSuperClass).map(OntClass::asSuperClass);
     }
 
     /**
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 1111eb3bc0..3e0235e5a2 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
@@ -123,14 +123,15 @@ public class OntModelOWL2QLSpecTest {
         OntClass oc1 = c1.inModel(m).as(OntClass.ObjectSomeValuesFrom.class);
         OntClass oc3 = c3.inModel(m).as(OntClass.ObjectSomeValuesFrom.class);
 
-        Assertions.assertNull(oc1.asSubClass());
+        Assertions.assertFalse(oc1.canAsSubClass());
+        Assertions.assertThrows(OntJenaException.Unsupported.class, 
oc1::asSubClass);
         Assertions.assertSame(oc3, oc3.asSubClass());
         Assertions.assertSame(oc1, oc1.asSuperClass());
         Assertions.assertSame(oc3, oc3.asSuperClass());
 
         Assertions.assertThrows(OntJenaException.Unsupported.class, () -> 
m.createObjectSomeValuesFrom(p, oc1));
 
-        Assertions.assertNull(m.createObjectSomeValuesFrom(p, 
c0).asSubClass());
+        Assertions.assertThrows(OntJenaException.Unsupported.class, () -> 
m.createObjectSomeValuesFrom(p, c0).asSubClass());
         Assertions.assertEquals(4, m.ontObjects(OntClass.class).count());
         Assertions.assertEquals(3, 
m.ontObjects(OntClass.ObjectSomeValuesFrom.class).count());
     }
@@ -249,6 +250,7 @@ public class OntModelOWL2QLSpecTest {
             "OWL2_QL_MEM_TRANS_INF",
     })
     public void testIndividuals(TestSpec spec) {
+        // class assertions in OWL 2 QL can involve only atomic classes
         OntModel m = OntModelFactory.createModel(spec.inst);
         OntObjectProperty op = m.createObjectProperty("p");
         OntDataProperty dp = m.createDataProperty("d");
@@ -279,7 +281,7 @@ public class OntModelOWL2QLSpecTest {
         Assertions.assertEquals(List.of(), 
c4.individuals().collect(Collectors.toList()));
         Assertions.assertEquals(List.of(), 
c5.individuals().collect(Collectors.toList()));
 
-        Assertions.assertEquals(List.of(c0), 
i0.classes().collect(Collectors.toList()));
+        Assertions.assertEquals(Set.of(c0), 
i0.classes().collect(Collectors.toSet()));
         Assertions.assertEquals(List.of(), 
i1.classes().collect(Collectors.toList()));
         Assertions.assertEquals(List.of(), 
i2.classes().collect(Collectors.toList()));
         Assertions.assertEquals(List.of(), 
i3.classes().collect(Collectors.toList()));
@@ -344,4 +346,72 @@ public class OntModelOWL2QLSpecTest {
         Assertions.assertEquals(List.of(c0), 
c1.equivalentClasses().collect(Collectors.toList()));
         Assertions.assertEquals(List.of(), 
c2.equivalentClasses().collect(Collectors.toList()));
     }
+
+    @ParameterizedTest
+    @EnumSource(names = {
+            "OWL2_QL_MEM",
+            "OWL2_QL_MEM_RDFS_INF",
+            "OWL2_QL_MEM_TRANS_INF",
+    })
+    public void testDisjointEquivalentAxioms(TestSpec spec) {
+        OntModel data = OntModelFactory.createModel();
+        OntObjectProperty p0 = data.createObjectProperty("p0");
+        OntDataProperty p1 = data.createDataProperty("p1");
+
+        OntClass c0 = data.createOntClass("c0");
+        OntClass c1 = data.createDataHasValue(p1, data.createTypedLiteral(42));
+        OntClass c2 = data.createObjectOneOf(data.createIndividual("X"));
+
+        OntClass c3 = data.createObjectSomeValuesFrom(p0, c0);
+        OntClass c4 = data.createObjectAllValuesFrom(p0, c2);
+        OntClass c5 = data.createDataMinCardinality(p1, 42, 
data.getDatatype(XSD.xstring));
+        OntClass c6 = data.createDataMaxCardinality(p1, 0, 
data.getDatatype(XSD.xstring));
+
+        OntClass c7 = data.createObjectIntersectionOf(c3, c0);
+        OntClass c8 = data.createObjectIntersectionOf(c1, c2);
+
+        OntClass c9 = data.createObjectComplementOf(c2);
+        OntClass c10 = data.createObjectComplementOf(c9);
+
+        OntClass c11 = data.createObjectSomeValuesFrom(p0, data.getOWLThing());
+        OntClass c12 = data.createDataSomeValuesFrom(p1, 
data.getDatatype(XSD.xstring));
+
+        OntModel m = OntModelFactory.createModel(data.getGraph(), spec.inst);
+
+        OntClass mc0 = c0.inModel(m).as(OntClass.class);
+        Assertions.assertThrows(OntJenaException.Conversion.class, () -> 
c1.inModel(m).as(OntClass.class));
+        Assertions.assertThrows(OntJenaException.Conversion.class, () -> 
c2.inModel(m).as(OntClass.class));
+        OntClass mc3 = c3.inModel(m).as(OntClass.class);
+        Assertions.assertThrows(OntJenaException.Conversion.class, () -> 
c4.inModel(m).as(OntClass.class));
+        Assertions.assertThrows(OntJenaException.Conversion.class, () -> 
c5.inModel(m).as(OntClass.class));
+        Assertions.assertThrows(OntJenaException.Conversion.class, () -> 
c6.inModel(m).as(OntClass.class));
+        OntClass mc7 = c7.inModel(m).as(OntClass.class);
+        Assertions.assertThrows(OntJenaException.Conversion.class, () ->  
c8.inModel(m).as(OntClass.class));
+        Assertions.assertThrows(OntJenaException.Conversion.class, () -> 
c9.inModel(m).as(OntClass.class));
+        Assertions.assertThrows(OntJenaException.Conversion.class, () -> 
c10.inModel(m).as(OntClass.class));
+        OntClass mc11 = c11.inModel(m).as(OntClass.class);
+        OntClass mc12 = c12.inModel(m).as(OntClass.class);
+
+        Assertions.assertTrue(mc0.canAsEquivalentClass());
+        Assertions.assertTrue(mc0.canAsDisjointClass());
+        Assertions.assertFalse(mc3.canAsEquivalentClass());
+        Assertions.assertFalse(mc3.canAsDisjointClass());
+        Assertions.assertFalse(mc7.canAsEquivalentClass());
+        Assertions.assertFalse(mc7.canAsDisjointClass());
+        Assertions.assertTrue(mc11.canAsEquivalentClass());
+        Assertions.assertTrue(mc11.canAsDisjointClass());
+        Assertions.assertTrue(mc12.canAsEquivalentClass());
+        Assertions.assertTrue(mc12.canAsDisjointClass());
+
+        Assertions.assertSame(mc0, mc0.asEquivalentClass());
+        Assertions.assertSame(mc0, mc0.asDisjointClass());
+        Assertions.assertSame(mc11, mc11.asEquivalentClass());
+        Assertions.assertSame(mc11, mc11.asDisjointClass());
+        Assertions.assertSame(mc12, mc12.asEquivalentClass());
+        Assertions.assertSame(mc12, mc12.asDisjointClass());
+        Assertions.assertThrows(OntJenaException.Unsupported.class, 
mc3::asDisjointClass);
+        Assertions.assertThrows(OntJenaException.Unsupported.class, 
mc3::asEquivalentClass);
+        Assertions.assertThrows(OntJenaException.Unsupported.class, 
mc7::asDisjointClass);
+        Assertions.assertThrows(OntJenaException.Unsupported.class, 
mc7::asEquivalentClass);
+    }
 }
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 cc94ffd89b..879fb1ac91 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
@@ -39,6 +39,7 @@ import org.junit.jupiter.params.provider.EnumSource;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 import static org.apache.jena.ontapi.OntModelOWLSpecsTest.testListObjects;
@@ -345,6 +346,177 @@ public class OntModelOWL2RLSpecTest {
         Assertions.assertEquals(3, 
m.ontObjects(OntClass.ObjectAllValuesFrom.class).count());
     }
 
+
+    @ParameterizedTest
+    @EnumSource(names = {
+            "OWL2_RL_MEM",
+            "OWL2_RL_MEM_RDFS_INF",
+            "OWL2_RL_MEM_TRANS_INF",
+    })
+    public void testClassAssertions(TestSpec spec) {
+        // OWL 2 RL restricts class expressions in positive assertions to 
superClassExpression.
+        // All other assertions are the same as in the structural specification
+
+        OntModel data = OntModelFactory.createModel();
+        OntObjectProperty p0 = data.createObjectProperty("p0");
+        OntDataProperty p1 = data.createDataProperty("p1");
+
+        OntClass c0 = data.createOntClass("c0"); // can be super
+        OntClass c1 = data.createDataHasValue(p1, 
data.createTypedLiteral(42)); // can be super
+        OntClass c2 = data.createObjectOneOf(data.createIndividual("X")); // 
cannot be super, can be sub
+
+        OntClass c3 = data.createObjectSomeValuesFrom(p0, c0); // cannot be 
super
+        OntClass c4 = data.createObjectAllValuesFrom(p0, c2); // cannot be 
super, cannot be sub
+        OntClass c5 = data.createDataMinCardinality(p1, 42, 
data.getDatatype(XSD.xstring)); // cannot be super and sub
+        OntClass c6 = data.createDataMaxCardinality(p1, 0, 
data.getDatatype(XSD.xstring)); // can be super
+
+        OntClass c7 = data.createObjectIntersectionOf(c1, c0); // can be 
supper, can be sub
+        OntClass c8 = data.createObjectIntersectionOf(c1, c2); // cannot be 
supper, can be sub
+
+        OntClass c9 = data.createObjectComplementOf(c2); // can be super, 
cannot be sub
+        OntClass c10 = data.createObjectComplementOf(c9); // cannot be super, 
cannot be sub
+
+        
data.createIndividual("i1").attachClass(c3).attachClass(c4).attachClass(c5).attachClass(c7);
+        
data.createIndividual("i2").attachClass(c1).attachClass(c2).attachClass(c6);
+        
data.createIndividual("i3").attachClass(c9).attachClass(c10).attachClass(c8);
+
+        OntModel m = OntModelFactory.createModel(data.getGraph(), spec.inst);
+
+        Assertions.assertEquals(List.of(c7), 
m.getIndividual("i1").classes().toList());
+        Assertions.assertEquals(Set.of(c1, c6), 
m.getIndividual("i2").classes().collect(Collectors.toSet()));
+        Assertions.assertEquals(List.of(c9), 
m.getIndividual("i3").classes().toList());
+
+        
Assertions.assertTrue(c0.inModel(m).as(OntClass.class).canAsAssertionClass());
+        
Assertions.assertTrue(c1.inModel(m).as(OntClass.class).canAsAssertionClass());
+        
Assertions.assertFalse(c2.inModel(m).as(OntClass.class).canAsAssertionClass());
+        Assertions.assertThrows(OntJenaException.Unsupported.class, 
c2.inModel(m).as(OntClass.class)::asAssertionClass);
+        
Assertions.assertFalse(c3.inModel(m).as(OntClass.class).canAsAssertionClass());
+        Assertions.assertThrows(OntJenaException.Unsupported.class, 
c3.inModel(m).as(OntClass.class)::asAssertionClass);
+        Assertions.assertThrows(OntJenaException.Conversion.class, () -> 
c4.inModel(m).as(OntClass.class));
+        Assertions.assertThrows(OntJenaException.Conversion.class, () -> 
c5.inModel(m).as(OntClass.class));
+        
Assertions.assertTrue(c6.inModel(m).as(OntClass.class).canAsAssertionClass());
+        
Assertions.assertTrue(c7.inModel(m).as(OntClass.class).canAsAssertionClass());
+        
Assertions.assertFalse(c8.inModel(m).as(OntClass.class).canAsAssertionClass());
+        Assertions.assertThrows(OntJenaException.Unsupported.class, 
c8.inModel(m).as(OntClass.class)::asAssertionClass);
+        
Assertions.assertTrue(c9.inModel(m).as(OntClass.class).canAsAssertionClass());
+        Assertions.assertThrows(OntJenaException.Conversion.class, () -> 
c10.inModel(m).as(OntClass.class));
+    }
+
+    @ParameterizedTest
+    @EnumSource(names = {
+            "OWL2_RL_MEM",
+            "OWL2_RL_MEM_RDFS_INF",
+            "OWL2_RL_MEM_TRANS_INF",
+    })
+    public void testDisjointAxiom(TestSpec spec) {
+        OntModel data = OntModelFactory.createModel();
+        OntObjectProperty p0 = data.createObjectProperty("p0");
+        OntDataProperty p1 = data.createDataProperty("p1");
+
+        OntClass c0 = data.createOntClass("c0"); // can be super, can be sub
+        OntClass c1 = data.createDataHasValue(p1, 
data.createTypedLiteral(42)); // can be super, can be sub
+        OntClass c2 = data.createObjectOneOf(data.createIndividual("X")); // 
cannot be super, can be sub
+
+        OntClass c3 = data.createObjectSomeValuesFrom(p0, c0); // cannot be 
super, can be sub
+        OntClass c4 = data.createObjectAllValuesFrom(p0, c2); // cannot be 
super, cannot be sub
+        OntClass c5 = data.createDataMinCardinality(p1, 42, 
data.getDatatype(XSD.xstring)); // cannot be super and sub
+        OntClass c6 = data.createDataMaxCardinality(p1, 0, 
data.getDatatype(XSD.xstring)); // can be super, cannot be sub
+
+        OntClass c7 = data.createObjectIntersectionOf(c1, c0); // can be 
supper, can be sub
+        OntClass c8 = data.createObjectIntersectionOf(c1, c2); // cannot be 
supper, can be sub
+
+        OntClass c9 = data.createObjectComplementOf(c2); // can be super, 
cannot be sub
+        OntClass c10 = data.createObjectComplementOf(c9); // cannot be super, 
cannot be sub
+
+        OntModel m = OntModelFactory.createModel(data.getGraph(), spec.inst);
+
+        OntClass mc0 = c0.inModel(m).as(OntClass.class);
+        OntClass mc1 = c1.inModel(m).as(OntClass.class);
+        OntClass mc2 = c2.inModel(m).as(OntClass.class);
+        OntClass mc3 = c3.inModel(m).as(OntClass.class);
+        OntClass mc6 = c6.inModel(m).as(OntClass.class);
+        OntClass mc7 = c7.inModel(m).as(OntClass.class);
+        OntClass mc8 = c8.inModel(m).as(OntClass.class);
+        OntClass mc9 = c9.inModel(m).as(OntClass.class);
+
+        Assertions.assertTrue(mc0.canAsDisjointClass());
+        Assertions.assertTrue(mc1.canAsDisjointClass());
+        Assertions.assertTrue(mc2.canAsDisjointClass());
+        Assertions.assertTrue(mc3.canAsDisjointClass());
+        Assertions.assertThrows(OntJenaException.Conversion.class, () -> 
c4.inModel(m).as(OntClass.class));
+        Assertions.assertThrows(OntJenaException.Conversion.class, () -> 
c5.inModel(m).as(OntClass.class));
+        Assertions.assertFalse(mc6.canAsDisjointClass());
+        Assertions.assertTrue(mc7.canAsDisjointClass());
+        Assertions.assertTrue(mc8.canAsDisjointClass());
+        Assertions.assertFalse(mc9.canAsDisjointClass());
+        Assertions.assertThrows(OntJenaException.Conversion.class, () -> 
c10.inModel(m).as(OntClass.class));
+
+        Assertions.assertSame(mc0, mc0.asDisjointClass());
+        Assertions.assertSame(mc1, mc1.asDisjointClass());
+        Assertions.assertSame(mc2, mc2.asDisjointClass());
+        Assertions.assertSame(mc3, mc3.asDisjointClass());
+        Assertions.assertNotSame(mc7, mc7.asDisjointClass());
+        Assertions.assertEquals(mc7, mc7.asDisjointClass());
+        Assertions.assertNotSame(mc8, mc8.asDisjointClass());
+        Assertions.assertEquals(mc8, mc8.asDisjointClass());
+        Assertions.assertThrows(OntJenaException.Unsupported.class, 
mc6::asDisjointClass);
+        Assertions.assertThrows(OntJenaException.Unsupported.class, 
mc9::asDisjointClass);
+    }
+
+    @ParameterizedTest
+    @EnumSource(names = {
+            "OWL2_RL_MEM",
+            "OWL2_RL_MEM_RDFS_INF",
+            "OWL2_RL_MEM_TRANS_INF",
+    })
+    public void testEquivalentAxiom(TestSpec spec) {
+        OntModel data = OntModelFactory.createModel();
+        OntObjectProperty p0 = data.createObjectProperty("p0");
+        OntDataProperty p1 = data.createDataProperty("p1");
+
+        OntClass c0 = data.createOntClass("c0"); // can be super, can be sub, 
can be equiv
+        OntClass c1 = data.createDataHasValue(p1, 
data.createTypedLiteral(42)); // can be super, can be sub, can be equiv
+        OntClass c2 = data.createObjectOneOf(data.createIndividual("X")); // 
cannot be super, can be sub, cannot be equiv
+
+        OntClass c3 = data.createObjectSomeValuesFrom(p0, c0); // cannot be 
super, can be sub, cannot be equiv
+        OntClass c6 = data.createDataMaxCardinality(p1, 0, 
data.getDatatype(XSD.xstring)); // can be super, cannot be sub, cannot be equiv
+
+        OntClass c7 = data.createObjectIntersectionOf(c1, c0); // can be 
supper, can be sub, can be equiv
+        OntClass c8 = data.createObjectIntersectionOf(c1, c2); // cannot be 
supper, can be sub, cannot be equiv
+        OntClass c9 = data.createObjectComplementOf(c2); // can be super, 
cannot be sub, cannot be equiv
+
+        OntModel m = OntModelFactory.createModel(data.getGraph(), spec.inst);
+
+        OntClass mc0 = c0.inModel(m).as(OntClass.class);
+        OntClass mc1 = c1.inModel(m).as(OntClass.class);
+        OntClass mc2 = c2.inModel(m).as(OntClass.class);
+        OntClass mc3 = c3.inModel(m).as(OntClass.class);
+        OntClass mc6 = c6.inModel(m).as(OntClass.class);
+        OntClass mc7 = c7.inModel(m).as(OntClass.class);
+        OntClass mc8 = c8.inModel(m).as(OntClass.class);
+        OntClass mc9 = c9.inModel(m).as(OntClass.class);
+
+        Assertions.assertFalse(m.getOWLThing().canAsEquivalentClass());
+        Assertions.assertTrue(mc0.canAsEquivalentClass());
+        Assertions.assertTrue(mc1.canAsEquivalentClass());
+        Assertions.assertFalse(mc2.canAsEquivalentClass());
+        Assertions.assertFalse(mc3.canAsEquivalentClass());
+        Assertions.assertFalse(mc6.canAsEquivalentClass());
+        Assertions.assertTrue(mc7.canAsEquivalentClass());
+        Assertions.assertFalse(mc8.canAsEquivalentClass());
+        Assertions.assertFalse(mc9.canAsEquivalentClass());
+
+        Assertions.assertSame(mc0, mc0.asEquivalentClass());
+        Assertions.assertSame(mc1, mc1.asEquivalentClass());
+        Assertions.assertNotSame(mc7, mc7.asEquivalentClass());
+        Assertions.assertEquals(mc7, mc7.asEquivalentClass());
+        Assertions.assertThrows(OntJenaException.Unsupported.class, 
mc2::asEquivalentClass);
+        Assertions.assertThrows(OntJenaException.Unsupported.class, 
mc3::asEquivalentClass);
+        Assertions.assertThrows(OntJenaException.Unsupported.class, 
mc6::asEquivalentClass);
+        Assertions.assertThrows(OntJenaException.Unsupported.class, 
mc8::asEquivalentClass);
+        Assertions.assertThrows(OntJenaException.Unsupported.class, 
mc9::asEquivalentClass);
+    }
+
     @ParameterizedTest
     @EnumSource(names = {
             "OWL2_RL_MEM",
diff --git a/jena-ontapi/src/test/java/org/apache/jena/ontapi/StreamsTest.java 
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/StreamsTest.java
index 665aa79a57..fa881f6d5a 100644
--- a/jena-ontapi/src/test/java/org/apache/jena/ontapi/StreamsTest.java
+++ b/jena-ontapi/src/test/java/org/apache/jena/ontapi/StreamsTest.java
@@ -22,7 +22,6 @@ import org.apache.jena.ontapi.impl.UnionGraphImpl;
 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.OntIndividual;
 import org.apache.jena.ontapi.model.OntModel;
 import org.apache.jena.ontapi.model.OntObject;
 import org.apache.jena.sparql.graph.GraphFactory;
@@ -91,8 +90,6 @@ public class StreamsTest {
     public void testSetBasedMethods() {
         OntModel m = OntModelFactory.createModel();
         OntClass.Named a = m.createOntClass("C1");
-        OntIndividual i = 
a.addSuperClass(m.createOntClass("C2").addSuperClass(m.getOWLThing()))
-                .createIndividual("I");
         OntDataProperty p = m.createDataProperty("D1")
                 
.addSuperProperty(m.createDataProperty("D2").addSuperProperty(m.getOWLBottomDataProperty()));
 
@@ -101,9 +98,6 @@ public class StreamsTest {
         Supplier<Stream<?>> s3 = () -> a.subClasses(true);
         Supplier<Stream<?>> s4 = () -> a.superClasses(true);
 
-        Supplier<Stream<?>> s5 = () -> i.classes(false);
-        Supplier<Stream<?>> s6 = () -> i.classes(true);
-
         Supplier<Stream<?>> s7 = () -> p.superProperties(false);
         Supplier<Stream<?>> s8 = () -> p.subProperties(false);
         Supplier<Stream<?>> s9 = () -> p.superProperties(true);
@@ -111,7 +105,7 @@ public class StreamsTest {
 
         Supplier<Stream<?>> s11 = p::content;
 
-        Stream.of(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11).forEach(s -> {
+        Stream.of(s1, s2, s3, s4, s7, s8, s9, s10, s11).forEach(s -> {
             assertTrueConstant(s.get(), Spliterator.NONNULL);
             assertTrueConstant(s.get(), Spliterator.DISTINCT);
             assertTrueConstant(s.get(), Spliterator.IMMUTABLE);

Reply via email to