tmf: Add TextTrace abstract class with trace validation status
authorPatrick Tasse <patrick.tasse@gmail.com>
Wed, 29 Jan 2014 16:46:12 +0000 (11:46 -0500)
committerBernd Hufmann <bernd.hufmann@ericsson.com>
Thu, 13 Feb 2014 18:55:36 +0000 (13:55 -0500)
Change-Id: I1e027b4ee4e9581bcee2df99edaf7fde7cc9ee12
Signed-off-by: Patrick Tasse <patrick.tasse@gmail.com>
Reviewed-on: https://git.eclipse.org/r/21833
Reviewed-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
IP-Clean: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
Tested-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
org.eclipse.linuxtools.tmf.core/META-INF/MANIFEST.MF
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/project/model/TraceTypeHelper.java
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTrace.java
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TraceValidationStatus.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTrace.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTraceContext.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTraceEventContent.java [new file with mode: 0644]

index c6fde6dfe13ae0836468ded37e92bc979cd3d98a..26e3b6a23d975c2227b141867dc70ae6de398a65 100644 (file)
@@ -49,5 +49,6 @@ Export-Package: org.eclipse.linuxtools.internal.tmf.core;x-friends:="org.eclipse
  org.eclipse.linuxtools.tmf.core.trace.indexer,
  org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint,
  org.eclipse.linuxtools.tmf.core.trace.location,
+ org.eclipse.linuxtools.tmf.core.trace.text,
  org.eclipse.linuxtools.tmf.core.uml2sd,
  org.eclipse.linuxtools.tmf.core.util
index f27024522a3f4dbc1f14cd3706edfedd868547b6..4331bdbcd7ff213b42a8b4773d77323c5d26c5d8 100644 (file)
@@ -12,7 +12,6 @@
 
 package org.eclipse.linuxtools.tmf.core.project.model;
 
-import org.eclipse.core.runtime.Status;
 import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
 
 /**
@@ -102,7 +101,7 @@ public class TraceTypeHelper {
     }
 
     private boolean standardValidate(String path) {
-        final boolean valid = fTrace.validate(null, path).equals(Status.OK_STATUS);
+        final boolean valid = fTrace.validate(null, path).isOK();
         return valid;
     }
 
@@ -121,4 +120,4 @@ public class TraceTypeHelper {
         return fName;
     }
 
-}
\ No newline at end of file
+}
index 9fcfc7d6499a17cad10cf0e9bb8e01168db09f51..df9c37fe0c2a3076aa674f4bd3ab69ceb075d3fe 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2013 Ericsson, École Polytechnique de Montréal
+ * Copyright (c) 2009, 2014 Ericsson, École Polytechnique de Montréal
  *
  * All rights reserved. This program and the accompanying materials are
  * made available under the terms of the Eclipse Public License v1.0 which
@@ -159,14 +159,18 @@ public interface ITmfTrace extends ITmfEventProvider {
     void initTrace(IResource resource, String path, Class<? extends ITmfEvent> type) throws TmfTraceException;
 
     /**
-     * Validate that the trace is of the correct type.
+     * Validate that the trace is of the correct type. The implementation should
+     * return a TraceValidationStatus to indicate success with a certain level
+     * of confidence.
      *
      * @param project
      *            the eclipse project
      * @param path
      *            the trace path
+     *
      * @return an IStatus object with validation result. Use severity OK to
      *         indicate success.
+     * @see {@link TraceValidationStatus}
      * @since 2.0
      */
     IStatus validate(IProject project, String path);
diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TraceValidationStatus.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TraceValidationStatus.java
new file mode 100644 (file)
index 0000000..70ee92a
--- /dev/null
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2014 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.tmf.core.trace;
+
+import org.eclipse.core.runtime.Status;
+
+/**
+ * A class representing the validation status of a trace against a particular
+ * trace type.
+ *
+ * @since 3.0
+ */
+public class TraceValidationStatus extends Status {
+
+    private int fConfidence;
+
+    /**
+     * Construct a successful validation status with a confidence level
+     *
+     * @param confidence the confidence level, 0 is lowest
+     * @param pluginId the unique identifier of the relevant plug-in
+     */
+    public TraceValidationStatus(int confidence, String pluginId) {
+        super(OK, pluginId, OK_STATUS.getMessage());
+        if (confidence < 0) {
+            throw new IllegalArgumentException();
+        }
+        fConfidence = confidence;
+    }
+
+    /**
+     * Gets the confidence level
+     *
+     * @return the confidence level, 0 is lowest
+     */
+    public int getConfidence() {
+        return fConfidence;
+    }
+}
diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTrace.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTrace.java
new file mode 100644 (file)
index 0000000..d03bddc
--- /dev/null
@@ -0,0 +1,329 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2014 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.tmf.core.trace.text;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.linuxtools.internal.tmf.core.Activator;
+import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
+import org.eclipse.linuxtools.tmf.core.event.TmfEvent;
+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.TmfContext;
+import org.eclipse.linuxtools.tmf.core.trace.TmfTrace;
+import org.eclipse.linuxtools.tmf.core.trace.TraceValidationStatus;
+import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation;
+import org.eclipse.linuxtools.tmf.core.trace.location.TmfLongLocation;
+
+/**
+ * Extension of TmfTrace for handling of line-based text traces parsed using
+ * regular expressions. Each line that matches the first line pattern indicates
+ * the start of a new event. The subsequent lines can contain additional
+ * information that is added to the current event.
+ *
+ * @param <T>
+ *            TmfEvent class returned by this trace
+ *
+ * @since 3.0
+ */
+public abstract class TextTrace<T extends TmfEvent> extends TmfTrace implements ITmfEventParser {
+
+    private static final TmfLongLocation NULL_LOCATION = new TmfLongLocation((Long) null);
+    private static final int MAX_LINES = 100;
+    private static final int MAX_CONFIDENCE = 100;
+
+    /** The default separator used for multi-line fields */
+    protected static final String SEPARATOR = " | "; //$NON-NLS-1$
+
+    /** The text file */
+    protected BufferedRandomAccessFile fFile;
+
+    /**
+     * Constructor
+     */
+    public TextTrace() {
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * The default implementation computes the confidence as the percentage of
+     * lines in the first 100 lines of the file which match the first line
+     * pattern.
+     */
+    @Override
+    public IStatus validate(IProject project, String path) {
+        File file = new File(path);
+        if (!file.exists()) {
+            return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "File not found: " + path); //$NON-NLS-1$
+        }
+        if (!file.isFile()) {
+            return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Not a file. It's a directory: " + path); //$NON-NLS-1$
+        }
+        int confidence = 0;
+        try (BufferedRandomAccessFile rafile = new BufferedRandomAccessFile(path, "r")) { //$NON-NLS-1$
+            int lineCount = 0;
+            int matches = 0;
+            String line = rafile.getNextLine();
+            while ((line != null) && (lineCount++ < MAX_LINES)) {
+                Matcher matcher = getFirstLinePattern().matcher(line);
+                if (matcher.find()) {
+                    matches++;
+                }
+                confidence = MAX_CONFIDENCE * matches / lineCount;
+                line = rafile.getNextLine();
+            }
+        } catch (IOException e) {
+            Activator.logError("Error validating file: " + path, e); //$NON-NLS-1$
+            return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "IOException validating file: " + path, e); //$NON-NLS-1$
+        }
+
+        return new TraceValidationStatus(confidence, Activator.PLUGIN_ID);
+
+    }
+
+    @Override
+    public void initTrace(IResource resource, String path, Class<? extends ITmfEvent> type) throws TmfTraceException {
+        super.initTrace(resource, path, type);
+        try {
+            fFile = new BufferedRandomAccessFile(getPath(), "r"); //$NON-NLS-1$
+        } catch (IOException e) {
+            throw new TmfTraceException(e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public synchronized void dispose() {
+        super.dispose();
+        if (fFile != null) {
+            try {
+                fFile.close();
+            } catch (IOException e) {
+            } finally {
+                fFile = null;
+            }
+        }
+    }
+
+    @Override
+    public synchronized TmfContext seekEvent(ITmfLocation location) {
+        TextTraceContext context = new TextTraceContext(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());
+            }
+            long rawPos = fFile.getFilePointer();
+            String line = fFile.getNextLine();
+            while (line != null) {
+                Matcher matcher = getFirstLinePattern().matcher(line);
+                if (matcher.find()) {
+                    context.setLocation(new TmfLongLocation(rawPos));
+                    context.firstLineMatcher = matcher;
+                    context.firstLine = line;
+                    context.nextLineLocation = fFile.getFilePointer();
+                    return context;
+                }
+                rawPos = fFile.getFilePointer();
+                line = fFile.getNextLine();
+            }
+            return context;
+        } catch (IOException e) {
+            Activator.logError("Error seeking file: " + getPath(), e); //$NON-NLS-1$
+            return context;
+        }
+    }
+
+    @Override
+    public synchronized TmfContext seekEvent(double ratio) {
+        if (fFile == null) {
+            return new TextTraceContext(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--;
+            }
+            ITmfLocation location = new TmfLongLocation(Long.valueOf(pos));
+            TmfContext context = seekEvent(location);
+            context.setRank(ITmfContext.UNKNOWN_RANK);
+            return context;
+        } catch (IOException e) {
+            Activator.logError("Error seeking file: " + getPath(), e); //$NON-NLS-1$
+            return new TextTraceContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK);
+        }
+    }
+
+    @Override
+    public double getLocationRatio(ITmfLocation location) {
+        if (fFile == null) {
+            return 0;
+        }
+        try {
+            long length = fFile.length();
+            if (length == 0) {
+                return 0;
+            }
+            if (location.getLocationInfo() instanceof Long) {
+                return (double) ((Long) location.getLocationInfo()) / length;
+            }
+        } catch (IOException e) {
+            Activator.logError("Error reading file: " + getPath(), e); //$NON-NLS-1$
+        }
+        return 0;
+    }
+
+    @Override
+    public ITmfLocation getCurrentLocation() {
+        return null;
+    }
+
+    @Override
+    public ITmfEvent parseEvent(ITmfContext tmfContext) {
+        ITmfContext context = seekEvent(tmfContext.getLocation());
+        return parse(context);
+    }
+
+    @Override
+    public synchronized T getNext(ITmfContext context) {
+        ITmfContext savedContext = new TmfContext(context.getLocation(), context.getRank());
+        T event = parse(context);
+        if (event != null) {
+            updateAttributes(savedContext, event.getTimestamp());
+            context.increaseRank();
+        }
+        return event;
+    }
+
+    /**
+     * Parse the next event. The context is advanced.
+     *
+     * @param tmfContext
+     *            the context
+     * @return the next event or null
+     */
+    protected synchronized T parse(ITmfContext tmfContext) {
+        if (fFile == null) {
+            return null;
+        }
+        if (!(tmfContext instanceof TextTraceContext)) {
+            return null;
+        }
+        TextTraceContext context = (TextTraceContext) tmfContext;
+        if (context.getLocation() == null || !(context.getLocation().getLocationInfo() instanceof Long) || NULL_LOCATION.equals(context.getLocation())) {
+            return null;
+        }
+
+        T event = parseFirstLine(context.firstLineMatcher, context.firstLine);
+
+        try {
+            if (fFile.getFilePointer() != context.nextLineLocation) {
+                fFile.seek(context.nextLineLocation);
+            }
+            long rawPos = fFile.getFilePointer();
+            String line = fFile.getNextLine();
+            while (line != null) {
+                Matcher matcher = getFirstLinePattern().matcher(line);
+                if (matcher.find()) {
+                    context.setLocation(new TmfLongLocation(rawPos));
+                    context.firstLineMatcher = matcher;
+                    context.firstLine = line;
+                    context.nextLineLocation = fFile.getFilePointer();
+                    return event;
+                }
+                parseNextLine(event, line);
+                rawPos = fFile.getFilePointer();
+                line = fFile.getNextLine();
+            }
+        } catch (IOException e) {
+            Activator.logError("Error reading file: " + getPath(), e); //$NON-NLS-1$
+        }
+
+        context.setLocation(NULL_LOCATION);
+        return event;
+    }
+
+    /**
+     * Gets the first line pattern.
+     *
+     * @return The first line pattern
+     */
+    protected abstract Pattern getFirstLinePattern();
+
+    /**
+     * Parses the first line data and returns a new event.
+     *
+     * @param matcher
+     *            The matcher
+     * @param line
+     *            The line to parse
+     * @return The parsed event
+     */
+    protected abstract T parseFirstLine(Matcher matcher, String line);
+
+    /**
+     * Parses the next line data for the current event.
+     *
+     * @param event
+     *            The current event being parsed
+     * @param line
+     *            The line to parse
+     */
+    protected abstract void parseNextLine(T event, String line);
+
+    // ------------------------------------------------------------------------
+    // Helper methods
+    // ------------------------------------------------------------------------
+
+    /**
+     * Strip quotes surrounding a string
+     *
+     * @param input
+     *            The input string
+     * @return The string without quotes
+     */
+    protected static String replaceQuotes(String input) {
+        String out = input.replaceAll("^\"|(\"\\s*)$", "");  //$NON-NLS-1$//$NON-NLS-2$
+        return out;
+    }
+
+    /**
+     * Strip brackets surrounding a string
+     *
+     * @param input
+     *            The input string
+     * @return The string without brackets
+     */
+    protected static String replaceBrackets(String input) {
+        String out = input.replaceAll("^\\{|(\\}\\s*)$", "");  //$NON-NLS-1$//$NON-NLS-2$
+        return out;
+    }
+
+}
diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTraceContext.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTraceContext.java
new file mode 100644 (file)
index 0000000..0b20528
--- /dev/null
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2014 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.tmf.core.trace.text;
+
+import java.util.regex.Matcher;
+
+import org.eclipse.linuxtools.tmf.core.trace.TmfContext;
+import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation;
+
+/**
+ * Implementation of a TmfContext for text traces.
+ *
+ * @since 3.0
+ */
+public class TextTraceContext extends TmfContext {
+
+    /** The Matcher object for the first line. */
+    public Matcher firstLineMatcher;
+    /** The first line string */
+    public String firstLine;
+    /** The location of the next line */
+    public long nextLineLocation;
+
+    /**
+     * Constructor
+     *
+     * @param location
+     *            Trace location
+     * @param rank
+     *            Event rank
+     */
+    public TextTraceContext(final ITmfLocation location, final long rank) {
+        super(location, rank);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = super.hashCode();
+        result = prime * result + ((firstLine == null) ? 0 : firstLine.hashCode());
+        result = prime * result + ((firstLineMatcher == null) ? 0 : firstLineMatcher.hashCode());
+        result = prime * result + (int) (nextLineLocation ^ (nextLineLocation >>> 32));
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        TextTraceContext other = (TextTraceContext) obj;
+        if (firstLine == null) {
+            if (other.firstLine != null) {
+                return false;
+            }
+        } else if (!firstLine.equals(other.firstLine)) {
+            return false;
+        }
+        if (firstLineMatcher == null) {
+            if (other.firstLineMatcher != null) {
+                return false;
+            }
+        } else if (!firstLineMatcher.equals(other.firstLineMatcher)) {
+            return false;
+        }
+        if (nextLineLocation != other.nextLineLocation) {
+            return false;
+        }
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTraceEventContent.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/text/TextTraceEventContent.java
new file mode 100644 (file)
index 0000000..89af738
--- /dev/null
@@ -0,0 +1,310 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2014 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
+ *   Bernd Hufmann - Updated equals, clone and hashCode to consider StringBuffer values
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.trace.text;
+
+import java.util.Arrays;
+
+import org.eclipse.linuxtools.tmf.core.event.ITmfEventField;
+
+/**
+ * Implementation of ITmfEventField for Text Traces.
+ *
+ * @since 3.0
+ */
+public class TextTraceEventContent implements ITmfEventField, Cloneable {
+
+    private String fName;
+    private Object fValue;
+    private TextTraceEventContent[] fFields;
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    /**
+     * Constructor for a root event content
+     *
+     * @param fieldNames
+     *            the array of field names
+     */
+    public TextTraceEventContent(String[] fieldNames) {
+        this(ITmfEventField.ROOT_FIELD_ID);
+        fFields = new TextTraceEventContent[fieldNames.length];
+        for (int i = 0; i < fFields.length; i++) {
+            fFields[i] = new TextTraceEventContent(fieldNames[i]);
+        }
+    }
+
+    /**
+     * Constructor for a subfield
+     *
+     * @param fieldNames
+     *            the array of field names
+     */
+    private TextTraceEventContent(String fieldName) {
+        fName = fieldName;
+    }
+
+    // ------------------------------------------------------------------------
+    // ITmfEventField
+    // ------------------------------------------------------------------------
+
+    @Override
+    public String getName() {
+        return fName;
+    }
+
+    @Override
+    public Object getValue() {
+        return fValue;
+    }
+
+    @Override
+    public String[] getFieldNames() {
+        String[] fieldNames = new String[fFields.length];
+        for (int i = 0; i < fieldNames.length; i++) {
+            fieldNames[i] = fFields[i].getName();
+        }
+        return fieldNames;
+    }
+
+    @Override
+    public String getFieldName(int index) {
+        if (index >= 0 && index < fFields.length) {
+            return fFields[index].getName();
+        }
+        return null;
+    }
+
+    @Override
+    public ITmfEventField[] getFields() {
+        return fFields;
+    }
+
+    @Override
+    public ITmfEventField getField(String name) {
+        for (int i = 0; i < fFields.length; i++) {
+            if (fFields[i].getName().equals(name)) {
+                return fFields[i];
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public ITmfEventField getField(int index) {
+        if (index >= 0 && index < fFields.length) {
+            return fFields[index];
+        }
+        return null;
+    }
+
+    @Override
+    public String getFormattedValue() {
+        return fValue.toString();
+    }
+
+    @Override
+    public ITmfEventField getSubField(String[] names) {
+        ITmfEventField field = this;
+        for (String name : names) {
+            field = field.getField(name);
+            if (field == null) {
+                return null;
+            }
+        }
+        return field;
+    }
+
+    // ------------------------------------------------------------------------
+    // Convenience getters and setters
+    // ------------------------------------------------------------------------
+
+    /**
+     * Get a subfield value by name
+     *
+     * @param name
+     *            a subfield name
+     * @return field value object
+     */
+    public Object getFieldValue(String name) {
+        for (int i = 0; i < fFields.length; i++) {
+            if (fFields[i].getName().equals(name)) {
+                return fFields[i].getValue();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Get a subfield value by index
+     *
+     * @param index
+     *            a subfield index
+     * @return field value object
+     */
+    public Object getFieldValue(int index) {
+        if (index >= 0 && index < fFields.length) {
+            return fFields[index].getValue();
+        }
+        return null;
+    }
+
+    /**
+     * Set the content value
+     *
+     * @param value
+     *            the content value
+     */
+    public void setValue(Object value) {
+        fValue = value;
+    }
+
+    /**
+     * Set a subfield value by name
+     *
+     * @param name
+     *            a subfield name
+     * @param value
+     *            the subfield value
+     */
+    public void setFieldValue(String name, Object value) {
+        for (int i = 0; i < fFields.length; i++) {
+            if (fFields[i].getName().equals(name)) {
+                fFields[i].fValue = value;
+            }
+        }
+    }
+
+    /**
+     * Set a subfield value by index
+     *
+     * @param index
+     *            a subfield index
+     * @param value
+     *            the subfield value
+     */
+    public void setFieldValue(int index, Object value) {
+        if (index >= 0 && index < fFields.length) {
+            fFields[index].fValue = value;
+        }
+    }
+
+    // ------------------------------------------------------------------------
+    // Cloneable
+    // ------------------------------------------------------------------------
+
+    @Override
+    public TextTraceEventContent clone() {
+        TextTraceEventContent clone = null;
+        try {
+            clone = (TextTraceEventContent) super.clone();
+            clone.fName = fName;
+            if (fValue instanceof StringBuffer) {
+                StringBuffer value = new StringBuffer(fValue.toString());
+                clone.fValue = value;
+            } else {
+                clone.fValue = fValue;
+            }
+            clone.fFields = (fFields != null) ? fFields.clone() : null;
+            if (fFields != null) {
+                for (int i = 0; i < fFields.length; i++) {
+                    clone.fFields[i] = fFields[i].clone();
+                }
+            }
+        } catch (CloneNotSupportedException e) {
+        }
+        return clone;
+    }
+
+    // ------------------------------------------------------------------------
+    // Object
+    // ------------------------------------------------------------------------
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + Arrays.hashCode(fFields);
+        result = prime * result + ((fName == null) ? 0 : fName.hashCode());
+        int tmpHash = 0; // initialize for fValue equals null;
+        if (fValue != null) {
+            if (fValue instanceof StringBuffer) {
+                tmpHash = fValue.toString().hashCode();
+            } else {
+                tmpHash = fValue.hashCode();
+            }
+        }
+        result = prime * result + tmpHash;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        TextTraceEventContent other = (TextTraceEventContent) obj;
+        if (!Arrays.equals(fFields, other.fFields)) {
+            return false;
+        }
+        if (fName == null) {
+            if (other.fName != null) {
+                return false;
+            }
+        } else if (!fName.equals(other.fName)) {
+            return false;
+        }
+        if (fValue == null) {
+            if (other.fValue != null) {
+                return false;
+            }
+        } else {
+            if ((fValue instanceof StringBuffer) && (other.fValue instanceof StringBuffer)) {
+                if (!fValue.toString().equals(other.fValue.toString())) {
+                    return false;
+                }
+            } else if (!fValue.equals(other.fValue)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        if (fName == ITmfEventField.ROOT_FIELD_ID) {
+            for (int i = 0; i < getFields().length; i++) {
+                ITmfEventField field = getFields()[i];
+                if (i != 0) {
+                    sb.append(", "); //$NON-NLS-1$
+                }
+                sb.append(field.toString());
+            }
+        } else {
+            sb.append(fName);
+            sb.append('=');
+            sb.append(fValue);
+        }
+        return sb.toString();
+    }
+
+}
This page took 0.047611 seconds and 5 git commands to generate.