Verified Owner
Top Description Inners Fields Constructors Methods
org.jabref.logic.shared

public Class DBMSSynchronizer

extends Object
implements DatabaseSynchronizer
Class Inheritance
All Implemented Interfaces
org.jabref.logic.shared.DatabaseSynchronizer
Imports
java.nio.file.Path, java.sql.Connection, .SQLException, java.util.ArrayList, .HashMap, .HashSet, .Iterator, .LinkedHashMap, .List, .Map, .Objects, .Optional, .Set, java.util.concurrent.ConcurrentHashMap, .Executor, .ExecutorService, .Executors, .RejectedExecutionException, .TimeUnit, java.util.concurrent.atomic.AtomicBoolean, .AtomicReference, java.util.concurrent.locks.ReentrantLock, org.jabref.logic.bibtex.FieldPreferences, org.jabref.logic.citationkeypattern.GlobalCitationKeyPatterns, org.jabref.logic.exporter.BibDatabaseWriter, .MetaDataSerializer, org.jabref.logic.importer.ParseException, org.jabref.logic.importer.util.MetaDataParser, org.jabref.logic.shared.event.ConnectionLostEvent, .ConnectionRestoredEvent, .SharedEntriesNotPresentEvent, .SharedWriteFailedEvent, .UpdateRefusedEvent, org.jabref.logic.shared.exception.OfflineLockException, .SharedEntryNotPresentException, org.jabref.logic.shared.notifications.FieldChange, .Notifier, org.jabref.logic.util.BackgroundTask, .Directories, .TaskExecutor, org.jabref.model.database.BibDatabase, .BibDatabaseContext, org.jabref.model.database.event.EntriesAddedEvent, .EntriesRemovedEvent, org.jabref.model.entry.BibEntry, org.jabref.model.entry.event.EntriesEvent, .EntriesEventSource, .FieldChangedEvent, org.jabref.model.entry.field.Field, .FieldFactory, org.jabref.model.metadata.MetaData, org.jabref.model.metadata.event.MetaDataChangedEvent, org.jabref.model.util.FileUpdateMonitor, com.google.common.annotations.VisibleForTesting, com.google.common.eventbus.EventBus, .Subscribe, org.jspecify.annotations.NonNull, .Nullable, org.slf4j.Logger, .LoggerFactory

Synchronizes the shared or local databases with their opposite side. Local changes are pushed by EntriesEvent using Google's Guava EventBus.

Threading model:

Connection loss: once a write finds the connection dead, the synchronizer goes offline - every change is recorded in OfflineChanges (in memory and on disk) instead of being written, pulls are skipped, and a background loop reconnects with backoff. Back online, the recorded changes are written through the same optimistic lock as any other change, then everything is pulled.

Undo: a change pulled from the database is applied to the local model without going on the undo journal, and that is a decision rather than an omission - see ADR-0072. Undoing one locally would take back something the shared database still holds, leaving this copy out of step until the next push, and what happens then is a question about who owns a change. What the local user meets instead: their own recorded change refuses to apply once a pulled change has moved the value on, and says so, rather than overwriting the newer value (org.jabref.model.undo.BibChange#apply); and the pulled change marks the library as needing a save, because it arrives as org.jabref.model.entry.event.EntriesEventSource#SHARED.

Nested and Inner Type Summary

Modifier and TypeClass and Description
private static interface
private static record
DBMSSynchronizer.RemoteChanges

What the shared database has that the local library has not.

Field Summary

Modifier and TypeField and Description
private final BibDatabase
private final BibDatabaseContext
private volatile boolean
private final AtomicBoolean
private Connection
private DatabaseConnection
private DBMSProcessor
private String
private final AtomicReference<BibEntry>
private final EventBus
private final FieldPreferences
private final FileUpdateMonitor
private final GlobalCitationKeyPatterns
private static final long
private final Character
private volatile Map<String, String>
private static final Logger
private static final long
private MetaData
private Notifier
private OfflineChanges
private final Path
private final @Nullable ExecutorService
private final ReentrantLock
private final Executor
private boolean
private final Set<Integer>
private final Executor
private final TaskExecutor
private final String

Constructor Summary

AccessConstructor and Description
public
DBMSSynchronizer(@NonNull BibDatabaseContext bibDatabaseContext, Character keywordSeparator, FieldPreferences fieldPreferences, @NonNull GlobalCitationKeyPatterns globalCiteKeyPattern, FileUpdateMonitor fileMonitor, String userAndHost, TaskExecutor taskExecutor)

public
DBMSSynchronizer(@NonNull BibDatabaseContext bibDatabaseContext, Character keywordSeparator, FieldPreferences fieldPreferences, @NonNull GlobalCitationKeyPatterns globalCiteKeyPattern, FileUpdateMonitor fileMonitor, String userAndHost, TaskExecutor taskExecutor, Executor remoteUpdateExecutor)

pack-priv
DBMSSynchronizer(@NonNull BibDatabaseContext bibDatabaseContext, Character keywordSeparator, FieldPreferences fieldPreferences, @NonNull GlobalCitationKeyPatterns globalCiteKeyPattern, FileUpdateMonitor fileMonitor, String userAndHost, TaskExecutor taskExecutor, Executor remoteUpdateExecutor, Executor syncExecutor, Path offlineChangesDirectory)

Method Summary

Modifier and TypeMethod and Description
public void
applyMetaData()

Applies the MetaData on all local and shared BibEntries.

private void
public void
applyRemoteFieldChange(FieldChange fieldChange)

Applies a field change received from another client.

private void
applyRemoteMetaData(Map<String, String> sharedMetaData)

Model thread

private boolean
applySaveActions(BibEntry bibEntry)

Returns: whether a save action changed the entry

private void
applySaveActionsToBufferedEntry()

Model thread: the save actions mutate the entry, which the database worker must not do.

private boolean

Returns:

true if the connection is valid, else false.
checkCurrentConnection
()

Checks whether the current SQL connection is valid; a dead one takes the synchronizer offline.

private static void
public void
private void
doApplyMetaData()

Model thread: applies the save actions locally; the entries they changed are written afterwards.

private void
private DBMSSynchronizer.RemoteChanges
fetchRemoteChanges()

Database worker.

public DatabaseConnectionProperties
public String
private void
goOffline()

Takes the synchronizer offline: from now on changes are recorded instead of written, and a scheduled task tries to get a new connection.

public void
handleRemoteDatabaseChange()

Schedules a full synchronization requested by another shared-database client.

public void
handleRemoteFieldChange(FieldChange fieldChange)

Schedules a field update received from another shared-database client.

public void
handleRemoteMetaDataChange()

Schedules a metadata update received from another shared-database client.

private void
handleWriteFailure(String message, SQLException exception, Runnable record)

Database worker.

private boolean

Returns:

whether the work ran
ifNotPullingAlready
(Runnable work)

Runs the given work only when no other thread is applying a pull right now.

public void
initializeDatabases()

Sets the table structure of shared database if needed and pulls all shared entries to the new local database.

private boolean

Returns:

whether the entries reached the shared database
insertSharedEntries
(List<BibEntry> bibEntries)

Database worker

private static boolean
isEventSourceAccepted(EntriesEvent event)

Only local changes (and their undo) are written; changes applied from the shared side are not echoed back.

private boolean
public void
listen(EntriesAddedEvent event)

Listening method.

public void
listen(FieldChangedEvent event)

Listening method.

public void
listen(EntriesRemovedEvent event)

Listening method.

public void
listen(MetaDataChangedEvent event)

Listening method.

private List<BibEntry>

Returns:

the entries whose shared version still is the one the removal was recorded against
onlyUnchangedSharedEntries
(List<BibEntry> entriesToRemove)

Database worker: the optimistic lock for a recorded removal, which DBMSProcessor#removeEntries cannot express.

public void
private static void
overwriteLocalEntry(BibEntry localEntry, BibEntry sharedEntry)

Writes a pulled entry over the local one.

public void
pullChanges()

Implements org.jabref.logic.shared.DatabaseSynchronizer.pullChanges.

Synchronizes the local BibEntries and applies the fetched MetaData on them.

private void
pullEntries()

Brings the local entries up to date with the shared database: fetches on the database worker, applies on the model thread.

private void
private void
reconnect(long delayMillis)

public void
private boolean

Returns:

whether the removal reached the shared database
removeSharedEntries
(List<BibEntry> bibEntries)

Database worker

private boolean

Returns:

whether there was anything to replay
replayOfflineChanges
(boolean
whether the local library was just loaded from the shared database and needs the recorded state restored - after a reconnect it holds the changes already, plus micro-edits made since the record
afterRestart
)

Writes the changes recorded while offline through the same paths as live changes: applied to the local library (model thread) where a restart lost them, then written (database worker) - a shared entry that moved on meanwhile refuses the write and the user merges, like any other conflict.

private void
reviveEntriesDeletedMeanwhile(List<BibEntry> entriesToWrite, List<BibEntry> entriesToInsert)

Database worker: a shared row deleted during the outage must not take the changes recorded against it with it.

private void
scheduleReconnect(long delayMillis)

One attempt per scheduled task, so that waiting for the next one occupies no thread

public void
public void
public void
synchronizeLocalDatabase()

Implements org.jabref.logic.shared.DatabaseSynchronizer.synchronizeLocalDatabase.

Synchronizes the local database with shared one.

public void
synchronizeSharedEntry(BibEntry bibEntry)

Implements org.jabref.logic.shared.DatabaseSynchronizer.synchronizeSharedEntry.

Writes the merged entry of a resolved conflict.

private void
useConnection(DatabaseConnection newConnection)

Database worker: replaces the dead connection, then synchronizes what happened meanwhile

private void
private void
writeBufferedEntry()

Database worker: writes the buffered micro-edited entry (if any) as a whole

private boolean

Returns:

whether the write reached the shared database
writeOrRecord
(String failureMessage, DBMSSynchronizer.DatabaseWrite write, Runnable record)

Database worker: runs the write and asks other clients to pull, or records the change when the connection is gone

private boolean
writeRecordedMetaData(Map<String, String> recordedMetaData, OfflineChanges.Recorded recorded)

Database worker: recorded metadata is merged into what the shared side has now, so that metadata other clients changed during the outage (a group they added, say) survives

private boolean

Returns:

whether the entry reached the shared database - a refused or failed (and thus rolled back) update must not be announced to other clients
writeSharedEntry
(BibEntry bibEntry)

Database worker.

private boolean
writeSharedMetaData(Map<String, String> serializedMetaData)

Database worker.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

bibDatabaseback to summary
private final BibDatabase bibDatabase
bibDatabaseContextback to summary
private final BibDatabaseContext bibDatabaseContext
closedback to summary
private volatile boolean closed
connectedback to summary
private final AtomicBoolean connected
currentConnectionback to summary
private Connection currentConnection
dbmsConnectionback to summary
private DatabaseConnection dbmsConnection
dbmsProcessorback to summary
private DBMSProcessor dbmsProcessor
dbNameback to summary
private String dbName
entryWithPendingChangesback to summary
private final AtomicReference<BibEntry> entryWithPendingChanges
eventBusback to summary
private final EventBus eventBus
fieldPreferencesback to summary
private final FieldPreferences fieldPreferences
fileMonitorback to summary
private final FileUpdateMonitor fileMonitor
globalCiteKeyPatternback to summary
private final GlobalCitationKeyPatterns globalCiteKeyPattern
INITIAL_RECONNECT_DELAY_MILLISback to summary
private static final long INITIAL_RECONNECT_DELAY_MILLIS
keywordSeparatorback to summary
private final Character keywordSeparator
lastSharedMetaDataback to summary
private volatile Map<String, String> lastSharedMetaData
LOGGERback to summary
private static final Logger LOGGER
MAX_RECONNECT_DELAY_MILLISback to summary
private static final long MAX_RECONNECT_DELAY_MILLIS
metaDataback to summary
private MetaData metaData
notifierback to summary
private Notifier notifier
offlineChangesback to summary
private OfflineChanges offlineChanges
offlineChangesDirectoryback to summary
private final Path offlineChangesDirectory
ownedSyncExecutorback to summary
private final @Nullable ExecutorService ownedSyncExecutor
pullLockback to summary
private final ReentrantLock pullLock
remoteUpdateExecutorback to summary
private final Executor remoteUpdateExecutor
sharedDatabaseOpenback to summary
private boolean sharedDatabaseOpen
sharedIdsInConflictback to summary
private final Set<Integer> sharedIdsInConflict
syncExecutorback to summary
private final Executor syncExecutor
taskExecutorback to summary
private final TaskExecutor taskExecutor
userAndHostback to summary
private final String userAndHost

Constructor Detail

DBMSSynchronizerback to summary
public DBMSSynchronizer(@NonNull BibDatabaseContext bibDatabaseContext, Character keywordSeparator, FieldPreferences fieldPreferences, @NonNull GlobalCitationKeyPatterns globalCiteKeyPattern, FileUpdateMonitor fileMonitor, String userAndHost, TaskExecutor taskExecutor)
DBMSSynchronizerback to summary
public DBMSSynchronizer(@NonNull BibDatabaseContext bibDatabaseContext, Character keywordSeparator, FieldPreferences fieldPreferences, @NonNull GlobalCitationKeyPatterns globalCiteKeyPattern, FileUpdateMonitor fileMonitor, String userAndHost, TaskExecutor taskExecutor, Executor remoteUpdateExecutor)
DBMSSynchronizerback to summary
pack-priv DBMSSynchronizer(@NonNull BibDatabaseContext bibDatabaseContext, Character keywordSeparator, FieldPreferences fieldPreferences, @NonNull GlobalCitationKeyPatterns globalCiteKeyPattern, FileUpdateMonitor fileMonitor, String userAndHost, TaskExecutor taskExecutor, Executor remoteUpdateExecutor, Executor syncExecutor, Path offlineChangesDirectory)
Annotations
@VisibleForTesting

Method Detail

applyMetaDataback to summary
public void applyMetaData()

Applies the MetaData on all local and shared BibEntries.

applyRemoteChangesback to summary
private void applyRemoteChanges(DBMSSynchronizer.RemoteChanges remoteChanges)

Model thread

applyRemoteFieldChangeback to summary
public void applyRemoteFieldChange(FieldChange fieldChange)

Applies a field change received from another client. Any state that does not exactly match the received change (content-less payload, unknown entry, diverged field value) falls back to pulling everything from the database.

applyRemoteMetaDataback to summary
private void applyRemoteMetaData(Map<String, String> sharedMetaData)

Model thread

applySaveActionsback to summary
private boolean applySaveActions(BibEntry bibEntry)
Returns:boolean

whether a save action changed the entry

applySaveActionsToBufferedEntryback to summary
private void applySaveActionsToBufferedEntry()

Model thread: the save actions mutate the entry, which the database worker must not do. Only the flush queued from here includes them; a flush before a remote-triggered pull writes the entry as it is.

checkCurrentConnectionback to summary
private boolean checkCurrentConnection()

Checks whether the current SQL connection is valid; a dead one takes the synchronizer offline.

Returns:boolean

true if the connection is valid, else false.

closeQuietlyback to summary
private static void closeQuietly(Connection connection)
closeSharedDatabaseback to summary
public void closeSharedDatabase()

Implements org.jabref.logic.shared.DatabaseSynchronizer.closeSharedDatabase.

Annotations
@Override
doApplyMetaDataback to summary
private void doApplyMetaData()

Model thread: applies the save actions locally; the entries they changed are written afterwards.

doApplyRemoteFieldChangeback to summary
private void doApplyRemoteFieldChange(FieldChange fieldChange)
fetchRemoteChangesback to summary
private DBMSSynchronizer.RemoteChanges fetchRemoteChanges() throws SQLException

Database worker. Transfers only what differs: the id/version mapping plus the entries that are new or newer on the shared side.

getConnectionPropertiesback to summary
public DatabaseConnectionProperties getConnectionProperties()

Implements org.jabref.logic.shared.DatabaseSynchronizer.getConnectionProperties.

Annotations
@Override
getDBNameback to summary
public String getDBName()

Implements org.jabref.logic.shared.DatabaseSynchronizer.getDBName.

Annotations
@Override
goOfflineback to summary
private void goOffline()

Takes the synchronizer offline: from now on changes are recorded instead of written, and a scheduled task tries to get a new connection.

handleRemoteDatabaseChangeback to summary
public void handleRemoteDatabaseChange()

Schedules a full synchronization requested by another shared-database client.

handleRemoteFieldChangeback to summary
public void handleRemoteFieldChange(FieldChange fieldChange)

Schedules a field update received from another shared-database client.

handleRemoteMetaDataChangeback to summary
public void handleRemoteMetaDataChange()

Schedules a metadata update received from another shared-database client.

handleWriteFailureback to summary
private void handleWriteFailure(String message, SQLException exception, Runnable record)

Database worker. A dead connection takes the synchronizer offline and the change is recorded for later; a failure on a live connection is transient and only reported (repeating that write would fail the same way).

ifNotPullingAlreadyback to summary
private boolean ifNotPullingAlready(Runnable work)

Runs the given work only when no other thread is applying a pull right now.

Returns:boolean

whether the work ran

initializeDatabasesback to summary
public void initializeDatabases() throws DatabaseNotSupportedException, SQLException

Sets the table structure of shared database if needed and pulls all shared entries to the new local database.

Exceptions
DatabaseNotSupportedException:
if the version of shared database does not match the version of current shared database support (DBMSProcessor).
insertSharedEntriesback to summary
private boolean insertSharedEntries(List<BibEntry> bibEntries)

Database worker

Returns:boolean

whether the entries reached the shared database

isEventSourceAcceptedback to summary
private static boolean isEventSourceAccepted(EntriesEvent event)

Only local changes (and their undo) are written; changes applied from the shared side are not echoed back.

isPresentLocalBibEntryback to summary
private boolean isPresentLocalBibEntry(BibEntry bibEntry)
listenback to summary
public void listen(EntriesAddedEvent event)

Listening method. Inserts a new BibEntry into shared database.

Annotations
@Subscribe
listenback to summary
public void listen(FieldChangedEvent event)

Listening method. Updates an existing shared BibEntry.

Annotations
@Subscribe
listenback to summary
public void listen(EntriesRemovedEvent event)

Listening method. Deletes the given list of BibEntry from shared database.

Annotations
@Subscribe
listenback to summary
public void listen(MetaDataChangedEvent event)

Listening method. Synchronizes the shared MetaData and applies them locally.

Annotations
@Subscribe
onlyUnchangedSharedEntriesback to summary
private List<BibEntry> onlyUnchangedSharedEntries(List<BibEntry> entriesToRemove) throws SQLException

Database worker: the optimistic lock for a recorded removal, which DBMSProcessor#removeEntries cannot express. An entry another client changed during the outage is kept - the pull that ends the replay brings it back locally, rather than the collaborator losing their work.

Returns:List<BibEntry>

the entries whose shared version still is the one the removal was recorded against

openSharedDatabaseback to summary
public void openSharedDatabase(DatabaseConnection connection) throws DatabaseNotSupportedException, SQLException

Implements org.jabref.logic.shared.DatabaseSynchronizer.openSharedDatabase.

Annotations
@Override
overwriteLocalEntryback to summary
private static void overwriteLocalEntry(BibEntry localEntry, BibEntry sharedEntry)

Writes a pulled entry over the local one. Nothing is recorded: the change is not this user's to take back — see the class javadoc.

pullChangesback to summary
public void pullChanges()

Implements org.jabref.logic.shared.DatabaseSynchronizer.pullChanges.

Synchronizes the local BibEntries and applies the fetched MetaData on them.

Annotations
@Override
pullEntriesback to summary
private void pullEntries()

Brings the local entries up to date with the shared database: fetches on the database worker, applies on the model thread. A failed fetch leaves the local library as it is.

pullMetaDataback to summary
private void pullMetaData()
reconnectback to summary
private void reconnect(long delayMillis)
registerListenerback to summary
public void registerListener(Object listener)

Implements org.jabref.logic.shared.DatabaseSynchronizer.registerListener.

Annotations
@Override
removeSharedEntriesback to summary
private boolean removeSharedEntries(List<BibEntry> bibEntries)

Database worker

Returns:boolean

whether the removal reached the shared database

replayOfflineChangesback to summary
private boolean replayOfflineChanges(boolean afterRestart)

Writes the changes recorded while offline through the same paths as live changes: applied to the local library (model thread) where a restart lost them, then written (database worker) - a shared entry that moved on meanwhile refuses the write and the user merges, like any other conflict. Ends with a pull.

Every record is dropped only once it reached the shared database, so that closing, a crash or a refused write in between leaves it recorded for the next attempt.

Parameters
afterRestart:boolean

whether the local library was just loaded from the shared database and needs the recorded state restored - after a reconnect it holds the changes already, plus micro-edits made since the record

Returns:boolean

whether there was anything to replay

reviveEntriesDeletedMeanwhileback to summary
private void reviveEntriesDeletedMeanwhile(List<BibEntry> entriesToWrite, List<BibEntry> entriesToInsert)

Database worker: a shared row deleted during the outage must not take the changes recorded against it with it. Such an entry is re-inserted as a new shared entry instead of being updated - an update would fail with SharedEntryNotPresentException and pull the deletion, which removes the user's edited entry.

scheduleReconnectback to summary
private void scheduleReconnect(long delayMillis)

One attempt per scheduled task, so that waiting for the next one occupies no thread

setDBNameback to summary
public void setDBName(String dbName)

Implements org.jabref.logic.shared.DatabaseSynchronizer.setDBName.

Annotations
@Override
setMetaDataback to summary
public void setMetaData(MetaData metaData)
synchronizeLocalDatabaseback to summary
public void synchronizeLocalDatabase()

Implements org.jabref.logic.shared.DatabaseSynchronizer.synchronizeLocalDatabase.

Synchronizes the local database with shared one. Possible update types are: removal, update, or insert of a BibEntry.

Annotations
@Override
synchronizeSharedEntryback to summary
public void synchronizeSharedEntry(BibEntry bibEntry)

Implements org.jabref.logic.shared.DatabaseSynchronizer.synchronizeSharedEntry.

Writes the merged entry of a resolved conflict. The entry is a detached copy, so the save actions may run on the caller's thread.

Annotations
@Override
useConnectionback to summary
private void useConnection(DatabaseConnection newConnection)

Database worker: replaces the dead connection, then synchronizes what happened meanwhile

withPullLockback to summary
private void withPullLock(Runnable work)
writeBufferedEntryback to summary
private void writeBufferedEntry()

Database worker: writes the buffered micro-edited entry (if any) as a whole

writeOrRecordback to summary
private boolean writeOrRecord(String failureMessage, DBMSSynchronizer.DatabaseWrite write, Runnable record)

Database worker: runs the write and asks other clients to pull, or records the change when the connection is gone

Returns:boolean

whether the write reached the shared database

writeRecordedMetaDataback to summary
private boolean writeRecordedMetaData(Map<String, String> recordedMetaData, OfflineChanges.Recorded recorded)

Database worker: recorded metadata is merged into what the shared side has now, so that metadata other clients changed during the outage (a group they added, say) survives

writeSharedEntryback to summary
private boolean writeSharedEntry(BibEntry bibEntry)

Database worker.

Returns:boolean

whether the entry reached the shared database - a refused or failed (and thus rolled back) update must not be announced to other clients

writeSharedMetaDataback to summary
private boolean writeSharedMetaData(Map<String, String> serializedMetaData)

Database worker. Other clients are notified by the database function (see DBMSProcessor.setUp).

org.jabref.logic.shared back to summary

private Interface DBMSSynchronizer.DatabaseWrite

Annotations
@FunctionalInterface

Method Summary

Modifier and TypeMethod and Description
public void
run()

Method Detail

runback to summary
public void run() throws SQLException
org.jabref.logic.shared back to summary

private final Record DBMSSynchronizer.RemoteChanges

extends Record
Class Inheritance
Record Components
removedIds:Set<Integer> 
changedEntries:List<BibEntry> 

What the shared database has that the local library has not. Determined on the database worker against the local ids as of the fetch, applied on the model thread.

Field Summary

Modifier and TypeField and Description
private final List<BibEntry>
changedEntries

Record Component accessed by changedEntries().

private final Set<Integer>
removedIds

Record Component accessed by removedIds().

Constructor Summary

AccessConstructor and Description
private
RemoteChanges(Set<Integer> removedIds, List<BibEntry> changedEntries)

Method Summary

Modifier and TypeMethod and Description
public List<BibEntry>
changedEntries()

Record Component getter of changedEntries.

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 Set<Integer>
removedIds()

Record Component getter of removedIds.

public final String
toString()

Implements abstract java.lang.Record.toString.

Returns a string representation of the record.

Field Detail

changedEntriesback to summary
private final List<BibEntry> changedEntries

Record Component accessed by changedEntries().

removedIdsback to summary
private final Set<Integer> removedIds

Record Component accessed by removedIds().

Constructor Detail

RemoteChangesback to summary
private RemoteChanges(Set<Integer> removedIds, List<BibEntry> changedEntries)

Method Detail

changedEntriesback to summary
public List<BibEntry> changedEntries()

Record Component getter of changedEntries.

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.

removedIdsback to summary
public Set<Integer> removedIds()

Record Component getter of removedIds.

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.