tmf : Avoid concatenating nonliterals in a StringBuffer
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / parsers / custom / CustomXmlTrace.java
CommitLineData
6151d86c 1/*******************************************************************************
c9b31f60 2 * Copyright (c) 2010, 2015 Ericsson
6151d86c
PT
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
c9b31f60 11 * Bernd Hufmann - Add trace type id handling
6151d86c
PT
12 *******************************************************************************/
13
2bdf0193 14package org.eclipse.tracecompass.tmf.core.parsers.custom;
6151d86c
PT
15
16import java.io.ByteArrayInputStream;
eb8ea213 17import java.io.File;
6151d86c
PT
18import java.io.IOException;
19import java.io.RandomAccessFile;
032ecd45 20import java.nio.ByteBuffer;
6151d86c
PT
21
22import javax.xml.parsers.DocumentBuilder;
23import javax.xml.parsers.DocumentBuilderFactory;
24import javax.xml.parsers.ParserConfigurationException;
eb8ea213 25
6151d86c
PT
26import org.eclipse.core.resources.IProject;
27import org.eclipse.core.resources.IResource;
a3db8436
AM
28import org.eclipse.core.runtime.IStatus;
29import org.eclipse.core.runtime.Status;
c9b31f60 30import org.eclipse.jdt.annotation.NonNull;
2bdf0193 31import org.eclipse.tracecompass.internal.tmf.core.Activator;
b04903a2 32import org.eclipse.tracecompass.internal.tmf.core.parsers.custom.CustomEventAspects;
2bdf0193 33import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
b04903a2 34import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect;
2bdf0193
AM
35import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
36import org.eclipse.tracecompass.tmf.core.io.BufferedRandomAccessFile;
0bc16991
MAL
37import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
38import org.eclipse.tracecompass.tmf.core.signal.TmfTraceRangeUpdatedSignal;
2bdf0193
AM
39import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
40import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
2bdf0193 41import org.eclipse.tracecompass.tmf.core.trace.TmfContext;
c9b31f60 42import org.eclipse.tracecompass.tmf.core.trace.TmfTrace;
d26d67f5 43import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
2bdf0193
AM
44import org.eclipse.tracecompass.tmf.core.trace.TraceValidationStatus;
45import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfPersistentlyIndexable;
46import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfTraceIndexer;
47import org.eclipse.tracecompass.tmf.core.trace.indexer.TmfBTreeTraceIndexer;
48import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint;
49import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpoint;
50import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation;
51import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation;
6151d86c
PT
52import org.w3c.dom.Document;
53import org.w3c.dom.Element;
54import org.w3c.dom.Node;
55import org.w3c.dom.NodeList;
56import org.xml.sax.EntityResolver;
57import org.xml.sax.ErrorHandler;
58import org.xml.sax.InputSource;
59import org.xml.sax.SAXException;
60import org.xml.sax.SAXParseException;
61
a0a88f65
AM
62/**
63 * Trace object for custom XML trace parsers.
64 *
65 * @author Patrick Tassé
66 */
c9b31f60 67public class CustomXmlTrace extends TmfTrace implements ITmfPersistentlyIndexable {
6151d86c 68
661becf8 69 private static final TmfLongLocation NULL_LOCATION = new TmfLongLocation(-1L);
6151d86c 70 private static final int DEFAULT_CACHE_SIZE = 100;
cd43d683
PT
71 private static final int MAX_LINES = 100;
72 private static final int CONFIDENCE = 100;
6151d86c
PT
73
74 private final CustomXmlTraceDefinition fDefinition;
75 private final CustomXmlEventType fEventType;
a7418109 76 private final CustomXmlInputElement fRecordInputElement;
6151d86c 77 private BufferedRandomAccessFile fFile;
c9b31f60
BH
78 private final String fTraceTypeId;
79
80 private static final char SEPARATOR = ':';
81 private static final String CUSTOM_XML_TRACE_TYPE_PREFIX = "custom.xml.trace" + SEPARATOR; //$NON-NLS-1$
82 private static final String LINUX_TOOLS_CUSTOM_XML_TRACE_TYPE_PREFIX = "org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTrace" + SEPARATOR; //$NON-NLS-1$
83 private static final String EARLY_TRACE_COMPASS_CUSTOM_XML_TRACE_TYPE_PREFIX = "org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTrace" + SEPARATOR; //$NON-NLS-1$
6151d86c 84
a0a88f65
AM
85 /**
86 * Basic constructor
87 *
eb8ea213
MK
88 * @param definition
89 * Trace definition
a0a88f65 90 */
6151d86c
PT
91 public CustomXmlTrace(final CustomXmlTraceDefinition definition) {
92 fDefinition = definition;
93 fEventType = new CustomXmlEventType(fDefinition);
94 fRecordInputElement = getRecordInputElement(fDefinition.rootInputElement);
c9b31f60 95 fTraceTypeId = buildTraceTypeId(definition.categoryName, definition.definitionName);
6151d86c
PT
96 setCacheSize(DEFAULT_CACHE_SIZE);
97 }
98
a0a88f65
AM
99 /**
100 * Full constructor
101 *
102 * @param resource
103 * Trace resource
104 * @param definition
105 * Trace definition
106 * @param path
107 * Path to the trace/log file
108 * @param pageSize
109 * Page size to use
110 * @throws TmfTraceException
111 * If the trace/log couldn't be opened
112 */
113 public CustomXmlTrace(final IResource resource,
114 final CustomXmlTraceDefinition definition, final String path,
115 final int pageSize) throws TmfTraceException {
6151d86c
PT
116 this(definition);
117 setCacheSize((pageSize > 0) ? pageSize : DEFAULT_CACHE_SIZE);
118 initTrace(resource, path, CustomXmlEvent.class);
119 }
120
121 @Override
122 public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> eventType) throws TmfTraceException {
123 super.initTrace(resource, path, eventType);
0bc16991
MAL
124 initFile();
125 }
126
127 private void initFile() throws TmfTraceException {
128 closeFile();
6151d86c
PT
129 try {
130 fFile = new BufferedRandomAccessFile(getPath(), "r"); //$NON-NLS-1$
131 } catch (IOException e) {
132 throw new TmfTraceException(e.getMessage(), e);
133 }
6151d86c
PT
134 }
135
136 @Override
137 public synchronized void dispose() {
138 super.dispose();
0bc16991
MAL
139 closeFile();
140 }
141
142 private void closeFile() {
6151d86c
PT
143 if (fFile != null) {
144 try {
145 fFile.close();
146 } catch (IOException e) {
147 } finally {
148 fFile = null;
149 }
150 }
151 }
152
b0422293
PT
153 @Override
154 public ITmfTraceIndexer getIndexer() {
155 return super.getIndexer();
156 }
157
b04903a2
AM
158 @Override
159 public Iterable<ITmfEventAspect> getEventAspects() {
160 return CustomEventAspects.generateAspects(fDefinition);
161 }
162
6151d86c
PT
163 @Override
164 public synchronized TmfContext seekEvent(final ITmfLocation location) {
165 final CustomXmlTraceContext context = new CustomXmlTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK);
166 if (NULL_LOCATION.equals(location) || fFile == null) {
167 return context;
168 }
169 try {
170 if (location == null) {
171 fFile.seek(0);
172 } else if (location.getLocationInfo() instanceof Long) {
173 fFile.seek((Long) location.getLocationInfo());
174 }
6151d86c 175 long rawPos = fFile.getFilePointer();
cd43d683
PT
176 String line = fFile.getNextLine();
177 while (line != null) {
a7418109 178 final int idx = indexOfElement(fRecordInputElement.getElementName(), line, 0);
6151d86c
PT
179 if (idx != -1) {
180 context.setLocation(new TmfLongLocation(rawPos + idx));
181 return context;
182 }
183 rawPos = fFile.getFilePointer();
cd43d683 184 line = fFile.getNextLine();
6151d86c
PT
185 }
186 return context;
187 } catch (final IOException e) {
47aafe74 188 Activator.logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$
6151d86c
PT
189 return context;
190 }
191
192 }
193
194 @Override
195 public synchronized TmfContext seekEvent(final double ratio) {
196 if (fFile == null) {
197 return new CustomTxtTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK);
198 }
199 try {
91f6e587 200 long pos = Math.round(ratio * fFile.length());
6151d86c
PT
201 while (pos > 0) {
202 fFile.seek(pos - 1);
203 if (fFile.read() == '\n') {
204 break;
205 }
206 pos--;
207 }
208 final ITmfLocation location = new TmfLongLocation(pos);
209 final TmfContext context = seekEvent(location);
210 context.setRank(ITmfContext.UNKNOWN_RANK);
211 return context;
212 } catch (final IOException e) {
47aafe74 213 Activator.logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$
6151d86c
PT
214 return new CustomXmlTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK);
215 }
216 }
217
218 @Override
219 public synchronized double getLocationRatio(final ITmfLocation location) {
220 if (fFile == null) {
221 return 0;
222 }
223 try {
224 if (location.getLocationInfo() instanceof Long) {
0126a8ca 225 return ((Long) location.getLocationInfo()).doubleValue() / fFile.length();
6151d86c
PT
226 }
227 } catch (final IOException e) {
47aafe74 228 Activator.logError("Error getting location ration. File: " + getPath(), e); //$NON-NLS-1$
6151d86c
PT
229 }
230 return 0;
231 }
232
233 @Override
234 public ITmfLocation getCurrentLocation() {
235 // TODO Auto-generated method stub
236 return null;
237 }
238
239 @Override
240 public synchronized CustomXmlEvent parseEvent(final ITmfContext tmfContext) {
241 ITmfContext context = seekEvent(tmfContext.getLocation());
242 return parse(context);
243 }
244
245 @Override
246 public synchronized CustomXmlEvent getNext(final ITmfContext context) {
4c9f2944 247 final ITmfContext savedContext = new TmfContext(context.getLocation(), context.getRank());
6151d86c
PT
248 final CustomXmlEvent event = parse(context);
249 if (event != null) {
5904c11e 250 updateAttributes(savedContext, event);
6151d86c
PT
251 context.increaseRank();
252 }
253 return event;
254 }
255
256 private synchronized CustomXmlEvent parse(final ITmfContext tmfContext) {
257 if (fFile == null) {
258 return null;
259 }
260 if (!(tmfContext instanceof CustomXmlTraceContext)) {
261 return null;
262 }
263
264 final CustomXmlTraceContext context = (CustomXmlTraceContext) tmfContext;
9cbe7899 265 if (context.getLocation() == null || !(context.getLocation().getLocationInfo() instanceof Long) || NULL_LOCATION.equals(context.getLocation())) {
6151d86c
PT
266 return null;
267 }
268
269 CustomXmlEvent event = null;
270 try {
a7418109
MK
271 // Below +1 for the <
272 if (fFile.getFilePointer() != (Long) context.getLocation().getLocationInfo() + 1) {
273 fFile.seek((Long) context.getLocation().getLocationInfo() + 1);
6151d86c
PT
274 }
275 final StringBuffer elementBuffer = new StringBuffer("<"); //$NON-NLS-1$
276 readElement(elementBuffer, fFile);
277 final Element element = parseElementBuffer(elementBuffer);
278
279 event = extractEvent(element, fRecordInputElement);
280 ((StringBuffer) event.getContent().getValue()).append(elementBuffer);
281
6151d86c 282 long rawPos = fFile.getFilePointer();
cd43d683
PT
283 String line = fFile.getNextLine();
284 while (line != null) {
a7418109 285 final int idx = indexOfElement(fRecordInputElement.getElementName(), line, 0);
6151d86c
PT
286 if (idx != -1) {
287 context.setLocation(new TmfLongLocation(rawPos + idx));
288 return event;
289 }
290 rawPos = fFile.getFilePointer();
cd43d683 291 line = fFile.getNextLine();
6151d86c
PT
292 }
293 } catch (final IOException e) {
47aafe74 294 Activator.logError("Error parsing event. File: " + getPath(), e); //$NON-NLS-1$
6151d86c
PT
295
296 }
297 context.setLocation(NULL_LOCATION);
298 return event;
299 }
300
301 private Element parseElementBuffer(final StringBuffer elementBuffer) {
302 try {
303 final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
304 final DocumentBuilder db = dbf.newDocumentBuilder();
305
306 // The following allows xml parsing without access to the dtd
eb8ea213 307 final EntityResolver resolver = new EntityResolver() {
6151d86c 308 @Override
eb8ea213 309 public InputSource resolveEntity(final String publicId, final String systemId) {
6151d86c
PT
310 final String empty = ""; //$NON-NLS-1$
311 final ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());
312 return new InputSource(bais);
313 }
314 };
315 db.setEntityResolver(resolver);
316
317 // The following catches xml parsing exceptions
eb8ea213 318 db.setErrorHandler(new ErrorHandler() {
6151d86c 319 @Override
a7418109
MK
320 public void error(final SAXParseException saxparseexception) throws SAXException {
321 }
eb8ea213 322
6151d86c 323 @Override
a7418109
MK
324 public void warning(final SAXParseException saxparseexception) throws SAXException {
325 }
eb8ea213 326
6151d86c
PT
327 @Override
328 public void fatalError(final SAXParseException saxparseexception) throws SAXException {
329 throw saxparseexception;
eb8ea213
MK
330 }
331 });
6151d86c
PT
332
333 final Document doc = db.parse(new ByteArrayInputStream(elementBuffer.toString().getBytes()));
334 return doc.getDocumentElement();
335 } catch (final ParserConfigurationException e) {
47aafe74 336 Activator.logError("Error parsing element buffer. File:" + getPath(), e); //$NON-NLS-1$
6151d86c 337 } catch (final SAXException e) {
47aafe74 338 Activator.logError("Error parsing element buffer. File:" + getPath(), e); //$NON-NLS-1$
6151d86c 339 } catch (final IOException e) {
47aafe74 340 Activator.logError("Error parsing element buffer. File: " + getPath(), e); //$NON-NLS-1$
6151d86c
PT
341 }
342 return null;
343 }
344
9fa9acbb
PT
345 private static int indexOfElement(String elementName, String line, int fromIndex) {
346 final String recordElementStart = '<' + elementName;
347 int index = line.indexOf(recordElementStart, fromIndex);
348 if (index == -1) {
349 return index;
350 }
351 int nextCharIndex = index + recordElementStart.length();
352 if (nextCharIndex < line.length()) {
353 char c = line.charAt(nextCharIndex);
354 // Check that the match is not just a substring of another element
355 if (Character.isLetterOrDigit(c)) {
356 return indexOfElement(elementName, line, nextCharIndex);
357 }
358 }
359 return index;
360 }
361
6151d86c
PT
362 private void readElement(final StringBuffer buffer, final RandomAccessFile raFile) {
363 try {
364 int numRead = 0;
365 boolean startTagClosed = false;
366 int i;
367 while ((i = raFile.read()) != -1) {
368 numRead++;
eb8ea213 369 final char c = (char) i;
6151d86c
PT
370 buffer.append(c);
371 if (c == '"') {
372 readQuote(buffer, raFile, '"');
373 } else if (c == '\'') {
374 readQuote(buffer, raFile, '\'');
375 } else if (c == '<') {
376 readElement(buffer, raFile);
377 } else if (c == '/' && numRead == 1) {
378 break; // found "</"
379 } else if (c == '-' && numRead == 3 && buffer.substring(buffer.length() - 3, buffer.length() - 1).equals("!-")) { //$NON-NLS-1$
380 readComment(buffer, raFile); // found "<!--"
381 } else if (i == '>') {
382 if (buffer.charAt(buffer.length() - 2) == '/') {
383 break; // found "/>"
384 } else if (startTagClosed) {
385 break; // found "<...>...</...>"
386 }
387 else {
388 startTagClosed = true; // found "<...>"
389 }
390 }
391 }
392 return;
393 } catch (final IOException e) {
394 return;
395 }
396 }
397
398 private static void readQuote(final StringBuffer buffer,
399 final RandomAccessFile raFile, final char eq) {
400 try {
401 int i;
402 while ((i = raFile.read()) != -1) {
eb8ea213 403 final char c = (char) i;
6151d86c
PT
404 buffer.append(c);
405 if (c == eq)
406 {
407 break; // found matching end-quote
408 }
409 }
410 return;
411 } catch (final IOException e) {
412 return;
413 }
414 }
415
416 private static void readComment(final StringBuffer buffer,
417 final RandomAccessFile raFile) {
418 try {
419 int numRead = 0;
420 int i;
421 while ((i = raFile.read()) != -1) {
422 numRead++;
eb8ea213 423 final char c = (char) i;
6151d86c
PT
424 buffer.append(c);
425 if (c == '>' && numRead >= 2 && buffer.substring(buffer.length() - 3, buffer.length() - 1).equals("--")) //$NON-NLS-1$
426 {
427 break; // found "-->"
428 }
429 }
430 return;
431 } catch (final IOException e) {
432 return;
433 }
434 }
435
a0a88f65
AM
436 /**
437 * Parse an XML element.
438 *
439 * @param parentElement
440 * The parent element
441 * @param buffer
442 * The contents to parse
443 * @return The parsed content
444 */
6151d86c
PT
445 public static StringBuffer parseElement(final Element parentElement, final StringBuffer buffer) {
446 final NodeList nodeList = parentElement.getChildNodes();
447 String separator = null;
448 for (int i = 0; i < nodeList.getLength(); i++) {
449 final Node node = nodeList.item(i);
25d47c54
MK
450 short nodeType = node.getNodeType();
451 if (nodeType == Node.ELEMENT_NODE) {
6151d86c
PT
452 if (separator == null) {
453 separator = " | "; //$NON-NLS-1$
454 } else {
455 buffer.append(separator);
456 }
457 final Element element = (Element) node;
458 if (!element.hasChildNodes()) {
459 buffer.append(element.getNodeName());
460 } else if (element.getChildNodes().getLength() == 1 && element.getFirstChild().getNodeType() == Node.TEXT_NODE) {
0d57407a
JCK
461 buffer.append(element.getNodeName());
462 buffer.append(':');
463 buffer.append(element.getFirstChild().getNodeValue().trim());
6151d86c
PT
464 } else {
465 buffer.append(element.getNodeName());
466 buffer.append(" [ "); //$NON-NLS-1$
467 parseElement(element, buffer);
468 buffer.append(" ]"); //$NON-NLS-1$
469 }
25d47c54
MK
470 } else if ((nodeType == Node.TEXT_NODE) && (!node.getNodeValue().trim().isEmpty())) {
471 buffer.append(node.getNodeValue().trim());
6151d86c
PT
472 }
473 }
474 return buffer;
475 }
476
a0a88f65
AM
477 /**
478 * Get an input element if it is a valid record input. If not, we will look
479 * into its children for valid inputs.
480 *
481 * @param inputElement
482 * The main element to check for.
483 * @return The record element
484 */
a7418109
MK
485 public CustomXmlInputElement getRecordInputElement(final CustomXmlInputElement inputElement) {
486 if (inputElement.isLogEntry()) {
6151d86c 487 return inputElement;
a7418109
MK
488 } else if (inputElement.getChildElements() != null) {
489 for (final CustomXmlInputElement childInputElement : inputElement.getChildElements()) {
490 final CustomXmlInputElement recordInputElement = getRecordInputElement(childInputElement);
6151d86c
PT
491 if (recordInputElement != null) {
492 return recordInputElement;
493 }
494 }
495 }
496 return null;
497 }
498
a0a88f65
AM
499 /**
500 * Extract a trace event from an XML element.
501 *
502 * @param element
503 * The element
504 * @param inputElement
505 * The input element
506 * @return The extracted event
507 */
a7418109 508 public CustomXmlEvent extractEvent(final Element element, final CustomXmlInputElement inputElement) {
e1de2fd4 509 final CustomXmlEvent event = new CustomXmlEvent(fDefinition, this, TmfTimestamp.ZERO, fEventType);
6151d86c
PT
510 event.setContent(new CustomEventContent(event, new StringBuffer()));
511 parseElement(element, event, inputElement);
512 return event;
513 }
514
a7418109
MK
515 private void parseElement(final Element element, final CustomXmlEvent event, final CustomXmlInputElement inputElement) {
516 if (inputElement.getInputName() != null && !inputElement.getInputName().equals(CustomXmlTraceDefinition.TAG_IGNORE)) {
517 event.parseInput(parseElement(element, new StringBuffer()).toString(), inputElement.getInputName(), inputElement.getInputAction(), inputElement.getInputFormat());
6151d86c 518 }
a7418109
MK
519 if (inputElement.getAttributes() != null) {
520 for (final CustomXmlInputAttribute attribute : inputElement.getAttributes()) {
521 event.parseInput(element.getAttribute(attribute.getAttributeName()), attribute.getInputName(), attribute.getInputAction(), attribute.getInputFormat());
6151d86c
PT
522 }
523 }
524 final NodeList childNodes = element.getChildNodes();
a7418109 525 if (inputElement.getChildElements() != null) {
6151d86c
PT
526 for (int i = 0; i < childNodes.getLength(); i++) {
527 final Node node = childNodes.item(i);
528 if (node instanceof Element) {
a7418109
MK
529 for (final CustomXmlInputElement child : inputElement.getChildElements()) {
530 if (node.getNodeName().equals(child.getElementName())) {
6151d86c
PT
531 parseElement((Element) node, event, child);
532 break;
533 }
534 }
535 }
536 }
537 }
538 return;
539 }
540
a0a88f65
AM
541 /**
542 * Retrieve the trace definition.
543 *
544 * @return The trace definition
545 */
6151d86c
PT
546 public CustomTraceDefinition getDefinition() {
547 return fDefinition;
548 }
549
cd43d683
PT
550 /**
551 * {@inheritDoc}
552 * <p>
553 * The default implementation sets the confidence to 100 if any of the first
554 * 100 lines of the file contains a valid record input element, and 0
555 * otherwise.
556 */
6151d86c 557 @Override
a94410d9 558 public IStatus validate(IProject project, String path) {
cd43d683
PT
559 File file = new File(path);
560 if (!file.exists() || !file.isFile() || !file.canRead()) {
561 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CustomTrace_FileNotFound + ": " + path); //$NON-NLS-1$
562 }
d26d67f5
BH
563 try {
564 if (!TmfTraceUtils.isText(file)) {
565 return new TraceValidationStatus(0, Activator.PLUGIN_ID);
566 }
567 } catch (IOException e) {
568 Activator.logError("Error validating file: " + path, e); //$NON-NLS-1$
569 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "IOException validating file: " + path, e); //$NON-NLS-1$
570 }
cd43d683
PT
571 try (BufferedRandomAccessFile rafile = new BufferedRandomAccessFile(path, "r")) { //$NON-NLS-1$
572 int lineCount = 0;
cd43d683
PT
573 long rawPos = 0;
574 String line = rafile.getNextLine();
575 while ((line != null) && (lineCount++ < MAX_LINES)) {
a7418109 576 final int idx = indexOfElement(fRecordInputElement.getElementName(), line, 0);
cd43d683
PT
577 if (idx != -1) {
578 rafile.seek(rawPos + idx + 1); // +1 is for the <
579 final StringBuffer elementBuffer = new StringBuffer("<"); //$NON-NLS-1$
580 readElement(elementBuffer, rafile);
581 final Element element = parseElementBuffer(elementBuffer);
582 if (element != null) {
583 rafile.close();
584 return new TraceValidationStatus(CONFIDENCE, Activator.PLUGIN_ID);
eb8ea213 585 }
cd43d683
PT
586 }
587 rawPos = rafile.getFilePointer();
588 line = rafile.getNextLine();
eb8ea213 589 }
cd43d683
PT
590 } catch (IOException e) {
591 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "IOException validating file: " + path, e); //$NON-NLS-1$
a94410d9 592 }
cd43d683 593 return new TraceValidationStatus(0, Activator.PLUGIN_ID);
6151d86c 594 }
032ecd45
MAL
595
596 private static int fCheckpointSize = -1;
597
598 @Override
599 public synchronized int getCheckpointSize() {
600 if (fCheckpointSize == -1) {
601 TmfCheckpoint c = new TmfCheckpoint(TmfTimestamp.ZERO, new TmfLongLocation(0L), 0);
602 ByteBuffer b = ByteBuffer.allocate(ITmfCheckpoint.MAX_SERIALIZE_SIZE);
603 b.clear();
604 c.serialize(b);
605 fCheckpointSize = b.position();
606 }
607
608 return fCheckpointSize;
609 }
610
611 @Override
612 public ITmfLocation restoreLocation(ByteBuffer bufferIn) {
613 return new TmfLongLocation(bufferIn);
614 }
615
616 @Override
617 protected ITmfTraceIndexer createIndexer(int interval) {
618 return new TmfBTreeTraceIndexer(this, interval);
619 }
c9b31f60
BH
620
621 @Override
622 public String getTraceTypeId() {
623 return fTraceTypeId;
624 }
625
626 /**
627 * Build the trace type id for a custom XML trace
628 *
629 * @param category
630 * the category
631 * @param definitionName
632 * the definition name
633 * @return the trace type id
634 */
635 public static @NonNull String buildTraceTypeId(String category, String definitionName) {
636 return CUSTOM_XML_TRACE_TYPE_PREFIX + category + SEPARATOR + definitionName;
637 }
638
639 /**
640 * Checks whether the given trace type ID is a custom XML trace type ID
641 *
642 * @param traceTypeId
643 * the trace type ID to check
644 * @return <code>true</code> if it's a custom text trace type ID else <code>false</code>
645 */
646 public static boolean isCustomTraceTypeId(@NonNull String traceTypeId) {
647 return traceTypeId.startsWith(CUSTOM_XML_TRACE_TYPE_PREFIX);
648 }
649
650 /**
651 * This methods builds a trace type ID from a given ID taking into
652 * consideration any format changes that were done for the IDs of custom
653 * XML traces. For example, such format change took place when moving to
654 * Trace Compass. Trace type IDs that are part of the plug-in extension for
655 * trace types won't be changed.
656 *
657 * This method is useful for IDs that were persisted in the workspace before
658 * the format changes (e.g. in the persistent properties of a trace
659 * resource).
660 *
661 * It ensures backwards compatibility of the workspace for custom XML
662 * traces.
663 *
664 * @param traceTypeId
665 * the legacy trace type ID
666 * @return the trace type id in Trace Compass format
667 */
668 public static @NonNull String buildCompatibilityTraceTypeId(@NonNull String traceTypeId) {
669 // Handle early Trace Compass custom XML trace type IDs
670 if (traceTypeId.startsWith(EARLY_TRACE_COMPASS_CUSTOM_XML_TRACE_TYPE_PREFIX)) {
671 return CUSTOM_XML_TRACE_TYPE_PREFIX + traceTypeId.substring(EARLY_TRACE_COMPASS_CUSTOM_XML_TRACE_TYPE_PREFIX.length());
672 }
673
674 // Handle Linux Tools custom XML trace type IDs (with and without category)
675 int index = traceTypeId.lastIndexOf(SEPARATOR);
676 if ((index != -1) && (traceTypeId.startsWith(LINUX_TOOLS_CUSTOM_XML_TRACE_TYPE_PREFIX))) {
677 String definitionName = index < traceTypeId.length() ? traceTypeId.substring(index + 1) : ""; //$NON-NLS-1$
678 if (traceTypeId.contains(CustomXmlTrace.class.getSimpleName() + SEPARATOR) && traceTypeId.indexOf(SEPARATOR) == index) {
679 return buildTraceTypeId(CustomXmlTraceDefinition.CUSTOM_XML_CATEGORY, definitionName);
680 }
681 return CUSTOM_XML_TRACE_TYPE_PREFIX + traceTypeId.substring(LINUX_TOOLS_CUSTOM_XML_TRACE_TYPE_PREFIX.length());
682 }
683 return traceTypeId;
684 }
0bc16991
MAL
685
686 @TmfSignalHandler
687 @Override
688 public void traceRangeUpdated(TmfTraceRangeUpdatedSignal signal) {
689 if (signal.getTrace() == this) {
690 try {
691 synchronized (this) {
692 // Reset the file handle in case it has reached the end of the
693 // file already. Otherwise, it will not be able to read new data
694 // pass the previous end.
695 initFile();
696 }
697 } catch (TmfTraceException e) {
698 Activator.logError(e.getLocalizedMessage(), e);
699 }
700 }
701 super.traceRangeUpdated(signal);
702 }
6151d86c 703}
This page took 0.112989 seconds and 5 git commands to generate.