]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.message/src/org/simantics/message/internal/Messages.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.message / src / org / simantics / message / internal / Messages.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.message.internal;\r
13 \r
14 import java.util.ArrayList;\r
15 import java.util.List;\r
16 \r
17 import org.eclipse.core.runtime.IStatus;\r
18 import org.eclipse.core.runtime.ListenerList;\r
19 import org.eclipse.core.runtime.OperationCanceledException;\r
20 import org.eclipse.core.runtime.Status;\r
21 import org.simantics.message.ILogListener;\r
22 import org.simantics.message.ILogger;\r
23 \r
24 /**\r
25  * A logger for IStatus instances.\r
26  * \r
27  * <p>\r
28  * Meant to be used by any Simantics UI's for logging messages that should be\r
29  * relevant to the user's normal workflow instead of the kinds of\r
30  * code-error-like messages that go into the normal eclipse Error Log.\r
31  * </p>\r
32  * \r
33  * <p>\r
34  * Use {@link #getDefault()} to get a hold of the singleton instance of Messages\r
35  * or even more directly, you can use {@link #defaultLog(IStatus)} to\r
36  * effectively perform <code>getDefault().log(status)</code>.\r
37  * </p>\r
38  * \r
39  * <p>\r
40  * Originally copied from <code>org.eclipse.core.internal.runtime.Log</code>\r
41  * since the code was internal to eclipse and not usable as such. Modifications\r
42  * have been made since.\r
43  * </p>\r
44  * \r
45  * @author Tuukka Lehtonen\r
46  */\r
47 final class Messages implements ILogger {\r
48 \r
49     /**\r
50      * The log listeners.\r
51      */\r
52     ListenerList  listeners = new ListenerList();\r
53 \r
54     /**\r
55      * A queue of messages that have been received before the first listener is\r
56      * added.\r
57      */\r
58     List<IStatus> queue = new ArrayList<IStatus>();\r
59 \r
60     @Override\r
61     public void addLogListener(ILogListener listener) {\r
62         synchronized (listeners) {\r
63             boolean firstListener = listeners.isEmpty();\r
64             listeners.add(listener);\r
65             if (firstListener) {\r
66                 for (IStatus s : queue) {\r
67                     listener.logging(s, Activator.PLUGIN_ID);\r
68                 }\r
69                 queue.clear();\r
70             }\r
71         }\r
72     }\r
73 \r
74     @Override\r
75     public String getName() {\r
76         return "Platform Log";\r
77     }\r
78 \r
79     @Override\r
80     public void log(IStatus status) {\r
81         Object[] ls;\r
82         // This synchronizes properly with addLogListener.\r
83         synchronized (listeners) {\r
84             ls = listeners.getListeners();\r
85         }\r
86         if (ls.length == 0) {\r
87             queue.add(status);\r
88             return;\r
89         }\r
90         for (Object l : ls) {\r
91             try {\r
92                 ((ILogListener) l).logging(status, Activator.PLUGIN_ID);\r
93             } catch (Exception e) {\r
94                 handleException(e);\r
95             } catch (LinkageError e) {\r
96                 handleException(e);\r
97             }\r
98         }\r
99     }\r
100 \r
101     private void handleException(Throwable e) {\r
102         if (!(e instanceof OperationCanceledException)) {\r
103             // Got an error while logging. Delegate to Error Log, which is meant\r
104             // for errors in the code instead of these user level notifications.\r
105             Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Message logging failed, see exception for cause.", e));\r
106         }\r
107     }\r
108 \r
109     @Override\r
110     public void removeLogListener(ILogListener listener) {\r
111         listeners.remove(listener);\r
112     }\r
113 \r
114 }\r