Skip to contentMethod: lambda$addTransactionalChanges$2(Collection, TransactionalChange)
1: /*
2: * JOPA
3: * Copyright (C) 2024 Czech Technical University in Prague
4: *
5: * This library is free software; you can redistribute it and/or
6: * modify it under the terms of the GNU Lesser General Public
7: * License as published by the Free Software Foundation; either
8: * version 3.0 of the License, or (at your option) any later version.
9: *
10: * This library is distributed in the hope that it will be useful,
11: * but WITHOUT ANY WARRANTY; without even the implied warranty of
12: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13: * Lesser General Public License for more details.
14: *
15: * You should have received a copy of the GNU Lesser General Public
16: * License along with this library.
17: */
18: package cz.cvut.kbss.ontodriver.owlapi;
19:
20: import cz.cvut.kbss.ontodriver.descriptor.AxiomDescriptor;
21: import cz.cvut.kbss.ontodriver.descriptor.AxiomValueDescriptor;
22: import cz.cvut.kbss.ontodriver.model.Axiom;
23: import cz.cvut.kbss.ontodriver.owlapi.change.TransactionalChange;
24: import cz.cvut.kbss.ontodriver.owlapi.connector.Connector;
25: import cz.cvut.kbss.ontodriver.owlapi.connector.OntologySnapshot;
26: import cz.cvut.kbss.ontodriver.owlapi.exception.OwlapiDriverException;
27: import cz.cvut.kbss.ontodriver.owlapi.list.ReferencedListHandler;
28: import cz.cvut.kbss.ontodriver.owlapi.list.SimpleListHandler;
29: import cz.cvut.kbss.ontodriver.owlapi.query.OwlapiPreparedStatement;
30: import cz.cvut.kbss.ontodriver.owlapi.query.OwlapiStatement;
31: import cz.cvut.kbss.ontodriver.owlapi.query.StatementExecutorFactory;
32: import cz.cvut.kbss.ontodriver.owlapi.util.IdentifierGenerator;
33: import org.semanticweb.owlapi.model.OWLAxiom;
34: import org.semanticweb.owlapi.model.OWLDataFactory;
35: import org.semanticweb.owlapi.model.OWLOntology;
36: import org.semanticweb.owlapi.reasoner.OWLReasoner;
37:
38: import java.net.URI;
39: import java.util.ArrayList;
40: import java.util.Collection;
41: import java.util.Collections;
42: import java.util.List;
43: import java.util.Set;
44:
45: /**
46: * Adapter between OntoDriver API and OWLAPI.
47: */
48: public class OwlapiAdapter {
49:
50: private final Connector connector;
51: private OntologySnapshot ontologySnapshot;
52:
53: private StatementExecutorFactory statementExecutorFactory;
54:
55: private TransactionState transactionState = TransactionState.INITIAL;
56: private List<TransactionalChange> pendingChanges = new ArrayList<>();
57:
58: private enum TransactionState {
59: INITIAL, RUNNING
60: }
61:
62: public OwlapiAdapter(Connector connector) {
63: this.connector = connector;
64: }
65:
66: private void startTransactionIfNotActive() {
67: if (transactionState == TransactionState.INITIAL) {
68: this.ontologySnapshot = connector.getOntologySnapshot();
69: this.transactionState = TransactionState.RUNNING;
70: this.statementExecutorFactory = new StatementExecutorFactory(ontologySnapshot, connector);
71: }
72: }
73:
74: void commit() {
75: if (transactionState != TransactionState.RUNNING) {
76: return;
77: }
78: if (!pendingChanges.isEmpty()) {
79: connector.applyChanges(pendingChanges);
80: this.pendingChanges = new ArrayList<>();
81: }
82: transactionCleanup();
83: }
84:
85: private void transactionCleanup() {
86: connector.closeSnapshot(ontologySnapshot);
87: this.ontologySnapshot = null;
88: this.transactionState = TransactionState.INITIAL;
89: }
90:
91: void rollback() {
92: if (transactionState != TransactionState.RUNNING) {
93: return;
94: }
95: if (!pendingChanges.isEmpty()) {
96: pendingChanges = new ArrayList<>();
97: }
98: transactionCleanup();
99: }
100:
101: boolean isConsistent(URI context) {
102: startTransactionIfNotActive();
103:
104: return reasoner().isConsistent();
105: }
106:
107: private OWLReasoner reasoner() {
108: return ontologySnapshot.getReasoner();
109: }
110:
111: private OWLOntology ontology() {
112: return ontologySnapshot.getOntology();
113: }
114:
115: private OWLDataFactory dataFactory() {
116: return ontologySnapshot.getDataFactory();
117: }
118:
119: List<URI> getContexts() {
120: startTransactionIfNotActive();
121: return Collections.singletonList(connector.getOntologyUri());
122: }
123:
124: boolean containsAxiom(Axiom<?> axiom, Set<URI> contexts) {
125: startTransactionIfNotActive();
126: final Collection<OWLAxiom> owlAxiom = asOwlAxioms(axiom);
127: boolean contains;
128: for (OWLAxiom ax : owlAxiom) {
129: if (axiom.getAssertion().isInferred()) {
130: contains = reasoner().isEntailed(ax);
131: } else {
132: contains = ontology().containsAxiom(ax);
133: }
134: if (contains) {
135: return true;
136: }
137: }
138: return false;
139: }
140:
141: boolean isInferred(Axiom<?> axiom, Set<URI> contexts) {
142: startTransactionIfNotActive();
143: final Collection<OWLAxiom> owlAxiom = asOwlAxioms(axiom);
144: reasoner().flush();
145: return owlAxiom.stream().anyMatch(a -> reasoner().isEntailed(a) && !ontology().containsAxiom(a));
146: }
147:
148: private Collection<OWLAxiom> asOwlAxioms(Axiom<?> axiom) {
149: final Collection<OWLAxiom> owlAxioms = new ArrayList<>(3);
150: final AxiomAdapter axiomAdapter = new AxiomAdapter(dataFactory());
151: switch (axiom.getAssertion().getType()) {
152: case CLASS:
153: owlAxioms.add(axiomAdapter.toOwlClassAssertionAxiom(axiom));
154: break;
155: case OBJECT_PROPERTY:
156: owlAxioms.add(axiomAdapter.toOwlObjectPropertyAssertionAxiom(axiom));
157: break;
158: case DATA_PROPERTY:
159: owlAxioms.add(axiomAdapter.toOwlDataPropertyAssertionAxiom(axiom));
160: break;
161: case ANNOTATION_PROPERTY:
162: owlAxioms.add(axiomAdapter.toOwlAnnotationPropertyAssertionAxiom(axiom));
163: break;
164: default:
165: owlAxioms.add(axiomAdapter.toOwlClassAssertionAxiom(axiom));
166: owlAxioms.add(axiomAdapter.toOwlObjectPropertyAssertionAxiom(axiom));
167: owlAxioms.add(axiomAdapter.toOwlDataPropertyAssertionAxiom(axiom));
168: owlAxioms.add(axiomAdapter.toOwlAnnotationPropertyAssertionAxiom(axiom));
169: break;
170: }
171: return owlAxioms;
172: }
173:
174: Collection<Axiom<?>> find(AxiomDescriptor descriptor) {
175: startTransactionIfNotActive();
176: return new MainAxiomLoader(this, ontologySnapshot).findAxioms(descriptor);
177: }
178:
179: void persist(AxiomValueDescriptor descriptor) {
180: startTransactionIfNotActive();
181: new AxiomSaver(this, ontologySnapshot).persist(descriptor);
182: }
183:
184: URI generateIdentifier(URI classUri) {
185: startTransactionIfNotActive();
186: return new IdentifierGenerator(ontology()).generateIdentifier(classUri);
187: }
188:
189: void update(AxiomValueDescriptor descriptor) {
190: startTransactionIfNotActive();
191: new EpistemicAxiomRemover(this, ontologySnapshot).remove(descriptor);
192: new AxiomSaver(this, ontologySnapshot).persist(descriptor);
193: }
194:
195: void remove(AxiomDescriptor descriptor) {
196: startTransactionIfNotActive();
197: new EpistemicAxiomRemover(this, ontologySnapshot).remove(descriptor);
198: }
199:
200: TypesHandler getTypesHandler() {
201: startTransactionIfNotActive();
202: return new TypesHandler(this, ontologySnapshot);
203: }
204:
205: PropertiesHandler getPropertiesHandler() {
206: startTransactionIfNotActive();
207: return new PropertiesHandler(this, ontologySnapshot);
208: }
209:
210: public void addTransactionalChanges(Collection<TransactionalChange> changes) {
211: pendingChanges.removeIf(tc -> changes.stream().anyMatch(toAdd -> toAdd.overrides(tc)));
212: pendingChanges.addAll(changes);
213: }
214:
215: public SimpleListHandler getSimpleListHandler() {
216: startTransactionIfNotActive();
217: return new SimpleListHandler(this, ontologySnapshot);
218: }
219:
220: public ReferencedListHandler getReferencedListHandler() {
221: startTransactionIfNotActive();
222: return new ReferencedListHandler(this, ontologySnapshot);
223: }
224:
225: public OwlapiStatement createStatement(OwlapiConnection connection) {
226: startTransactionIfNotActive();
227: return new OwlapiStatement(statementExecutorFactory, connection);
228: }
229:
230: public OwlapiPreparedStatement prepareStatement(String statement, OwlapiConnection connection) {
231: startTransactionIfNotActive();
232: return new OwlapiPreparedStatement(statementExecutorFactory, connection, statement);
233: }
234:
235: public <T> T unwrap(Class<T> cls) throws OwlapiDriverException {
236: startTransactionIfNotActive();
237: if (cls.isAssignableFrom(this.getClass())) {
238: return cls.cast(this);
239: } else if (cls.isAssignableFrom(OWLOntology.class)) {
240: return cls.cast(ontology());
241: } else if (cls.isAssignableFrom(OWLReasoner.class)) {
242: return cls.cast(reasoner());
243: }
244: throw new OwlapiDriverException("Unsupported type " + cls);
245: }
246: }