--- /dev/null
+/*******************************************************************************\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.message.internal;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.ListenerList;\r
+import org.eclipse.core.runtime.OperationCanceledException;\r
+import org.eclipse.core.runtime.Status;\r
+import org.simantics.message.ILogListener;\r
+import org.simantics.message.ILogger;\r
+\r
+/**\r
+ * A logger for IStatus instances.\r
+ * \r
+ * <p>\r
+ * Meant to be used by any Simantics UI's for logging messages that should be\r
+ * relevant to the user's normal workflow instead of the kinds of\r
+ * code-error-like messages that go into the normal eclipse Error Log.\r
+ * </p>\r
+ * \r
+ * <p>\r
+ * Use {@link #getDefault()} to get a hold of the singleton instance of Messages\r
+ * or even more directly, you can use {@link #defaultLog(IStatus)} to\r
+ * effectively perform <code>getDefault().log(status)</code>.\r
+ * </p>\r
+ * \r
+ * <p>\r
+ * Originally copied from <code>org.eclipse.core.internal.runtime.Log</code>\r
+ * since the code was internal to eclipse and not usable as such. Modifications\r
+ * have been made since.\r
+ * </p>\r
+ * \r
+ * @author Tuukka Lehtonen\r
+ */\r
+final class Messages implements ILogger {\r
+\r
+ /**\r
+ * The log listeners.\r
+ */\r
+ ListenerList listeners = new ListenerList();\r
+\r
+ /**\r
+ * A queue of messages that have been received before the first listener is\r
+ * added.\r
+ */\r
+ List<IStatus> queue = new ArrayList<IStatus>();\r
+\r
+ @Override\r
+ public void addLogListener(ILogListener listener) {\r
+ synchronized (listeners) {\r
+ boolean firstListener = listeners.isEmpty();\r
+ listeners.add(listener);\r
+ if (firstListener) {\r
+ for (IStatus s : queue) {\r
+ listener.logging(s, Activator.PLUGIN_ID);\r
+ }\r
+ queue.clear();\r
+ }\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public String getName() {\r
+ return "Platform Log";\r
+ }\r
+\r
+ @Override\r
+ public void log(IStatus status) {\r
+ Object[] ls;\r
+ // This synchronizes properly with addLogListener.\r
+ synchronized (listeners) {\r
+ ls = listeners.getListeners();\r
+ }\r
+ if (ls.length == 0) {\r
+ queue.add(status);\r
+ return;\r
+ }\r
+ for (Object l : ls) {\r
+ try {\r
+ ((ILogListener) l).logging(status, Activator.PLUGIN_ID);\r
+ } catch (Exception e) {\r
+ handleException(e);\r
+ } catch (LinkageError e) {\r
+ handleException(e);\r
+ }\r
+ }\r
+ }\r
+\r
+ private void handleException(Throwable e) {\r
+ if (!(e instanceof OperationCanceledException)) {\r
+ // Got an error while logging. Delegate to Error Log, which is meant\r
+ // for errors in the code instead of these user level notifications.\r
+ Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Message logging failed, see exception for cause.", e));\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void removeLogListener(ILogListener listener) {\r
+ listeners.remove(listener);\r
+ }\r
+\r
+}\r