tmf: Clean up tmf.core.trace package
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / internal / tmf / ui / parsers / custom / CustomTxtTrace.java
1 /*******************************************************************************
2 * Copyright (c) 2010, 2013 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Patrick Tasse - Initial API and implementation
11 *******************************************************************************/
12
13 package org.eclipse.linuxtools.internal.tmf.ui.parsers.custom;
14
15 import java.io.FileNotFoundException;
16 import java.io.IOException;
17 import java.util.HashMap;
18 import java.util.Iterator;
19 import java.util.List;
20 import java.util.Map.Entry;
21 import java.util.regex.Matcher;
22
23 import org.eclipse.core.resources.IProject;
24 import org.eclipse.core.resources.IResource;
25 import org.eclipse.core.runtime.IStatus;
26 import org.eclipse.core.runtime.Status;
27 import org.eclipse.linuxtools.internal.tmf.ui.Activator;
28 import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomTxtTraceDefinition.InputLine;
29 import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
30 import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
31 import org.eclipse.linuxtools.tmf.core.io.BufferedRandomAccessFile;
32 import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
33 import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
34 import org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser;
35 import org.eclipse.linuxtools.tmf.core.trace.TmfContext;
36 import org.eclipse.linuxtools.tmf.core.trace.TmfTrace;
37 import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer;
38 import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation;
39 import org.eclipse.linuxtools.tmf.core.trace.location.TmfLongLocation;
40
41 /**
42 * Base class for custom plain text traces.
43 *
44 * @author Patrick Tassé
45 */
46 public class CustomTxtTrace extends TmfTrace implements ITmfEventParser {
47
48 private static final TmfLongLocation NULL_LOCATION = new TmfLongLocation((Long) null);
49 private static final int DEFAULT_CACHE_SIZE = 100;
50
51 private final CustomTxtTraceDefinition fDefinition;
52 private final CustomTxtEventType fEventType;
53 private BufferedRandomAccessFile fFile;
54
55 /**
56 * Basic constructor.
57 *
58 * @param definition
59 * Text trace definition
60 */
61 public CustomTxtTrace(final CustomTxtTraceDefinition definition) {
62 fDefinition = definition;
63 fEventType = new CustomTxtEventType(fDefinition);
64 setCacheSize(DEFAULT_CACHE_SIZE);
65 }
66
67 /**
68 * Full constructor.
69 *
70 * @param resource
71 * Trace's resource.
72 * @param definition
73 * Text trace definition
74 * @param path
75 * Path to the trace file
76 * @param cacheSize
77 * Cache size to use
78 * @throws TmfTraceException
79 * If we couldn't open the trace at 'path'
80 */
81 public CustomTxtTrace(final IResource resource,
82 final CustomTxtTraceDefinition definition, final String path,
83 final int cacheSize) throws TmfTraceException {
84 this(definition);
85 setCacheSize((cacheSize > 0) ? cacheSize : DEFAULT_CACHE_SIZE);
86 initTrace(resource, path, CustomTxtEvent.class);
87 }
88
89 @Override
90 public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> eventType) throws TmfTraceException {
91 super.initTrace(resource, path, eventType);
92 try {
93 fFile = new BufferedRandomAccessFile(getPath(), "r"); //$NON-NLS-1$
94 } catch (IOException e) {
95 throw new TmfTraceException(e.getMessage(), e);
96 }
97 }
98
99 @Override
100 public synchronized void dispose() {
101 super.dispose();
102 if (fFile != null) {
103 try {
104 fFile.close();
105 } catch (IOException e) {
106 } finally {
107 fFile = null;
108 }
109 }
110 }
111
112 @Override
113 public ITmfTraceIndexer getIndexer() {
114 return super.getIndexer();
115 }
116
117 @Override
118 public synchronized TmfContext seekEvent(final ITmfLocation location) {
119 final CustomTxtTraceContext context = new CustomTxtTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK);
120 if (NULL_LOCATION.equals(location) || fFile == null) {
121 return context;
122 }
123 try {
124 if (location == null) {
125 fFile.seek(0);
126 } else if (location.getLocationInfo() instanceof Long) {
127 fFile.seek((Long) location.getLocationInfo());
128 }
129 String line;
130 long rawPos = fFile.getFilePointer();
131 while ((line = fFile.getNextLine()) != null) {
132 for (final InputLine input : getFirstLines()) {
133 final Matcher matcher = input.getPattern().matcher(line);
134 if (matcher.find()) {
135 context.setLocation(new TmfLongLocation(rawPos));
136 context.firstLineMatcher = matcher;
137 context.firstLine = line;
138 context.nextLineLocation = fFile.getFilePointer();
139 context.inputLine = input;
140 return context;
141 }
142 }
143 rawPos = fFile.getFilePointer();
144 }
145 return context;
146 } catch (final FileNotFoundException e) {
147 Activator.getDefault().logError("Error seeking event. File not found: " + getPath(), e); //$NON-NLS-1$
148 return context;
149 } catch (final IOException e) {
150 Activator.getDefault().logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$
151 return context;
152 }
153
154 }
155
156 @Override
157 public synchronized TmfContext seekEvent(final double ratio) {
158 if (fFile == null) {
159 return new CustomTxtTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK);
160 }
161 try {
162 long pos = Math.round(ratio * fFile.length());
163 while (pos > 0) {
164 fFile.seek(pos - 1);
165 if (fFile.read() == '\n') {
166 break;
167 }
168 pos--;
169 }
170 final ITmfLocation location = new TmfLongLocation(pos);
171 final TmfContext context = seekEvent(location);
172 context.setRank(ITmfContext.UNKNOWN_RANK);
173 return context;
174 } catch (final IOException e) {
175 Activator.getDefault().logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$
176 return new CustomTxtTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK);
177 }
178 }
179
180 @Override
181 public synchronized double getLocationRatio(final ITmfLocation location) {
182 if (fFile == null) {
183 return 0;
184 }
185 try {
186 if (location.getLocationInfo() instanceof Long) {
187 return (double) ((Long) location.getLocationInfo()) / fFile.length();
188 }
189 } catch (final IOException e) {
190 Activator.getDefault().logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$
191 }
192 return 0;
193 }
194
195 @Override
196 public ITmfLocation getCurrentLocation() {
197 // TODO Auto-generated method stub
198 return null;
199 }
200
201 @Override
202 public synchronized CustomTxtEvent parseEvent(final ITmfContext tmfContext) {
203 ITmfContext context = seekEvent(tmfContext.getLocation());
204 return parse(context);
205 }
206
207 @Override
208 public synchronized CustomTxtEvent getNext(final ITmfContext context) {
209 final ITmfContext savedContext = new TmfContext(context.getLocation(), context.getRank());
210 final CustomTxtEvent event = parse(context);
211 if (event != null) {
212 updateAttributes(savedContext, event.getTimestamp());
213 context.increaseRank();
214 }
215 return event;
216 }
217
218 private synchronized CustomTxtEvent parse(final ITmfContext tmfContext) {
219 if (fFile == null) {
220 return null;
221 }
222 if (!(tmfContext instanceof CustomTxtTraceContext)) {
223 return null;
224 }
225
226 final CustomTxtTraceContext context = (CustomTxtTraceContext) tmfContext;
227 if (context.getLocation() == null || !(context.getLocation().getLocationInfo() instanceof Long) || NULL_LOCATION.equals(context.getLocation())) {
228 return null;
229 }
230
231 CustomTxtEvent event = parseFirstLine(context);
232
233 final HashMap<InputLine, Integer> countMap = new HashMap<InputLine, Integer>();
234 InputLine currentInput = null;
235 if (context.inputLine.childrenInputs != null && context.inputLine.childrenInputs.size() > 0) {
236 currentInput = context.inputLine.childrenInputs.get(0);
237 countMap.put(currentInput, 0);
238 }
239
240 try {
241 if (fFile.getFilePointer() != context.nextLineLocation) {
242 fFile.seek(context.nextLineLocation);
243 }
244 String line;
245 long rawPos = fFile.getFilePointer();
246 while ((line = fFile.getNextLine()) != null) {
247 boolean processed = false;
248 if (currentInput == null) {
249 for (final InputLine input : getFirstLines()) {
250 final Matcher matcher = input.getPattern().matcher(line);
251 if (matcher.find()) {
252 context.setLocation(new TmfLongLocation(rawPos));
253 context.firstLineMatcher = matcher;
254 context.firstLine = line;
255 context.nextLineLocation = fFile.getFilePointer();
256 context.inputLine = input;
257 return event;
258 }
259 }
260 } else {
261 if (countMap.get(currentInput) >= currentInput.getMinCount()) {
262 final List<InputLine> nextInputs = currentInput.getNextInputs(countMap);
263 if (nextInputs.size() == 0 || nextInputs.get(nextInputs.size() - 1).getMinCount() == 0) {
264 for (final InputLine input : getFirstLines()) {
265 final Matcher matcher = input.getPattern().matcher(line);
266 if (matcher.find()) {
267 context.setLocation(new TmfLongLocation(rawPos));
268 context.firstLineMatcher = matcher;
269 context.firstLine = line;
270 context.nextLineLocation = fFile.getFilePointer();
271 context.inputLine = input;
272 return event;
273 }
274 }
275 }
276 for (final InputLine input : nextInputs) {
277 final Matcher matcher = input.getPattern().matcher(line);
278 if (matcher.find()) {
279 event.processGroups(input, matcher);
280 currentInput = input;
281 if (countMap.get(currentInput) == null) {
282 countMap.put(currentInput, 1);
283 } else {
284 countMap.put(currentInput, countMap.get(currentInput) + 1);
285 }
286 Iterator<InputLine> iter = countMap.keySet().iterator();
287 while (iter.hasNext()) {
288 final InputLine inputLine = iter.next();
289 if (inputLine.level > currentInput.level) {
290 iter.remove();
291 }
292 }
293 if (currentInput.childrenInputs != null && currentInput.childrenInputs.size() > 0) {
294 currentInput = currentInput.childrenInputs.get(0);
295 countMap.put(currentInput, 0);
296 } else if (countMap.get(currentInput) >= currentInput.getMaxCount()) {
297 if (currentInput.getNextInputs(countMap).size() > 0) {
298 currentInput = currentInput.getNextInputs(countMap).get(0);
299 if (countMap.get(currentInput) == null) {
300 countMap.put(currentInput, 0);
301 }
302 iter = countMap.keySet().iterator();
303 while (iter.hasNext()) {
304 final InputLine inputLine = iter.next();
305 if (inputLine.level > currentInput.level) {
306 iter.remove();
307 }
308 }
309 } else {
310 currentInput = null;
311 }
312 }
313 processed = true;
314 break;
315 }
316 }
317 }
318 if (!processed && currentInput != null) {
319 final Matcher matcher = currentInput.getPattern().matcher(line);
320 if (matcher.find()) {
321 event.processGroups(currentInput, matcher);
322 countMap.put(currentInput, countMap.get(currentInput) + 1);
323 if (currentInput.childrenInputs != null && currentInput.childrenInputs.size() > 0) {
324 currentInput = currentInput.childrenInputs.get(0);
325 countMap.put(currentInput, 0);
326 } else if (countMap.get(currentInput) >= currentInput.getMaxCount()) {
327 if (currentInput.getNextInputs(countMap).size() > 0) {
328 currentInput = currentInput.getNextInputs(countMap).get(0);
329 if (countMap.get(currentInput) == null) {
330 countMap.put(currentInput, 0);
331 }
332 final Iterator<InputLine> iter = countMap.keySet().iterator();
333 while (iter.hasNext()) {
334 final InputLine inputLine = iter.next();
335 if (inputLine.level > currentInput.level) {
336 iter.remove();
337 }
338 }
339 } else {
340 currentInput = null;
341 }
342 }
343 }
344 ((StringBuffer) event.getContent().getValue()).append("\n").append(line); //$NON-NLS-1$
345 }
346 }
347 rawPos = fFile.getFilePointer();
348 }
349 } catch (final IOException e) {
350 Activator.getDefault().logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$
351 }
352 for (final Entry<InputLine, Integer> entry : countMap.entrySet()) {
353 if (entry.getValue() < entry.getKey().getMinCount()) {
354 event = null;
355 }
356 }
357 context.setLocation(NULL_LOCATION);
358 return event;
359 }
360
361 /**
362 * @return The first few lines of the text file
363 */
364 public List<InputLine> getFirstLines() {
365 return fDefinition.inputs;
366 }
367
368 /**
369 * Parse the first line of the trace (to recognize the type).
370 *
371 * @param context
372 * Trace context
373 * @return The first event
374 */
375 public CustomTxtEvent parseFirstLine(final CustomTxtTraceContext context) {
376 final CustomTxtEvent event = new CustomTxtEvent(fDefinition, this, TmfTimestamp.ZERO, "", fEventType, ""); //$NON-NLS-1$ //$NON-NLS-2$
377 event.processGroups(context.inputLine, context.firstLineMatcher);
378 event.setContent(new CustomEventContent(event, new StringBuffer(context.firstLine)));
379 return event;
380 }
381
382 /**
383 * Get the trace definition.
384 *
385 * @return The trace definition
386 */
387 public CustomTraceDefinition getDefinition() {
388 return fDefinition;
389 }
390
391 @Override
392 public IStatus validate(IProject project, String path) {
393 if( fileExists(path)) {
394 return Status.OK_STATUS;
395 }
396 return new Status(IStatus.ERROR, Activator.PLUGIN_ID ,Messages.CustomTrace_FileNotFound + ": " + path); //$NON-NLS-1$
397 }
398 }
This page took 0.040393 seconds and 5 git commands to generate.