]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.message.ui/src/org/simantics/message/ui/LogReader.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.message.ui / src / org / simantics / message / ui / LogReader.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.message.ui;
13
14 import java.io.BufferedReader;
15 import java.io.File;
16 import java.io.FileNotFoundException;
17 import java.io.IOException;
18 import java.io.InputStreamReader;
19 import java.io.PrintWriter;
20 import java.io.StringWriter;
21 import java.util.ArrayList;
22 import java.util.Date;
23 import java.util.List;
24
25 import org.eclipse.core.runtime.IStatus;
26 import org.eclipse.ui.IMemento;
27 import org.simantics.message.IDetailStatus;
28
29 class LogReader {
30         private static final int SESSION_STATE = 10;
31         public static final long MAX_FILE_LENGTH = 1024 * 1024;
32         private static final int ENTRY_STATE = 20;
33         private static final int SUBENTRY_STATE = 30;
34     private static final int MESSAGE_STATE = 40;
35     private static final int DETAILS_STATE = 45;
36         private static final int STACK_STATE = 50;
37         private static final int TEXT_STATE = 60;
38         private static final int UNKNOWN_STATE = 70;
39
40         public static LogSession parseLogFile(File file, List<Object> entries, IMemento memento) {
41                 if (memento.getString(LogView.P_USE_LIMIT).equals("true") //$NON-NLS-1$
42                                 && memento.getInteger(LogView.P_LOG_LIMIT).intValue() == 0)
43                         return null;
44
45                 ArrayList<Object> parents = new ArrayList<Object>();
46                 LogEntry current = null;
47                 LogSession session = null;
48                 int writerState = UNKNOWN_STATE;
49                 StringWriter swriter = null;
50                 PrintWriter writer = null;
51                 int state = UNKNOWN_STATE;
52                 LogSession currentSession = null;
53                 BufferedReader reader = null;
54                 try {
55
56                         reader = new BufferedReader(new InputStreamReader(new TailInputStream(file, MAX_FILE_LENGTH), "UTF-8")); //$NON-NLS-1$
57                         for (;;) {
58                                 String line = reader.readLine();
59                                 if (line == null)
60                                         break;
61                                 line = line.trim();
62
63                                 if (line.startsWith("!SESSION")) { //$NON-NLS-1$
64                                         state = SESSION_STATE;
65                                 } else if (line.startsWith("!ENTRY")) { //$NON-NLS-1$
66                                         state = ENTRY_STATE;
67                                 } else if (line.startsWith("!SUBENTRY")) { //$NON-NLS-1$
68                                         state = SUBENTRY_STATE;
69                 } else if (line.startsWith("!MESSAGE")) { //$NON-NLS-1$
70                     state = MESSAGE_STATE;
71                 } else if (line.startsWith("!DETAILS")) { //$NON-NLS-1$
72                     state = DETAILS_STATE;
73                                 } else if (line.startsWith("!STACK")) { //$NON-NLS-1$
74                                         state = STACK_STATE;
75                                 } else
76                                         state = TEXT_STATE;
77
78                                 if (state == TEXT_STATE) {
79                                         if (writer != null)
80                                                 writer.println(line);
81                                         continue;
82                                 }
83
84                                 if (writer != null) {
85                                         setData(current, session, writerState, swriter);
86                                         writerState = UNKNOWN_STATE;
87                                         swriter = null;
88                                         writer.close();
89                                         writer = null;
90                                 }
91
92                                 if (state == STACK_STATE) {
93                                         swriter = new StringWriter();
94                                         writer = new PrintWriter(swriter, true);
95                                         writerState = STACK_STATE;
96                                 } else if (state == SESSION_STATE) {
97                                         session = new LogSession();
98                                         session.processLogLine(line);
99                                         swriter = new StringWriter();
100                                         writer = new PrintWriter(swriter, true);
101                                         writerState = SESSION_STATE;
102                                         currentSession = updateCurrentSession(currentSession, session);
103                                         // if current session is most recent and not showing all sessions
104                                         if (currentSession.equals(session) && !memento.getString(LogView.P_SHOW_ALL_SESSIONS).equals("true")) //$NON-NLS-1$
105                                                 entries.clear();
106                                 } else if (state == ENTRY_STATE) {
107                                         if (currentSession == null) { // create fake session if there was no any
108                                                 currentSession = new LogSession();
109                                         }
110                                         LogEntry entry = new LogEntry();
111                                         entry.setSession(currentSession);
112                                         entry.processEntry(line);
113                                         setNewParent(parents, entry, 0);
114                                         current = entry;
115                                         addEntry(current, entries, memento);
116                                 } else if (state == SUBENTRY_STATE) {
117                                         if (parents.size() > 0) {
118                                                 LogEntry entry = new LogEntry();
119                                                 entry.setSession(session);
120                                                 int depth = entry.processSubEntry(line);
121                                                 setNewParent(parents, entry, depth);
122                                                 current = entry;
123                                                 LogEntry parent = (LogEntry) parents.get(depth - 1);
124                                                 parent.addChild(entry);
125                                         }
126                                 } else if (state == MESSAGE_STATE) {
127                                         swriter = new StringWriter();
128                                         writer = new PrintWriter(swriter, true);
129                                         String message = ""; //$NON-NLS-1$
130                                         if (line.length() > 8)
131                                                 message = line.substring(9).trim();
132                                         message = message.trim();
133                                         if (current != null)
134                                                 current.setMessage(message);
135                                         writerState = MESSAGE_STATE;
136                                 } else if (state == DETAILS_STATE) {
137                     swriter = new StringWriter();
138                     writer = new PrintWriter(swriter, true);
139                     String desc = ""; //$NON-NLS-1$
140                     if (line.length() > 8)
141                         desc = line.substring(9).trim();
142                     desc = desc.trim();
143                     if (current != null)
144                         current.setDetailedDescription(desc);
145                     writerState = DETAILS_STATE;
146                                 }
147                         }
148
149                         if (swriter != null && current != null && writerState == STACK_STATE) {
150                                 writerState = UNKNOWN_STATE;
151                                 current.setStack(swriter.toString());
152                         }
153                 } catch (FileNotFoundException e) { // do nothing
154                 } catch (IOException e) { // do nothing
155                 } finally {
156                         try {
157                                 if (reader != null)
158                                         reader.close();
159                         } catch (IOException e1) { // do nothing
160                         }
161                         if (writer != null) {
162                                 setData(current, session, writerState, swriter);
163                                 writer.close();
164                         }
165                 }
166
167                 return currentSession;
168         }
169
170         /**
171          * Assigns data from writer to appropriate field of current Log Entry or Session,
172          * depending on writer state.
173          */
174         private static void setData(LogEntry current, LogSession session, int writerState, StringWriter swriter) {
175                 if (writerState == STACK_STATE && current != null) {
176                         current.setStack(swriter.toString());
177                 } else if (writerState == SESSION_STATE && session != null) {
178                         session.setSessionData(swriter.toString());
179         } else if (writerState == MESSAGE_STATE && current != null) {
180             StringBuilder sb = new StringBuilder(current.getMessage());
181             sb.append(swriter.toString());
182             current.setMessage(sb.toString().trim());
183         } else if (writerState == DETAILS_STATE && current != null) {
184             StringBuilder sb = new StringBuilder(current.getDetailedDescription());
185             sb.append(swriter.toString());
186             current.setDetailedDescription(sb.toString().trim());
187         }
188         }
189
190         /**
191          * Updates the {@link currentSession} to be the one that is not null or has most recent date.
192          * @param session
193          */
194         private static LogSession updateCurrentSession(LogSession currentSession, LogSession session) {
195                 if (currentSession == null) {
196                         return session;
197                 }
198                 Date currentDate = currentSession.getDate();
199                 Date sessionDate = session.getDate();
200                 if (currentDate == null && sessionDate != null)
201                         return session;
202                 else if (currentDate != null && sessionDate == null)
203                         return session;
204                 else if (currentDate != null && sessionDate != null && sessionDate.after(currentDate))
205                         return session;
206
207                 return currentSession;
208         }
209
210         /**
211          * Adds entry to the list if it's not filtered. Removes entries exceeding the count limit.
212          * 
213          * @param entry
214          * @param entries
215          * @param memento
216          */
217         private static void addEntry(LogEntry entry, List<Object> entries, IMemento memento) {
218
219                 if (isLogged(entry, memento)) {
220                         entries.add(entry);
221
222                         if (memento.getString(LogView.P_USE_LIMIT).equals("true")) {//$NON-NLS-1$
223                                 int limit = memento.getInteger(LogView.P_LOG_LIMIT).intValue();
224                                 if (entries.size() > limit) {
225                                         entries.remove(0);
226                                 }
227                         }
228                 }
229         }
230
231         /**
232          * Returns whether given entry is logged (true) or filtered (false).
233          * 
234          * @param entry
235          * @param memento
236          * @return is entry logged or filtered
237          */
238         public static boolean isLogged(LogEntry entry, IMemento memento) {
239                 int severity = entry.getSeverity();
240                 switch (severity) {
241                         case IStatus.INFO :
242                                 return memento.getString(LogView.P_LOG_INFO).equals("true"); //$NON-NLS-1$
243                         case IStatus.WARNING :
244                                 return memento.getString(LogView.P_LOG_WARNING).equals("true"); //$NON-NLS-1$
245                         case IStatus.ERROR :
246                                 return memento.getString(LogView.P_LOG_ERROR).equals("true"); //$NON-NLS-1$
247             case IDetailStatus.DEBUG :
248                 return memento.getString(LogView.P_LOG_DEBUG).equals("true"); //$NON-NLS-1$
249                 }
250
251                 return false;
252         }
253
254         private static void setNewParent(ArrayList<Object> parents, LogEntry entry, int depth) {
255                 if (depth + 1 > parents.size())
256                         parents.add(entry);
257                 else
258                         parents.set(depth, entry);
259         }
260 }