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);