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