Skip to content

Method: getQueryExecutor()

1: /**
2: * Copyright (C) 2022 Czech Technical University in Prague
3: * <p>
4: * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
5: * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
6: * version.
7: * <p>
8: * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
9: * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
10: * details. You should have received a copy of the GNU General Public License along with this program. If not, see
11: * <http://www.gnu.org/licenses/>.
12: */
13: package cz.cvut.kbss.ontodriver.sesame;
14:
15: import cz.cvut.kbss.ontodriver.Closeable;
16: import cz.cvut.kbss.ontodriver.Wrapper;
17: import cz.cvut.kbss.ontodriver.descriptor.*;
18: import cz.cvut.kbss.ontodriver.exception.IdentifierGenerationException;
19: import cz.cvut.kbss.ontodriver.exception.OntoDriverException;
20: import cz.cvut.kbss.ontodriver.model.Axiom;
21: import cz.cvut.kbss.ontodriver.sesame.config.Constants;
22: import cz.cvut.kbss.ontodriver.sesame.config.RuntimeConfiguration;
23: import cz.cvut.kbss.ontodriver.sesame.connector.Connector;
24: import cz.cvut.kbss.ontodriver.sesame.connector.StatementExecutor;
25: import cz.cvut.kbss.ontodriver.sesame.exceptions.SesameDriverException;
26: import cz.cvut.kbss.ontodriver.sesame.util.SesameUtils;
27: import cz.cvut.kbss.ontodriver.util.IdentifierUtils;
28: import cz.cvut.kbss.ontodriver.util.Transaction;
29: import org.eclipse.rdf4j.model.Resource;
30: import org.eclipse.rdf4j.model.Value;
31: import org.eclipse.rdf4j.model.ValueFactory;
32: import org.eclipse.rdf4j.model.vocabulary.RDF;
33:
34: import java.net.URI;
35: import java.util.*;
36: import java.util.stream.Collectors;
37:
38: import static cz.cvut.kbss.ontodriver.sesame.util.SesameUtils.toSesameIri;
39:
40: class SesameAdapter implements Closeable, Wrapper {
41:
42: /**
43: * Maximum number of attempts to generate a unique identifier
44: */
45: private static final int ID_GENERATION_THRESHOLD = 64;
46:
47: private final Connector connector;
48: private final ValueFactory valueFactory;
49: private final RuntimeConfiguration config;
50: private final Transaction transaction;
51:
52: private boolean open = true;
53:
54: public SesameAdapter(Connector connector, RuntimeConfiguration config) {
55: assert connector != null;
56:
57: this.connector = connector;
58: this.valueFactory = connector.getValueFactory();
59: this.config = config;
60: this.transaction = new Transaction();
61: }
62:
63: Connector getConnector() {
64: return connector;
65: }
66:
67: ValueFactory getValueFactory() {
68: return valueFactory;
69: }
70:
71: RuntimeConfiguration getConfig() {
72: return config;
73: }
74:
75: @Override
76: public void close() throws OntoDriverException {
77: if (!open) {
78: return;
79: }
80: try {
81: connector.close();
82: } finally {
83: this.open = false;
84: }
85: }
86:
87: @Override
88: public boolean isOpen() {
89: return open;
90: }
91:
92: void commit() throws SesameDriverException {
93: if (transaction.isActive()) {
94: transaction.commit();
95: connector.commit();
96: transaction.afterCommit();
97: }
98: }
99:
100: void rollback() throws SesameDriverException {
101: if (transaction.isActive()) {
102: transaction.rollback();
103: connector.rollback();
104: transaction.afterRollback();
105: }
106: }
107:
108: boolean isConsistent(URI context) {
109: // Sesame currently doesn't support any consistency checking
110: // functionality
111: return true;
112: }
113:
114: List<URI> getContexts() throws SesameDriverException {
115: final List<Resource> contextIds = connector.getContexts();
116: final List<URI> contexts = new ArrayList<>(contextIds.size());
117: for (Resource res : contextIds) {
118: final URI context = SesameUtils.toJavaUri(res);
119: // We support only named contexts (no blank nodes)
120: if (context != null) {
121: contexts.add(context);
122: }
123: }
124: return contexts;
125: }
126:
127: URI generateIdentifier(URI classUri) throws SesameDriverException {
128: startTransactionIfNotActive();
129: boolean unique = false;
130: URI id = null;
131: int counter = 0;
132: while (!unique && counter++ < ID_GENERATION_THRESHOLD) {
133: id = IdentifierUtils.generateIdentifier(classUri);
134: unique = isIdentifierUnique(id, classUri);
135: }
136: if (!unique) {
137: throw new IdentifierGenerationException("Unable to generate a unique identifier.");
138: }
139: return id;
140:
141: }
142:
143: private void startTransactionIfNotActive() throws SesameDriverException {
144: if (!transaction.isActive()) {
145: connector.begin();
146: transaction.begin();
147: }
148: }
149:
150: private boolean isIdentifierUnique(URI identifier, URI classUri) throws SesameDriverException {
151: return !connector.containsStatement(
152: toSesameIri(identifier, valueFactory), RDF.TYPE,
153: toSesameIri(classUri, valueFactory), true, Collections.emptySet());
154: }
155:
156: boolean contains(Axiom<?> axiom, Set<URI> contexts) throws SesameDriverException {
157: startTransactionIfNotActive();
158: Value value;
159: if (SesameUtils.isResourceIdentifier(axiom.getValue().getValue())) {
160: value = valueFactory.createIRI(axiom.getValue().stringValue());
161: } else {
162: final String lang =
163: axiom.getAssertion().hasLanguage() ? axiom.getAssertion().getLanguage() : Constants.DEFAULT_LANG;
164: value = SesameUtils.createLiteral(axiom.getValue().getValue(), lang, valueFactory);
165: }
166: return connector.containsStatement(
167: toSesameIri(axiom.getSubject().getIdentifier(), valueFactory),
168: toSesameIri(axiom.getAssertion().getIdentifier(), valueFactory), value,
169: axiom.getAssertion().isInferred(),
170: contexts.stream().map(c -> toSesameIri(c, valueFactory)).collect(Collectors.toSet()));
171:
172: }
173:
174: Collection<Axiom<?>> find(AxiomDescriptor axiomDescriptor) throws SesameDriverException {
175: startTransactionIfNotActive();
176: return new AxiomLoader(connector, config).loadAxioms(axiomDescriptor);
177: }
178:
179: void persist(AxiomValueDescriptor axiomDescriptor) throws SesameDriverException {
180: startTransactionIfNotActive();
181: new AxiomSaver(connector).persistAxioms(axiomDescriptor);
182: }
183:
184: void update(AxiomValueDescriptor axiomDescriptor) throws SesameDriverException {
185: startTransactionIfNotActive();
186: new EpistemicAxiomRemover(connector, valueFactory).remove(axiomDescriptor);
187: new AxiomSaver(connector).persistAxioms(axiomDescriptor);
188: }
189:
190: void remove(AxiomDescriptor axiomDescriptor) throws SesameDriverException {
191: startTransactionIfNotActive();
192: new EpistemicAxiomRemover(connector, valueFactory).remove(axiomDescriptor);
193: }
194:
195: StatementExecutor getQueryExecutor() {
196: return connector;
197: }
198:
199: ListHandler<SimpleListDescriptor, SimpleListValueDescriptor> getSimpleListHandler() throws SesameDriverException {
200: startTransactionIfNotActive();
201: return ListHandler.createForSimpleList(connector, valueFactory);
202: }
203:
204: ListHandler<ReferencedListDescriptor, ReferencedListValueDescriptor> getReferencedListHandler() throws
205: SesameDriverException {
206: startTransactionIfNotActive();
207: return ListHandler.createForReferencedList(connector, valueFactory);
208: }
209:
210: TypesHandler getTypesHandler() throws SesameDriverException {
211: startTransactionIfNotActive();
212: return new TypesHandler(connector, valueFactory);
213: }
214:
215: @Override
216: public <T> T unwrap(Class<T> cls) throws OntoDriverException {
217: if (cls.isAssignableFrom(this.getClass())) {
218: return cls.cast(this);
219: } else if (cls.isAssignableFrom(valueFactory.getClass())) {
220: return cls.cast(valueFactory);
221: }
222: return connector.unwrap(cls);
223: }
224: }