]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.workbench/src/org/simantics/workbench/internal/SessionWatchdog.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.workbench / src / org / simantics / workbench / internal / SessionWatchdog.java
index eac35964f411d2b25ac281d2b6322cfbc0b4f0e5..483652e0b04d2ad551e86861fd8bc22d82946409 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.workbench.internal;\r
-\r
-import java.io.PrintWriter;\r
-import java.io.StringWriter;\r
-\r
-import org.eclipse.jface.dialogs.IDialogConstants;\r
-import org.eclipse.jface.dialogs.TrayDialog;\r
-import org.eclipse.jface.layout.GridDataFactory;\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.widgets.Composite;\r
-import org.eclipse.swt.widgets.Control;\r
-import org.eclipse.swt.widgets.Display;\r
-import org.eclipse.swt.widgets.Label;\r
-import org.eclipse.swt.widgets.Shell;\r
-import org.eclipse.swt.widgets.Text;\r
-import org.eclipse.ui.IWorkbenchWindow;\r
-import org.eclipse.ui.PlatformUI;\r
-import org.simantics.PlatformException;\r
-import org.simantics.SimanticsPlatform;\r
-import org.simantics.db.Session;\r
-import org.simantics.db.SessionManager;\r
-import org.simantics.db.SessionReference;\r
-import org.simantics.db.event.SessionEvent;\r
-import org.simantics.db.event.SessionListener;\r
-import org.simantics.db.management.ISessionContext;\r
-import org.simantics.db.management.ISessionContextChangedListener;\r
-import org.simantics.db.management.ISessionContextProvider;\r
-import org.simantics.db.management.SessionContextChangedEvent;\r
-import org.simantics.db.service.LifecycleSupport;\r
-import org.simantics.utils.ui.ErrorLogger;\r
-\r
-/**\r
- * SessionWatchdog is essentially a session manager event listener that catches\r
- * exceptions happening within the session connection. Currently the only\r
- * procedure to take when a connection exception comes is to just kill the\r
- * application since there's really no client-visible way of recovering from the\r
- * errors.\r
- * \r
- * <p>\r
- * Note that SessionWatchdog is currently for use with the eclipse Workbench UI.\r
- * It is not intended for headless application use.\r
- * </p>\r
- * \r
- * @author Tuukka Lehtonen\r
- */\r
-public class SessionWatchdog implements SessionListener, ISessionContextChangedListener {\r
-\r
-    SessionManager currentManager;\r
-\r
-    public void attach(ISessionContextProvider scp) {\r
-        scp.addContextChangedListener(this);\r
-    }\r
-\r
-    private void attach(Session session) {\r
-        SessionManager sessionManager = null;\r
-        synchronized (this) {\r
-            sessionManager = toSessionManager(session);\r
-            if (sessionManager == currentManager)\r
-                return;\r
-        }\r
-\r
-        if (currentManager != null) {\r
-            currentManager.removeSessionListener(this);\r
-        }\r
-        this.currentManager = sessionManager;\r
-        if (sessionManager != null) {\r
-            sessionManager.addSessionListener(this);\r
-        }\r
-    }\r
-\r
-    private SessionManager toSessionManager(Session s) {\r
-        if (s == null)\r
-            return null;\r
-        LifecycleSupport ls = s.peekService(LifecycleSupport.class);\r
-        if (ls == null)\r
-            return null;\r
-        return ls.getSessionManager();\r
-    }\r
-\r
-    @Override\r
-    public void sessionContextChanged(SessionContextChangedEvent event) {\r
-        ISessionContext sc = event.getNewValue();\r
-        attach((sc != null) ? sc.getSession() : (Session) null);\r
-    }\r
-\r
-    @Override\r
-    public void sessionOpened(SessionEvent e) {\r
-        //System.err.println(this + ": session opened: " + e.getSession() + "\n" + e.getCause());\r
-    }\r
-\r
-    @Override\r
-    public void sessionClosed(SessionEvent e) {\r
-        //System.err.println(this + ": session closed: " + e.getSession() + "\n" + e.getCause());\r
-        if (e.getCause() != null) {\r
-            ErrorLogger.defaultLogError(e.getCause());\r
-\r
-            // TODO: attempt reconnection, this is the right place for that.\r
-            reconnect(e.getSession());\r
-        }\r
-    }\r
-\r
-    private void reconnect(Session deadSession) {\r
-//        Session s = deadSession;\r
-//\r
-//        LifecycleSupport ls = s.getService(LifecycleSupport.class);\r
-//        SessionReference sr = ls.getSessionReference();\r
-\r
-        // TODO: make it possible to get the old user authenticator agent from the dead session!\r
-//        SessionUserSupport sus = s.getService(SessionUserSupport.class);\r
-//        String userName = sus.getUserName();\r
-//        String localDigest = sus.getUserLocalDigest();\r
-//        String remoteDigest = sus.getUserRemoteDigest();\r
-//        currentManager.createSession(sr,\r
-//                UserAuthenticationAgents.staticAgent(\r
-//                        UserAuthenticators.byNameAndDigest(userName, localDigest, remoteDigest)));\r
-    }\r
-\r
-    @Override\r
-    public void sessionException(SessionEvent e) {\r
-        // First things first, log the error.\r
-        ErrorLogger.defaultLogError(e.getCause());\r
-\r
-        Session s = e.getSession();\r
-        LifecycleSupport ls = s.getService(LifecycleSupport.class);\r
-        SessionReference sr = ls.getSessionReference();\r
-\r
-        Display display = Display.getDefault();\r
-        display.asyncExec(dialogOpener(e.getCause(), sr));\r
-    }\r
-\r
-    private Runnable dialogOpener(final Throwable cause, final SessionReference sr) {\r
-        return new Runnable() {\r
-            @Override\r
-            public void run() {\r
-                IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();\r
-                if (window == null)\r
-                    return;\r
-                Shell shell = window.getShell();\r
-                if (shell == null)\r
-                    return;\r
-\r
-                DatabaseConnectionProblemDialog d = new DatabaseConnectionProblemDialog(shell, cause, sr);\r
-                d.setBlockOnOpen(true);\r
-                d.open();\r
-                // The user chose to continue, but this will with 99.9%\r
-                // certainty just result in a program that is stuck.\r
-                return;\r
-            }\r
-        };\r
-    }\r
-\r
-    private static void shutdown() {\r
-        // Try to kill all active servers nicely and possibly with force\r
-        // if nice doesn't work.\r
-        try {\r
-            SimanticsPlatform.INSTANCE.shutdown(null);\r
-        } catch (PlatformException e) {\r
-            e.printStackTrace();\r
-        }\r
-\r
-        // The workbench won't close if we try to close it using\r
-        // PlatformUI.getWorkbench().close() so we'll just kill the\r
-        // process for now.\r
-        System.exit(-2);\r
-    }\r
-\r
-    class DatabaseConnectionProblemDialog extends TrayDialog {\r
-\r
-        Throwable cause;\r
-        SessionReference sr;\r
-\r
-        public DatabaseConnectionProblemDialog(Shell shell, Throwable cause, SessionReference sr) {\r
-            super(shell);\r
-            this.cause = cause;\r
-            this.sr = sr;\r
-\r
-            setShellStyle(SWT.TITLE | SWT.APPLICATION_MODAL | SWT.RESIZE | getDefaultOrientation());\r
-        }\r
-\r
-        @Override\r
-        protected boolean isResizable() {\r
-            return true;\r
-        }\r
-\r
-        @Override\r
-        protected void configureShell(Shell newShell) {\r
-            super.configureShell(newShell);\r
-            newShell.setSize(700, 600);\r
-            newShell.setText("Database Connection Problem");\r
-        }\r
-\r
-        @Override\r
-        protected void createButtonsForButtonBar(Composite parent) {\r
-            createButton(parent, IDialogConstants.PROCEED_ID, "Continue", false);\r
-            createButton(parent, IDialogConstants.CLOSE_ID, IDialogConstants.CLOSE_LABEL, true);\r
-        }\r
-\r
-        @Override\r
-        protected void buttonPressed(int buttonId) {\r
-            if (IDialogConstants.CLOSE_ID == buttonId) {\r
-                shutdown();\r
-            } else if (IDialogConstants.PROCEED_ID == buttonId) {\r
-                // Continue == CANCEL.\r
-                cancelPressed();\r
-            }\r
-        }\r
-\r
-        @Override\r
-        protected Control createDialogArea(Composite parent) {\r
-            Composite c = (Composite) super.createDialogArea(parent);\r
-\r
-            Text text = new Text(c, SWT.MULTI | SWT.READ_ONLY | SWT.WRAP);\r
-            StringBuilder sb = new StringBuilder();\r
-            sb.append("Our apologies, it seems that the database connection to used by the workbench has been unexpectedly disconnected. We are working on these stability problems.");\r
-            sb.append("\n\n");\r
-            sb.append("Session Reference was: " + sr);\r
-            sb.append("\n\n");\r
-            sb.append("Unfortunately nothing can be done at this point to recover your unsaved work. The program will be forcibly closed if you select close. You may select continue to attempt recovery but be warned that this will most likely not achieve anything useful.");\r
-            sb.append("\n\n");\r
-            sb.append("TODO: implement a possibility to attempt reconnection here if the database is still up and running!");\r
-            text.setText(sb.toString());\r
-            GridDataFactory.fillDefaults().grab(true, true).applyTo(text);\r
-\r
-            Label causeLabel = new Label(c, SWT.NONE);\r
-            causeLabel.setText("Exception:");\r
-            GridDataFactory.fillDefaults().grab(true, false).applyTo(causeLabel);\r
-\r
-            Text causeText = new Text(c, SWT.MULTI | SWT.READ_ONLY | SWT.WRAP | SWT.BORDER);\r
-            StringWriter sw = new StringWriter();\r
-            cause.printStackTrace(new PrintWriter(sw));\r
-            causeText.setText(sw.toString());\r
-            GridDataFactory.fillDefaults().grab(true, true).applyTo(causeText);\r
-\r
-            return c;\r
-        }\r
-\r
-    }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.workbench.internal;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.TrayDialog;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.simantics.PlatformException;
+import org.simantics.SimanticsPlatform;
+import org.simantics.db.Session;
+import org.simantics.db.SessionManager;
+import org.simantics.db.SessionReference;
+import org.simantics.db.event.SessionEvent;
+import org.simantics.db.event.SessionListener;
+import org.simantics.db.management.ISessionContext;
+import org.simantics.db.management.ISessionContextChangedListener;
+import org.simantics.db.management.ISessionContextProvider;
+import org.simantics.db.management.SessionContextChangedEvent;
+import org.simantics.db.service.LifecycleSupport;
+import org.simantics.utils.ui.ErrorLogger;
+
+/**
+ * SessionWatchdog is essentially a session manager event listener that catches
+ * exceptions happening within the session connection. Currently the only
+ * procedure to take when a connection exception comes is to just kill the
+ * application since there's really no client-visible way of recovering from the
+ * errors.
+ * 
+ * <p>
+ * Note that SessionWatchdog is currently for use with the eclipse Workbench UI.
+ * It is not intended for headless application use.
+ * </p>
+ * 
+ * @author Tuukka Lehtonen
+ */
+public class SessionWatchdog implements SessionListener, ISessionContextChangedListener {
+
+    SessionManager currentManager;
+
+    public void attach(ISessionContextProvider scp) {
+        scp.addContextChangedListener(this);
+    }
+
+    private void attach(Session session) {
+        SessionManager sessionManager = null;
+        synchronized (this) {
+            sessionManager = toSessionManager(session);
+            if (sessionManager == currentManager)
+                return;
+        }
+
+        if (currentManager != null) {
+            currentManager.removeSessionListener(this);
+        }
+        this.currentManager = sessionManager;
+        if (sessionManager != null) {
+            sessionManager.addSessionListener(this);
+        }
+    }
+
+    private SessionManager toSessionManager(Session s) {
+        if (s == null)
+            return null;
+        LifecycleSupport ls = s.peekService(LifecycleSupport.class);
+        if (ls == null)
+            return null;
+        return ls.getSessionManager();
+    }
+
+    @Override
+    public void sessionContextChanged(SessionContextChangedEvent event) {
+        ISessionContext sc = event.getNewValue();
+        attach((sc != null) ? sc.getSession() : (Session) null);
+    }
+
+    @Override
+    public void sessionOpened(SessionEvent e) {
+        //System.err.println(this + ": session opened: " + e.getSession() + "\n" + e.getCause());
+    }
+
+    @Override
+    public void sessionClosed(SessionEvent e) {
+        //System.err.println(this + ": session closed: " + e.getSession() + "\n" + e.getCause());
+        if (e.getCause() != null) {
+            ErrorLogger.defaultLogError(e.getCause());
+
+            // TODO: attempt reconnection, this is the right place for that.
+            reconnect(e.getSession());
+        }
+    }
+
+    private void reconnect(Session deadSession) {
+//        Session s = deadSession;
+//
+//        LifecycleSupport ls = s.getService(LifecycleSupport.class);
+//        SessionReference sr = ls.getSessionReference();
+
+        // TODO: make it possible to get the old user authenticator agent from the dead session!
+//        SessionUserSupport sus = s.getService(SessionUserSupport.class);
+//        String userName = sus.getUserName();
+//        String localDigest = sus.getUserLocalDigest();
+//        String remoteDigest = sus.getUserRemoteDigest();
+//        currentManager.createSession(sr,
+//                UserAuthenticationAgents.staticAgent(
+//                        UserAuthenticators.byNameAndDigest(userName, localDigest, remoteDigest)));
+    }
+
+    @Override
+    public void sessionException(SessionEvent e) {
+        // First things first, log the error.
+        ErrorLogger.defaultLogError(e.getCause());
+
+        Session s = e.getSession();
+        LifecycleSupport ls = s.getService(LifecycleSupport.class);
+        SessionReference sr = ls.getSessionReference();
+
+        Display display = Display.getDefault();
+        display.asyncExec(dialogOpener(e.getCause(), sr));
+    }
+
+    private Runnable dialogOpener(final Throwable cause, final SessionReference sr) {
+        return new Runnable() {
+            @Override
+            public void run() {
+                IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+                if (window == null)
+                    return;
+                Shell shell = window.getShell();
+                if (shell == null)
+                    return;
+
+                DatabaseConnectionProblemDialog d = new DatabaseConnectionProblemDialog(shell, cause, sr);
+                d.setBlockOnOpen(true);
+                d.open();
+                // The user chose to continue, but this will with 99.9%
+                // certainty just result in a program that is stuck.
+                return;
+            }
+        };
+    }
+
+    private static void shutdown() {
+        // Try to kill all active servers nicely and possibly with force
+        // if nice doesn't work.
+        try {
+            SimanticsPlatform.INSTANCE.shutdown(null);
+        } catch (PlatformException e) {
+            e.printStackTrace();
+        }
+
+        // The workbench won't close if we try to close it using
+        // PlatformUI.getWorkbench().close() so we'll just kill the
+        // process for now.
+        System.exit(-2);
+    }
+
+    class DatabaseConnectionProblemDialog extends TrayDialog {
+
+        Throwable cause;
+        SessionReference sr;
+
+        public DatabaseConnectionProblemDialog(Shell shell, Throwable cause, SessionReference sr) {
+            super(shell);
+            this.cause = cause;
+            this.sr = sr;
+
+            setShellStyle(SWT.TITLE | SWT.APPLICATION_MODAL | SWT.RESIZE | getDefaultOrientation());
+        }
+
+        @Override
+        protected boolean isResizable() {
+            return true;
+        }
+
+        @Override
+        protected void configureShell(Shell newShell) {
+            super.configureShell(newShell);
+            newShell.setSize(700, 600);
+            newShell.setText("Database Connection Problem");
+        }
+
+        @Override
+        protected void createButtonsForButtonBar(Composite parent) {
+            createButton(parent, IDialogConstants.PROCEED_ID, "Continue", false);
+            createButton(parent, IDialogConstants.CLOSE_ID, IDialogConstants.CLOSE_LABEL, true);
+        }
+
+        @Override
+        protected void buttonPressed(int buttonId) {
+            if (IDialogConstants.CLOSE_ID == buttonId) {
+                shutdown();
+            } else if (IDialogConstants.PROCEED_ID == buttonId) {
+                // Continue == CANCEL.
+                cancelPressed();
+            }
+        }
+
+        @Override
+        protected Control createDialogArea(Composite parent) {
+            Composite c = (Composite) super.createDialogArea(parent);
+
+            Text text = new Text(c, SWT.MULTI | SWT.READ_ONLY | SWT.WRAP);
+            StringBuilder sb = new StringBuilder();
+            sb.append("Our apologies, it seems that the database connection to used by the workbench has been unexpectedly disconnected. We are working on these stability problems.");
+            sb.append("\n\n");
+            sb.append("Session Reference was: " + sr);
+            sb.append("\n\n");
+            sb.append("Unfortunately nothing can be done at this point to recover your unsaved work. The program will be forcibly closed if you select close. You may select continue to attempt recovery but be warned that this will most likely not achieve anything useful.");
+            sb.append("\n\n");
+            sb.append("TODO: implement a possibility to attempt reconnection here if the database is still up and running!");
+            text.setText(sb.toString());
+            GridDataFactory.fillDefaults().grab(true, true).applyTo(text);
+
+            Label causeLabel = new Label(c, SWT.NONE);
+            causeLabel.setText("Exception:");
+            GridDataFactory.fillDefaults().grab(true, false).applyTo(causeLabel);
+
+            Text causeText = new Text(c, SWT.MULTI | SWT.READ_ONLY | SWT.WRAP | SWT.BORDER);
+            StringWriter sw = new StringWriter();
+            cause.printStackTrace(new PrintWriter(sw));
+            causeText.setText(sw.toString());
+            GridDataFactory.fillDefaults().grab(true, true).applyTo(causeText);
+
+            return c;
+        }
+
+    }
+
+}