Commit | Line | Data |
---|---|---|
c3c5c786 FC |
1 | /*******************************************************************************\r |
2 | * Copyright (c) 2010 Ericsson\r | |
6256d8ad | 3 | *\r |
c3c5c786 FC |
4 | * All rights reserved. This program and the accompanying materials are\r |
5 | * made available under the terms of the Eclipse Public License v1.0 which\r | |
6 | * accompanies this distribution, and is available at\r | |
7 | * http://www.eclipse.org/legal/epl-v10.html\r | |
6256d8ad | 8 | *\r |
c3c5c786 FC |
9 | * Contributors:\r |
10 | * Patrick Tasse - Initial API and implementation\r | |
11 | *******************************************************************************/\r | |
12 | \r | |
d34665f9 | 13 | package org.eclipse.linuxtools.internal.tmf.ui.parsers.custom;\r |
c3c5c786 | 14 | \r |
c3c5c786 FC |
15 | import java.io.FileNotFoundException;\r |
16 | import java.io.IOException;\r | |
c3c5c786 FC |
17 | import java.util.HashMap;\r |
18 | import java.util.Iterator;\r | |
19 | import java.util.List;\r | |
20 | import java.util.Map.Entry;\r | |
21 | import java.util.regex.Matcher;\r | |
c3c5c786 | 22 | \r |
2352aed9 | 23 | import org.eclipse.core.resources.IProject;\r |
25e48683 | 24 | import org.eclipse.core.resources.IResource;\r |
8fd82db5 | 25 | import org.eclipse.linuxtools.internal.tmf.ui.Activator;\r |
d34665f9 | 26 | import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomTxtTraceDefinition.InputLine;\r |
6256d8ad | 27 | import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;\r |
6c13869b | 28 | import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;\r |
b4f71e4a | 29 | import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;\r |
6c13869b FC |
30 | import org.eclipse.linuxtools.tmf.core.io.BufferedRandomAccessFile;\r |
31 | import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;\r | |
7e6347b0 | 32 | import org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser;\r |
6c13869b | 33 | import org.eclipse.linuxtools.tmf.core.trace.ITmfLocation;\r |
6c13869b | 34 | import org.eclipse.linuxtools.tmf.core.trace.TmfContext;\r |
cb8c854e | 35 | import org.eclipse.linuxtools.tmf.core.trace.TmfLongLocation;\r |
6c13869b | 36 | import org.eclipse.linuxtools.tmf.core.trace.TmfTrace;\r |
c3c5c786 | 37 | \r |
6256d8ad | 38 | public class CustomTxtTrace extends TmfTrace implements ITmfEventParser {\r |
c3c5c786 | 39 | \r |
cb8c854e | 40 | private static final TmfLongLocation NULL_LOCATION = new TmfLongLocation((Long) null);\r |
3118edf1 | 41 | private static final int DEFAULT_CACHE_SIZE = 100;\r |
1b70b6dc | 42 | \r |
25e48683 FC |
43 | private final CustomTxtTraceDefinition fDefinition;\r |
44 | private final CustomTxtEventType fEventType;\r | |
2a4fba11 | 45 | private BufferedRandomAccessFile fFile;\r |
4bf17f4a | 46 | \r |
25e48683 | 47 | public CustomTxtTrace(final CustomTxtTraceDefinition definition) {\r |
4bf17f4a | 48 | fDefinition = definition;\r |
49 | fEventType = new CustomTxtEventType(fDefinition);\r | |
c843ebb5 | 50 | setCacheSize(DEFAULT_CACHE_SIZE);\r |
4bf17f4a | 51 | }\r |
52 | \r | |
c843ebb5 PT |
53 | public CustomTxtTrace(final IResource resource, final CustomTxtTraceDefinition definition, final String path, final int cacheSize) throws TmfTraceException {\r |
54 | this(definition);\r | |
55 | setCacheSize((cacheSize > 0) ? cacheSize : DEFAULT_CACHE_SIZE);\r | |
56 | initTrace(resource, path, CustomTxtEvent.class);\r | |
c3c5c786 FC |
57 | }\r |
58 | \r | |
1b70b6dc | 59 | @Override\r |
6256d8ad | 60 | public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> eventType) throws TmfTraceException {\r |
25e48683 | 61 | super.initTrace(resource, path, eventType);\r |
2a4fba11 PT |
62 | try {\r |
63 | fFile = new BufferedRandomAccessFile(getPath(), "r"); //$NON-NLS-1$\r | |
64 | } catch (IOException e) {\r | |
65 | throw new TmfTraceException(e.getMessage(), e);\r | |
66 | }\r | |
64e16ee9 | 67 | indexTrace(false);\r |
c3c5c786 FC |
68 | }\r |
69 | \r | |
70 | @Override\r | |
2a4fba11 PT |
71 | public synchronized void dispose() {\r |
72 | super.dispose();\r | |
73 | if (fFile != null) {\r | |
74 | try {\r | |
75 | fFile.close();\r | |
76 | } catch (IOException e) {\r | |
77 | } finally {\r | |
78 | fFile = null;\r | |
79 | }\r | |
80 | }\r | |
81 | }\r | |
82 | \r | |
83 | @Override\r | |
1e1bef82 | 84 | public synchronized TmfContext seekEvent(final ITmfLocation location) {\r |
2352aed9 | 85 | final CustomTxtTraceContext context = new CustomTxtTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK);\r |
2a4fba11 | 86 | if (NULL_LOCATION.equals(location) || fFile == null) {\r |
c3c5c786 | 87 | return context;\r |
2a4fba11 | 88 | }\r |
c3c5c786 | 89 | try {\r |
2a4fba11 PT |
90 | if (location == null) {\r |
91 | fFile.seek(0);\r | |
6bab4511 AM |
92 | } else if (location.getLocationData() instanceof Long) {\r |
93 | fFile.seek((Long) location.getLocationData());\r | |
09e86496 | 94 | }\r |
c3c5c786 | 95 | String line;\r |
2a4fba11 PT |
96 | long rawPos = fFile.getFilePointer();\r |
97 | while ((line = fFile.getNextLine()) != null) {\r | |
25e48683 FC |
98 | for (final InputLine input : getFirstLines()) {\r |
99 | final Matcher matcher = input.getPattern().matcher(line);\r | |
c3c5c786 | 100 | if (matcher.find()) {\r |
cb8c854e | 101 | context.setLocation(new TmfLongLocation(rawPos));\r |
c3c5c786 | 102 | context.firstLineMatcher = matcher;\r |
d7fcacc9 | 103 | context.firstLine = line;\r |
2a4fba11 | 104 | context.nextLineLocation = fFile.getFilePointer();\r |
c3c5c786 FC |
105 | context.inputLine = input;\r |
106 | return context;\r | |
107 | }\r | |
108 | }\r | |
2a4fba11 | 109 | rawPos = fFile.getFilePointer();\r |
c3c5c786 FC |
110 | }\r |
111 | return context;\r | |
25e48683 | 112 | } catch (final FileNotFoundException e) {\r |
8fd82db5 | 113 | Activator.getDefault().logError("Error seeking event. File not found: " + getPath(), e); //$NON-NLS-1$\r |
c3c5c786 | 114 | return context;\r |
25e48683 | 115 | } catch (final IOException e) {\r |
8fd82db5 | 116 | Activator.getDefault().logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$\r |
c3c5c786 FC |
117 | return context;\r |
118 | }\r | |
25e48683 | 119 | \r |
c3c5c786 FC |
120 | }\r |
121 | \r | |
c76c54bb | 122 | @Override\r |
2a4fba11 PT |
123 | public synchronized TmfContext seekEvent(final double ratio) {\r |
124 | if (fFile == null) {\r | |
125 | return new CustomTxtTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK);\r | |
126 | }\r | |
c76c54bb | 127 | try {\r |
2a4fba11 | 128 | long pos = (long) (ratio * fFile.length());\r |
a79913eb | 129 | while (pos > 0) {\r |
2a4fba11 PT |
130 | fFile.seek(pos - 1);\r |
131 | if (fFile.read() == '\n') {\r | |
09e86496 FC |
132 | break;\r |
133 | }\r | |
a79913eb FC |
134 | pos--;\r |
135 | }\r | |
1e1bef82 | 136 | final ITmfLocation location = new TmfLongLocation(pos);\r |
7e6347b0 | 137 | final TmfContext context = seekEvent(location);\r |
c76c54bb FC |
138 | context.setRank(ITmfContext.UNKNOWN_RANK);\r |
139 | return context;\r | |
25e48683 | 140 | } catch (final IOException e) {\r |
8fd82db5 | 141 | Activator.getDefault().logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$\r |
2352aed9 | 142 | return new CustomTxtTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK);\r |
c76c54bb FC |
143 | }\r |
144 | }\r | |
145 | \r | |
146 | @Override\r | |
1e1bef82 | 147 | public synchronized double getLocationRatio(final ITmfLocation location) {\r |
2a4fba11 PT |
148 | if (fFile == null) {\r |
149 | return 0;\r | |
150 | }\r | |
c76c54bb | 151 | try {\r |
6bab4511 AM |
152 | if (location.getLocationData() instanceof Long) {\r |
153 | return (double) ((Long) location.getLocationData()) / fFile.length();\r | |
c76c54bb | 154 | }\r |
25e48683 | 155 | } catch (final IOException e) {\r |
8fd82db5 | 156 | Activator.getDefault().logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$\r |
c76c54bb FC |
157 | }\r |
158 | return 0;\r | |
159 | }\r | |
160 | \r | |
c3c5c786 | 161 | @Override\r |
1e1bef82 | 162 | public ITmfLocation getCurrentLocation() {\r |
c3c5c786 FC |
163 | // TODO Auto-generated method stub\r |
164 | return null;\r | |
165 | }\r | |
166 | \r | |
2a4fba11 PT |
167 | @Override\r |
168 | public synchronized CustomTxtEvent parseEvent(final ITmfContext tmfContext) {\r | |
169 | ITmfContext context = seekEvent(tmfContext.getLocation());\r | |
170 | return parse(context);\r | |
171 | }\r | |
172 | \r | |
c3c5c786 | 173 | @Override\r |
c32744d6 | 174 | public synchronized CustomTxtEvent getNext(final ITmfContext context) {\r |
25e48683 | 175 | final ITmfContext savedContext = context.clone();\r |
2a4fba11 | 176 | final CustomTxtEvent event = parse(context);\r |
c3c5c786 | 177 | if (event != null) {\r |
d337369a | 178 | updateAttributes(savedContext, event.getTimestamp());\r |
cbdacf03 | 179 | context.increaseRank();\r |
c3c5c786 FC |
180 | }\r |
181 | return event;\r | |
182 | }\r | |
183 | \r | |
2a4fba11 PT |
184 | private synchronized CustomTxtEvent parse(final ITmfContext tmfContext) {\r |
185 | if (fFile == null) {\r | |
186 | return null;\r | |
187 | }\r | |
188 | if (!(tmfContext instanceof CustomTxtTraceContext)) {\r | |
c3c5c786 | 189 | return null;\r |
2a4fba11 | 190 | }\r |
25e48683 FC |
191 | \r |
192 | final CustomTxtTraceContext context = (CustomTxtTraceContext) tmfContext;\r | |
6bab4511 | 193 | if (!(context.getLocation().getLocationData() instanceof Long) || NULL_LOCATION.equals(context.getLocation())) {\r |
c3c5c786 | 194 | return null;\r |
2a4fba11 | 195 | }\r |
c3c5c786 FC |
196 | \r |
197 | CustomTxtEvent event = parseFirstLine(context);\r | |
198 | \r | |
25e48683 | 199 | final HashMap<InputLine, Integer> countMap = new HashMap<InputLine, Integer>();\r |
c3c5c786 FC |
200 | InputLine currentInput = null;\r |
201 | if (context.inputLine.childrenInputs != null && context.inputLine.childrenInputs.size() > 0) {\r | |
202 | currentInput = context.inputLine.childrenInputs.get(0);\r | |
203 | countMap.put(currentInput, 0);\r | |
204 | }\r | |
25e48683 | 205 | \r |
2a4fba11 PT |
206 | try {\r |
207 | if (fFile.getFilePointer() != context.nextLineLocation) {\r | |
208 | fFile.seek(context.nextLineLocation);\r | |
209 | }\r | |
210 | String line;\r | |
211 | long rawPos = fFile.getFilePointer();\r | |
212 | while ((line = fFile.getNextLine()) != null) {\r | |
213 | boolean processed = false;\r | |
214 | if (currentInput == null) {\r | |
215 | for (final InputLine input : getFirstLines()) {\r | |
216 | final Matcher matcher = input.getPattern().matcher(line);\r | |
217 | if (matcher.find()) {\r | |
cb8c854e | 218 | context.setLocation(new TmfLongLocation(rawPos));\r |
2a4fba11 PT |
219 | context.firstLineMatcher = matcher;\r |
220 | context.firstLine = line;\r | |
221 | context.nextLineLocation = fFile.getFilePointer();\r | |
222 | context.inputLine = input;\r | |
223 | return event;\r | |
c3c5c786 | 224 | }\r |
2a4fba11 PT |
225 | }\r |
226 | } else {\r | |
227 | if (countMap.get(currentInput) >= currentInput.getMinCount()) {\r | |
228 | final List<InputLine> nextInputs = currentInput.getNextInputs(countMap);\r | |
229 | if (nextInputs.size() == 0 || nextInputs.get(nextInputs.size() - 1).getMinCount() == 0) {\r | |
230 | for (final InputLine input : getFirstLines()) {\r | |
25e48683 | 231 | final Matcher matcher = input.getPattern().matcher(line);\r |
c3c5c786 | 232 | if (matcher.find()) {\r |
cb8c854e | 233 | context.setLocation(new TmfLongLocation(rawPos));\r |
2a4fba11 PT |
234 | context.firstLineMatcher = matcher;\r |
235 | context.firstLine = line;\r | |
236 | context.nextLineLocation = fFile.getFilePointer();\r | |
237 | context.inputLine = input;\r | |
238 | return event;\r | |
c3c5c786 FC |
239 | }\r |
240 | }\r | |
241 | }\r | |
2a4fba11 PT |
242 | for (final InputLine input : nextInputs) {\r |
243 | final Matcher matcher = input.getPattern().matcher(line);\r | |
c3c5c786 | 244 | if (matcher.find()) {\r |
2a4fba11 PT |
245 | event.processGroups(input, matcher);\r |
246 | currentInput = input;\r | |
247 | if (countMap.get(currentInput) == null) {\r | |
248 | countMap.put(currentInput, 1);\r | |
249 | } else {\r | |
250 | countMap.put(currentInput, countMap.get(currentInput) + 1);\r | |
251 | }\r | |
252 | Iterator<InputLine> iter = countMap.keySet().iterator();\r | |
253 | while (iter.hasNext()) {\r | |
254 | final InputLine inputLine = iter.next();\r | |
255 | if (inputLine.level > currentInput.level) {\r | |
256 | iter.remove();\r | |
257 | }\r | |
258 | }\r | |
c3c5c786 FC |
259 | if (currentInput.childrenInputs != null && currentInput.childrenInputs.size() > 0) {\r |
260 | currentInput = currentInput.childrenInputs.get(0);\r | |
261 | countMap.put(currentInput, 0);\r | |
2a4fba11 | 262 | } else if (countMap.get(currentInput) >= currentInput.getMaxCount()) {\r |
25e48683 FC |
263 | if (currentInput.getNextInputs(countMap).size() > 0) {\r |
264 | currentInput = currentInput.getNextInputs(countMap).get(0);\r | |
09e86496 | 265 | if (countMap.get(currentInput) == null) {\r |
25e48683 | 266 | countMap.put(currentInput, 0);\r |
09e86496 | 267 | }\r |
2a4fba11 | 268 | iter = countMap.keySet().iterator();\r |
25e48683 FC |
269 | while (iter.hasNext()) {\r |
270 | final InputLine inputLine = iter.next();\r | |
09e86496 | 271 | if (inputLine.level > currentInput.level) {\r |
25e48683 | 272 | iter.remove();\r |
09e86496 | 273 | }\r |
c3c5c786 | 274 | }\r |
09e86496 | 275 | } else {\r |
25e48683 | 276 | currentInput = null;\r |
09e86496 | 277 | }\r |
2a4fba11 PT |
278 | }\r |
279 | processed = true;\r | |
280 | break;\r | |
281 | }\r | |
282 | }\r | |
283 | }\r | |
284 | if (! processed) {\r | |
285 | final Matcher matcher = currentInput.getPattern().matcher(line);\r | |
286 | if (matcher.find()) {\r | |
287 | event.processGroups(currentInput, matcher);\r | |
288 | countMap.put(currentInput, countMap.get(currentInput) + 1);\r | |
289 | if (currentInput.childrenInputs != null && currentInput.childrenInputs.size() > 0) {\r | |
290 | currentInput = currentInput.childrenInputs.get(0);\r | |
291 | countMap.put(currentInput, 0);\r | |
292 | } else if (countMap.get(currentInput) >= currentInput.getMaxCount()) {\r | |
293 | if (currentInput.getNextInputs(countMap).size() > 0) {\r | |
294 | currentInput = currentInput.getNextInputs(countMap).get(0);\r | |
295 | if (countMap.get(currentInput) == null) {\r | |
296 | countMap.put(currentInput, 0);\r | |
297 | }\r | |
298 | final Iterator<InputLine> iter = countMap.keySet().iterator();\r | |
299 | while (iter.hasNext()) {\r | |
300 | final InputLine inputLine = iter.next();\r | |
301 | if (inputLine.level > currentInput.level) {\r | |
302 | iter.remove();\r | |
303 | }\r | |
304 | }\r | |
305 | } else {\r | |
306 | currentInput = null;\r | |
307 | }\r | |
c3c5c786 FC |
308 | }\r |
309 | }\r | |
2a4fba11 | 310 | ((StringBuffer) event.getContent().getValue()).append("\n").append(line); //$NON-NLS-1$\r |
c3c5c786 | 311 | }\r |
c3c5c786 | 312 | }\r |
2a4fba11 | 313 | rawPos = fFile.getFilePointer();\r |
c3c5c786 | 314 | }\r |
2a4fba11 PT |
315 | } catch (final IOException e) {\r |
316 | Activator.getDefault().logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$\r | |
c3c5c786 | 317 | }\r |
2a4fba11 | 318 | for (final Entry<InputLine, Integer> entry : countMap.entrySet()) {\r |
09e86496 | 319 | if (entry.getValue() < entry.getKey().getMinCount()) {\r |
c3c5c786 | 320 | event = null;\r |
09e86496 | 321 | }\r |
2a4fba11 | 322 | }\r |
d7fcacc9 | 323 | context.setLocation(NULL_LOCATION);\r |
c3c5c786 FC |
324 | return event;\r |
325 | }\r | |
326 | \r | |
327 | public List<InputLine> getFirstLines() {\r | |
328 | return fDefinition.inputs;\r | |
329 | }\r | |
25e48683 FC |
330 | \r |
331 | public CustomTxtEvent parseFirstLine(final CustomTxtTraceContext context) {\r | |
332 | final CustomTxtEvent event = new CustomTxtEvent(fDefinition, this, TmfTimestamp.ZERO, "", fEventType, ""); //$NON-NLS-1$ //$NON-NLS-2$\r | |
c3c5c786 | 333 | event.processGroups(context.inputLine, context.firstLineMatcher);\r |
2a4fba11 | 334 | event.setContent(new CustomEventContent(event, new StringBuffer(context.firstLine)));\r |
c3c5c786 FC |
335 | return event;\r |
336 | }\r | |
25e48683 | 337 | \r |
c3c5c786 FC |
338 | public CustomTraceDefinition getDefinition() {\r |
339 | return fDefinition;\r | |
340 | }\r | |
2352aed9 FC |
341 | \r |
342 | /* (non-Javadoc)\r | |
343 | * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#validate(org.eclipse.core.resources.IProject, java.lang.String)\r | |
344 | */\r | |
345 | @Override\r | |
346 | public boolean validate(IProject project, String path) {\r | |
347 | return fileExists(path);\r | |
348 | }\r | |
c3c5c786 | 349 | }\r |