Skip to content

Commit 090963e

Browse files
committed
ont-api: add model-impl for OWLObjectPropertyRangeAxiom (#2) + add tests
1 parent 34ce6ed commit 090963e

File tree

6 files changed

+277
-15
lines changed

6 files changed

+277
-15
lines changed

src/main/java/com/github/owlcs/ontapi/internal/axioms/ObjectPropertyRangeTranslator.java

+226-15
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,31 @@
1414

1515
package com.github.owlcs.ontapi.internal.axioms;
1616

17-
import org.semanticweb.owlapi.model.OWLAnnotation;
18-
import org.semanticweb.owlapi.model.OWLClassExpression;
19-
import org.semanticweb.owlapi.model.OWLObjectPropertyExpression;
20-
import org.semanticweb.owlapi.model.OWLObjectPropertyRangeAxiom;
21-
import com.github.owlcs.ontapi.internal.InternalConfig;
22-
import com.github.owlcs.ontapi.internal.InternalObjectFactory;
23-
import com.github.owlcs.ontapi.internal.ONTObject;
24-
import com.github.owlcs.ontapi.internal.ONTWrapperImpl;
17+
import com.github.owlcs.ontapi.DataFactory;
18+
import com.github.owlcs.ontapi.internal.*;
19+
import com.github.owlcs.ontapi.internal.objects.*;
2520
import com.github.owlcs.ontapi.jena.model.OntCE;
21+
import com.github.owlcs.ontapi.jena.model.OntGraphModel;
2622
import com.github.owlcs.ontapi.jena.model.OntOPE;
2723
import com.github.owlcs.ontapi.jena.model.OntStatement;
24+
import org.apache.jena.graph.Triple;
25+
import org.semanticweb.owlapi.model.*;
2826

27+
import java.util.Arrays;
2928
import java.util.Collection;
29+
import java.util.Set;
30+
import java.util.function.BiFunction;
31+
import java.util.function.Supplier;
32+
import java.util.stream.Stream;
3033

3134
/**
32-
* See {@link AbstractPropertyRangeTranslator}.
35+
* A translator that provides {@link OWLObjectPropertyRangeAxiom} implementations.
36+
* A Property Domain Axiom is a statement with predicate {@link org.apache.jena.vocabulary.RDFS#domain rdfs:domain}.
3337
* <p>
3438
* Created by @szuev on 28.09.2016.
3539
*/
36-
public class ObjectPropertyRangeTranslator extends AbstractPropertyRangeTranslator<OWLObjectPropertyRangeAxiom, OntOPE> {
40+
public class ObjectPropertyRangeTranslator
41+
extends AbstractPropertyRangeTranslator<OWLObjectPropertyRangeAxiom, OntOPE> {
3742

3843
@Override
3944
Class<OntOPE> getView() {
@@ -47,14 +52,220 @@ protected boolean filter(OntStatement statement, InternalConfig config) {
4752

4853
@Override
4954
public ONTObject<OWLObjectPropertyRangeAxiom> toAxiom(OntStatement statement,
50-
InternalObjectFactory reader,
55+
Supplier<OntGraphModel> model,
56+
InternalObjectFactory factory,
5157
InternalConfig config) {
52-
ONTObject<? extends OWLObjectPropertyExpression> p = reader.getProperty(statement.getSubject(getView()));
53-
ONTObject<? extends OWLClassExpression> ce = reader.getClass(statement.getObject().as(OntCE.class));
54-
Collection<ONTObject<OWLAnnotation>> annotations = reader.getAnnotations(statement, config);
55-
OWLObjectPropertyRangeAxiom res = reader.getOWLDataFactory()
58+
return AxiomImpl.create(statement, model, factory, config);
59+
}
60+
61+
@Override
62+
public ONTObject<OWLObjectPropertyRangeAxiom> toAxiom(OntStatement statement,
63+
InternalObjectFactory factory,
64+
InternalConfig config) {
65+
ONTObject<? extends OWLObjectPropertyExpression> p = factory.getProperty(statement.getSubject(getView()));
66+
ONTObject<? extends OWLClassExpression> ce = factory.getClass(statement.getObject(OntCE.class));
67+
Collection<ONTObject<OWLAnnotation>> annotations = factory.getAnnotations(statement, config);
68+
OWLObjectPropertyRangeAxiom res = factory.getOWLDataFactory()
5669
.getOWLObjectPropertyRangeAxiom(p.getOWLObject(), ce.getOWLObject(), ONTObject.toSet(annotations));
5770
return ONTWrapperImpl.create(res, statement).append(annotations).append(p).append(ce);
5871
}
5972

73+
/**
74+
* @see com.github.owlcs.ontapi.owlapi.axioms.OWLObjectPropertyRangeAxiomImpl
75+
*/
76+
public abstract static class AxiomImpl
77+
extends RangeAxiomImpl<OWLObjectPropertyRangeAxiom, OWLObjectPropertyExpression, OWLClassExpression>
78+
implements OWLObjectPropertyRangeAxiom {
79+
80+
protected AxiomImpl(Triple t, Supplier<OntGraphModel> m) {
81+
super(t, m);
82+
}
83+
84+
protected AxiomImpl(Object subject, String predicate, Object object, Supplier<OntGraphModel> m) {
85+
super(subject, predicate, object, m);
86+
}
87+
88+
/**
89+
* Creates an {@link ONTObject} container that is also {@link OWLObjectPropertyRangeAxiom}.
90+
*
91+
* @param statement {@link OntStatement}, not {@code null}
92+
* @param model {@link OntGraphModel} provider, not {@code null}
93+
* @param factory {@link InternalObjectFactory}, not {@code null}
94+
* @param config {@link InternalConfig}, not {@code null}
95+
* @return {@link AxiomImpl}
96+
*/
97+
public static AxiomImpl create(OntStatement statement,
98+
Supplier<OntGraphModel> model,
99+
InternalObjectFactory factory,
100+
InternalConfig config) {
101+
return WithTwoObjects.create(statement, model,
102+
SimpleImpl.FACTORY, ComplexImpl.FACTORY, SET_HASH_CODE, factory, config);
103+
}
104+
105+
@Override
106+
public ONTObject<? extends OWLObjectPropertyExpression> getURISubject(InternalObjectFactory factory) {
107+
return ONTObjectPropertyImpl.find(getSubjectURI(), factory, model);
108+
}
109+
110+
@Override
111+
public ONTObject<? extends OWLObjectPropertyExpression> subjectFromStatement(OntStatement statement,
112+
InternalObjectFactory factory) {
113+
return factory.getProperty(statement.getSubject(OntOPE.class));
114+
}
115+
116+
@Override
117+
public ONTObject<? extends OWLClassExpression> getURIObject(InternalObjectFactory factory) {
118+
return ONTClassImpl.find(getObjectURI(), factory, model);
119+
}
120+
121+
@Override
122+
public ONTObject<? extends OWLClassExpression> objectFromStatement(OntStatement statement,
123+
InternalObjectFactory factory) {
124+
return factory.getClass(statement.getObject(OntCE.class));
125+
}
126+
127+
@FactoryAccessor
128+
@Override
129+
protected OWLObjectPropertyRangeAxiom createAnnotatedAxiom(Collection<OWLAnnotation> annotations) {
130+
return getDataFactory().getOWLObjectPropertyRangeAxiom(eraseModel(getProperty()),
131+
eraseModel(getRange()), annotations);
132+
}
133+
134+
@FactoryAccessor
135+
@Override
136+
public OWLSubClassOfAxiom asOWLSubClassOfAxiom() {
137+
DataFactory df = getDataFactory();
138+
return df.getOWLSubClassOfAxiom(df.getOWLThing(),
139+
df.getOWLObjectAllValuesFrom(eraseModel(getProperty()), eraseModel(getRange())));
140+
}
141+
142+
@Override
143+
public final boolean canContainAnnotationProperties() {
144+
return isAnnotated();
145+
}
146+
147+
/**
148+
* An {@link OWLObjectPropertyRangeAxiom}
149+
* that has named object property and class expressions and has no annotations.
150+
*/
151+
public static class SimpleImpl extends AxiomImpl
152+
implements Simple<OWLObjectPropertyExpression, OWLClassExpression> {
153+
154+
private static final BiFunction<Triple, Supplier<OntGraphModel>, SimpleImpl> FACTORY = SimpleImpl::new;
155+
156+
protected SimpleImpl(Triple t, Supplier<OntGraphModel> m) {
157+
super(t, m);
158+
}
159+
160+
@Override
161+
public Set<OWLObjectProperty> getObjectPropertySet() {
162+
return createSet(getONTSubject().getOWLObject().asOWLObjectProperty());
163+
}
164+
165+
@Override
166+
public Set<OWLClass> getNamedClassSet() {
167+
return createSet(getONTObject().getOWLObject().asOWLClass());
168+
}
169+
170+
@Override
171+
public Set<OWLClassExpression> getClassExpressionSet() {
172+
return createSet(getONTObject().getOWLObject());
173+
}
174+
175+
@SuppressWarnings("unchecked")
176+
@Override
177+
public Set<OWLEntity> getSignatureSet() {
178+
return (Set<OWLEntity>) getOWLComponentsAsSet();
179+
}
180+
181+
@Override
182+
public boolean containsObjectProperty(OWLObjectProperty property) {
183+
return getSubjectURI().equals(ONTEntityImpl.getURI(property));
184+
}
185+
186+
@Override
187+
public boolean containsNamedClass(OWLClass clazz) {
188+
return getObjectURI().equals(ONTEntityImpl.getURI(clazz));
189+
}
190+
191+
@Override
192+
protected boolean sameContent(ONTStatementImpl other) {
193+
return false;
194+
}
195+
196+
@Override
197+
public boolean canContainDatatypes() {
198+
return false;
199+
}
200+
201+
@Override
202+
public boolean canContainAnonymousIndividuals() {
203+
return false;
204+
}
205+
206+
@Override
207+
public boolean canContainNamedIndividuals() {
208+
return false;
209+
}
210+
211+
@Override
212+
public boolean canContainDataProperties() {
213+
return false;
214+
}
215+
}
216+
217+
/**
218+
* An {@link OWLObjectPropertyRangeAxiom}
219+
* that either has annotations
220+
* or anonymous object/class expressions in main triple's subject/object positions respectively.
221+
* It has a public constructor since it is more generic then {@link SimpleImpl}.
222+
*/
223+
public static class ComplexImpl extends AxiomImpl
224+
implements Complex<ComplexImpl, OWLObjectPropertyExpression, OWLClassExpression> {
225+
226+
private static final BiFunction<Triple, Supplier<OntGraphModel>, ComplexImpl> FACTORY = ComplexImpl::new;
227+
228+
protected final InternalCache.Loading<ComplexImpl, Object[]> content;
229+
230+
public ComplexImpl(Triple t, Supplier<OntGraphModel> m) {
231+
this(strip(t.getSubject()), t.getPredicate().getURI(), strip(t.getObject()), m);
232+
}
233+
234+
protected ComplexImpl(Object s, String p, Object o, Supplier<OntGraphModel> m) {
235+
super(s, p, o, m);
236+
this.content = createContentCache();
237+
}
238+
239+
@Override
240+
public InternalCache.Loading<ComplexImpl, Object[]> getContentCache() {
241+
return content;
242+
}
243+
244+
@Override
245+
protected boolean sameContent(ONTStatementImpl other) {
246+
return other instanceof ComplexImpl && Arrays.equals(getContent(), ((ComplexImpl) other).getContent());
247+
}
248+
249+
@Override
250+
public ONTObject<OWLObjectPropertyRangeAxiom> merge(ONTObject<OWLObjectPropertyRangeAxiom> other) {
251+
if (this == other) {
252+
return this;
253+
}
254+
if (other instanceof AxiomImpl && sameTriple((AxiomImpl) other)) {
255+
return this;
256+
}
257+
ComplexImpl res = new ComplexImpl(subject, predicate, object, model) {
258+
@Override
259+
public Stream<Triple> triples() {
260+
return Stream.concat(ComplexImpl.this.triples(), other.triples());
261+
}
262+
};
263+
if (hasContent()) {
264+
res.putContent(getContent());
265+
}
266+
res.hashCode = hashCode;
267+
return res;
268+
}
269+
}
270+
}
60271
}

src/test/java/com/github/owlcs/ontapi/tests/TestFactory.java

+26
Original file line numberDiff line numberDiff line change
@@ -2719,6 +2719,32 @@ public String toString() {
27192719
"df.getRDFSLabel(df.getOWLAnonymousIndividual(\"_:b0\"))))";
27202720
}
27212721
}
2722+
, new AxiomData() {
2723+
@Override
2724+
public AxiomType getType() {
2725+
return AxiomType.OBJECT_PROPERTY_RANGE;
2726+
}
2727+
2728+
@Override
2729+
public OWLObject create(OWLDataFactory df) {
2730+
return df.getOWLObjectPropertyRangeAxiom(df.getOWLObjectInverseOf(df.getOWLObjectProperty("P")),
2731+
df.getOWLObjectIntersectionOf(df.getOWLClass("C"), df.getOWLThing()),
2732+
Collections.singleton(df.getRDFSComment("comm",
2733+
Stream.of(df.getOWLAnnotation(df.getRDFSIsDefinedBy(), IRI.create("X")),
2734+
df.getOWLAnnotation(df.getOWLIncompatibleWith(),
2735+
df.getOWLLiteral("x", "x"))))));
2736+
}
2737+
2738+
@Override
2739+
public String toString() {
2740+
return "df.getOWLObjectPropertyRangeAxiom(" +
2741+
"df.getOWLObjectInverseOf(df.getOWLObjectProperty(\"P\")), " +
2742+
"df.getOWLObjectIntersectionOf(df.getOWLClass(\"C\"), df.getOWLThing()), " +
2743+
"Collections.singleton(df.getRDFSComment(\"comm\", " +
2744+
"Stream.of(df.getOWLAnnotation(df.getRDFSIsDefinedBy(), IRI.create(\"X\")), " +
2745+
"df.getOWLAnnotation(df.getOWLIncompatibleWith(), df.getOWLLiteral(\"x\", \"x\"))))))";
2746+
}
2747+
}
27222748
);
27232749
}
27242750

src/test/java/com/github/owlcs/ontapi/tests/internal/AxiomPropertiesTest.java

+6
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,12 @@ public void testDataPropertyRange() {
120120
testAxiom(data, (Function<OWLDataPropertyRangeAxiom, Object>) HasRange::getRange, HasProperty::getProperty);
121121
}
122122

123+
@Test
124+
public void testObjectPropertyRange() {
125+
List<TestFactory.AxiomData> data = CommonAxiomsTest.getAxiomData(AxiomType.OBJECT_PROPERTY_RANGE);
126+
testAxiom(data, (Function<OWLObjectPropertyRangeAxiom, Object>) HasRange::getRange, HasProperty::getProperty);
127+
}
128+
123129
@SuppressWarnings("unchecked")
124130
@SafeVarargs
125131
private static <X extends OWLAxiom> void testAxiom(List<TestFactory.AxiomData> data,

src/test/java/com/github/owlcs/ontapi/tests/internal/CommonAxiomsTest.java

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ public static List<AxiomData> getData() {
6868
, AxiomType.ANNOTATION_PROPERTY_DOMAIN
6969
, AxiomType.ANNOTATION_PROPERTY_RANGE
7070
, AxiomType.DATA_PROPERTY_RANGE
71+
, AxiomType.OBJECT_PROPERTY_RANGE
7172
);
7273
}
7374

src/test/java/com/github/owlcs/ontapi/tests/internal/ModelObjectTest.java

+7
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,13 @@ public void testDataPropertyRangeEraseModelMethods() {
270270
Arrays.asList(df.getRDFSComment("x"), df.getRDFSLabel("y"))));
271271
}
272272

273+
@Test
274+
public void testObjectPropertyRangeEraseModelMethods() {
275+
testUnaryPropAxiom(df -> df.getOWLObjectPropertyRangeAxiom(df.getOWLObjectProperty("X"),
276+
df.getOWLObjectUnionOf(),
277+
Arrays.asList(df.getRDFSComment("x"), df.getRDFSLabel("y"))));
278+
}
279+
273280
@SuppressWarnings("unchecked")
274281
private <X extends OWLNaryAxiom & OWLSubClassOfAxiomSetShortCut> void testSubClassShortCutNaryAxiom(X expected) {
275282
X actual = testNaryAxiom(expected);

src/test/java/com/github/owlcs/ontapi/tests/internal/ONTObjectMergeTest.java

+11
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,17 @@ void doTest() {
419419
}
420420
},
421421

422+
OBJECT_PROPERTY_RANGE {
423+
@Override
424+
void doTest() {
425+
test(g -> {
426+
OntNOP p = g.createObjectProperty("X");
427+
createInverse(p).addRange(g.createIntersectionOf(g.getOWLThing(), g.createComplementOf(g.getOWLThing())));
428+
createInverse(p).addRange(g.createIntersectionOf(g.getOWLThing(), g.createComplementOf(g.getOWLThing())));
429+
}, 22, AxiomType.OBJECT_PROPERTY_RANGE, 2, 2);
430+
}
431+
},
432+
422433
INVERSE_FUNCTIONAL_OBJECT_PROPERTY {
423434
@Override
424435
void doTest() {

0 commit comments

Comments
 (0)