Skip to content

Package: SnapshotStorageConnector

SnapshotStorageConnector

nameinstructionbranchcomplexitylinemethod
SnapshotStorageConnector(AbstractStorageConnector)
M: 0 C: 8
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
add(List, String)
M: 0 C: 13
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
applyAdditions()
M: 0 C: 19
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
applyRemovals()
M: 0 C: 19
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
applyTransactionUpdateQueries()
M: 0 C: 18
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
begin()
M: 0 C: 31
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 8
100%
M: 0 C: 1
100%
cleanup()
M: 0 C: 10
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
commit()
M: 0 C: 23
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 10
100%
M: 0 C: 1
100%
contains(Resource, Property, RDFNode, Collection)
M: 0 C: 22
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
executeAskQuery(Query, Statement.StatementOntology)
M: 0 C: 19
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
executeSelectQuery(Query, Statement.StatementOntology)
M: 0 C: 19
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
executeUpdate(String, Statement.StatementOntology)
M: 16 C: 25
61%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 2 C: 8
80%
M: 0 C: 1
100%
find(Resource, Property, RDFNode, Collection)
M: 0 C: 28
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 6
100%
M: 0 C: 1
100%
getContexts()
M: 0 C: 20
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
lambda$applyAdditions$1(Dataset, String)
M: 0 C: 10
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$applyRemovals$0(Dataset, String)
M: 0 C: 10
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$contains$3(Resource, Property, RDFNode, String)
M: 0 C: 9
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$find$2(Resource, Property, RDFNode, String)
M: 0 C: 10
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
remove(List, String)
M: 0 C: 13
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
remove(Resource, Property, RDFNode, String)
M: 0 C: 19
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
rollback()
M: 0 C: 11
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
snapshotCentralDataset()
M: 0 C: 16
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%

Coverage

1: /**
2: * Copyright (C) 2020 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.jena.connector;
14:
15: import cz.cvut.kbss.ontodriver.Statement.StatementOntology;
16: import cz.cvut.kbss.ontodriver.jena.config.JenaConfigParam;
17: import cz.cvut.kbss.ontodriver.jena.exception.JenaDriverException;
18: import cz.cvut.kbss.ontodriver.jena.query.AbstractResultSet;
19: import org.apache.jena.query.Dataset;
20: import org.apache.jena.query.Query;
21: import org.apache.jena.rdf.model.Property;
22: import org.apache.jena.rdf.model.RDFNode;
23: import org.apache.jena.rdf.model.Resource;
24: import org.apache.jena.rdf.model.Statement;
25: import org.apache.jena.update.UpdateAction;
26:
27: import java.util.*;
28: import java.util.stream.Collectors;
29:
30: /**
31: * This connector implements the {@link cz.cvut.kbss.ontodriver.jena.config.JenaOntoDriverProperties#SNAPSHOT}-based
32: * transactional strategy.
33: * <p>
34: * It is also used when inference is required from the driver.
35: */
36: public class SnapshotStorageConnector extends SharedStorageConnector {
37:
38: final AbstractStorageConnector centralConnector;
39:
40: private LocalModel transactionalChanges;
41: private List<String> transactionalUpdates;
42:
43: SnapshotStorageConnector(AbstractStorageConnector centralConnector) {
44: super(centralConnector.configuration);
45: this.centralConnector = centralConnector;
46: }
47:
48: @Override
49: public void begin() {
50: ensureOpen();
51:• if (transaction.isActive()) {
52: throw new IllegalStateException("Transaction is already active.");
53: }
54: transaction.begin();
55: snapshotCentralDataset();
56: this.transactionalUpdates = new ArrayList<>();
57: this.transactionalChanges = new LocalModel(configuration.is(JenaConfigParam.TREAT_DEFAULT_GRAPH_AS_UNION));
58: }
59:
60: void snapshotCentralDataset() {
61: final SnapshotStorage s = new SnapshotStorage(configuration);
62: s.addCentralData(centralConnector.getStorage().getDataset());
63: this.storage = s;
64: }
65:
66: @Override
67: public void commit() throws JenaDriverException {
68: ensureTransactionalState();
69: transaction.commit();
70: try {
71: centralConnector.begin();
72: applyRemovals();
73: applyAdditions();
74: applyTransactionUpdateQueries();
75: centralConnector.commit();
76: } finally {
77: cleanup();
78: transaction.afterCommit();
79: }
80:
81: }
82:
83: private void applyRemovals() {
84: final Dataset removed = transactionalChanges.getRemoved();
85: centralConnector.remove(removed.getDefaultModel().listStatements().toList(), null);
86: removed.listNames()
87: .forEachRemaining(n -> centralConnector.remove(removed.getNamedModel(n).listStatements().toList(), n));
88: }
89:
90: private void applyAdditions() {
91: final Dataset added = transactionalChanges.getAdded();
92: centralConnector.add(added.getDefaultModel().listStatements().toList(), null);
93: added.listNames()
94: .forEachRemaining(n -> centralConnector.add(added.getNamedModel(n).listStatements().toList(), n));
95: }
96:
97: private void applyTransactionUpdateQueries() throws JenaDriverException {
98:• for (String query : transactionalUpdates) {
99: centralConnector.executeUpdate(query, StatementOntology.CENTRAL);
100: }
101: }
102:
103: @Override
104: public void rollback() {
105: ensureTransactionalState();
106: transaction.rollback();
107: cleanup();
108: transaction.afterRollback();
109: }
110:
111: private void cleanup() {
112: this.storage = null;
113: this.transactionalChanges = null;
114: this.transactionalUpdates = null;
115: }
116:
117: @Override
118: public List<Statement> find(Resource subject, Property property, RDFNode value, Collection<String> contexts) {
119: ensureTransactionalState();
120:• if (contexts.isEmpty()) {
121: return storage.getDefaultGraph().listStatements(subject, property, value).toList();
122: } else {
123: return contexts.stream()
124: .map(ctx -> storage.getNamedGraph(ctx).listStatements(subject, property, value).toList())
125: .flatMap(Collection::stream).collect(Collectors.toList());
126: }
127: }
128:
129: @Override
130: public boolean contains(Resource subject, Property property, RDFNode value, Collection<String> contexts) {
131: ensureTransactionalState();
132:• if (contexts.isEmpty()) {
133: return storage.getDefaultGraph().contains(subject, property, value);
134: } else {
135: return contexts.stream().anyMatch(c -> storage.getNamedGraph(c).contains(subject, property, value));
136: }
137: }
138:
139: @Override
140: public List<String> getContexts() {
141: ensureTransactionalState();
142: final Iterator<String> contexts = storage.getDataset().listNames();
143: final List<String> result = new ArrayList<>();
144: contexts.forEachRemaining(result::add);
145: return result;
146: }
147:
148: @Override
149: public void add(List<Statement> statements, String context) {
150: ensureTransactionalState();
151: storage.add(statements, context);
152: transactionalChanges.addStatements(statements, context);
153: }
154:
155: @Override
156: public void remove(List<Statement> statements, String context) {
157: ensureTransactionalState();
158: storage.remove(statements, context);
159: transactionalChanges.removeStatements(statements, context);
160: }
161:
162: @Override
163: public void remove(Resource subject, Property property, RDFNode object, String context) {
164: ensureTransactionalState();
165:• final List<Statement> toRemove = find(subject, property, object,
166: context != null ? Collections.singleton(context) : Collections.emptySet());
167: remove(toRemove, context);
168: }
169:
170: @Override
171: public AbstractResultSet executeSelectQuery(Query query, StatementOntology target) throws JenaDriverException {
172: ensureOpen();
173:• if (target == StatementOntology.TRANSACTIONAL) {
174: transaction.verifyActive();
175: return super.executeSelectQuery(query, target);
176: } else {
177: return centralConnector.executeSelectQuery(query, target);
178: }
179: }
180:
181: @Override
182: public AbstractResultSet executeAskQuery(Query query, StatementOntology target) throws JenaDriverException {
183: ensureOpen();
184:• if (target == StatementOntology.TRANSACTIONAL) {
185: transaction.verifyActive();
186: return super.executeAskQuery(query, target);
187: } else {
188: return centralConnector.executeAskQuery(query, target);
189: }
190: }
191:
192: @Override
193: public void executeUpdate(String query, StatementOntology target) throws JenaDriverException {
194: ensureOpen();
195:• if (target == StatementOntology.TRANSACTIONAL) {
196: transaction.verifyActive();
197: try {
198: UpdateAction.parseExecute(query, storage.getDataset());
199: transactionalUpdates.add(query);
200: } catch (RuntimeException e) {
201: throw new JenaDriverException("Execution of update " + query + " failed.", e);
202: }
203: } else {
204: centralConnector.executeUpdate(query, target);
205: }
206: }
207: }