Merge branch 'master' into lttng-kepler
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / internal / tmf / ui / parsers / custom / CustomXmlTrace.java
index 93e1fbbd115301c515e54ba8744e43ba0f6bdd77..338c0315a6d7898f41980e6369bf903876fb1f85 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2010 Ericsson\r
- *\r
- * All rights reserved. This program and the accompanying materials are\r
- * made available under the terms of the Eclipse Public License v1.0 which\r
- * accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *   Patrick Tasse - Initial API and implementation\r
- *******************************************************************************/\r
-\r
-package org.eclipse.linuxtools.internal.tmf.ui.parsers.custom;\r
-\r
-import java.io.ByteArrayInputStream;\r
-import java.io.IOException;\r
-import java.io.RandomAccessFile;\r
-\r
-import javax.xml.parsers.DocumentBuilder;\r
-import javax.xml.parsers.DocumentBuilderFactory;\r
-import javax.xml.parsers.ParserConfigurationException;\r
-\r
-import org.eclipse.core.resources.IProject;\r
-import org.eclipse.core.resources.IResource;\r
-import org.eclipse.linuxtools.internal.tmf.ui.Activator;\r
-import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomXmlTraceDefinition.InputAttribute;\r
-import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomXmlTraceDefinition.InputElement;\r
-import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;\r
-import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;\r
-import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;\r
-import org.eclipse.linuxtools.tmf.core.io.BufferedRandomAccessFile;\r
-import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;\r
-import org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser;\r
-import org.eclipse.linuxtools.tmf.core.trace.ITmfLocation;\r
-import org.eclipse.linuxtools.tmf.core.trace.TmfContext;\r
-import org.eclipse.linuxtools.tmf.core.trace.TmfLongLocation;\r
-import org.eclipse.linuxtools.tmf.core.trace.TmfTrace;\r
-import org.w3c.dom.Document;\r
-import org.w3c.dom.Element;\r
-import org.w3c.dom.Node;\r
-import org.w3c.dom.NodeList;\r
-import org.xml.sax.EntityResolver;\r
-import org.xml.sax.ErrorHandler;\r
-import org.xml.sax.InputSource;\r
-import org.xml.sax.SAXException;\r
-import org.xml.sax.SAXParseException;\r
-\r
-public class CustomXmlTrace extends TmfTrace implements ITmfEventParser {\r
-\r
-    private static final TmfLongLocation NULL_LOCATION = new TmfLongLocation((Long) null);\r
-    private static final int DEFAULT_CACHE_SIZE = 100;\r
-\r
-    private final CustomXmlTraceDefinition fDefinition;\r
-    private final CustomXmlEventType fEventType;\r
-    private final InputElement fRecordInputElement;\r
-    private BufferedRandomAccessFile fFile;\r
-\r
-    public CustomXmlTrace(final CustomXmlTraceDefinition definition) {\r
-        fDefinition = definition;\r
-        fEventType = new CustomXmlEventType(fDefinition);\r
-        fRecordInputElement = getRecordInputElement(fDefinition.rootInputElement);\r
-        setCacheSize(DEFAULT_CACHE_SIZE);\r
-    }\r
-\r
-    public CustomXmlTrace(final IResource resource, final CustomXmlTraceDefinition definition, final String path, final int pageSize) throws TmfTraceException {\r
-        this(definition);\r
-        setCacheSize((pageSize > 0) ? pageSize : DEFAULT_CACHE_SIZE);\r
-        initTrace(resource, path, CustomXmlEvent.class);\r
-    }\r
-\r
-    @Override\r
-    public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> eventType) throws TmfTraceException {\r
-        super.initTrace(resource, path, eventType);\r
-        try {\r
-            fFile = new BufferedRandomAccessFile(getPath(), "r"); //$NON-NLS-1$\r
-        } catch (IOException e) {\r
-            throw new TmfTraceException(e.getMessage(), e);\r
-        }\r
-        indexTrace(false);\r
-    }\r
-\r
-    @Override\r
-    public synchronized void dispose() {\r
-        super.dispose();\r
-        if (fFile != null) {\r
-            try {\r
-                fFile.close();\r
-            } catch (IOException e) {\r
-            } finally {\r
-                fFile = null;\r
-            }\r
-        }\r
-    }\r
-\r
-    @Override\r
-    public synchronized TmfContext seekEvent(final ITmfLocation location) {\r
-        final CustomXmlTraceContext context = new CustomXmlTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK);\r
-        if (NULL_LOCATION.equals(location) || fFile == null) {\r
-            return context;\r
-        }\r
-        try {\r
-            if (location == null) {\r
-                fFile.seek(0);\r
-            } else if (location.getLocationInfo() instanceof Long) {\r
-                fFile.seek((Long) location.getLocationInfo());\r
-            }\r
-            String line;\r
-            final String recordElementStart = "<" + fRecordInputElement.elementName; //$NON-NLS-1$\r
-            long rawPos = fFile.getFilePointer();\r
-\r
-            while ((line = fFile.getNextLine()) != null) {\r
-                final int idx = line.indexOf(recordElementStart);\r
-                if (idx != -1) {\r
-                    context.setLocation(new TmfLongLocation(rawPos + idx));\r
-                    return context;\r
-                }\r
-                rawPos = fFile.getFilePointer();\r
-            }\r
-            return context;\r
-        } catch (final IOException e) {\r
-            Activator.getDefault().logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$\r
-            return context;\r
-        }\r
-\r
-    }\r
-\r
-    @Override\r
-    public synchronized TmfContext seekEvent(final double ratio) {\r
-        if (fFile == null) {\r
-            return new CustomTxtTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK);\r
-        }\r
-        try {\r
-            long pos = (long) (ratio * fFile.length());\r
-            while (pos > 0) {\r
-                fFile.seek(pos - 1);\r
-                if (fFile.read() == '\n') {\r
-                    break;\r
-                }\r
-                pos--;\r
-            }\r
-            final ITmfLocation location = new TmfLongLocation(pos);\r
-            final TmfContext context = seekEvent(location);\r
-            context.setRank(ITmfContext.UNKNOWN_RANK);\r
-            return context;\r
-        } catch (final IOException e) {\r
-            Activator.getDefault().logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$\r
-            return new CustomXmlTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK);\r
-        }\r
-    }\r
-\r
-    @Override\r
-    public synchronized double getLocationRatio(final ITmfLocation location) {\r
-        if (fFile == null) {\r
-            return 0;\r
-        }\r
-        try {\r
-            if (location.getLocationInfo() instanceof Long) {\r
-                return (double) ((Long) location.getLocationInfo()) / fFile.length();\r
-            }\r
-        } catch (final IOException e) {\r
-            Activator.getDefault().logError("Error getting location ration. File: " + getPath(), e); //$NON-NLS-1$\r
-        }\r
-        return 0;\r
-    }\r
-\r
-    @Override\r
-    public ITmfLocation getCurrentLocation() {\r
-        // TODO Auto-generated method stub\r
-        return null;\r
-    }\r
-\r
-    @Override\r
-    public synchronized CustomXmlEvent parseEvent(final ITmfContext tmfContext) {\r
-        ITmfContext context = seekEvent(tmfContext.getLocation());\r
-        return parse(context);\r
-    }\r
-\r
-    @Override\r
-    public synchronized CustomXmlEvent getNext(final ITmfContext context) {\r
-        final ITmfContext savedContext = context.clone();\r
-        final CustomXmlEvent event = parse(context);\r
-        if (event != null) {\r
-            updateAttributes(savedContext, event.getTimestamp());\r
-            context.increaseRank();\r
-        }\r
-        return event;\r
-    }\r
-\r
-    private synchronized CustomXmlEvent parse(final ITmfContext tmfContext) {\r
-        if (fFile == null) {\r
-            return null;\r
-        }\r
-        if (!(tmfContext instanceof CustomXmlTraceContext)) {\r
-            return null;\r
-        }\r
-\r
-        final CustomXmlTraceContext context = (CustomXmlTraceContext) tmfContext;\r
-        if (!(context.getLocation().getLocationInfo() instanceof Long) || NULL_LOCATION.equals(context.getLocation())) {\r
-            return null;\r
-        }\r
-\r
-        CustomXmlEvent event = null;\r
-        try {\r
-            if (fFile.getFilePointer() != (Long)context.getLocation().getLocationInfo() + 1)\r
-            {\r
-                fFile.seek((Long)context.getLocation().getLocationInfo() + 1); // +1 is for the <\r
-            }\r
-            final StringBuffer elementBuffer = new StringBuffer("<"); //$NON-NLS-1$\r
-            readElement(elementBuffer, fFile);\r
-            final Element element = parseElementBuffer(elementBuffer);\r
-\r
-            event = extractEvent(element, fRecordInputElement);\r
-            ((StringBuffer) event.getContent().getValue()).append(elementBuffer);\r
-\r
-            String line;\r
-            final String recordElementStart = "<" + fRecordInputElement.elementName; //$NON-NLS-1$\r
-            long rawPos = fFile.getFilePointer();\r
-\r
-            while ((line = fFile.getNextLine()) != null) {\r
-                final int idx = line.indexOf(recordElementStart);\r
-                if (idx != -1) {\r
-                    context.setLocation(new TmfLongLocation(rawPos + idx));\r
-                    return event;\r
-                }\r
-                rawPos = fFile.getFilePointer();\r
-            }\r
-        } catch (final IOException e) {\r
-            Activator.getDefault().logError("Error parsing event. File: " + getPath(), e); //$NON-NLS-1$\r
-\r
-        }\r
-        context.setLocation(NULL_LOCATION);\r
-        return event;\r
-    }\r
-\r
-    private Element parseElementBuffer(final StringBuffer elementBuffer) {\r
-        try {\r
-            final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\r
-            final DocumentBuilder db = dbf.newDocumentBuilder();\r
-\r
-            // The following allows xml parsing without access to the dtd\r
-            final EntityResolver resolver = new EntityResolver () {\r
-                @Override\r
-                public InputSource resolveEntity (final String publicId, final String systemId) {\r
-                    final String empty = ""; //$NON-NLS-1$\r
-                    final ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());\r
-                    return new InputSource(bais);\r
-                }\r
-            };\r
-            db.setEntityResolver(resolver);\r
-\r
-            // The following catches xml parsing exceptions\r
-            db.setErrorHandler(new ErrorHandler(){\r
-                @Override\r
-                public void error(final SAXParseException saxparseexception) throws SAXException {}\r
-                @Override\r
-                public void warning(final SAXParseException saxparseexception) throws SAXException {}\r
-                @Override\r
-                public void fatalError(final SAXParseException saxparseexception) throws SAXException {\r
-                    throw saxparseexception;\r
-                }});\r
-\r
-            final Document doc = db.parse(new ByteArrayInputStream(elementBuffer.toString().getBytes()));\r
-            return doc.getDocumentElement();\r
-        } catch (final ParserConfigurationException e) {\r
-            Activator.getDefault().logError("Error parsing element buffer. File:" + getPath(), e); //$NON-NLS-1$\r
-        } catch (final SAXException e) {\r
-            Activator.getDefault().logError("Error parsing element buffer. File:" + getPath(), e); //$NON-NLS-1$\r
-        } catch (final IOException e) {\r
-            Activator.getDefault().logError("Error parsing element buffer. File: " + getPath(), e); //$NON-NLS-1$\r
-        }\r
-        return null;\r
-    }\r
-\r
-    private void readElement(final StringBuffer buffer, final RandomAccessFile raFile) {\r
-        try {\r
-            int numRead = 0;\r
-            boolean startTagClosed = false;\r
-            int i;\r
-            while ((i = raFile.read()) != -1) {\r
-                numRead++;\r
-                final char c = (char)i;\r
-                buffer.append(c);\r
-                if (c == '"') {\r
-                    readQuote(buffer, raFile, '"');\r
-                } else if (c == '\'') {\r
-                    readQuote(buffer, raFile, '\'');\r
-                } else if (c == '<') {\r
-                    readElement(buffer, raFile);\r
-                } else if (c == '/' && numRead == 1) {\r
-                    break; // found "</"\r
-                } else if (c == '-' && numRead == 3 && buffer.substring(buffer.length() - 3, buffer.length() - 1).equals("!-")) { //$NON-NLS-1$\r
-                    readComment(buffer, raFile); // found "<!--"\r
-                } else if (i == '>') {\r
-                    if (buffer.charAt(buffer.length() - 2) == '/') {\r
-                        break; // found "/>"\r
-                    } else if (startTagClosed) {\r
-                        break; // found "<...>...</...>"\r
-                    }\r
-                    else {\r
-                        startTagClosed = true; // found "<...>"\r
-                    }\r
-                }\r
-            }\r
-            return;\r
-        } catch (final IOException e) {\r
-            return;\r
-        }\r
-    }\r
-\r
-    private static void readQuote(final StringBuffer buffer,\r
-            final RandomAccessFile raFile, final char eq) {\r
-        try {\r
-            int i;\r
-            while ((i = raFile.read()) != -1) {\r
-                final char c = (char)i;\r
-                buffer.append(c);\r
-                if (c == eq)\r
-                {\r
-                    break; // found matching end-quote\r
-                }\r
-            }\r
-            return;\r
-        } catch (final IOException e) {\r
-            return;\r
-        }\r
-    }\r
-\r
-    private static void readComment(final StringBuffer buffer,\r
-            final RandomAccessFile raFile) {\r
-        try {\r
-            int numRead = 0;\r
-            int i;\r
-            while ((i = raFile.read()) != -1) {\r
-                numRead++;\r
-                final char c = (char)i;\r
-                buffer.append(c);\r
-                if (c == '>' && numRead >= 2 && buffer.substring(buffer.length() - 3, buffer.length() - 1).equals("--")) //$NON-NLS-1$\r
-                {\r
-                    break; // found "-->"\r
-                }\r
-            }\r
-            return;\r
-        } catch (final IOException e) {\r
-            return;\r
-        }\r
-    }\r
-\r
-    public static StringBuffer parseElement(final Element parentElement, final StringBuffer buffer) {\r
-        final NodeList nodeList = parentElement.getChildNodes();\r
-        String separator = null;\r
-        for (int i = 0; i < nodeList.getLength(); i++) {\r
-            final Node node = nodeList.item(i);\r
-            if (node.getNodeType() == Node.ELEMENT_NODE) {\r
-                if (separator == null) {\r
-                    separator = " | "; //$NON-NLS-1$\r
-                } else {\r
-                    buffer.append(separator);\r
-                }\r
-                final Element element = (Element) node;\r
-                if (!element.hasChildNodes()) {\r
-                    buffer.append(element.getNodeName());\r
-                } else if (element.getChildNodes().getLength() == 1 && element.getFirstChild().getNodeType() == Node.TEXT_NODE) {\r
-                    buffer.append(element.getNodeName() + ":" + element.getFirstChild().getNodeValue().trim()); //$NON-NLS-1$\r
-                } else {\r
-                    buffer.append(element.getNodeName());\r
-                    buffer.append(" [ "); //$NON-NLS-1$\r
-                    parseElement(element, buffer);\r
-                    buffer.append(" ]"); //$NON-NLS-1$\r
-                }\r
-            } else if (node.getNodeType() == Node.TEXT_NODE) {\r
-                if (node.getNodeValue().trim().length() != 0) {\r
-                    buffer.append(node.getNodeValue().trim());\r
-                }\r
-            }\r
-        }\r
-        return buffer;\r
-    }\r
-\r
-    public InputElement getRecordInputElement(final InputElement inputElement) {\r
-        if (inputElement.logEntry) {\r
-            return inputElement;\r
-        } else if (inputElement.childElements != null) {\r
-            for (final InputElement childInputElement : inputElement.childElements) {\r
-                final InputElement recordInputElement = getRecordInputElement(childInputElement);\r
-                if (recordInputElement != null) {\r
-                    return recordInputElement;\r
-                }\r
-            }\r
-        }\r
-        return null;\r
-    }\r
-\r
-    public CustomXmlEvent extractEvent(final Element element, final InputElement inputElement) {\r
-        final CustomXmlEvent event = new CustomXmlEvent(fDefinition, this, TmfTimestamp.ZERO, "", fEventType,""); //$NON-NLS-1$ //$NON-NLS-2$\r
-        event.setContent(new CustomEventContent(event, new StringBuffer()));\r
-        parseElement(element, event, inputElement);\r
-        return event;\r
-    }\r
-\r
-    private void parseElement(final Element element, final CustomXmlEvent event, final InputElement inputElement) {\r
-        if (inputElement.inputName != null && !inputElement.inputName.equals(CustomXmlTraceDefinition.TAG_IGNORE)) {\r
-            event.parseInput(parseElement(element, new StringBuffer()).toString(), inputElement.inputName, inputElement.inputAction, inputElement.inputFormat);\r
-        }\r
-        if (inputElement.attributes != null) {\r
-            for (final InputAttribute attribute : inputElement.attributes) {\r
-                event.parseInput(element.getAttribute(attribute.attributeName), attribute.inputName, attribute.inputAction, attribute.inputFormat);\r
-            }\r
-        }\r
-        final NodeList childNodes = element.getChildNodes();\r
-        if (inputElement.childElements != null) {\r
-            for (int i = 0; i < childNodes.getLength(); i++) {\r
-                final Node node = childNodes.item(i);\r
-                if (node instanceof Element) {\r
-                    for (final InputElement child : inputElement.childElements) {\r
-                        if (node.getNodeName().equals(child.elementName)) {\r
-                            parseElement((Element) node, event, child);\r
-                            break;\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        return;\r
-    }\r
-\r
-    public CustomTraceDefinition getDefinition() {\r
-        return fDefinition;\r
-    }\r
-\r
-    /* (non-Javadoc)\r
-     * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#validate(org.eclipse.core.resources.IProject, java.lang.String)\r
-     */\r
-    @Override\r
-    public boolean validate(IProject project, String path) {\r
-        return fileExists(path);\r
-    }\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2010 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Patrick Tasse - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.internal.tmf.ui.parsers.custom;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.linuxtools.internal.tmf.ui.Activator;
+import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomXmlTraceDefinition.InputAttribute;
+import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomXmlTraceDefinition.InputElement;
+import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
+import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
+import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
+import org.eclipse.linuxtools.tmf.core.io.BufferedRandomAccessFile;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfLocation;
+import org.eclipse.linuxtools.tmf.core.trace.TmfContext;
+import org.eclipse.linuxtools.tmf.core.trace.TmfLongLocation;
+import org.eclipse.linuxtools.tmf.core.trace.TmfTrace;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+public class CustomXmlTrace extends TmfTrace implements ITmfEventParser {
+
+    private static final TmfLongLocation NULL_LOCATION = new TmfLongLocation((Long) null);
+    private static final int DEFAULT_CACHE_SIZE = 100;
+
+    private final CustomXmlTraceDefinition fDefinition;
+    private final CustomXmlEventType fEventType;
+    private final InputElement fRecordInputElement;
+    private BufferedRandomAccessFile fFile;
+
+    public CustomXmlTrace(final CustomXmlTraceDefinition definition) {
+        fDefinition = definition;
+        fEventType = new CustomXmlEventType(fDefinition);
+        fRecordInputElement = getRecordInputElement(fDefinition.rootInputElement);
+        setCacheSize(DEFAULT_CACHE_SIZE);
+    }
+
+    public CustomXmlTrace(final IResource resource, final CustomXmlTraceDefinition definition, final String path, final int pageSize) throws TmfTraceException {
+        this(definition);
+        setCacheSize((pageSize > 0) ? pageSize : DEFAULT_CACHE_SIZE);
+        initTrace(resource, path, CustomXmlEvent.class);
+    }
+
+    @Override
+    public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> eventType) throws TmfTraceException {
+        super.initTrace(resource, path, eventType);
+        try {
+            fFile = new BufferedRandomAccessFile(getPath(), "r"); //$NON-NLS-1$
+        } catch (IOException e) {
+            throw new TmfTraceException(e.getMessage(), e);
+        }
+        indexTrace(false);
+    }
+
+    @Override
+    public synchronized void dispose() {
+        super.dispose();
+        if (fFile != null) {
+            try {
+                fFile.close();
+            } catch (IOException e) {
+            } finally {
+                fFile = null;
+            }
+        }
+    }
+
+    @Override
+    public synchronized TmfContext seekEvent(final ITmfLocation location) {
+        final CustomXmlTraceContext context = new CustomXmlTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK);
+        if (NULL_LOCATION.equals(location) || fFile == null) {
+            return context;
+        }
+        try {
+            if (location == null) {
+                fFile.seek(0);
+            } else if (location.getLocationInfo() instanceof Long) {
+                fFile.seek((Long) location.getLocationInfo());
+            }
+            String line;
+            final String recordElementStart = "<" + fRecordInputElement.elementName; //$NON-NLS-1$
+            long rawPos = fFile.getFilePointer();
+
+            while ((line = fFile.getNextLine()) != null) {
+                final int idx = line.indexOf(recordElementStart);
+                if (idx != -1) {
+                    context.setLocation(new TmfLongLocation(rawPos + idx));
+                    return context;
+                }
+                rawPos = fFile.getFilePointer();
+            }
+            return context;
+        } catch (final IOException e) {
+            Activator.getDefault().logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$
+            return context;
+        }
+
+    }
+
+    @Override
+    public synchronized TmfContext seekEvent(final double ratio) {
+        if (fFile == null) {
+            return new CustomTxtTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK);
+        }
+        try {
+            long pos = (long) (ratio * fFile.length());
+            while (pos > 0) {
+                fFile.seek(pos - 1);
+                if (fFile.read() == '\n') {
+                    break;
+                }
+                pos--;
+            }
+            final ITmfLocation location = new TmfLongLocation(pos);
+            final TmfContext context = seekEvent(location);
+            context.setRank(ITmfContext.UNKNOWN_RANK);
+            return context;
+        } catch (final IOException e) {
+            Activator.getDefault().logError("Error seeking event. File: " + getPath(), e); //$NON-NLS-1$
+            return new CustomXmlTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK);
+        }
+    }
+
+    @Override
+    public synchronized double getLocationRatio(final ITmfLocation location) {
+        if (fFile == null) {
+            return 0;
+        }
+        try {
+            if (location.getLocationInfo() instanceof Long) {
+                return (double) ((Long) location.getLocationInfo()) / fFile.length();
+            }
+        } catch (final IOException e) {
+            Activator.getDefault().logError("Error getting location ration. File: " + getPath(), e); //$NON-NLS-1$
+        }
+        return 0;
+    }
+
+    @Override
+    public ITmfLocation getCurrentLocation() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public synchronized CustomXmlEvent parseEvent(final ITmfContext tmfContext) {
+        ITmfContext context = seekEvent(tmfContext.getLocation());
+        return parse(context);
+    }
+
+    @Override
+    public synchronized CustomXmlEvent getNext(final ITmfContext context) {
+        final ITmfContext savedContext = context.clone();
+        final CustomXmlEvent event = parse(context);
+        if (event != null) {
+            updateAttributes(savedContext, event.getTimestamp());
+            context.increaseRank();
+        }
+        return event;
+    }
+
+    private synchronized CustomXmlEvent parse(final ITmfContext tmfContext) {
+        if (fFile == null) {
+            return null;
+        }
+        if (!(tmfContext instanceof CustomXmlTraceContext)) {
+            return null;
+        }
+
+        final CustomXmlTraceContext context = (CustomXmlTraceContext) tmfContext;
+        if (!(context.getLocation().getLocationInfo() instanceof Long) || NULL_LOCATION.equals(context.getLocation())) {
+            return null;
+        }
+
+        CustomXmlEvent event = null;
+        try {
+            if (fFile.getFilePointer() != (Long)context.getLocation().getLocationInfo() + 1)
+            {
+                fFile.seek((Long)context.getLocation().getLocationInfo() + 1); // +1 is for the <
+            }
+            final StringBuffer elementBuffer = new StringBuffer("<"); //$NON-NLS-1$
+            readElement(elementBuffer, fFile);
+            final Element element = parseElementBuffer(elementBuffer);
+
+            event = extractEvent(element, fRecordInputElement);
+            ((StringBuffer) event.getContent().getValue()).append(elementBuffer);
+
+            String line;
+            final String recordElementStart = "<" + fRecordInputElement.elementName; //$NON-NLS-1$
+            long rawPos = fFile.getFilePointer();
+
+            while ((line = fFile.getNextLine()) != null) {
+                final int idx = line.indexOf(recordElementStart);
+                if (idx != -1) {
+                    context.setLocation(new TmfLongLocation(rawPos + idx));
+                    return event;
+                }
+                rawPos = fFile.getFilePointer();
+            }
+        } catch (final IOException e) {
+            Activator.getDefault().logError("Error parsing event. File: " + getPath(), e); //$NON-NLS-1$
+
+        }
+        context.setLocation(NULL_LOCATION);
+        return event;
+    }
+
+    private Element parseElementBuffer(final StringBuffer elementBuffer) {
+        try {
+            final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+            final DocumentBuilder db = dbf.newDocumentBuilder();
+
+            // The following allows xml parsing without access to the dtd
+            final EntityResolver resolver = new EntityResolver () {
+                @Override
+                public InputSource resolveEntity (final String publicId, final String systemId) {
+                    final String empty = ""; //$NON-NLS-1$
+                    final ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());
+                    return new InputSource(bais);
+                }
+            };
+            db.setEntityResolver(resolver);
+
+            // The following catches xml parsing exceptions
+            db.setErrorHandler(new ErrorHandler(){
+                @Override
+                public void error(final SAXParseException saxparseexception) throws SAXException {}
+                @Override
+                public void warning(final SAXParseException saxparseexception) throws SAXException {}
+                @Override
+                public void fatalError(final SAXParseException saxparseexception) throws SAXException {
+                    throw saxparseexception;
+                }});
+
+            final Document doc = db.parse(new ByteArrayInputStream(elementBuffer.toString().getBytes()));
+            return doc.getDocumentElement();
+        } catch (final ParserConfigurationException e) {
+            Activator.getDefault().logError("Error parsing element buffer. File:" + getPath(), e); //$NON-NLS-1$
+        } catch (final SAXException e) {
+            Activator.getDefault().logError("Error parsing element buffer. File:" + getPath(), e); //$NON-NLS-1$
+        } catch (final IOException e) {
+            Activator.getDefault().logError("Error parsing element buffer. File: " + getPath(), e); //$NON-NLS-1$
+        }
+        return null;
+    }
+
+    private void readElement(final StringBuffer buffer, final RandomAccessFile raFile) {
+        try {
+            int numRead = 0;
+            boolean startTagClosed = false;
+            int i;
+            while ((i = raFile.read()) != -1) {
+                numRead++;
+                final char c = (char)i;
+                buffer.append(c);
+                if (c == '"') {
+                    readQuote(buffer, raFile, '"');
+                } else if (c == '\'') {
+                    readQuote(buffer, raFile, '\'');
+                } else if (c == '<') {
+                    readElement(buffer, raFile);
+                } else if (c == '/' && numRead == 1) {
+                    break; // found "</"
+                } else if (c == '-' && numRead == 3 && buffer.substring(buffer.length() - 3, buffer.length() - 1).equals("!-")) { //$NON-NLS-1$
+                    readComment(buffer, raFile); // found "<!--"
+                } else if (i == '>') {
+                    if (buffer.charAt(buffer.length() - 2) == '/') {
+                        break; // found "/>"
+                    } else if (startTagClosed) {
+                        break; // found "<...>...</...>"
+                    }
+                    else {
+                        startTagClosed = true; // found "<...>"
+                    }
+                }
+            }
+            return;
+        } catch (final IOException e) {
+            return;
+        }
+    }
+
+    private static void readQuote(final StringBuffer buffer,
+            final RandomAccessFile raFile, final char eq) {
+        try {
+            int i;
+            while ((i = raFile.read()) != -1) {
+                final char c = (char)i;
+                buffer.append(c);
+                if (c == eq)
+                {
+                    break; // found matching end-quote
+                }
+            }
+            return;
+        } catch (final IOException e) {
+            return;
+        }
+    }
+
+    private static void readComment(final StringBuffer buffer,
+            final RandomAccessFile raFile) {
+        try {
+            int numRead = 0;
+            int i;
+            while ((i = raFile.read()) != -1) {
+                numRead++;
+                final char c = (char)i;
+                buffer.append(c);
+                if (c == '>' && numRead >= 2 && buffer.substring(buffer.length() - 3, buffer.length() - 1).equals("--")) //$NON-NLS-1$
+                {
+                    break; // found "-->"
+                }
+            }
+            return;
+        } catch (final IOException e) {
+            return;
+        }
+    }
+
+    public static StringBuffer parseElement(final Element parentElement, final StringBuffer buffer) {
+        final NodeList nodeList = parentElement.getChildNodes();
+        String separator = null;
+        for (int i = 0; i < nodeList.getLength(); i++) {
+            final Node node = nodeList.item(i);
+            if (node.getNodeType() == Node.ELEMENT_NODE) {
+                if (separator == null) {
+                    separator = " | "; //$NON-NLS-1$
+                } else {
+                    buffer.append(separator);
+                }
+                final Element element = (Element) node;
+                if (!element.hasChildNodes()) {
+                    buffer.append(element.getNodeName());
+                } else if (element.getChildNodes().getLength() == 1 && element.getFirstChild().getNodeType() == Node.TEXT_NODE) {
+                    buffer.append(element.getNodeName() + ":" + element.getFirstChild().getNodeValue().trim()); //$NON-NLS-1$
+                } else {
+                    buffer.append(element.getNodeName());
+                    buffer.append(" [ "); //$NON-NLS-1$
+                    parseElement(element, buffer);
+                    buffer.append(" ]"); //$NON-NLS-1$
+                }
+            } else if (node.getNodeType() == Node.TEXT_NODE) {
+                if (node.getNodeValue().trim().length() != 0) {
+                    buffer.append(node.getNodeValue().trim());
+                }
+            }
+        }
+        return buffer;
+    }
+
+    public InputElement getRecordInputElement(final InputElement inputElement) {
+        if (inputElement.logEntry) {
+            return inputElement;
+        } else if (inputElement.childElements != null) {
+            for (final InputElement childInputElement : inputElement.childElements) {
+                final InputElement recordInputElement = getRecordInputElement(childInputElement);
+                if (recordInputElement != null) {
+                    return recordInputElement;
+                }
+            }
+        }
+        return null;
+    }
+
+    public CustomXmlEvent extractEvent(final Element element, final InputElement inputElement) {
+        final CustomXmlEvent event = new CustomXmlEvent(fDefinition, this, TmfTimestamp.ZERO, "", fEventType,""); //$NON-NLS-1$ //$NON-NLS-2$
+        event.setContent(new CustomEventContent(event, new StringBuffer()));
+        parseElement(element, event, inputElement);
+        return event;
+    }
+
+    private void parseElement(final Element element, final CustomXmlEvent event, final InputElement inputElement) {
+        if (inputElement.inputName != null && !inputElement.inputName.equals(CustomXmlTraceDefinition.TAG_IGNORE)) {
+            event.parseInput(parseElement(element, new StringBuffer()).toString(), inputElement.inputName, inputElement.inputAction, inputElement.inputFormat);
+        }
+        if (inputElement.attributes != null) {
+            for (final InputAttribute attribute : inputElement.attributes) {
+                event.parseInput(element.getAttribute(attribute.attributeName), attribute.inputName, attribute.inputAction, attribute.inputFormat);
+            }
+        }
+        final NodeList childNodes = element.getChildNodes();
+        if (inputElement.childElements != null) {
+            for (int i = 0; i < childNodes.getLength(); i++) {
+                final Node node = childNodes.item(i);
+                if (node instanceof Element) {
+                    for (final InputElement child : inputElement.childElements) {
+                        if (node.getNodeName().equals(child.elementName)) {
+                            parseElement((Element) node, event, child);
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        return;
+    }
+
+    public CustomTraceDefinition getDefinition() {
+        return fDefinition;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#validate(org.eclipse.core.resources.IProject, java.lang.String)
+     */
+    @Override
+    public boolean validate(IProject project, String path) {
+        return fileExists(path);
+    }
+}
This page took 0.044065 seconds and 5 git commands to generate.