1 /*******************************************************************************
2 * Copyright (c) 2010 Ericsson
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
10 * Patrick Tasse - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
;
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
;
23 import org
.eclipse
.core
.resources
.IProject
;
24 import org
.eclipse
.core
.resources
.IResource
;
25 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.Activator
;
26 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomTxtTraceDefinition
.InputLine
;
27 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEvent
;
28 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfTimestamp
;
29 import org
.eclipse
.linuxtools
.tmf
.core
.exceptions
.TmfTraceException
;
30 import org
.eclipse
.linuxtools
.tmf
.core
.io
.BufferedRandomAccessFile
;
31 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfContext
;
32 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfEventParser
;
33 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfLocation
;
34 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfTraceIndexer
;
35 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfContext
;
36 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfLongLocation
;
37 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfTrace
;
39 public class CustomTxtTrace
extends TmfTrace
implements ITmfEventParser
{
41 private static final TmfLongLocation NULL_LOCATION
= new TmfLongLocation((Long
) null);
42 private static final int DEFAULT_CACHE_SIZE
= 100;
44 private final CustomTxtTraceDefinition fDefinition
;
45 private final CustomTxtEventType fEventType
;
46 private BufferedRandomAccessFile fFile
;
48 public CustomTxtTrace(final CustomTxtTraceDefinition definition
) {
49 fDefinition
= definition
;
50 fEventType
= new CustomTxtEventType(fDefinition
);
51 setCacheSize(DEFAULT_CACHE_SIZE
);
54 public CustomTxtTrace(final IResource resource
, final CustomTxtTraceDefinition definition
, final String path
, final int cacheSize
) throws TmfTraceException
{
56 setCacheSize((cacheSize
> 0) ? cacheSize
: DEFAULT_CACHE_SIZE
);
57 initTrace(resource
, path
, CustomTxtEvent
.class);
61 public void initTrace(final IResource resource
, final String path
, final Class
<?
extends ITmfEvent
> eventType
) throws TmfTraceException
{
62 super.initTrace(resource
, path
, eventType
);
64 fFile
= new BufferedRandomAccessFile(getPath(), "r"); //$NON-NLS-1$
65 } catch (IOException e
) {
66 throw new TmfTraceException(e
.getMessage(), e
);
71 public synchronized void dispose() {
76 } catch (IOException e
) {
84 public ITmfTraceIndexer
getIndexer() {
85 return super.getIndexer();
89 public synchronized TmfContext
seekEvent(final ITmfLocation location
) {
90 final CustomTxtTraceContext context
= new CustomTxtTraceContext(NULL_LOCATION
, ITmfContext
.UNKNOWN_RANK
);
91 if (NULL_LOCATION
.equals(location
) || fFile
== null) {
95 if (location
== null) {
97 } else if (location
.getLocationInfo() instanceof Long
) {
98 fFile
.seek((Long
) location
.getLocationInfo());
101 long rawPos
= fFile
.getFilePointer();
102 while ((line
= fFile
.getNextLine()) != null) {
103 for (final InputLine input
: getFirstLines()) {
104 final Matcher matcher
= input
.getPattern().matcher(line
);
105 if (matcher
.find()) {
106 context
.setLocation(new TmfLongLocation(rawPos
));
107 context
.firstLineMatcher
= matcher
;
108 context
.firstLine
= line
;
109 context
.nextLineLocation
= fFile
.getFilePointer();
110 context
.inputLine
= input
;
114 rawPos
= fFile
.getFilePointer();
117 } catch (final FileNotFoundException e
) {
118 Activator
.getDefault().logError("Error seeking event. File not found: " + getPath(), e
); //$NON-NLS-1$
120 } catch (final IOException e
) {
121 Activator
.getDefault().logError("Error seeking event. File: " + getPath(), e
); //$NON-NLS-1$
128 public synchronized TmfContext
seekEvent(final double ratio
) {
130 return new CustomTxtTraceContext(NULL_LOCATION
, ITmfContext
.UNKNOWN_RANK
);
133 long pos
= Math
.round(ratio
* fFile
.length());
136 if (fFile
.read() == '\n') {
141 final ITmfLocation location
= new TmfLongLocation(pos
);
142 final TmfContext context
= seekEvent(location
);
143 context
.setRank(ITmfContext
.UNKNOWN_RANK
);
145 } catch (final IOException e
) {
146 Activator
.getDefault().logError("Error seeking event. File: " + getPath(), e
); //$NON-NLS-1$
147 return new CustomTxtTraceContext(NULL_LOCATION
, ITmfContext
.UNKNOWN_RANK
);
152 public synchronized double getLocationRatio(final ITmfLocation location
) {
157 if (location
.getLocationInfo() instanceof Long
) {
158 return (double) ((Long
) location
.getLocationInfo()) / fFile
.length();
160 } catch (final IOException e
) {
161 Activator
.getDefault().logError("Error seeking event. File: " + getPath(), e
); //$NON-NLS-1$
167 public ITmfLocation
getCurrentLocation() {
168 // TODO Auto-generated method stub
173 public synchronized CustomTxtEvent
parseEvent(final ITmfContext tmfContext
) {
174 ITmfContext context
= seekEvent(tmfContext
.getLocation());
175 return parse(context
);
179 public synchronized CustomTxtEvent
getNext(final ITmfContext context
) {
180 final ITmfContext savedContext
= new TmfContext(context
.getLocation(), context
.getRank());
181 final CustomTxtEvent event
= parse(context
);
183 updateAttributes(savedContext
, event
.getTimestamp());
184 context
.increaseRank();
189 private synchronized CustomTxtEvent
parse(final ITmfContext tmfContext
) {
193 if (!(tmfContext
instanceof CustomTxtTraceContext
)) {
197 final CustomTxtTraceContext context
= (CustomTxtTraceContext
) tmfContext
;
198 if (context
.getLocation() == null || !(context
.getLocation().getLocationInfo() instanceof Long
) || NULL_LOCATION
.equals(context
.getLocation())) {
202 CustomTxtEvent event
= parseFirstLine(context
);
204 final HashMap
<InputLine
, Integer
> countMap
= new HashMap
<InputLine
, Integer
>();
205 InputLine currentInput
= null;
206 if (context
.inputLine
.childrenInputs
!= null && context
.inputLine
.childrenInputs
.size() > 0) {
207 currentInput
= context
.inputLine
.childrenInputs
.get(0);
208 countMap
.put(currentInput
, 0);
212 if (fFile
.getFilePointer() != context
.nextLineLocation
) {
213 fFile
.seek(context
.nextLineLocation
);
216 long rawPos
= fFile
.getFilePointer();
217 while ((line
= fFile
.getNextLine()) != null) {
218 boolean processed
= false;
219 if (currentInput
== null) {
220 for (final InputLine input
: getFirstLines()) {
221 final Matcher matcher
= input
.getPattern().matcher(line
);
222 if (matcher
.find()) {
223 context
.setLocation(new TmfLongLocation(rawPos
));
224 context
.firstLineMatcher
= matcher
;
225 context
.firstLine
= line
;
226 context
.nextLineLocation
= fFile
.getFilePointer();
227 context
.inputLine
= input
;
232 if (countMap
.get(currentInput
) >= currentInput
.getMinCount()) {
233 final List
<InputLine
> nextInputs
= currentInput
.getNextInputs(countMap
);
234 if (nextInputs
.size() == 0 || nextInputs
.get(nextInputs
.size() - 1).getMinCount() == 0) {
235 for (final InputLine input
: getFirstLines()) {
236 final Matcher matcher
= input
.getPattern().matcher(line
);
237 if (matcher
.find()) {
238 context
.setLocation(new TmfLongLocation(rawPos
));
239 context
.firstLineMatcher
= matcher
;
240 context
.firstLine
= line
;
241 context
.nextLineLocation
= fFile
.getFilePointer();
242 context
.inputLine
= input
;
247 for (final InputLine input
: nextInputs
) {
248 final Matcher matcher
= input
.getPattern().matcher(line
);
249 if (matcher
.find()) {
250 event
.processGroups(input
, matcher
);
251 currentInput
= input
;
252 if (countMap
.get(currentInput
) == null) {
253 countMap
.put(currentInput
, 1);
255 countMap
.put(currentInput
, countMap
.get(currentInput
) + 1);
257 Iterator
<InputLine
> iter
= countMap
.keySet().iterator();
258 while (iter
.hasNext()) {
259 final InputLine inputLine
= iter
.next();
260 if (inputLine
.level
> currentInput
.level
) {
264 if (currentInput
.childrenInputs
!= null && currentInput
.childrenInputs
.size() > 0) {
265 currentInput
= currentInput
.childrenInputs
.get(0);
266 countMap
.put(currentInput
, 0);
267 } else if (countMap
.get(currentInput
) >= currentInput
.getMaxCount()) {
268 if (currentInput
.getNextInputs(countMap
).size() > 0) {
269 currentInput
= currentInput
.getNextInputs(countMap
).get(0);
270 if (countMap
.get(currentInput
) == null) {
271 countMap
.put(currentInput
, 0);
273 iter
= countMap
.keySet().iterator();
274 while (iter
.hasNext()) {
275 final InputLine inputLine
= iter
.next();
276 if (inputLine
.level
> currentInput
.level
) {
290 final Matcher matcher
= currentInput
.getPattern().matcher(line
);
291 if (matcher
.find()) {
292 event
.processGroups(currentInput
, matcher
);
293 countMap
.put(currentInput
, countMap
.get(currentInput
) + 1);
294 if (currentInput
.childrenInputs
!= null && currentInput
.childrenInputs
.size() > 0) {
295 currentInput
= currentInput
.childrenInputs
.get(0);
296 countMap
.put(currentInput
, 0);
297 } else if (countMap
.get(currentInput
) >= currentInput
.getMaxCount()) {
298 if (currentInput
.getNextInputs(countMap
).size() > 0) {
299 currentInput
= currentInput
.getNextInputs(countMap
).get(0);
300 if (countMap
.get(currentInput
) == null) {
301 countMap
.put(currentInput
, 0);
303 final Iterator
<InputLine
> iter
= countMap
.keySet().iterator();
304 while (iter
.hasNext()) {
305 final InputLine inputLine
= iter
.next();
306 if (inputLine
.level
> currentInput
.level
) {
315 ((StringBuffer
) event
.getContent().getValue()).append("\n").append(line
); //$NON-NLS-1$
318 rawPos
= fFile
.getFilePointer();
320 } catch (final IOException e
) {
321 Activator
.getDefault().logError("Error seeking event. File: " + getPath(), e
); //$NON-NLS-1$
323 for (final Entry
<InputLine
, Integer
> entry
: countMap
.entrySet()) {
324 if (entry
.getValue() < entry
.getKey().getMinCount()) {
328 context
.setLocation(NULL_LOCATION
);
332 public List
<InputLine
> getFirstLines() {
333 return fDefinition
.inputs
;
336 public CustomTxtEvent
parseFirstLine(final CustomTxtTraceContext context
) {
337 final CustomTxtEvent event
= new CustomTxtEvent(fDefinition
, this, TmfTimestamp
.ZERO
, "", fEventType
, ""); //$NON-NLS-1$ //$NON-NLS-2$
338 event
.processGroups(context
.inputLine
, context
.firstLineMatcher
);
339 event
.setContent(new CustomEventContent(event
, new StringBuffer(context
.firstLine
)));
343 public CustomTraceDefinition
getDefinition() {
348 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#validate(org.eclipse.core.resources.IProject, java.lang.String)
351 public boolean validate(IProject project
, String path
) {
352 return fileExists(path
);