Verified Owner
Top Description Inners Fields Constructors Methods
org.jabref.logic.ai.summarization.migration

public final Class SummariesMigrationV1

extends Object
Class Inheritance
Imports
java.io.IOException, .InputStream, .ObjectInputStream, .ObjectStreamClass, java.nio.ByteBuffer, java.nio.file.Path, java.time.Instant, .LocalDateTime, .ZoneId, java.util.Map, .Optional, org.jabref.logic.ai.summarization.repositories.SummariesRepository, org.jabref.logic.l10n.Localization, org.jabref.logic.util.Directories, .NotificationService, org.jabref.model.ai.AiMetadata, org.jabref.model.ai.llm.AiProvider, org.jabref.model.ai.summarization.AiSummary, .AiSummaryIdentifier, .SummarizatorKind, org.jabref.model.database.BibDatabaseContext, org.h2.mvstore.MVMap, .MVStore, .WriteBuffer, org.h2.mvstore.type.BasicDataType, org.slf4j.Logger, .LoggerFactory

Migrates summaries from the old v1 MVStore file to the new v2 repository.

Old format (v1): Stored in "ai/1/summaries.mv" file. Map keys like "summaries-bibDatabasePath" containing Map<String, Summary> where Summary = record(LocalDateTime timestamp, AiProvider aiProvider, String model, String content) and AiProvider was at org.jabref.model.ai.AiProvider (now moved to org.jabref.model.ai.llm.AiProvider).

New format (v2): Stored in "ai/2/summaries.mv" file via repository. Uses AiSummaryIdentifier(libraryId, citationKey) to store AiSummary objects.

Problem: Both the Summary class and AiProvider enum no longer exist at their old paths, so MVStore's internal ObjectDataType fails with ClassNotFoundException before our code can intercept it.

Solution: Open the map with a custom RawBytesDataType that reads MVStore's binary page format and returns the raw Java-serialized bytes without invoking the standard ObjectInputStream. Then a ClassRemappingObjectInputStream deserializes those bytes while remapping the two deleted class names to current inner types.

Nested and Inner Type Summary

Modifier and TypeClass and Description
private static class
SummariesMigrationV1.ClassRemappingObjectInputStream

Custom ObjectInputStream that remaps the deleted/moved class names to current inner types, so that Java's serialization machinery can instantiate them from the raw bytes.

pack-priv static record
SummariesMigrationV1.OldSummary

Represents the old Summary format from v1.

pack-priv static class
SummariesMigrationV1.RawBytesDataType

Reads raw Java-serialized bytes from MVStore's binary page format without invoking Java deserialization.

Field Summary

Modifier and TypeField and Description
private static final Logger
private static final String
private static final String
private static final String
private static final String

Constructor Summary

AccessConstructor and Description
private

Method Summary

Modifier and TypeMethod and Description
private static AiSummary
pack-priv static Optional<SummariesMigrationV1.OldSummary>
deserializeOldSummary(byte[] data)

Deserializes old Summary using a custom ObjectInputStream that remaps the old AiProvider class.

public static void
migrate(BibDatabaseContext
The database context containing the AI library ID
bibDatabaseContext
,
SummariesRepository
The new v2 summaries repository
repository
,
NotificationService
Service for notifying user of errors
notificationService
)

Migrates old summary data from v1 file to v2 repository.

pack-priv static void
migrate(Path oldFilePath, String libraryId, Path bibDatabasePath, SummariesRepository repository, NotificationService notificationService)

Migrates old summary data from a given v1 MVStore file path to v2 repository.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

LOGGERback to summary
private static final Logger LOGGER
OLD_AI_PROVIDER_CLASSback to summary
private static final String OLD_AI_PROVIDER_CLASS
OLD_SUMMARIES_FILE_NAMEback to summary
private static final String OLD_SUMMARIES_FILE_NAME
OLD_SUMMARY_CLASSback to summary
private static final String OLD_SUMMARY_CLASS
SUMMARIES_MAP_PREFIXback to summary
private static final String SUMMARIES_MAP_PREFIX

Constructor Detail

SummariesMigrationV1back to summary
private SummariesMigrationV1()

Method Detail

convertToNewSummaryback to summary
private static AiSummary convertToNewSummary(SummariesMigrationV1.OldSummary oldSummary)
deserializeOldSummaryback to summary
pack-priv static Optional<SummariesMigrationV1.OldSummary> deserializeOldSummary(byte[] data)

Deserializes old Summary using a custom ObjectInputStream that remaps the old AiProvider class.

migrateback to summary
public static void migrate(BibDatabaseContext bibDatabaseContext, SummariesRepository repository, NotificationService notificationService)

Migrates old summary data from v1 file to v2 repository.

Parameters
bibDatabaseContext:BibDatabaseContext

The database context containing the AI library ID

repository:SummariesRepository

The new v2 summaries repository

notificationService:NotificationService

Service for notifying user of errors

migrateback to summary
pack-priv static void migrate(Path oldFilePath, String libraryId, Path bibDatabasePath, SummariesRepository repository, NotificationService notificationService)

Migrates old summary data from a given v1 MVStore file path to v2 repository. Package-private to allow direct use in tests without depending on Directories.

org.jabref.logic.ai.summarization.migration back to summary

private Class SummariesMigrationV1.ClassRemappingObjectInputStream

extends ObjectInputStream
Class Inheritance

Custom ObjectInputStream that remaps the deleted/moved class names to current inner types, so that Java's serialization machinery can instantiate them from the raw bytes.

Constructor Summary

AccessConstructor and Description
public

Method Summary

Modifier and TypeMethod and Description
protected ObjectStreamClass
readClassDescriptor()

Overrides java.io.ObjectInputStream.readClassDescriptor.

Read a class descriptor from the serialization stream.

Inherited from java.io.ObjectInputStream:
availableclosedefaultReadObjectenableResolveObjectgetObjectInputFilterreadreadreadBooleanreadBytereadCharreadDoublereadFieldsreadFloatreadFullyreadFullyreadIntreadLinereadLongreadObjectreadObjectOverridereadShortreadStreamHeaderreadUnsharedreadUnsignedBytereadUnsignedShortreadUTFregisterValidationresolveClassresolveObjectresolveProxyClasssetObjectInputFilterskipBytes

Constructor Detail

ClassRemappingObjectInputStreamback to summary
public ClassRemappingObjectInputStream(InputStream in) throws IOException

Method Detail

readClassDescriptorback to summary
protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException

Overrides java.io.ObjectInputStream.readClassDescriptor.

Doc from java.io.ObjectInputStream.readClassDescriptor.

Read a class descriptor from the serialization stream. This method is called when the ObjectInputStream expects a class descriptor as the next item in the serialization stream. Subclasses of ObjectInputStream may override this method to read in class descriptors that have been written in non-standard formats (by subclasses of ObjectOutputStream which have overridden the writeClassDescriptor method). By default, this method reads class descriptors according to the format defined in the Object Serialization specification.

Annotations
@Override
Exceptions
IOException:
If an I/O error has occurred.
ClassNotFoundException:
If the Class of a serialized object used in the class descriptor representation cannot be found
org.jabref.logic.ai.summarization.migration back to summary

pack-priv final Record SummariesMigrationV1.OldSummary

extends Record
implements Serializable
Class Inheritance
All Implemented Interfaces
java.io.Serializable
Record Components
timestamp:LocalDateTime 
aiProvider:AiProvider 
model:String 
content:String 

Represents the old Summary format from v1. This must match the structure of the old record.

Field Summary

Modifier and TypeField and Description
private final AiProvider
aiProvider

Record Component accessed by aiProvider().

private final String
content

Record Component accessed by content().

private final String
model

Record Component accessed by model().

private final LocalDateTime
timestamp

Record Component accessed by timestamp().

Constructor Summary

AccessConstructor and Description
pack-priv
OldSummary(LocalDateTime timestamp, AiProvider aiProvider, String model, String content)

Method Summary

Modifier and TypeMethod and Description
public AiProvider
aiProvider()

Record Component getter of aiProvider.

public String
content()

Record Component getter of content.

public final boolean
equals(Object o)

Implements abstract java.lang.Record.equals.

Indicates whether some other object is "equal to" this one.

public final int
hashCode()

Implements abstract java.lang.Record.hashCode.

Returns a hash code value for the record.

public String
model()

Record Component getter of model.

public LocalDateTime
timestamp()

Record Component getter of timestamp.

public final String
toString()

Implements abstract java.lang.Record.toString.

Returns a string representation of the record.

Field Detail

aiProviderback to summary
private final AiProvider aiProvider

Record Component accessed by aiProvider().

contentback to summary
private final String content

Record Component accessed by content().

modelback to summary
private final String model

Record Component accessed by model().

timestampback to summary
private final LocalDateTime timestamp

Record Component accessed by timestamp().

Constructor Detail

OldSummaryback to summary
pack-priv OldSummary(LocalDateTime timestamp, AiProvider aiProvider, String model, String content)

Method Detail

aiProviderback to summary
public AiProvider aiProvider()

Record Component getter of aiProvider.

contentback to summary
public String content()

Record Component getter of content.

equalsback to summary
public final boolean equals(Object o)

Implements abstract java.lang.Record.equals.

Doc from java.lang.Record.equals.

Indicates whether some other object is "equal to" this one. In addition to the general contract of Object.equals, record classes must further obey the invariant that when a record instance is "copied" by passing the result of the record component accessor methods to the canonical constructor, as follows:

    R copy = new R(r.c1(), r.c2(), ..., r.cn());
then it must be the case that r.equals(copy).
hashCodeback to summary
public final int hashCode()

Implements abstract java.lang.Record.hashCode.

Doc from java.lang.Record.hashCode.

Returns a hash code value for the record. Obeys the general contract of Object.hashCode. For records, hashing behavior is constrained by the refined contract of Record.equals, so that any two records created from the same components must have the same hash code.

modelback to summary
public String model()

Record Component getter of model.

timestampback to summary
public LocalDateTime timestamp()

Record Component getter of timestamp.

toStringback to summary
public final String toString()

Implements abstract java.lang.Record.toString.

Doc from java.lang.Record.toString.

Returns a string representation of the record. In accordance with the general contract of Object#toString(), the toString method returns a string that "textually represents" this record. The result should be a concise but informative representation that is easy for a person to read.

In addition to this general contract, record classes must further participate in the invariant that any two records which are equal must produce equal strings. This invariant is necessarily relaxed in the rare case where corresponding equal component values might fail to produce equal strings for themselves.

org.jabref.logic.ai.summarization.migration back to summary

pack-priv Class SummariesMigrationV1.RawBytesDataType

extends BasicDataType<byte[]>
Class Inheritance

Reads raw Java-serialized bytes from MVStore's binary page format without invoking Java deserialization. MVStore's ObjectDataType stores each serializable value as:

By returning the raw bytes we defer deserialization to ClassRemappingObjectInputStream, which can remap deleted/moved class names before they ever reach the class loader.

Field Summary

Modifier and TypeField and Description
private static final int

Constructor Summary

AccessConstructor and Description
pack-priv

Method Summary

Modifier and TypeMethod and Description
public byte[][]
createStorage(int size)

Implements org.h2.mvstore.type.DataType.createStorage.

Create storage object of array type to hold values

public int
getMemory(byte[] obj)

Implements abstract org.h2.mvstore.type.BasicDataType.getMemory.

Implements org.h2.mvstore.type.DataType.getMemory.

Calculates the amount of used memory in bytes.

public byte[]
read(ByteBuffer buff)

Implements abstract org.h2.mvstore.type.BasicDataType.read.

Implements org.h2.mvstore.type.DataType.read.

Read an object.

private static int
readVarInt(ByteBuffer buff)

Reads a variable-length encoded int from buff, using the same encoding that H2's DataUtils.readVarInt writes.

public void
write(WriteBuffer buff, byte[] obj)

Implements abstract org.h2.mvstore.type.BasicDataType.write.

Implements org.h2.mvstore.type.DataType.write.

Write an object.

Inherited from org.h2.mvstore.type.BasicDataType:
binarySearchcastcompareequalshashCodeisMemoryEstimationAllowedreadwrite

Field Detail

TYPE_SERIALIZED_OBJECTback to summary
private static final int TYPE_SERIALIZED_OBJECT

Constructor Detail

RawBytesDataTypeback to summary
pack-priv RawBytesDataType()

Method Detail

createStorageback to summary
public byte[][] createStorage(int size)

Implements org.h2.mvstore.type.DataType.createStorage.

Doc from org.h2.mvstore.type.DataType.createStorage.

Create storage object of array type to hold values

Annotations
@Override
getMemoryback to summary
public int getMemory(byte[] obj)

Implements abstract org.h2.mvstore.type.BasicDataType.getMemory.

Implements org.h2.mvstore.type.DataType.getMemory.

Doc from org.h2.mvstore.type.DataType.getMemory.

Calculates the amount of used memory in bytes.

Annotations
@Override
readback to summary
public byte[] read(ByteBuffer buff)

Implements abstract org.h2.mvstore.type.BasicDataType.read.

Implements org.h2.mvstore.type.DataType.read.

Doc from org.h2.mvstore.type.DataType.read.

Read an object.

Annotations
@Override
readVarIntback to summary
private static int readVarInt(ByteBuffer buff)

Reads a variable-length encoded int from buff, using the same encoding that H2's DataUtils.readVarInt writes. Implemented inline to avoid a dependency on whether org.h2.mvstore.DataUtils is exported by the H2 module.

writeback to summary
public void write(WriteBuffer buff, byte[] obj)

Implements abstract org.h2.mvstore.type.BasicDataType.write.

Implements org.h2.mvstore.type.DataType.write.

Doc from org.h2.mvstore.type.DataType.write.

Write an object.

Annotations
@Override