Package: ChangeTrackingStorageConnector
ChangeTrackingStorageConnector
name | instruction | branch | complexity | line | method | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ChangeTrackingStorageConnector(AbstractStorageConnector) |
|
|
|
|
|
||||||||||||||||||||
add(List, String) |
|
|
|
|
|
||||||||||||||||||||
begin() |
|
|
|
|
|
||||||||||||||||||||
close() |
|
|
|
|
|
||||||||||||||||||||
commit() |
|
|
|
|
|
||||||||||||||||||||
contains(Resource, Property, RDFNode, Collection) |
|
|
|
|
|
||||||||||||||||||||
executeAskQuery(Query, Statement.StatementOntology) |
|
|
|
|
|
||||||||||||||||||||
executeSelectQuery(Query, Statement.StatementOntology) |
|
|
|
|
|
||||||||||||||||||||
executeUpdate(String, Statement.StatementOntology) |
|
|
|
|
|
||||||||||||||||||||
find(Resource, Property, RDFNode, Collection) |
|
|
|
|
|
||||||||||||||||||||
getContexts() |
|
|
|
|
|
||||||||||||||||||||
lambda$mergeAddedStatements$1(Dataset, String) |
|
|
|
|
|
||||||||||||||||||||
lambda$mergeRemovedStatements$0(Dataset, String) |
|
|
|
|
|
||||||||||||||||||||
mergeAddedStatements() |
|
|
|
|
|
||||||||||||||||||||
mergeRemovedStatements() |
|
|
|
|
|
||||||||||||||||||||
remove(List, String) |
|
|
|
|
|
||||||||||||||||||||
remove(Resource, Property, RDFNode, String) |
|
|
|
|
|
||||||||||||||||||||
removePropertyValues(Collection) |
|
|
|
|
|
||||||||||||||||||||
rollback() |
|
|
|
|
|
||||||||||||||||||||
unwrap(Class) |
|
|
|
|
|
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.*;
27:
28: import java.util.*;
29:
30: /**
31: * This connector tracks transactional changes and writes them on commit to the {@link SharedStorageConnector}.
32: */
33: public class ChangeTrackingStorageConnector extends AbstractStorageConnector {
34:
35: private final AbstractStorageConnector centralConnector;
36:
37: private final boolean useDefaultAsUnion;
38:
39: private LocalModel localModel;
40:
41: ChangeTrackingStorageConnector(AbstractStorageConnector centralConnector) {
42: super(centralConnector.configuration);
43: this.centralConnector = centralConnector;
44:• this.useDefaultAsUnion =
45:• configuration != null && configuration.is(JenaConfigParam.TREAT_DEFAULT_GRAPH_AS_UNION);
46: }
47:
48: @Override
49: public void begin() {
50: transaction.begin();
51: this.localModel = new LocalModel(useDefaultAsUnion);
52: }
53:
54: @Override
55: public void commit() throws JenaDriverException {
56: transaction.commit();
57: try {
58: centralConnector.begin();
59: mergeRemovedStatements();
60: mergeAddedStatements();
61: centralConnector.commit();
62: transaction.afterCommit();
63: } catch (JenaDriverException e) {
64: transaction.rollback();
65: centralConnector.rollback();
66: transaction.afterRollback();
67: throw e;
68: } finally {
69: this.localModel = null;
70: }
71: }
72:
73: private void mergeRemovedStatements() {
74: final Dataset removed = localModel.getRemoved();
75: centralConnector.remove(removed.getDefaultModel().listStatements().toList(), null);
76: removed.listNames().forEachRemaining(context -> {
77: final Model model = removed.getNamedModel(context);
78: centralConnector.remove(model.listStatements().toList(), context);
79: });
80: centralConnector.removePropertyValues(localModel.getRemovedSubjectPredicateStatements());
81: }
82:
83: private void mergeAddedStatements() {
84: final Dataset added = localModel.getAdded();
85: centralConnector.add(added.getDefaultModel().listStatements().toList(), null);
86: added.listNames().forEachRemaining(context -> {
87: final Model model = added.getNamedModel(context);
88: centralConnector.add(model.listStatements().toList(), context);
89: });
90: }
91:
92: @Override
93: public void rollback() {
94: transaction.rollback();
95: this.localModel = null;
96: transaction.afterRollback();
97: }
98:
99: @Override
100: public Collection<Statement> find(Resource subject, Property property, RDFNode value, Collection<String> contexts) {
101: transaction.verifyActive();
102: final Collection<Statement> existing = centralConnector.find(subject, property, value, contexts);
103: return localModel.enhanceStatements(existing, subject, property, value, contexts);
104: }
105:
106: @Override
107: public boolean contains(Resource subject, Property property, RDFNode value, Collection<String> contexts) {
108: transaction.verifyActive();
109: final LocalModel.Containment localStatus = localModel.contains(subject, property, value, contexts);
110:• return localStatus == LocalModel.Containment.ADDED ||
111: localStatus == LocalModel.Containment.UNKNOWN &&
112:• centralConnector.contains(subject, property, value, contexts);
113: }
114:
115: @Override
116: public List<String> getContexts() {
117: transaction.verifyActive();
118: final List<String> centralContexts = centralConnector.getContexts();
119: final Set<String> set = new LinkedHashSet<>(centralContexts);
120: set.addAll(localModel.getContexts());
121: return new ArrayList<>(set);
122: }
123:
124: @Override
125: public void add(List<Statement> statements, String context) {
126: transaction.verifyActive();
127: localModel.addStatements(statements, context);
128: }
129:
130: @Override
131: public void remove(List<Statement> statements, String context) {
132: transaction.verifyActive();
133: localModel.removeStatements(statements, context);
134: }
135:
136: @Override
137: public void remove(Resource subject, Property property, RDFNode object, String context) {
138: transaction.verifyActive();
139:• localModel.removeStatements(new ArrayList<>(find(subject, property, object, context != null ? Collections.singleton(context) : Collections.emptySet())), context);
140: }
141:
142: @Override
143: public void removePropertyValues(Collection<SubjectPredicateContext> spc) {
144: transaction.verifyActive();
145: localModel.removePropertyValues(spc);
146: }
147:
148: @Override
149: public AbstractResultSet executeSelectQuery(Query query, StatementOntology target) throws JenaDriverException {
150: Objects.requireNonNull(query);
151: // Since query results are not enhanced with transactional changes, do not require an active transaction
152: return centralConnector.executeSelectQuery(query, target);
153: }
154:
155: @Override
156: public AbstractResultSet executeAskQuery(Query query, StatementOntology target) throws JenaDriverException {
157: Objects.requireNonNull(query);
158: // Since query results are not enhanced with transactional changes, do not require an active transaction
159: return centralConnector.executeAskQuery(query, target);
160: }
161:
162: @Override
163: public void executeUpdate(String query, StatementOntology target) throws JenaDriverException {
164: Objects.requireNonNull(query);
165: // SPARQL Update queries have their own executor in Jena, so let them transcend the transactional boundaries
166: centralConnector.executeUpdate(query, target);
167: }
168:
169: @Override
170: public synchronized void close() {
171:• if (transaction.isActive()) {
172: rollback();
173: }
174: super.close();
175: }
176:
177: @Override
178: public <T> T unwrap(Class<T> cls) {
179: return centralConnector.unwrap(cls);
180: }
181: }