-
Notifications
You must be signed in to change notification settings - Fork 14
/
AbstractAxiomLoader.java
125 lines (111 loc) · 5.49 KB
/
AbstractAxiomLoader.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/**
* Copyright (C) 2020 Czech Technical University in Prague
* <p>
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
* version.
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details. You should have received a copy of the GNU General Public License along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*/
package cz.cvut.kbss.ontodriver.jena;
import cz.cvut.kbss.ontodriver.descriptor.AxiomDescriptor;
import cz.cvut.kbss.ontodriver.jena.util.JenaUtils;
import cz.cvut.kbss.ontodriver.model.*;
import org.apache.jena.datatypes.xsd.XSDDateTime;
import org.apache.jena.rdf.model.*;
import org.apache.jena.rdf.model.Literal;
import org.apache.jena.vocabulary.RDF;
import java.net.URI;
import java.util.*;
import static cz.cvut.kbss.ontodriver.model.Assertion.createDataPropertyAssertion;
import static cz.cvut.kbss.ontodriver.model.Assertion.createObjectPropertyAssertion;
abstract class AbstractAxiomLoader {
boolean inferred = false;
/**
* Checks whether the storage contains the specified axiom.
*
* @param axiom Axiom whose existence should be verified
* @param contexts Contexts to search, optional
* @return {@code true} if the axiom exists, {@code false} otherwise
*/
boolean contains(Axiom<?> axiom, Set<URI> contexts) {
final Resource subject = ResourceFactory.createResource(axiom.getSubject().getIdentifier().toString());
final Property property = ResourceFactory.createProperty(axiom.getAssertion().getIdentifier().toString());
final RDFNode object = JenaUtils.valueToRdfNode(axiom.getAssertion(), axiom.getValue());
return contains(subject, property, object, contexts);
}
abstract boolean contains(Resource subject, Property property, RDFNode object, Set<URI> context);
Assertion createAssertionForStatement(Statement statement) {
if (statement.getObject().isResource()) {
return createObjectPropertyAssertion(URI.create(statement.getPredicate().getURI()), inferred);
} else {
return createDataPropertyAssertion(URI.create(statement.getPredicate().getURI()), inferred);
}
}
/**
* Loads statements corresponding to subject and assertions specified by the arguments.
* <p>
* The specified descriptor is used in context and subject resolution.
*
* @param descriptor Loading descriptor, contains subject and context info
* @param assertions Assertions to load
* @return Matching axioms
*/
abstract Collection<Axiom<?>> find(AxiomDescriptor descriptor, Map<String, Assertion> assertions);
/**
* Loads all property statements with the specified subject.
* <p>
* Note that type assertion statements (those with property {@code rdf:type}) are skipped.
*
* @param subject Statement subject
* @param context Context identifier, optional
* @return Matching statements
*/
Collection<Axiom<?>> find(NamedResource subject, URI context) {
final Resource resource = ResourceFactory.createResource(subject.getIdentifier().toString());
final Collection<Statement> statements = findStatements(resource, null,
context != null ? Collections.singleton(context) : Collections.emptySet());
final List<Axiom<?>> axioms = new ArrayList<>(statements.size());
for (Statement statement : statements) {
if (statement.getPredicate().equals(RDF.type)) {
continue;
}
final Assertion a = createAssertionForStatement(statement);
resolveValue(a, statement.getObject()).ifPresent(v -> axioms.add(new AxiomImpl<>(subject, a, v)));
}
return axioms;
}
abstract Collection<Statement> findStatements(Resource subject, Property property, Collection<URI> contexts);
Optional<Value<?>> resolveValue(Assertion assertion, RDFNode object) {
if (object.isResource()) {
if (object.isAnon() || assertion.getType() == Assertion.AssertionType.DATA_PROPERTY) {
return Optional.empty();
}
return Optional.of(new Value<>(NamedResource.create(object.asResource().getURI())));
} else {
if (shouldSkipLiteral(assertion, object)) {
return Optional.empty();
}
Object val = JenaUtils.literalToValue(object.asLiteral());
// Jena does not like java.util.Date
if (val instanceof XSDDateTime) {
val = ((XSDDateTime) val).asCalendar().getTime();
}
return Optional.of(new Value<>(val));
}
}
private static boolean shouldSkipLiteral(Assertion assertion, RDFNode object) {
assert object.isLiteral();
return assertion.getType() == Assertion.AssertionType.OBJECT_PROPERTY ||
!doesLanguageMatch(assertion, object.asLiteral());
}
private static boolean doesLanguageMatch(Assertion assertion, Literal literal) {
if (!(literal.getValue() instanceof String) || !assertion.hasLanguage()) {
return true;
}
return Objects.equals(assertion.getLanguage(), literal.getLanguage()) || literal.getLanguage().isEmpty();
}
}