Skip to content

Commit ce9bd1a

Browse files
authored
GH-4866 add tests and fix for loading a persisted MemoryStore with RDF star triples (#4873)
2 parents 1d47c5a + d2dc80b commit ce9bd1a

File tree

5 files changed

+74
-7
lines changed

5 files changed

+74
-7
lines changed

core/rio/api/src/main/java/org/eclipse/rdf4j/rio/helpers/RDFStarUtil.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,30 @@ public static <T extends Value> T fromRDFEncodedValue(T encodedValue) {
7373
}
7474
}
7575

76+
/**
77+
* Converts the supplied value from an RDF-compatible representation to an RDF-star value.
78+
* <p>
79+
* See {@link #toRDFEncodedValue(Value)}.
80+
*
81+
* @param encodedValue an RDF {@link Value} to convert to RDF-star.
82+
* @param valueFactory the {@link ValueFactory} to use for parsing the triple.
83+
* @param <T>
84+
* @return the decoded RDF-star triple, if a {@link Triple} encoded as {@link IRI} was supplied, or the supplied
85+
* value otherwise.
86+
* @throws IllegalArgumentException if the supplied value looked like an RDF-star triple encoded as an IRI but it
87+
* could not be decoded successfully.
88+
*/
89+
public static <T extends Value> T fromRDFEncodedValue(T encodedValue, ValueFactory valueFactory) {
90+
try {
91+
return isEncodedTriple(encodedValue)
92+
? (T) NTriplesUtil.parseTriple(decode(
93+
encodedValue.stringValue().substring(TRIPLE_PREFIX.length())), valueFactory)
94+
: encodedValue;
95+
} catch (IllegalArgumentException e) {
96+
throw new IllegalArgumentException("Invalid RDF-star encoded triple: " + encodedValue);
97+
}
98+
}
99+
76100
/**
77101
* Checks if the supplied {@link Value} represents an RDF-star triple encoded as an IRI.
78102
*

core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/FileIO.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.eclipse.rdf4j.model.Namespace;
3636
import org.eclipse.rdf4j.model.Resource;
3737
import org.eclipse.rdf4j.model.Statement;
38+
import org.eclipse.rdf4j.model.Triple;
3839
import org.eclipse.rdf4j.model.Value;
3940
import org.eclipse.rdf4j.model.ValueFactory;
4041
import org.eclipse.rdf4j.model.util.Literals;
@@ -45,6 +46,7 @@
4546
import org.eclipse.rdf4j.sail.memory.model.MemIRI;
4647
import org.eclipse.rdf4j.sail.memory.model.MemResource;
4748
import org.eclipse.rdf4j.sail.memory.model.MemValue;
49+
import org.eclipse.rdf4j.sail.memory.model.MemValueFactory;
4850

4951
/**
5052
* Functionality to read and write MemoryStore to/from a file.
@@ -100,7 +102,7 @@ class FileIO {
100102
* Variables *
101103
*-----------*/
102104

103-
private final ValueFactory vf;
105+
private final MemValueFactory vf;
104106

105107
private final CharsetEncoder charsetEncoder = StandardCharsets.UTF_8.newEncoder();
106108

@@ -112,7 +114,7 @@ class FileIO {
112114
* Constructors *
113115
*--------------*/
114116

115-
public FileIO(ValueFactory vf) {
117+
public FileIO(MemValueFactory vf) {
116118
this.vf = vf;
117119
}
118120

@@ -320,7 +322,8 @@ private Value readValue(DataInputStream dataIn) throws IOException, ClassCastExc
320322
return vf.createLiteral(label, datatype);
321323
} else if (valueTypeMarker == RDFSTAR_TRIPLE_MARKER) {
322324
IRI rdfStarEncodedTriple = (IRI) readValue(dataIn);
323-
return RDFStarUtil.fromRDFEncodedValue(rdfStarEncodedTriple);
325+
Triple triple = (Triple) RDFStarUtil.fromRDFEncodedValue(rdfStarEncodedTriple, vf);
326+
return vf.getOrCreateMemTriple(triple);
324327
} else {
325328
throw new IOException("Invalid value type marker: " + valueTypeMarker);
326329
}

core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/MemoryStore.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.eclipse.rdf4j.sail.base.SailStore;
3333
import org.eclipse.rdf4j.sail.helpers.AbstractNotifyingSail;
3434
import org.eclipse.rdf4j.sail.helpers.DirectoryLockManager;
35+
import org.eclipse.rdf4j.sail.memory.model.MemValueFactory;
3536
import org.slf4j.Logger;
3637
import org.slf4j.LoggerFactory;
3738

@@ -286,7 +287,7 @@ protected void initializeInternal() throws SailException {
286287
SailSink explicit = store.getExplicitSailSource().sink(IsolationLevels.NONE);
287288
SailSink inferred = store.getInferredSailSource().sink(IsolationLevels.NONE);
288289
try {
289-
new FileIO(store.getValueFactory()).read(dataFile, explicit, inferred);
290+
new FileIO((MemValueFactory) store.getValueFactory()).read(dataFile, explicit, inferred);
290291
logger.debug("Data file read successfully");
291292
} catch (IOException e) {
292293
logger.error("Failed to read data file", e);
@@ -317,7 +318,8 @@ protected void initializeInternal() throws SailException {
317318
logger.debug("Initializing data file...");
318319
try (SailDataset explicit = store.getExplicitSailSource().dataset(IsolationLevels.SNAPSHOT);
319320
SailDataset inferred = store.getInferredSailSource().dataset(IsolationLevels.SNAPSHOT)) {
320-
new FileIO(store.getValueFactory()).write(explicit, inferred, syncFile, dataFile);
321+
new FileIO((MemValueFactory) store.getValueFactory()).write(explicit, inferred, syncFile,
322+
dataFile);
321323
}
322324
logger.debug("Data file initialized");
323325
} catch (IOException | SailException e) {
@@ -452,7 +454,8 @@ public void sync() throws SailException {
452454
IsolationLevels level = IsolationLevels.SNAPSHOT;
453455
try (SailDataset explicit = store.getExplicitSailSource().dataset(level);
454456
SailDataset inferred = store.getInferredSailSource().dataset(level)) {
455-
new FileIO(store.getValueFactory()).write(explicit, inferred, syncFile, dataFile);
457+
new FileIO((MemValueFactory) store.getValueFactory()).write(explicit, inferred, syncFile,
458+
dataFile);
456459
}
457460
contentsChanged = false;
458461
logger.debug("Data synced to file");

core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemValueFactory.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ public MemLiteral getOrCreateMemLiteral(Literal literal) {
378378
/**
379379
* See {@link #getOrCreateMemValue(Value)} for description.
380380
*/
381-
private MemTriple getOrCreateMemTriple(Triple triple) {
381+
public MemTriple getOrCreateMemTriple(Triple triple) {
382382
MemTriple memTriple = getMemTriple(triple);
383383

384384
if (memTriple == null) {
@@ -474,4 +474,8 @@ private Literal getSharedLiteral(MemLiteral newLiteral) {
474474
return literalRegistry.getOrAdd(newLiteral, () -> newLiteral);
475475
}
476476

477+
@Override
478+
public Triple createTriple(Resource subject, IRI predicate, Value object) {
479+
return getOrCreateMemTriple(super.createTriple(subject, predicate, object));
480+
}
477481
}

core/sail/memory/src/test/java/org/eclipse/rdf4j/sail/memory/StoreSerializationTest.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121
import org.eclipse.rdf4j.model.IRI;
2222
import org.eclipse.rdf4j.model.Literal;
2323
import org.eclipse.rdf4j.model.Statement;
24+
import org.eclipse.rdf4j.model.Triple;
2425
import org.eclipse.rdf4j.model.ValueFactory;
2526
import org.eclipse.rdf4j.model.vocabulary.RDF;
27+
import org.eclipse.rdf4j.model.vocabulary.RDFS;
2628
import org.eclipse.rdf4j.query.BindingSet;
2729
import org.eclipse.rdf4j.query.QueryEvaluationException;
2830
import org.eclipse.rdf4j.query.QueryLanguage;
@@ -171,4 +173,35 @@ public void testLongLiterals() {
171173
con.close();
172174
store.shutDown();
173175
}
176+
177+
@Test
178+
public void testMemTriple() {
179+
MemoryStore store = new MemoryStore(dataDir);
180+
store.init();
181+
182+
ValueFactory factory = store.getValueFactory();
183+
Triple triple = factory.createTriple(RDF.TYPE, RDF.TYPE, RDF.TYPE);
184+
Literal longLiteral = factory.createLiteral("a".repeat(4));
185+
186+
try (SailConnection con = store.getConnection()) {
187+
con.begin();
188+
con.addStatement(triple, RDFS.LABEL, longLiteral);
189+
con.commit();
190+
191+
}
192+
store.shutDown();
193+
194+
store = new MemoryStore(dataDir);
195+
store.init();
196+
197+
try (SailConnection con = store.getConnection()) {
198+
try (CloseableIteration<? extends Statement, SailException> iter = con.getStatements(null, RDFS.LABEL, null,
199+
false)) {
200+
assertTrue(iter.hasNext());
201+
Statement next = iter.next();
202+
assertEquals(next.getSubject(), triple);
203+
}
204+
}
205+
store.shutDown();
206+
}
174207
}

0 commit comments

Comments
 (0)