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.
| Modifier and Type | Class and Description |
|---|---|
| private static class | SummariesMigrationV1.
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.
Represents the old Summary format from v1. |
| pack-priv static class | SummariesMigrationV1.
Reads raw Java-serialized bytes from MVStore's binary page format without invoking Java deserialization. |
| Modifier and Type | Field and Description |
|---|---|
| private static final Logger | |
| private static final String | |
| private static final String | |
| private static final String | |
| private static final String |
| Access | Constructor and Description |
|---|---|
| private |
| Modifier and Type | Method and Description |
|---|---|
| private static AiSummary | |
| pack-priv static Optional | 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. |
| LOGGER | back to summary |
|---|---|
| private static final Logger LOGGER | |
| OLD_AI_PROVIDER_CLASS | back to summary |
|---|---|
| private static final String OLD_AI_PROVIDER_CLASS | |
| OLD_SUMMARIES_FILE_NAME | back to summary |
|---|---|
| private static final String OLD_SUMMARIES_FILE_NAME | |
| OLD_SUMMARY_CLASS | back to summary |
|---|---|
| private static final String OLD_SUMMARY_CLASS | |
| SUMMARIES_MAP_PREFIX | back to summary |
|---|---|
| private static final String SUMMARIES_MAP_PREFIX | |
| SummariesMigrationV1 | back to summary |
|---|---|
| private SummariesMigrationV1() | |
| convertToNewSummary | back to summary |
|---|---|
| private static AiSummary convertToNewSummary(SummariesMigrationV1. | |
| deserializeOldSummary | back to summary |
|---|---|
| pack-priv static Optional Deserializes old Summary using a custom ObjectInputStream that remaps the old AiProvider class. | |
| migrate | back to summary |
|---|---|
| public static void migrate(BibDatabaseContext bibDatabaseContext, SummariesRepository repository, NotificationService notificationService) Migrates old summary data from v1 file to v2 repository.
| |
| migrate | back 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 | |
| Access | Constructor and Description |
|---|---|
| public |
| Modifier and Type | Method and Description |
|---|---|
| protected ObjectStreamClass | readClassDescriptor()
Overrides java. Read a class descriptor from the serialization stream. |
| ClassRemappingObjectInputStream | back to summary |
|---|---|
| public ClassRemappingObjectInputStream(InputStream in) throws IOException | |
| readClassDescriptor | back to summary |
|---|---|
| protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException Overrides java. Doc from java. 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
| |
| Modifier and Type | Field and Description |
|---|---|
| private final AiProvider | aiProvider
Record Component accessed by aiProvider(). |
| private final String | |
| private final String | |
| private final LocalDateTime | timestamp
Record Component accessed by timestamp(). |
| Access | Constructor and Description |
|---|---|
| pack-priv |
| Modifier and Type | Method and Description |
|---|---|
| public AiProvider | |
| public String | |
| public final boolean | equals(Object o)
Implements abstract java. Indicates whether some other object is "equal to" this one. |
| public final int | |
| public String | |
| public LocalDateTime | |
| public final String | toString()
Implements abstract java. Returns a string representation of the record. |
| aiProvider | back to summary |
|---|---|
| private final AiProvider aiProvider Record Component accessed by aiProvider(). | |
| content | back to summary |
|---|---|
| private final String content Record Component accessed by content(). | |
| model | back to summary |
|---|---|
| private final String model Record Component accessed by model(). | |
| timestamp | back to summary |
|---|---|
| private final LocalDateTime timestamp Record Component accessed by timestamp(). | |
| OldSummary | back to summary |
|---|---|
| pack-priv OldSummary(LocalDateTime timestamp, AiProvider aiProvider, String model, String content) | |
| aiProvider | back to summary |
|---|---|
| public AiProvider aiProvider() Record Component getter of aiProvider. | |
| content | back to summary |
|---|---|
| public String content() Record Component getter of content. | |
| equals | back to summary |
|---|---|
| public final boolean equals(Object o) Implements abstract java. Doc from java. Indicates whether some other object is "equal to" this one. In addition
to the general contract of
R copy = new R(r.c1(), r.c2(), ..., r.cn());
then it must be the case that r.equals(copy).
| |
| hashCode | back to summary |
|---|---|
| public final int hashCode() Implements abstract java. Doc from java. Returns a hash code value for the record.
Obeys the general contract of | |
| model | back to summary |
|---|---|
| public String model() Record Component getter of model. | |
| timestamp | back to summary |
|---|---|
| public LocalDateTime timestamp() Record Component getter of timestamp. | |
| toString | back to summary |
|---|---|
| public final String toString() Implements abstract java. Doc from java. Returns a string representation of the record.
In accordance with the general contract of 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. | |
ObjectDataType stores each serializable value as:
19 (TYPE_SERIALIZED_OBJECT in H2 2.3.232)
0xACED 0x0005)
By returning the raw bytes we defer deserialization to ClassRemappingObjectInputStream,
which can remap deleted/moved class names before they ever reach the class loader.
| Modifier and Type | Field and Description |
|---|---|
| private static final int |
| Access | Constructor and Description |
|---|---|
| pack-priv |
| Modifier and Type | Method and Description |
|---|---|
| public byte[][] | createStorage(int size)
Implements org. Create storage object of array type to hold values |
| public int | getMemory(byte[] obj)
Implements abstract org. Implements org. Calculates the amount of used memory in bytes. |
| public byte[] | read(ByteBuffer buff)
Implements abstract org. Implements org. Read an object. |
| private static int | readVarInt(ByteBuffer buff)
Reads a variable-length encoded int from |
| public void | write(WriteBuffer buff, byte[] obj)
Implements abstract org. Implements org. Write an object. |
| TYPE_SERIALIZED_OBJECT | back to summary |
|---|---|
| private static final int TYPE_SERIALIZED_OBJECT | |
| RawBytesDataType | back to summary |
|---|---|
| pack-priv RawBytesDataType() | |
| createStorage | back to summary |
|---|---|
| public byte[][] createStorage(int size) Implements org. Doc from org. Create storage object of array type to hold values
| |
| getMemory | back to summary |
|---|---|
| public int getMemory(byte[] obj) Implements abstract org. Implements org. Doc from org. Calculates the amount of used memory in bytes.
| |
| read | back to summary |
|---|---|
| public byte[] read(ByteBuffer buff) Implements abstract org. Implements org. Doc from org. Read an object.
| |
| readVarInt | back to summary |
|---|---|
| private static int readVarInt(ByteBuffer buff) Reads a variable-length encoded int from | |
| write | back to summary |
|---|---|
| public void write(WriteBuffer buff, byte[] obj) Implements abstract org. Implements org. Doc from org. Write an object.
| |