Skip to contentMethod: executeUpdate(String)
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.connector;
16:
17: import cz.cvut.kbss.ontodriver.exception.OntoDriverException;
18: import cz.cvut.kbss.ontodriver.sesame.exceptions.SesameDriverException;
19: import info.aduna.iteration.Iterations;
20: import org.openrdf.model.*;
21: import org.openrdf.query.TupleQueryResult;
22: import org.openrdf.repository.RepositoryConnection;
23: import org.openrdf.repository.RepositoryException;
24:
25: import java.util.Collection;
26: import java.util.List;
27: import java.util.concurrent.locks.Lock;
28: import java.util.concurrent.locks.ReentrantReadWriteLock;
29:
30: class PoolingStorageConnector extends AbstractConnector {
31:
32: private static final ReentrantReadWriteLock LOCK = new ReentrantReadWriteLock();
33: private static Lock READ = LOCK.readLock();
34: private static Lock WRITE = LOCK.writeLock();
35:
36: private final StorageConnector centralConnector;
37:
38: private RepositoryConnection connection;
39: private LocalModel localModel;
40:
41: PoolingStorageConnector(StorageConnector centralConnector) {
42: this.centralConnector = centralConnector;
43: this.open = true;
44: }
45:
46: @Override
47: public TupleQueryResult executeSelectQuery(String query) throws SesameDriverException {
48: if (transaction.isActive()) {
49: return new ConnectionStatementExecutor(wrapConnection()).executeSelectQuery(query);
50: }
51: READ.lock();
52: try {
53: return centralConnector.executeSelectQuery(query);
54: } finally {
55: READ.unlock();
56: }
57: }
58:
59: private RepositoryConnection wrapConnection() {
60: return new TransactionalRepositoryConnection(connection);
61: }
62:
63: @Override
64: public boolean executeBooleanQuery(String query) throws SesameDriverException {
65: if (transaction.isActive()) {
66: return new ConnectionStatementExecutor(wrapConnection()).executeBooleanQuery(query);
67: }
68: READ.lock();
69: try {
70: return centralConnector.executeBooleanQuery(query);
71: } finally {
72: READ.unlock();
73: }
74: }
75:
76: @Override
77: public void executeUpdate(String query) throws SesameDriverException {
78: WRITE.lock();
79: try {
80: centralConnector.executeUpdate(query);
81: } finally {
82: WRITE.unlock();
83: }
84: }
85:
86: @Override
87: public List<Resource> getContexts() throws SesameDriverException {
88: READ.lock();
89: try {
90: return centralConnector.getContexts();
91: } finally {
92: READ.unlock();
93: }
94: }
95:
96: @Override
97: public ValueFactory getValueFactory() {
98: // We don't need to lock the central connector, as getting the value
99: // factory does not require communication with the repository
100: return centralConnector.getValueFactory();
101: }
102:
103: @Override
104: public void begin() throws SesameDriverException {
105: super.begin();
106: this.localModel = new LocalModel();
107: this.connection = centralConnector.acquireConnection();
108: }
109:
110: @Override
111: public void commit() throws SesameDriverException {
112: transaction.commit();
113: WRITE.lock();
114: try {
115: centralConnector.begin();
116: centralConnector.removeStatements(localModel.getRemovedStatements());
117: centralConnector.addStatements(localModel.getAddedStatements());
118: centralConnector.commit();
119: transaction.afterCommit();
120: } catch (SesameDriverException e) {
121: transaction.rollback();
122: centralConnector.rollback();
123: transaction.afterRollback();
124: throw e;
125: } finally {
126: WRITE.unlock();
127: centralConnector.releaseConnection(connection);
128: this.localModel = null;
129: }
130: }
131:
132: @Override
133: public void rollback() throws SesameDriverException {
134: transaction.rollback();
135: this.localModel = null;
136: centralConnector.releaseConnection(connection);
137: transaction.afterRollback();
138: }
139:
140: @Override
141: public void close() throws OntoDriverException {
142: if (open && transaction.isActive()) {
143: this.localModel = null;
144: centralConnector.releaseConnection(connection);
145: }
146: super.close();
147: }
148:
149: @Override
150: public void addStatements(Collection<Statement> statements) {
151: verifyTransactionActive();
152: assert statements != null;
153: localModel.addStatements(statements);
154: }
155:
156: @Override
157: public void removeStatements(Collection<Statement> statements) throws SesameDriverException {
158: verifyTransactionActive();
159: assert statements != null;
160: localModel.removeStatements(statements);
161: }
162:
163: @Override
164: public Collection<Statement> findStatements(Resource subject, URI property, Value value,
165: boolean includeInferred, URI... contexts) throws SesameDriverException {
166: verifyTransactionActive();
167: try {
168: final Collection<Statement> statements = Iterations
169: .asList(connection.getStatements(subject, property, value, includeInferred, contexts));
170: localModel.enhanceStatements(statements, subject, property, value, contexts);
171: return statements;
172: } catch (RepositoryException e) {
173: rollback();
174: throw new SesameDriverException(e);
175: }
176: }
177:
178: @Override
179: public <T> T unwrap(Class<T> cls) throws OntoDriverException {
180: if (cls.isAssignableFrom(this.getClass())) {
181: return cls.cast(this);
182: }
183: return centralConnector.unwrap(cls);
184: }
185: }