Skip to content

Method: resolveUnspecifiedProperty()

1: /**
2: * Copyright (C) 2023 Czech Technical University in Prague
3: *
4: * This program is free software: you can redistribute it and/or modify it under
5: * the terms of the GNU General Public License as published by the Free Software
6: * Foundation, either version 3 of the License, or (at your option) any
7: * later version.
8: *
9: * This program is distributed in the hope that it will be useful, but WITHOUT
10: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12: * details. You should have received a copy of the GNU General Public License
13: * along with this program. If not, see <http://www.gnu.org/licenses/>.
14: */
15: package cz.cvut.kbss.ontodriver.jena;
16:
17: import cz.cvut.kbss.ontodriver.descriptor.AxiomDescriptor;
18: import cz.cvut.kbss.ontodriver.jena.connector.StorageConnector;
19: import cz.cvut.kbss.ontodriver.model.Assertion;
20: import cz.cvut.kbss.ontodriver.model.Axiom;
21: import cz.cvut.kbss.ontodriver.model.AxiomImpl;
22: import cz.cvut.kbss.ontodriver.model.Value;
23: import cz.cvut.kbss.ontodriver.util.Vocabulary;
24: import org.apache.jena.rdf.model.*;
25:
26: import java.net.URI;
27: import java.util.*;
28: import java.util.stream.Collectors;
29:
30: class ExplicitAxiomLoader extends AbstractAxiomLoader {
31:
32: private static final Assertion UNSPECIFIED_ASSERTION = Assertion.createUnspecifiedPropertyAssertion(false);
33:
34: private final StorageConnector connector;
35:
36: private Map<String, Assertion> assertedProperties;
37: private Assertion unspecifiedProperty;
38:
39: ExplicitAxiomLoader(StorageConnector connector) {
40: this.connector = connector;
41: }
42:
43: @Override
44: boolean contains(Resource subject, Property property, RDFNode object, Set<URI> contexts) {
45: return connector
46: .contains(subject, property, object, contexts.stream().map(URI::toString).collect(Collectors.toSet()));
47: }
48:
49: @Override
50: Collection<Axiom<?>> find(AxiomDescriptor descriptor, Map<String, Assertion> assertions) {
51: this.assertedProperties = assertions;
52: this.unspecifiedProperty = resolveUnspecifiedProperty();
53: final Resource subject = ResourceFactory.createResource(descriptor.getSubject().getIdentifier().toString());
54: final Collection<Statement> statements = findStatements(subject, null, descriptor.getSubjectContexts());
55: final List<Axiom<?>> result = transformStatementsToAxioms(descriptor, statements);
56: result.addAll(loadAxiomsForPropertiesInContext(descriptor, subject));
57: return result;
58: }
59:
60: private Assertion resolveUnspecifiedProperty() {
61: final Optional<Assertion> unspecified =
62: assertedProperties.values().stream().filter(a -> a.equals(UNSPECIFIED_ASSERTION)).findAny();
63: return unspecified.orElse(null);
64: }
65:
66: @Override
67: Collection<Statement> findStatements(Resource subject, Property property, Collection<URI> contexts) {
68: return connector
69: .find(subject, property, null, contexts.stream().map(URI::toString).collect(Collectors.toSet()));
70: }
71:
72: private List<Axiom<?>> transformStatementsToAxioms(AxiomDescriptor descriptor, Collection<Statement> statements) {
73: final List<Axiom<?>> axioms = new ArrayList<>(statements.size());
74: for (Statement statement : statements) {
75: final Property property = statement.getPredicate();
76: if (shouldSkipProperty(property, descriptor)) {
77: continue;
78: }
79: final Assertion a =
80: assertedProperties.containsKey(property.getURI()) ? assertedProperties.get(property.getURI()) :
81: createAssertionForStatement(statement);
82: final Optional<Value<?>> value = resolveValue(a, statement.getObject());
83: value.ifPresent(v -> axioms.add(new AxiomImpl<>(descriptor.getSubject(), a, v)));
84: }
85: return axioms;
86: }
87:
88: private boolean shouldSkipProperty(Property property, AxiomDescriptor descriptor) {
89: final String propertyUri = property.getURI();
90: // If the property is not mapped and either there is not the unspecified property or the property is rdf:type,
91: // which is handled by Types
92: if (!assertedProperties.containsKey(propertyUri) && (unspecifiedProperty == null || propertyUri
93: .equals(Vocabulary.RDF_TYPE))) {
94: return true;
95: }
96: final Assertion a = assertedProperties.getOrDefault(propertyUri, unspecifiedProperty);
97: return !assertionContextMatchesSubject(descriptor.getSubjectContexts(), descriptor.getAssertionContexts(a));
98: }
99:
100: private List<Axiom<?>> loadAxiomsForPropertiesInContext(AxiomDescriptor descriptor, Resource subject) {
101: final List<Axiom<?>> axioms = new ArrayList<>();
102: for (Assertion a : assertedProperties.values()) {
103: final Set<URI> assertionCtx = descriptor.getAssertionContexts(a);
104: if (assertionContextMatchesSubject(descriptor.getSubjectContexts(), assertionCtx)) {
105: continue;
106: }
107: final Property property = ResourceFactory.createProperty(a.getIdentifier().toString());
108: final Collection<Statement> statements = findStatements(subject, property, assertionCtx);
109: statements.forEach(statement -> {
110: final Optional<Value<?>> value = resolveValue(a, statement.getObject());
111: value.ifPresent(v -> axioms.add(new AxiomImpl<>(descriptor.getSubject(), a, v)));
112: });
113: }
114: if (unspecifiedProperty != null && !assertionContextMatchesSubject(descriptor.getSubjectContexts(),
115: descriptor.getAssertionContexts(unspecifiedProperty))) {
116: final Collection<Statement> statements =
117: findStatements(subject, null, descriptor.getAssertionContexts(unspecifiedProperty));
118: for (Statement s : statements) {
119: final Assertion a = createAssertionForStatement(s);
120: final Optional<Value<?>> value = resolveValue(a, s.getObject());
121: value.ifPresent(v -> axioms.add(new AxiomImpl<>(descriptor.getSubject(), a, v)));
122: }
123: }
124: return axioms;
125: }
126:
127: private static boolean assertionContextMatchesSubject(Set<URI> subjectCtx, Set<URI> assertionCtx) {
128: return (subjectCtx.isEmpty() && assertionCtx.isEmpty()) ||
129: (!subjectCtx.isEmpty() && assertionCtx.stream().anyMatch(subjectCtx::contains));
130: }
131: }