Skip to content

Commit

Permalink
Add a test to ensure that an empty list is returned from in case of s…
Browse files Browse the repository at this point in the history
…erialization error (JabRef#11189)
  • Loading branch information
Alexandre CREMIEUX authored and Alexandre CREMIEUX committed Jan 27, 2025
1 parent 16cfd2c commit 33f5cdf
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.jabref.logic.importer.fileformat.BibtexParser;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.BibEntryPreferences;
import org.jabref.model.entry.field.Field;
import org.jabref.model.entry.field.UnknownField;

import com.google.common.annotations.VisibleForTesting;
Expand All @@ -40,10 +41,20 @@ public class MVStoreBibEntryRelationDAO implements BibEntryRelationDAO {
private final String insertionTimeStampMapName;
private final MVStore.Builder storeConfiguration;
private final int storeTTLInDays;
private final MVMap.Builder<String, LinkedHashSet<BibEntry>> mapConfiguration =
new MVMap.Builder<String, LinkedHashSet<BibEntry>>().valueType(new BibEntryHashSetSerializer());
private final MVMap.Builder<String, LinkedHashSet<BibEntry>> mapConfiguration;

MVStoreBibEntryRelationDAO(Path path, String mapName, int storeTTLInDays) {
this(
path,
mapName,
storeTTLInDays,
new MVStoreBibEntryRelationDAO.BibEntryHashSetSerializer()
);
}

MVStoreBibEntryRelationDAO(
Path path, String mapName, int storeTTLInDays, BasicDataType<LinkedHashSet<BibEntry>> serializer
) {
try {
if (!Files.exists(path.getParent())) {
Files.createDirectories(path.getParent());
Expand All @@ -61,6 +72,7 @@ public class MVStoreBibEntryRelationDAO implements BibEntryRelationDAO {
.autoCommitDisabled()
.fileName(path.toAbsolutePath().toString());
this.storeTTLInDays = storeTTLInDays;
this.mapConfiguration = new MVMap.Builder<String, LinkedHashSet<BibEntry>>().valueType(serializer);
}

@Override
Expand Down Expand Up @@ -139,21 +151,23 @@ boolean isUpdatable(final BibEntry entry, final Clock clock) {
.orElse(true);
}

private static class BibEntrySerializer extends BasicDataType<BibEntry> {
static class BibEntrySerializer extends BasicDataType<BibEntry> {

private final List<Field> fieldsToRemoveFromSerializedEntry = List.of(new UnknownField("_jabref_shared"));

private static String toString(BibEntry entry) {
return entry.toString();
}

private static Optional<BibEntry> fromString(String serializedString) {
private static Optional<BibEntry> fromString(String serializedString, List<Field> fieldsToRemove) {
try {
var importFormatPreferences = new ImportFormatPreferences(
new BibEntryPreferences('$'), null, null, null, null, null
);
return BibtexParser
.singleFromString(serializedString, importFormatPreferences)
.map(entry -> {
entry.clearField(new UnknownField("_jabref_shared"));
fieldsToRemove.forEach(entry::clearField);
return entry;
});
} catch (ParseException e) {
Expand All @@ -179,7 +193,10 @@ public BibEntry read(ByteBuffer buff) {
int serializedEntrySize = buff.getInt();
var serializedEntry = new byte[serializedEntrySize];
buff.get(serializedEntry);
return fromString(new String(serializedEntry, StandardCharsets.UTF_8))
return fromString(
new String(serializedEntry, StandardCharsets.UTF_8),
this.fieldsToRemoveFromSerializedEntry
)
.orElse(new BibEntry());
}

Expand All @@ -202,9 +219,17 @@ public boolean isMemoryEstimationAllowed() {
}
}

private static class BibEntryHashSetSerializer extends BasicDataType<LinkedHashSet<BibEntry>> {
static class BibEntryHashSetSerializer extends BasicDataType<LinkedHashSet<BibEntry>> {

private final BasicDataType<BibEntry> bibEntryDataType;

private final BasicDataType<BibEntry> bibEntryDataType = new BibEntrySerializer();
BibEntryHashSetSerializer() {
this.bibEntryDataType = new BibEntrySerializer();
}

BibEntryHashSetSerializer(BasicDataType<BibEntry> bibEntryDataType) {
this.bibEntryDataType = bibEntryDataType;
}

@Override
public int getMemory(LinkedHashSet<BibEntry> bibEntries) {
Expand All @@ -226,6 +251,7 @@ public void write(WriteBuffer buff, LinkedHashSet<BibEntry> bibEntries) {
public LinkedHashSet<BibEntry> read(ByteBuffer buff) {
return IntStream.range(0, buff.getInt())
.mapToObj(it -> this.bibEntryDataType.read(buff))
.filter(entry -> !entry.isEmpty())
.collect(Collectors.toCollection(LinkedHashSet::new));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.jabref.logic.citation.repository;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Clock;
Expand Down Expand Up @@ -188,4 +189,29 @@ void isUpdatableShouldReturnFalseAfterOneWeekWhenTTLisSetTo30(BibEntry entry) th
);
Assertions.assertFalse(dao.isUpdatable(entry, clockOneWeekAfter));
}

@ParameterizedTest
@MethodSource("createBibEntries")
void deserializerErrorShouldReturnEmptyList(BibEntry entry) throws IOException {
// GIVEN
var serializer = new MVStoreBibEntryRelationDAO.BibEntryHashSetSerializer(
new MVStoreBibEntryRelationDAO.BibEntrySerializer() {
@Override
public BibEntry read(ByteBuffer buffer) {
// Fake the return after an exception
return new BibEntry();
}
}
);
var file = Files.createFile(temporaryFolder.resolve(TEMPORARY_FOLDER_NAME));
var dao = new MVStoreBibEntryRelationDAO(file.toAbsolutePath(), MAP_NAME, 7, serializer);
var relations = createRelations(entry);
dao.cacheOrMergeRelations(entry, relations);

// WHEN
var deserializedRelations = dao.getRelations(entry);

// THEN
Assertions.assertTrue(deserializedRelations.isEmpty());
}
}

0 comments on commit 33f5cdf

Please sign in to comment.