Skip to content

Method: lambda$removePropertyValues$6(SubjectPredicateContext)

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.config.DriverConfiguration;
22: import cz.cvut.kbss.ontodriver.jena.exception.JenaDriverException;
23: import cz.cvut.kbss.ontodriver.jena.query.AbstractResultSet;
24: import cz.cvut.kbss.ontodriver.jena.query.AskResultSet;
25: import cz.cvut.kbss.ontodriver.jena.query.SelectResultSet;
26: import org.apache.jena.query.Dataset;
27: import org.apache.jena.query.Query;
28: import org.apache.jena.query.QueryExecution;
29: import org.apache.jena.query.ReadWrite;
30: import org.apache.jena.rdf.model.Property;
31: import org.apache.jena.rdf.model.RDFNode;
32: import org.apache.jena.rdf.model.Resource;
33: import org.apache.jena.rdf.model.Statement;
34: import org.apache.jena.system.Txn;
35: import org.apache.jena.update.UpdateAction;
36:
37: import java.util.ArrayList;
38: import java.util.Collection;
39: import java.util.Iterator;
40: import java.util.List;
41: import java.util.stream.Collectors;
42:
43: /**
44: * Main storage connector using the {@link cz.cvut.kbss.ontodriver.jena.config.JenaOntoDriverProperties#READ_COMMITTED}
45: * connector strategy.
46: * <p>
47: * Adding statements to it actually adds them to the repository.
48: * <p>
49: * Note on transactions:
50: * <p>
51: * Starting a transaction on this connector also starts a write transaction on the underlying dataset. Commit then
52: * commits the transaction. Therefore, these transactions should be short. Reading can happen in parallel (as per Jena
53: * documentation).
54: */
55: public class SharedStorageConnector extends AbstractStorageConnector {
56:
57: SharedStorageConnector(DriverConfiguration configuration) {
58: super(configuration);
59: }
60:
61: @Override
62: void initialize() {
63: this.storage = Storage.create(configuration);
64: }
65:
66: @Override
67: public synchronized void begin() {
68: ensureOpen();
69: transaction.begin();
70: storage.begin(ReadWrite.WRITE);
71: }
72:
73: @Override
74: public synchronized void commit() throws JenaDriverException {
75: ensureTransactionalState();
76: transaction.commit();
77: storage.writeChanges();
78: storage.commit();
79: transaction.afterCommit();
80: }
81:
82: void ensureTransactionalState() {
83: ensureOpen();
84: transaction.verifyActive();
85: }
86:
87: @Override
88: public void rollback() {
89: ensureOpen();
90: transaction.rollback();
91: storage.rollback();
92: transaction.afterRollback();
93: }
94:
95: @Override
96: public Collection<Statement> find(Resource subject, Property property, RDFNode value, Collection<String> contexts) {
97: ensureOpen();
98: return Txn.calculateRead(storage.getTransactional(), () -> {
99: final List<Statement> result;
100: if (contexts.isEmpty()) {
101: result = storage.getDefaultGraph().listStatements(subject, property, value).toList();
102: } else {
103: result = contexts.stream()
104: .map(c -> storage.getNamedGraph(c).listStatements(subject, property, value).toList())
105: .flatMap(Collection::stream).collect(Collectors.toList());
106: }
107: return result;
108: });
109: }
110:
111: @Override
112: public boolean contains(Resource subject, Property property, RDFNode value, Collection<String> contexts) {
113: ensureOpen();
114: return Txn.calculateRead(storage.getTransactional(), () -> {
115: if (contexts.isEmpty()) {
116: return storage.getDefaultGraph().contains(subject, property, value);
117: } else {
118: return contexts.stream().anyMatch(c -> storage.getNamedGraph(c).contains(subject, property, value));
119: }
120: });
121: }
122:
123: @Override
124: public List<String> getContexts() {
125: ensureOpen();
126: final Iterator<String> it = Txn
127: .calculateRead(storage.getTransactional(), () -> storage.getDataset().listNames());
128: final List<String> contexts = new ArrayList<>();
129: it.forEachRemaining(contexts::add);
130: return contexts;
131: }
132:
133: @Override
134: public void add(List<Statement> statements, String context) {
135: ensureTransactionalState();
136: storage.add(statements, context);
137: }
138:
139: @Override
140: public void remove(List<Statement> statements, String context) {
141: ensureTransactionalState();
142: storage.remove(statements, context);
143: }
144:
145: @Override
146: public void remove(Resource subject, Property property, RDFNode object, String context) {
147: ensureTransactionalState();
148: if (context != null) {
149: storage.remove(storage.getNamedGraph(context).listStatements(subject, property, object), context);
150: } else {
151: storage.remove(storage.getDefaultGraph().listStatements(subject, property, object), null);
152: }
153: }
154:
155: @Override
156: public void removePropertyValues(Collection<SubjectPredicateContext> spc) {
157: ensureTransactionalState();
158: spc.forEach(s -> {
159:• if (s.getContexts().isEmpty()) {
160: storage.remove(storage.getDefaultGraph()
161: .listStatements(s.getSubject(), s.getPredicate(), (RDFNode) null), null);
162: } else {
163: s.getContexts().forEach(c -> storage.remove(storage.getNamedGraph(c)
164: .listStatements(s.getSubject(), s.getPredicate(), (RDFNode) null), c));
165: }
166: });
167: }
168:
169: @Override
170: public AbstractResultSet executeSelectQuery(Query query, StatementOntology target) throws JenaDriverException {
171: ensureOpen();
172: try {
173: QueryExecution exec = storage.prepareQuery(query);
174: final org.apache.jena.query.ResultSet rs = exec.execSelect();
175: // The QueryExecution is closed by the SelectResultSet (so that it has access to the results)
176: return new SelectResultSet(exec, rs);
177: } catch (RuntimeException e) {
178: throw queryFailed(query, e);
179: }
180: }
181:
182: private static JenaDriverException queryFailed(Object query, RuntimeException e) {
183: return new JenaDriverException("Execution of query " + query + " failed.", e);
184: }
185:
186: @Override
187: public AbstractResultSet executeAskQuery(Query query, StatementOntology target) throws JenaDriverException {
188: ensureOpen();
189: try (final QueryExecution exec = storage.prepareQuery(query)) {
190: return new AskResultSet(exec.execAsk());
191: } catch (RuntimeException e) {
192: throw queryFailed(query, e);
193: }
194: }
195:
196: @Override
197: public void executeUpdate(String query, StatementOntology target) throws JenaDriverException {
198: ensureOpen();
199: try {
200: UpdateAction.parseExecute(query, storage.getDataset());
201: } catch (RuntimeException e) {
202: throw queryFailed(query, e);
203: }
204: }
205:
206: @Override
207: public synchronized void close() {
208: if (!isOpen()) {
209: return;
210: }
211: if (storage != null) {
212: storage.close();
213: }
214: super.close();
215: }
216:
217: /**
218: * Reloads data from the underlying storage (if possible).
219: * <p>
220: * Note that this applies only to RDF file-based storage access, other storage do not support reloading.
221: */
222: public synchronized void reloadStorage() {
223: ensureOpen();
224: storage.reload();
225: }
226:
227: /**
228: * Sets new dataset on the underlying storage.
229: * <p>
230: * Note that this is supported only for in-memory storage.
231: *
232: * @param dataset The dataset to use
233: */
234: public synchronized void setDataset(Dataset dataset) {
235: ensureOpen();
236: storage.setDataset(dataset);
237: }
238: }