/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.gui.communication.internal; import static de.rcenvironment.core.communication.connection.api.DisconnectReason.ERROR; import static de.rcenvironment.core.communication.connection.api.DisconnectReason.REMOTE_SHUTDOWN; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IStartup; import de.rcenvironment.core.communication.connection.api.ConnectionSetup; import de.rcenvironment.core.communication.connection.api.ConnectionSetupListener; import de.rcenvironment.core.communication.connection.api.ConnectionSetupListenerAdapter; import de.rcenvironment.core.communication.connection.api.DisconnectReason; import de.rcenvironment.core.utils.common.StringUtils; import de.rcenvironment.core.utils.incubator.ServiceRegistry; import de.rcenvironment.core.utils.incubator.ServiceRegistryPublisherAccess; /** * Listener class to show warning or information dialogs when network connections changed. * * @author Oliver Seebach * @author Robert Mischke */ public class NetworkConnectionListenerImpl implements IStartup { private static final String POPUP_TEXT_CONNECTION_WILL_BE_REATTEMPTED = "The connection will be automatically reattempted in the background."; private static final String POPUP_TEXT_CONNECTION_WILL_NOT_BE_REATTEMPTED = "The connection will not auto-reconnect. You can trigger a manual reconnect in the Network View."; private static final String DIALOG_TITLE = "Warning"; private final ServiceRegistryPublisherAccess serviceRegistryAccess; private boolean warningOpen = false; public NetworkConnectionListenerImpl() { serviceRegistryAccess = ServiceRegistry.createPublisherAccessFor(this); } /** * Registers an event listener for network changes as an OSGi service (whiteboard pattern). * * TODO register even sooner (in non-gui bundle) and store messages until the GUI becomes available? - misc_ro */ public void registerListener() { serviceRegistryAccess.registerService(ConnectionSetupListener.class, new ConnectionSetupListenerAdapter() { @Override public void onConnectionAttemptFailed(final ConnectionSetup setup, final boolean firstConsecutiveFailure, final boolean willAutoRetry) { // only show the first failure when auto-retrying if (!firstConsecutiveFailure) { return; } final String message = StringUtils.format("Failed to establish network connection to \"%s\".\n\n%s", setup.getDisplayName(), getAutoRetryRemark(willAutoRetry)); showMessageDialogAsync(message); } @Override public void onConnectionClosed(ConnectionSetup setup, DisconnectReason disconnectReason, boolean willAutoRetry) { if (setup.getDisconnectReason() == ERROR) { String message = StringUtils.format("Network connection to \"%s\" was closed due to a connection error.\n\n%s", setup.getDisplayName(), getAutoRetryRemark(willAutoRetry)); showMessageDialogAsync(message); } else if (setup.getDisconnectReason() == REMOTE_SHUTDOWN) { String message = StringUtils.format( "Network connection to \"%s\" was closed because the remote node is shutting down.\n\n%s", setup.getDisplayName(), getAutoRetryRemark(willAutoRetry)); showMessageDialogAsync(message); } } private String getAutoRetryRemark(final boolean willAutoRetry) { if (willAutoRetry) { return POPUP_TEXT_CONNECTION_WILL_BE_REATTEMPTED; } else { return POPUP_TEXT_CONNECTION_WILL_NOT_BE_REATTEMPTED; } } private void showMessageDialogAsync(final String message) { if (!warningOpen) { final Display display = Display.getDefault(); display.asyncExec(new Runnable() { @Override public void run() { Log log = LogFactory.getLog(getClass()); Shell shell = display.getActiveShell(); if (shell == null) { log.debug("No active shell to open message dialog; using fallback"); for (Shell testShell : display.getShells()) { if (testShell.isVisible()) { shell = testShell; break; } } if (shell == null) { log.error("Failed to open message dialog; message text: " + message); return; } } warningOpen = true; MessageBox warning = new MessageBox(shell, SWT.ICON_WARNING | SWT.OK); warning.setMessage(message); warning.setText(DIALOG_TITLE); int id = warning.open(); if (id == SWT.OK || id == SWT.CLOSE) { warningOpen = false; } } }); } } }); } @Override public void earlyStartup() { registerListener(); } }