package org.jabref.gui.shared; import java.sql.SQLException; import java.util.Objects; import java.util.Optional; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import org.jabref.Globals; import org.jabref.JabRefGUI; import org.jabref.gui.BasePanel; import org.jabref.gui.JabRefFrame; import org.jabref.gui.entryeditor.EntryEditor; import org.jabref.gui.undo.UndoableRemoveEntry; import org.jabref.logic.importer.ParserResult; import org.jabref.logic.l10n.Localization; import org.jabref.model.Defaults; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.database.BibDatabaseMode; import org.jabref.model.database.DatabaseLocation; import org.jabref.shared.DBMSConnectionProperties; import org.jabref.shared.DBMSSynchronizer; import org.jabref.shared.event.ConnectionLostEvent; import org.jabref.shared.event.SharedEntryNotPresentEvent; import org.jabref.shared.event.UpdateRefusedEvent; import org.jabref.shared.exception.DatabaseNotSupportedException; import org.jabref.shared.exception.InvalidDBMSConnectionPropertiesException; import org.jabref.shared.exception.NotASharedDatabaseException; import org.jabref.shared.prefs.SharedDatabasePreferences; import com.google.common.eventbus.Subscribe; public class SharedDatabaseUIManager { private final JabRefFrame jabRefFrame; private DBMSSynchronizer dbmsSynchronizer; public SharedDatabaseUIManager(JabRefFrame jabRefFrame) { this.jabRefFrame = jabRefFrame; } @Subscribe public void listen(ConnectionLostEvent connectionLostEvent) { jabRefFrame.output(Localization.lang("Connection lost.")); String[] options = {Localization.lang("Reconnect"), Localization.lang("Work offline"), Localization.lang("Close library")}; int answer = JOptionPane.showOptionDialog(jabRefFrame, Localization.lang("The connection to the server has been terminated.") + "\n\n", Localization.lang("Connection lost"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); if (answer == 0) { jabRefFrame.closeCurrentTab(); ConnectToSharedDatabaseDialog connectToSharedDatabaseDialog = new ConnectToSharedDatabaseDialog(jabRefFrame); connectToSharedDatabaseDialog.setVisible(true); } else if (answer == 1) { connectionLostEvent.getBibDatabaseContext().convertToLocalDatabase(); jabRefFrame.refreshTitleAndTabs(); jabRefFrame.updateEnabledState(); jabRefFrame.output(Localization.lang("Working offline.")); } else { jabRefFrame.closeCurrentTab(); } } @Subscribe public void listen(UpdateRefusedEvent updateRefusedEvent) { jabRefFrame.output(Localization.lang("Update refused.")); new MergeSharedEntryDialog(jabRefFrame, dbmsSynchronizer, updateRefusedEvent.getLocalBibEntry(), updateRefusedEvent.getSharedBibEntry(), updateRefusedEvent.getBibDatabaseContext().getMode()).showMergeDialog(); } @Subscribe public void listen(SharedEntryNotPresentEvent event) { BasePanel panel = jabRefFrame.getCurrentBasePanel(); EntryEditor entryEditor = panel.getCurrentEditor(); panel.getUndoManager().addEdit(new UndoableRemoveEntry(panel.getDatabase(), event.getBibEntry(), panel)); if (Objects.nonNull(entryEditor) && (entryEditor.getEntry() == event.getBibEntry())) { JOptionPane.showMessageDialog(jabRefFrame, Localization.lang("The BibEntry you currently work on has been deleted on the shared side.") + "\n" + Localization.lang("You can restore the entry using the \"Undo\" operation."), Localization.lang("Shared entry is no longer present"), JOptionPane.INFORMATION_MESSAGE); SwingUtilities.invokeLater(() -> panel.hideBottomComponent()); } } /** * Opens a new shared database tab with the given {@link DBMSConnectionProperties}. * * @param dbmsConnectionProperties Connection data * @param raiseTab If <code>true</code> the new tab gets selected. * @return BasePanel which also used by {@link SaveDatabaseAction} */ public BasePanel openNewSharedDatabaseTab(DBMSConnectionProperties dbmsConnectionProperties) throws SQLException, DatabaseNotSupportedException, InvalidDBMSConnectionPropertiesException { JabRefFrame frame = JabRefGUI.getMainFrame(); BibDatabaseMode selectedMode = Globals.prefs.getDefaultBibDatabaseMode(); BibDatabaseContext bibDatabaseContext = new BibDatabaseContext(new Defaults(selectedMode), DatabaseLocation.SHARED, Globals.prefs.getKeywordDelimiter(), Globals.prefs.getKeyPattern()); dbmsSynchronizer = bibDatabaseContext.getDBMSSynchronizer(); dbmsSynchronizer.openSharedDatabase(dbmsConnectionProperties); dbmsSynchronizer.registerListener(this); frame.output(Localization.lang("Connection_to_%0_server_established.", dbmsConnectionProperties.getType().toString())); return frame.addTab(bibDatabaseContext, true); } public void openSharedDatabaseFromParserResult(ParserResult parserResult) throws SQLException, DatabaseNotSupportedException, InvalidDBMSConnectionPropertiesException, NotASharedDatabaseException { Optional<String> sharedDatabaseIDOptional = parserResult.getDatabase().getSharedDatabaseID(); if (!sharedDatabaseIDOptional.isPresent()) { throw new NotASharedDatabaseException(); } String sharedDatabaseID = sharedDatabaseIDOptional.get(); DBMSConnectionProperties dbmsConnectionProperties = new DBMSConnectionProperties(new SharedDatabasePreferences(sharedDatabaseID)); JabRefFrame frame = JabRefGUI.getMainFrame(); BibDatabaseMode selectedMode = Globals.prefs.getDefaultBibDatabaseMode(); BibDatabaseContext bibDatabaseContext = new BibDatabaseContext(new Defaults(selectedMode), DatabaseLocation.SHARED, Globals.prefs.getKeywordDelimiter(), Globals.prefs.getKeyPattern()); bibDatabaseContext.getDatabase().setSharedDatabaseID(sharedDatabaseID); bibDatabaseContext.setDatabaseFile(parserResult.getDatabaseContext().getDatabaseFile().orElse(null)); dbmsSynchronizer = bibDatabaseContext.getDBMSSynchronizer(); dbmsSynchronizer.openSharedDatabase(dbmsConnectionProperties); dbmsSynchronizer.registerListener(this); parserResult.setDatabaseContext(bibDatabaseContext); frame.output(Localization.lang("Connection_to_%0_server_established.", dbmsConnectionProperties.getType().toString())); } }