Skip to contentMethod: startTransactionIfNotActive()
1: /**
2: * Copyright (C) 2016 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.sesame;
16:
17: import cz.cvut.kbss.ontodriver.Closeable;
18: import cz.cvut.kbss.ontodriver.Wrapper;
19: import cz.cvut.kbss.ontodriver.config.ConfigParam;
20: import cz.cvut.kbss.ontodriver.config.Configuration;
21: import cz.cvut.kbss.ontodriver.descriptor.*;
22: import cz.cvut.kbss.ontodriver.exception.IdentifierGenerationException;
23: import cz.cvut.kbss.ontodriver.exception.OntoDriverException;
24: import cz.cvut.kbss.ontodriver.model.Axiom;
25: import cz.cvut.kbss.ontodriver.sesame.connector.Connector;
26: import cz.cvut.kbss.ontodriver.sesame.connector.StatementExecutor;
27: import cz.cvut.kbss.ontodriver.sesame.exceptions.SesameDriverException;
28: import cz.cvut.kbss.ontodriver.sesame.util.SesameUtils;
29: import cz.cvut.kbss.ontodriver.util.IdentifierUtils;
30: import org.openrdf.model.Resource;
31: import org.openrdf.model.Statement;
32: import org.openrdf.model.Value;
33: import org.openrdf.model.ValueFactory;
34: import org.openrdf.model.vocabulary.RDF;
35:
36: import java.net.URI;
37: import java.util.ArrayList;
38: import java.util.Collection;
39: import java.util.List;
40:
41: class SesameAdapter implements Closeable, Wrapper {
42:
43: /**
44: * Maximum number of attempts to generate a unique identifier
45: */
46: private static final int ID_GENERATION_THRESHOLD = 64;
47:
48: private final Connector connector;
49: private final ValueFactory valueFactory;
50: private final String language;
51: private boolean open;
52: private final Transaction transaction;
53:
54: public SesameAdapter(Connector connector, Configuration configuration) {
55: assert connector != null;
56:
57: this.connector = connector;
58: this.valueFactory = connector.getValueFactory();
59: this.language = configuration.getProperty(ConfigParam.ONTOLOGY_LANGUAGE);
60: this.open = true;
61: this.transaction = new Transaction();
62: }
63:
64: Connector getConnector() {
65: return connector;
66: }
67:
68: ValueFactory getValueFactory() {
69: return valueFactory;
70: }
71:
72: String getLanguage() {
73: return language;
74: }
75:
76: @Override
77: public void close() throws OntoDriverException {
78: if (!open) {
79: return;
80: }
81: try {
82: connector.close();
83: } finally {
84: this.open = false;
85: }
86: }
87:
88: @Override
89: public boolean isOpen() {
90: return open;
91: }
92:
93: void commit() throws SesameDriverException {
94: if (transaction.isActive()) {
95: transaction.commit();
96: connector.commit();
97: transaction.afterCommit();
98: }
99: }
100:
101: void rollback() throws SesameDriverException {
102: if (transaction.isActive()) {
103: transaction.rollback();
104: connector.rollback();
105: transaction.afterRollback();
106: }
107: }
108:
109: boolean isConsistent(URI context) {
110: // Sesame currently doesn't support any consistency checking
111: // functionality
112: return true;
113: }
114:
115: List<URI> getContexts() throws SesameDriverException {
116: final List<Resource> contextIds = connector.getContexts();
117: final List<URI> contexts = new ArrayList<>(contextIds.size());
118: for (Resource res : contextIds) {
119: final URI context = SesameUtils.toJavaUri(res);
120: // We support only named contexts (no blank nodes)
121: if (context != null) {
122: contexts.add(context);
123: }
124: }
125: return contexts;
126: }
127:
128: URI generateIdentifier(URI classUri) throws SesameDriverException {
129: startTransactionIfNotActive();
130: boolean unique = false;
131: URI id = null;
132: int counter = 0;
133: while (!unique && counter++ < ID_GENERATION_THRESHOLD) {
134: id = IdentifierUtils.generateIdentifier(classUri);
135: unique = isIdentifierUnique(id, classUri);
136: }
137: if (!unique) {
138: throw new IdentifierGenerationException("Unable to generate a unique identifier.");
139: }
140: return id;
141:
142: }
143:
144: private void startTransactionIfNotActive() throws SesameDriverException {
145:• if (!transaction.isActive()) {
146: connector.begin();
147: transaction.begin();
148: }
149: }
150:
151: private boolean isIdentifierUnique(URI identifier, URI classUri) throws SesameDriverException {
152: final Collection<Statement> stmts = connector.findStatements(
153: SesameUtils.toSesameUri(identifier, valueFactory), RDF.TYPE,
154: SesameUtils.toSesameUri(classUri, valueFactory), true);
155: return stmts.isEmpty();
156: }
157:
158: boolean contains(Axiom<?> axiom, URI context) throws SesameDriverException {
159: startTransactionIfNotActive();
160: Value value;
161: if (SesameUtils.isResourceIdentifier(axiom.getValue().getValue())) {
162: value = valueFactory.createURI(axiom.getValue().stringValue());
163: } else {
164: value = SesameUtils.createDataPropertyLiteral(axiom.getValue().getValue(), language,
165: valueFactory);
166: }
167: final org.openrdf.model.URI sesameContext = SesameUtils.toSesameUri(context, valueFactory);
168: return !findStatements(
169: SesameUtils.toSesameUri(axiom.getSubject().getIdentifier(), valueFactory),
170: SesameUtils.toSesameUri(axiom.getAssertion().getIdentifier(), valueFactory), value,
171: axiom.getAssertion().isInferred(), sesameContext).isEmpty();
172: }
173:
174: private Collection<Statement> findStatements(Resource subject, org.openrdf.model.URI property, Value value,
175: boolean includeInferred, org.openrdf.model.URI context)
176: throws SesameDriverException {
177: if (context != null) {
178: return connector.findStatements(subject, property, value, includeInferred, context);
179: } else {
180: return connector.findStatements(subject, property, value, includeInferred);
181: }
182: }
183:
184: Collection<Axiom<?>> find(AxiomDescriptor axiomDescriptor) throws SesameDriverException {
185: startTransactionIfNotActive();
186: return new AxiomLoader(connector, valueFactory).loadAxioms(axiomDescriptor);
187: }
188:
189: void persist(AxiomValueDescriptor axiomDescriptor) throws SesameDriverException {
190: startTransactionIfNotActive();
191: new AxiomSaver(connector, valueFactory, language).persistAxioms(axiomDescriptor);
192: }
193:
194: void update(AxiomValueDescriptor axiomDescriptor) throws SesameDriverException {
195: startTransactionIfNotActive();
196: new EpistemicAxiomRemover(connector, valueFactory, language).remove(axiomDescriptor);
197: new AxiomSaver(connector, valueFactory, language).persistAxioms(axiomDescriptor);
198: }
199:
200: void remove(AxiomDescriptor axiomDescriptor) throws SesameDriverException {
201: startTransactionIfNotActive();
202: new EpistemicAxiomRemover(connector, valueFactory, language).remove(axiomDescriptor);
203: }
204:
205: StatementExecutor getQueryExecutor() {
206: return connector;
207: }
208:
209: ListHandler<SimpleListDescriptor, SimpleListValueDescriptor> getSimpleListHandler() throws SesameDriverException {
210: startTransactionIfNotActive();
211: return ListHandler.createForSimpleList(connector, valueFactory);
212: }
213:
214: ListHandler<ReferencedListDescriptor, ReferencedListValueDescriptor> getReferencedListHandler() throws
215: SesameDriverException {
216: startTransactionIfNotActive();
217: return ListHandler.createForReferencedList(connector, valueFactory);
218: }
219:
220: TypesHandler getTypesHandler() throws SesameDriverException {
221: startTransactionIfNotActive();
222: return new TypesHandler(connector, valueFactory);
223: }
224:
225: @Override
226: public <T> T unwrap(Class<T> cls) throws OntoDriverException {
227: if (cls.isAssignableFrom(this.getClass())) {
228: return cls.cast(this);
229: } else if (cls.isAssignableFrom(valueFactory.getClass())) {
230: return cls.cast(valueFactory);
231: }
232: return connector.unwrap(cls);
233: }
234: }