From 9447c7eef07733355f7dba80adaa08ad0f89b6e5 Mon Sep 17 00:00:00 2001 From: Alexandre Montplaisir Date: Sat, 8 Nov 2014 20:09:36 +0000 Subject: [PATCH] tmf: Introduce the core concept of event aspects An "event aspect" is a piece of information that can be extracted, directly or indirectly, from a trace event. Simple examples could be timestamp or event fields. But it could also be something indirect, like a state system request at the timestamp of the given event. This patch introduces the base ITmfEventAspect interface, some basic implementations, and simplifies the TmfEventTableColumns to use aspects instead, since part of it is now redundant. Fixes bug #451411. Change-Id: Ib045439d6084a6e6c7c276f1eddccfb13fe01be0 Signed-off-by: Alexandre Montplaisir Reviewed-on: https://git.eclipse.org/r/36363 Tested-by: Hudson CI Reviewed-by: Matthew Khouzam --- .../btf/ui/BtfEventTableColumns.java | 89 +++++---- .../ui/views/events/GdbEventTableColumns.java | 39 ++-- .../events/LttngEventTableColumns.java | 25 ++- .../META-INF/MANIFEST.MF | 1 + .../core/event/aspect/ITmfEventAspect.java | 178 ++++++++++++++++++ .../tmf/core/event/aspect/Messages.java | 49 +++++ .../tmf/core/event/aspect/TmfCpuAspect.java | 57 ++++++ .../event/aspect/TmfEventFieldAspect.java | 99 ++++++++++ .../event/aspect/TmfStateSystemAspect.java | 91 +++++++++ .../tmf/core/event/aspect/messages.properties | 21 +++ .../tmf/core/event/aspect/package-info.java | 14 ++ .../pcap/ui/editor/PcapEventTableColumns.java | 77 +++++--- .../META-INF/MANIFEST.MF | 1 - .../custom/CustomEventTableColumns.java | 36 ++-- .../events/columns/TmfContentsColumn.java | 47 ----- .../events/columns/TmfTimestampColumn.java | 45 ----- .../viewers/events/columns/TmfTypeColumn.java | 50 ----- .../tmf/ui/viewers/events/TmfEventsTable.java | 78 ++++---- .../events/columns/TmfEventTableColumn.java | 121 ++++++------ .../columns/TmfEventTableFieldColumn.java | 114 ----------- .../events/text/TmfTextEventTable.java | 2 - 21 files changed, 777 insertions(+), 457 deletions(-) create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/ITmfEventAspect.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/Messages.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/TmfCpuAspect.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/TmfEventFieldAspect.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/TmfStateSystemAspect.java create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/messages.properties create mode 100644 org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/package-info.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfContentsColumn.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfTimestampColumn.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfTypeColumn.java delete mode 100644 org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/columns/TmfEventTableFieldColumn.java diff --git a/org.eclipse.tracecompass.btf.ui/src/org/eclipse/tracecompass/btf/ui/BtfEventTableColumns.java b/org.eclipse.tracecompass.btf.ui/src/org/eclipse/tracecompass/btf/ui/BtfEventTableColumns.java index 7a9167fa94..7bcbfb2612 100644 --- a/org.eclipse.tracecompass.btf.ui/src/org/eclipse/tracecompass/btf/ui/BtfEventTableColumns.java +++ b/org.eclipse.tracecompass.btf.ui/src/org/eclipse/tracecompass/btf/ui/BtfEventTableColumns.java @@ -19,9 +19,10 @@ import org.eclipse.jdt.annotation.NonNull; import org.eclipse.tracecompass.btf.core.event.BtfEvent; import org.eclipse.tracecompass.btf.core.trace.BtfColumnNames; import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect; +import org.eclipse.tracecompass.tmf.core.event.aspect.TmfEventFieldAspect; import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.ITmfEventTableColumns; import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn; -import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableFieldColumn; import com.google.common.collect.ImmutableList; @@ -38,27 +39,33 @@ public class BtfEventTableColumns implements ITmfEventTableColumns { @SuppressWarnings("null") private static final @NonNull Collection BTF_COLUMNS = ImmutableList.of( - TmfEventTableColumn.BaseColumns.TIMESTAMP, - new BtfSourceColumn(), - new BtfSourceInstanceColumn(), - TmfEventTableColumn.BaseColumns.EVENT_TYPE, - new BtfTargetColumn(), - new BtfTargetInstanceColumn(), - new BtfEventColumn(), - new BtfNotesColumn() + new TmfEventTableColumn(ITmfEventAspect.BaseAspects.TIMESTAMP), + new TmfEventTableColumn(new BtfSourceAspect()), + new TmfEventTableColumn(new BtfSourceInstanceAspect()), + new TmfEventTableColumn(ITmfEventAspect.BaseAspects.EVENT_TYPE), + new TmfEventTableColumn(new BtfTargetAspect()), + new TmfEventTableColumn(new BtfTargetInstanceAspect()), + new TmfEventTableColumn(new BtfEventAspect()), + new TmfEventTableColumn(new BtfNotesAspect()) ); /** - * The "source" column, whose value comes from {@link ITmfEvent#getSource()} + * The "source" aspect, whose value comes from {@link ITmfEvent#getSource()} */ - private static class BtfSourceColumn extends TmfEventTableColumn { + private static class BtfSourceAspect implements ITmfEventAspect { - public BtfSourceColumn() { - super(BtfColumnNames.SOURCE.toString(), null); + @Override + public String getName() { + return BtfColumnNames.SOURCE.toString(); + } + + @Override + public String getHelpText() { + return EMPTY_STRING; } @Override - public String getItemString(ITmfEvent event) { + public String resolve(ITmfEvent event) { if (!(event instanceof BtfEvent)) { return EMPTY_STRING; } @@ -67,33 +74,40 @@ public class BtfEventTableColumns implements ITmfEventTableColumns { } @Override - public String getFilterFieldId() { + public String getFilterId() { return ITmfEvent.EVENT_FIELD_SOURCE; } } /** - * The "source instance" column, whose value comes from the field of the + * The "source instance" aspect, whose value comes from the field of the * same name. */ - private static class BtfSourceInstanceColumn extends TmfEventTableFieldColumn { - public BtfSourceInstanceColumn() { - super(BtfColumnNames.SOURCE_INSTANCE.toString()); + private static class BtfSourceInstanceAspect extends TmfEventFieldAspect { + public BtfSourceInstanceAspect() { + super(BtfColumnNames.SOURCE_INSTANCE.toString(), + BtfColumnNames.SOURCE_INSTANCE.toString()); } } /** - * The "target" column, taking its value from + * The "target" aspect, taking its value from * {@link ITmfEvent#getReference()}. */ - private static class BtfTargetColumn extends TmfEventTableColumn { + private static class BtfTargetAspect implements ITmfEventAspect { - public BtfTargetColumn() { - super(BtfColumnNames.TARGET.toString()); + @Override + public String getName() { + return BtfColumnNames.TARGET.toString(); + } + + @Override + public String getHelpText() { + return EMPTY_STRING; } @Override - public String getItemString(ITmfEvent event) { + public String resolve(ITmfEvent event) { if (!(event instanceof BtfEvent)) { return EMPTY_STRING; } @@ -102,27 +116,29 @@ public class BtfEventTableColumns implements ITmfEventTableColumns { } @Override - public String getFilterFieldId() { + public String getFilterId() { return ITmfEvent.EVENT_FIELD_REFERENCE; } } /** - * The "target instance" column, whose value comes from the field of the + * The "target instance" aspect, whose value comes from the field of the * same name. */ - private static class BtfTargetInstanceColumn extends TmfEventTableFieldColumn { - public BtfTargetInstanceColumn() { - super(BtfColumnNames.TARGET_INSTANCE.toString()); + private static class BtfTargetInstanceAspect extends TmfEventFieldAspect { + public BtfTargetInstanceAspect() { + super(BtfColumnNames.TARGET_INSTANCE.toString(), + BtfColumnNames.TARGET_INSTANCE.toString()); } } /** - * The "event" column, whose value comes from the field of the same name. + * The "event" aspect, whose value comes from the field of the same name. */ - private static class BtfEventColumn extends TmfEventTableFieldColumn { - public BtfEventColumn() { - super(BtfColumnNames.EVENT.toString()); + private static class BtfEventAspect extends TmfEventFieldAspect { + public BtfEventAspect() { + super(BtfColumnNames.EVENT.toString(), + BtfColumnNames.EVENT.toString()); } } @@ -130,9 +146,10 @@ public class BtfEventTableColumns implements ITmfEventTableColumns { * The "notes" column, whose value comes from the field of the same name, if * present. */ - private static class BtfNotesColumn extends TmfEventTableFieldColumn { - public BtfNotesColumn() { - super(BtfColumnNames.NOTES.toString()); + private static class BtfNotesAspect extends TmfEventFieldAspect { + public BtfNotesAspect() { + super(BtfColumnNames.NOTES.toString(), + BtfColumnNames.NOTES.toString()); } } diff --git a/org.eclipse.tracecompass.gdbtrace.ui/src/org/eclipse/tracecompass/internal/gdbtrace/ui/views/events/GdbEventTableColumns.java b/org.eclipse.tracecompass.gdbtrace.ui/src/org/eclipse/tracecompass/internal/gdbtrace/ui/views/events/GdbEventTableColumns.java index 4465ea14cf..a3afc54d20 100644 --- a/org.eclipse.tracecompass.gdbtrace.ui/src/org/eclipse/tracecompass/internal/gdbtrace/ui/views/events/GdbEventTableColumns.java +++ b/org.eclipse.tracecompass.gdbtrace.ui/src/org/eclipse/tracecompass/internal/gdbtrace/ui/views/events/GdbEventTableColumns.java @@ -18,9 +18,10 @@ import org.eclipse.jdt.annotation.NonNull; import org.eclipse.tracecompass.internal.gdbtrace.core.event.GdbTraceEvent; import org.eclipse.tracecompass.internal.gdbtrace.core.event.GdbTraceEventContent; import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect; +import org.eclipse.tracecompass.tmf.core.event.aspect.TmfEventFieldAspect; import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.ITmfEventTableColumns; import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn; -import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableFieldColumn; import com.google.common.collect.ImmutableList; @@ -37,31 +38,39 @@ public class GdbEventTableColumns implements ITmfEventTableColumns { @SuppressWarnings("null") static final @NonNull Collection GDB_COLUMNS = ImmutableList.of( - new GdbTraceFrameColumn(), - new GdbTracepointColumn(), - new GdbFileColumn() + new TmfEventTableColumn(new GdbTraceFrameAspect()), + new TmfEventTableColumn(new GdbTracepointAspect()), + new TmfEventTableColumn(new GdbFileAspect()) ); - private static class GdbTraceFrameColumn extends TmfEventTableFieldColumn { - public GdbTraceFrameColumn() { - super(GdbTraceEventContent.TRACE_FRAME); + private static class GdbTraceFrameAspect extends TmfEventFieldAspect { + public GdbTraceFrameAspect() { + super(GdbTraceEventContent.TRACE_FRAME, + GdbTraceEventContent.TRACE_FRAME); } } - private static class GdbTracepointColumn extends TmfEventTableFieldColumn { - public GdbTracepointColumn() { - super(GdbTraceEventContent.TRACEPOINT); + private static class GdbTracepointAspect extends TmfEventFieldAspect { + public GdbTracepointAspect() { + super(GdbTraceEventContent.TRACEPOINT, + GdbTraceEventContent.TRACEPOINT); } } - private static class GdbFileColumn extends TmfEventTableColumn { + private static class GdbFileAspect implements ITmfEventAspect { - public GdbFileColumn() { - super("File"); //$NON-NLS-1$ + @Override + public String getName() { + return "File"; //$NON-NLS-1$ + } + + @Override + public String getHelpText() { + return EMPTY_STRING; } @Override - public String getItemString(ITmfEvent event) { + public String resolve(ITmfEvent event) { if (!(event instanceof GdbTraceEvent)) { return EMPTY_STRING; } @@ -70,7 +79,7 @@ public class GdbEventTableColumns implements ITmfEventTableColumns { } @Override - public String getFilterFieldId() { + public String getFilterId() { return ITmfEvent.EVENT_FIELD_REFERENCE; } } diff --git a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/tracecompass/internal/lttng2/kernel/ui/viewers/events/LttngEventTableColumns.java b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/tracecompass/internal/lttng2/kernel/ui/viewers/events/LttngEventTableColumns.java index 2528b87b81..f9e016823b 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/tracecompass/internal/lttng2/kernel/ui/viewers/events/LttngEventTableColumns.java +++ b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/tracecompass/internal/lttng2/kernel/ui/viewers/events/LttngEventTableColumns.java @@ -16,6 +16,7 @@ import java.util.Collection; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect; import org.eclipse.tracecompass.tmf.ctf.core.event.CtfTmfEvent; import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.ITmfEventTableColumns; import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn; @@ -37,19 +38,25 @@ public class LttngEventTableColumns implements ITmfEventTableColumns { @SuppressWarnings("null") private static final @NonNull Collection LTTNG_COLUMNS = ImmutableList. of( - TmfEventTableColumn.BaseColumns.TIMESTAMP, - new LttngChannelColumn(), - TmfEventTableColumn.BaseColumns.EVENT_TYPE, - TmfEventTableColumn.BaseColumns.CONTENTS); + new TmfEventTableColumn(ITmfEventAspect.BaseAspects.TIMESTAMP), + new TmfEventTableColumn(new LttngChannelAspect()), + new TmfEventTableColumn(ITmfEventAspect.BaseAspects.EVENT_TYPE), + new TmfEventTableColumn(ITmfEventAspect.BaseAspects.CONTENTS)); - private static class LttngChannelColumn extends TmfEventTableColumn { + private static class LttngChannelAspect implements ITmfEventAspect { - public LttngChannelColumn() { - super(CHANNEL_HEADER); + @Override + public String getName() { + return CHANNEL_HEADER; + } + + @Override + public String getHelpText() { + return EMPTY_STRING; } @Override - public String getItemString(ITmfEvent event) { + public String resolve(ITmfEvent event) { if (!(event instanceof CtfTmfEvent)) { return EMPTY_STRING; } @@ -58,7 +65,7 @@ public class LttngEventTableColumns implements ITmfEventTableColumns { } @Override - public String getFilterFieldId() { + public String getFilterId() { return ITmfEvent.EVENT_FIELD_REFERENCE; } } diff --git a/org.eclipse.tracecompass.tmf.core/META-INF/MANIFEST.MF b/org.eclipse.tracecompass.tmf.core/META-INF/MANIFEST.MF index b9f2b17c45..92f0a59d8d 100644 --- a/org.eclipse.tracecompass.tmf.core/META-INF/MANIFEST.MF +++ b/org.eclipse.tracecompass.tmf.core/META-INF/MANIFEST.MF @@ -27,6 +27,7 @@ Export-Package: org.eclipse.tracecompass.internal.tmf.core;x-friends:="org.eclip org.eclipse.tracecompass.tmf.core.callstack, org.eclipse.tracecompass.tmf.core.component, org.eclipse.tracecompass.tmf.core.event, + org.eclipse.tracecompass.tmf.core.event.aspect, org.eclipse.tracecompass.tmf.core.event.collapse, org.eclipse.tracecompass.tmf.core.event.lookup, org.eclipse.tracecompass.tmf.core.event.matching, diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/ITmfEventAspect.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/ITmfEventAspect.java new file mode 100644 index 0000000000..f8fba86726 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/ITmfEventAspect.java @@ -0,0 +1,178 @@ +/******************************************************************************* + * 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: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event.aspect; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; + +/** + * An aspect is a piece of information that can be extracted, directly or + * indirectly, from a trace event. + * + * Simple examples could be timestamp, or event fields. But it could also be + * something like a state system request, at the timestamp of the given event. + * + * The aspect can then be used to populate event table columns, to filter + * on to only keep certain events, to plot XY charts, etc. + * + * @author Alexandre Montplaisir + */ +public interface ITmfEventAspect { + + /** + * Static definition of an empty string. You can use this instead of 'null'! + */ + String EMPTY_STRING = ""; //$NON-NLS-1$ + + /** + * Some basic aspects that all trace types should be able to use, using + * methods found in {@link ITmfEvent}. + */ + interface BaseAspects { + + /** + * Aspect for the event timestamp + */ + ITmfEventAspect TIMESTAMP = new ITmfEventAspect() { + @Override + public String getName() { + return Messages.getMessage(Messages.AspectName_Timestamp); + } + + @Override + public String getHelpText() { + return EMPTY_STRING; + } + + @Override + public String resolve(ITmfEvent event) { + String ret = event.getTimestamp().toString(); + return (ret == null ? EMPTY_STRING : ret); + } + + @Override + public @NonNull String getFilterId() { + return ITmfEvent.EVENT_FIELD_TIMESTAMP; + } + }; + + /** + * Aspect for the event type + */ + ITmfEventAspect EVENT_TYPE = new ITmfEventAspect() { + @Override + public String getName() { + return Messages.getMessage(Messages.AspectName_EventType); + } + + @Override + public String getHelpText() { + return Messages.getMessage(Messages.AspectHelpText_EventType); + } + + @Override + public String resolve(ITmfEvent event) { + ITmfEventType type = event.getType(); + if (type == null) { + return EMPTY_STRING; + } + String typeName = type.getName(); + return (typeName == null ? EMPTY_STRING : typeName); + } + + @Override + public @NonNull String getFilterId() { + return ITmfEvent.EVENT_FIELD_TYPE; + } + }; + + /** + * Aspect for the aggregated event contents (fields) + */ + ITmfEventAspect CONTENTS = new ITmfEventAspect() { + @Override + public String getName() { + return Messages.getMessage(Messages.AspectName_Contents); + } + + @Override + public String getHelpText() { + return Messages.getMessage(Messages.AspectHelpText_Contents); + } + + @Override + public String resolve(ITmfEvent event) { + String ret = event.getContent().toString(); + return (ret == null ? EMPTY_STRING : ret); + } + + @Override + public @NonNull String getFilterId() { + return ITmfEvent.EVENT_FIELD_CONTENT; + } + }; + } + + /** + * Get the name of this aspect. This name will be user-visible and, as such, + * should be localized. + * + * @return The name of this aspect. + */ + String getName(); + + /** + * Return a descriptive help text of what this aspect does. This could then + * be shown in tooltip or in option dialogs for instance. It should also be + * localized. + * + * You can return {@link #EMPTY_STRING} if you judge that the aspect name + * makes it obvious. + * + * @return The help text of this aspect + */ + String getHelpText(); + + /** + * The "functor" representing this aspect. Basically, what to do for an + * event that is passed in parameter. + * + * Note to implementers: + * + * The parameter type here is {@link ITmfEvent}. This is because you could + * receive any type of event here. Do not assume you will only receive + * events of your own trace type. It is perfectly fine to return + * {@link #EMPTY_STRING} for event types you don't support. + * + * You also can (and should) provide a more specific return type than + * Object. + * + * @param event + * The event to process + * @return The resulting tidbit of information for this event. + */ + Object resolve(ITmfEvent event); + + /** + * The filter ID of this aspect. This is currently used by the Filter View, + * and to filter on columns in the event table. + * + * TODO Remove this, replace with calls to {@link #resolve(ITmfEvent)} + * instead. + * + * @return The filter_id + */ + @Nullable String getFilterId(); +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/Messages.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/Messages.java new file mode 100644 index 0000000000..6b3b82e5a5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/Messages.java @@ -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: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event.aspect; + +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.osgi.util.NLS; + +@SuppressWarnings("javadoc") +public class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.tracecompass.tmf.core.event.aspect.messages"; //$NON-NLS-1$ + + public static @Nullable String AspectName_Timestamp; + public static @Nullable String AspectName_EventType; + public static @Nullable String AspectName_Contents; + public static @Nullable String AspectName_CPU; + + public static @Nullable String AspectHelpText_EventType; + public static @Nullable String AspectHelpText_Contents; + public static @Nullable String AspectHelpText_CPU; + public static @Nullable String AspectHelpText_Statesystem; + + static { + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } + + /** + * Helper method to expose externalized strings as non-null objects. + */ + static String getMessage(@Nullable String msg) { + if (msg == null) { + return ""; //$NON-NLS-1$ + } + return msg; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/TmfCpuAspect.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/TmfCpuAspect.java new file mode 100644 index 0000000000..ad8eb20acb --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/TmfCpuAspect.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * 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: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event.aspect; + +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; + +/** + * Event aspect representing the CPU of a trace event. Trace types that do have + * the notion of CPU can use this to expose it in their traces. + * + * TODO Move to an eventualy kernel-trace-specific plugin. + * + * @author Alexandre Montplaisir + */ +public abstract class TmfCpuAspect implements ITmfEventAspect { + + @Override + public final String getName() { + return Messages.getMessage(Messages.AspectName_CPU); + } + + @Override + public final String getHelpText() { + return Messages.getMessage(Messages.AspectHelpText_CPU); + } + + @Override + public abstract String resolve(ITmfEvent event); + + @Override + public boolean equals(@Nullable Object other) { + /* + * Consider all sub-instance of this type "equal", so that they get + * merged in a single CPU column/aspect. + */ + if (other instanceof TmfCpuAspect) { + return true; + } + return false; + } + + @Override + public int hashCode() { + return getName().hashCode(); + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/TmfEventFieldAspect.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/TmfEventFieldAspect.java new file mode 100644 index 0000000000..7f9ccae936 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/TmfEventFieldAspect.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * 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: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event.aspect; + +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; + +/** + * Event aspect representing a single field of an event. + * + * @author Alexandre Montplaisir + */ +public class TmfEventFieldAspect implements ITmfEventAspect { + + private final String fAspectName; + private final String fFieldName; + + /** + * Constructor + * + * @param aspectName + * The name of the aspect. Should be localized. + * @param fieldName + * The name of the field to look for in the trace. Should *not* + * be localized! + */ + public TmfEventFieldAspect(String aspectName, String fieldName) { + fAspectName = aspectName; + fFieldName = fieldName; + } + + @Override + public String getName() { + return fAspectName; + } + + @Override + public String getHelpText() { + return EMPTY_STRING; + } + + @Override + public String resolve(ITmfEvent event) { + ITmfEventField field = event.getContent().getField(fFieldName); + if (field == null) { + return EMPTY_STRING; + } + String fieldValue = field.getFormattedValue(); + return (fieldValue == null ? EMPTY_STRING : fieldValue); + } + + @Override + public @Nullable String getFilterId() { + return null; + } + + // ------------------------------------------------------------------------ + // hashCode/equals + // Typically we want identical field aspects to be merged together. + // ------------------------------------------------------------------------ + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + fAspectName.hashCode(); + result = prime * result + fFieldName.hashCode(); + return result; + } + + @Override + public boolean equals(@Nullable Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof TmfEventFieldAspect)) { + return false; + } + TmfEventFieldAspect other = (TmfEventFieldAspect) obj; + if (!fAspectName.equals(other.fAspectName)) { + return false; + } + if (!fFieldName.equals(other.fFieldName)) { + return false; + } + return true; + } +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/TmfStateSystemAspect.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/TmfStateSystemAspect.java new file mode 100644 index 0000000000..d3e8c59cab --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/TmfStateSystemAspect.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * 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: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.event.aspect; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.osgi.util.NLS; +import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; +import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException; +import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; + +/** + * Aspect representing a query in a given state system, at the timestamp of the + * event. + * + * This is a good example of how aspects can be "indirect" with regards to their + * events. + * + * @author Alexandre Montplaisir + */ +public class TmfStateSystemAspect implements ITmfEventAspect { + + private final @Nullable String fName; + private final ITmfStateSystem fSS; + private final int fAttribute; + + /** + * Constructor + * + * @param name + * The name of this aspect. You can use 'null' to use the + * default name, which is the (base) name of the attribute. + * @param ss + * The state system in which we want to query + * @param attributeQuark + * The quark of the attribute in the state system to look for + */ + public TmfStateSystemAspect(@Nullable String name, ITmfStateSystem ss, int attributeQuark) { + fName = name; + fSS = ss; + fAttribute = attributeQuark; + } + + @Override + public String getName() { + String name = fName; + if (name != null) { + return name; + } + + name = fSS.getAttributeName(fAttribute); + return (name == null ? EMPTY_STRING : name); + } + + @Override + public @NonNull String getHelpText() { + return Messages.getMessage(NLS.bind(Messages.AspectHelpText_Statesystem, + fSS.getSSID(), fSS.getFullAttributePath(fAttribute))); + } + + @Override + public String resolve(ITmfEvent event) { + try { + ITmfStateValue value = fSS.querySingleState(event.getTimestamp().getValue(), fAttribute).getStateValue(); + + @SuppressWarnings("null") + @NonNull String ret = value.toString(); + return ret; + } catch (AttributeNotFoundException | StateSystemDisposedException e) { + return EMPTY_STRING; + } + } + + @Override + public @Nullable String getFilterId() { + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/messages.properties b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/messages.properties new file mode 100644 index 0000000000..0e577d8af5 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/messages.properties @@ -0,0 +1,21 @@ +############################################################################### +# 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: +# Ericsson - Initial API and implementation +############################################################################### + +AspectName_Timestamp=Timestamp +AspectName_EventType=Event type +AspectName_Contents=Contents +AspectName_CPU=CPU + +AspectHelpText_EventType=The type of this event. This normally determines the field layout. +AspectHelpText_Contents=The fields (or payload) of this event +AspectHelpText_CPU=The CPU on which this event was taken +AspectHelpText_Statesystem=Request in state system {0}, for attribute: {1} diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/package-info.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/package-info.java new file mode 100644 index 0000000000..017c6d05f9 --- /dev/null +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/event/aspect/package-info.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +@org.eclipse.jdt.annotation.NonNullByDefault +package org.eclipse.tracecompass.tmf.core.event.aspect; diff --git a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/editor/PcapEventTableColumns.java b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/editor/PcapEventTableColumns.java index a4eb206357..a5a2b55bd3 100644 --- a/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/editor/PcapEventTableColumns.java +++ b/org.eclipse.tracecompass.tmf.pcap.ui/src/org/eclipse/tracecompass/internal/tmf/pcap/ui/editor/PcapEventTableColumns.java @@ -20,6 +20,7 @@ import org.eclipse.jdt.annotation.Nullable; import org.eclipse.tracecompass.internal.tmf.pcap.core.event.PcapEvent; import org.eclipse.tracecompass.internal.tmf.pcap.core.protocol.TmfPcapProtocol; import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect; import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.ITmfEventTableColumns; import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn; @@ -38,25 +39,31 @@ public class PcapEventTableColumns implements ITmfEventTableColumns { @SuppressWarnings("null") private static final @NonNull Collection PCAP_COLUMNS = ImmutableList.of( - TmfEventTableColumn.BaseColumns.TIMESTAMP, - new PcapSourceColumn(), - new PcapDestinationColumn(), - new PcapReferenceColumn(), - new PcapProtocolColumn(), - TmfEventTableColumn.BaseColumns.CONTENTS + new TmfEventTableColumn(ITmfEventAspect.BaseAspects.TIMESTAMP), + new TmfEventTableColumn(new PcapSourceAspect()), + new TmfEventTableColumn(new PcapDestinationAspect()), + new TmfEventTableColumn(new PcapReferenceAspect()), + new TmfEventTableColumn(new PcapProtocolAspect()), + new TmfEventTableColumn(ITmfEventAspect.BaseAspects.CONTENTS) ); /** * The "packet source" column for pcap events */ - private static class PcapSourceColumn extends TmfEventTableColumn { + private static class PcapSourceAspect implements ITmfEventAspect { - public PcapSourceColumn() { - super(getString(Messages.PcapEventsTable_Source)); + @Override + public String getName() { + return getString(Messages.PcapEventsTable_Source); + } + + @Override + public String getHelpText() { + return EMPTY_STRING; } @Override - public String getItemString(ITmfEvent event) { + public String resolve(ITmfEvent event) { if (!(event instanceof PcapEvent)) { return EMPTY_STRING; } @@ -67,7 +74,7 @@ public class PcapEventTableColumns implements ITmfEventTableColumns { } @Override - public @Nullable String getFilterFieldId() { + public @NonNull String getFilterId() { return PcapEvent.EVENT_FIELD_PACKET_SOURCE; } } @@ -75,14 +82,20 @@ public class PcapEventTableColumns implements ITmfEventTableColumns { /** * The "packet destination" column for pcap events */ - private static class PcapDestinationColumn extends TmfEventTableColumn { + private static class PcapDestinationAspect implements ITmfEventAspect { - public PcapDestinationColumn() { - super(getString(Messages.PcapEventsTable_Destination)); + @Override + public String getName() { + return getString(Messages.PcapEventsTable_Destination); + } + + @Override + public String getHelpText() { + return EMPTY_STRING; } @Override - public String getItemString(ITmfEvent event) { + public String resolve(ITmfEvent event) { if (!(event instanceof PcapEvent)) { return EMPTY_STRING; } @@ -92,7 +105,7 @@ public class PcapEventTableColumns implements ITmfEventTableColumns { } @Override - public @Nullable String getFilterFieldId() { + public @NonNull String getFilterId() { return PcapEvent.EVENT_FIELD_PACKET_DESTINATION; } } @@ -100,14 +113,20 @@ public class PcapEventTableColumns implements ITmfEventTableColumns { /** * The "packet reference" column for pcap events */ - private static class PcapReferenceColumn extends TmfEventTableColumn { + private static class PcapReferenceAspect implements ITmfEventAspect { - public PcapReferenceColumn() { - super(getString(Messages.PcapEventsTable_Reference)); + @Override + public String getName() { + return getString(Messages.PcapEventsTable_Reference); + } + + @Override + public String getHelpText() { + return EMPTY_STRING; } @Override - public String getItemString(ITmfEvent event) { + public String resolve(ITmfEvent event) { if (!(event instanceof PcapEvent)) { return EMPTY_STRING; } @@ -115,7 +134,7 @@ public class PcapEventTableColumns implements ITmfEventTableColumns { } @Override - public @Nullable String getFilterFieldId() { + public @Nullable String getFilterId() { return ITmfEvent.EVENT_FIELD_REFERENCE; } } @@ -123,14 +142,20 @@ public class PcapEventTableColumns implements ITmfEventTableColumns { /** * The "packet protocol" column for pcap events */ - private static class PcapProtocolColumn extends TmfEventTableColumn { + private static class PcapProtocolAspect implements ITmfEventAspect { - public PcapProtocolColumn() { - super(getString(Messages.PcapEventsTable_Protocol)); + @Override + public String getName() { + return getString(Messages.PcapEventsTable_Protocol); + } + + @Override + public String getHelpText() { + return EMPTY_STRING; } @Override - public String getItemString(ITmfEvent event) { + public String resolve(ITmfEvent event) { if (!(event instanceof PcapEvent)) { return EMPTY_STRING; } @@ -143,7 +168,7 @@ public class PcapEventTableColumns implements ITmfEventTableColumns { } @Override - public @Nullable String getFilterFieldId() { + public @Nullable String getFilterId() { return PcapEvent.EVENT_FIELD_PACKET_PROTOCOL; } } diff --git a/org.eclipse.tracecompass.tmf.ui/META-INF/MANIFEST.MF b/org.eclipse.tracecompass.tmf.ui/META-INF/MANIFEST.MF index 63f52706c3..b208b8c5c9 100644 --- a/org.eclipse.tracecompass.tmf.ui/META-INF/MANIFEST.MF +++ b/org.eclipse.tracecompass.tmf.ui/META-INF/MANIFEST.MF @@ -35,7 +35,6 @@ Export-Package: org.eclipse.tracecompass.internal.tmf.ui;x-friends:="org.eclipse org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace;x-friends:="org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests,org.eclipse.tracecompass.tmf.ui,org.eclipse.tracecompass.lttng2.control.ui", org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg;x-internal:=true, org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.importexport;x-internal:=true, - org.eclipse.tracecompass.internal.tmf.ui.viewers.events.columns;x-internal:=true, org.eclipse.tracecompass.tmf.ui, org.eclipse.tracecompass.tmf.ui.analysis, org.eclipse.tracecompass.tmf.ui.editors, diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/custom/CustomEventTableColumns.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/custom/CustomEventTableColumns.java index 65320cfb8d..78db09dae0 100644 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/custom/CustomEventTableColumns.java +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/parsers/custom/CustomEventTableColumns.java @@ -18,6 +18,7 @@ import java.util.List; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect; import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomEvent; import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTraceDefinition; import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTraceDefinition.OutputColumn; @@ -47,26 +48,37 @@ public class CustomEventTableColumns { * Column for custom events, which uses an integer ID to represent each * column. */ - private static final class CustomEventTableColumn extends TmfEventTableColumn { + private static final class CustomEventFieldAspect implements ITmfEventAspect { + private final @NonNull String fName; private final int fIndex; /** * Constructor * * @param name - * The name (title) of this column + * The name (title) of this aspect * @param idx - * The index of this column, which should be the index of the - * field in the event's content to display. + * The "index" of this aspect, which should be the index of + * the field in the event's content to display. */ - public CustomEventTableColumn(@NonNull String name, int idx) { - super(name); + public CustomEventFieldAspect(@NonNull String name, int idx) { + fName = name; fIndex = idx; } @Override - public String getItemString(ITmfEvent event) { + public String getName() { + return fName; + } + + @Override + public String getHelpText() { + return EMPTY_STRING; + } + + @Override + public String resolve(ITmfEvent event) { if (event instanceof CustomEvent) { String ret = ((CustomEvent) event).getEventString(fIndex); return (ret == null ? EMPTY_STRING : ret); @@ -75,8 +87,8 @@ public class CustomEventTableColumns { } @Override - public String getFilterFieldId() { - return getHeaderName(); + public String getFilterId() { + return fName; } } @@ -86,13 +98,13 @@ public class CustomEventTableColumns { * @param definition The {@link CustomTraceDefinition} of the trace for which you want the columns * @return The set of columns for the given trace. */ - public static Collection generateColumns(CustomTraceDefinition definition) { - ImmutableList.Builder builder = new ImmutableList.Builder<>(); + public static Collection generateColumns(CustomTraceDefinition definition) { + ImmutableList.Builder builder = new ImmutableList.Builder<>(); List outputs = definition.outputs; for (int i = 0; i < outputs.size(); i++) { String name = outputs.get(i).name; if (name != null) { - builder.add(new CustomEventTableColumn(name, i)); + builder.add(new TmfEventTableColumn(new CustomEventFieldAspect(name, i))); } } return builder.build(); diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfContentsColumn.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfContentsColumn.java deleted file mode 100644 index a9c45971cc..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfContentsColumn.java +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - * 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: - * Alexandre Montplaisir - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.tracecompass.internal.tmf.ui.viewers.events.columns; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.tracecompass.internal.tmf.ui.Messages; -import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; -import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn; - -/** - * Column for the event contents (fields) - * - * @author Alexandre Montplaisir - */ -public final class TmfContentsColumn extends TmfEventTableColumn { - - @SuppressWarnings("null") - private static final @NonNull String HEADER = Messages.TmfEventsTable_ContentColumnHeader; - - /** - * Constructor - */ - public TmfContentsColumn() { - super(HEADER); - } - - @Override - public String getItemString(ITmfEvent event) { - String ret = event.getContent().toString(); - return (ret == null ? EMPTY_STRING : ret); - } - - @Override - public String getFilterFieldId() { - return ITmfEvent.EVENT_FIELD_CONTENT; - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfTimestampColumn.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfTimestampColumn.java deleted file mode 100644 index 49c03fa247..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfTimestampColumn.java +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * 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: - * Alexandre Montplaisir - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.tracecompass.internal.tmf.ui.viewers.events.columns; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.tracecompass.internal.tmf.ui.Messages; -import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; -import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn; - -/** - * Column for the timestamps - */ -public final class TmfTimestampColumn extends TmfEventTableColumn { - - @SuppressWarnings("null") - private static final @NonNull String HEADER = Messages.TmfEventsTable_TimestampColumnHeader; - - /** - * Constructor - */ - public TmfTimestampColumn() { - super(HEADER); - } - - @Override - public String getItemString(ITmfEvent event) { - String ret = event.getTimestamp().toString(); - return (ret == null ? EMPTY_STRING : ret); - } - - @Override - public String getFilterFieldId() { - return ITmfEvent.EVENT_FIELD_TIMESTAMP; - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfTypeColumn.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfTypeColumn.java deleted file mode 100644 index 07810caf45..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/viewers/events/columns/TmfTypeColumn.java +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * 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: - * Alexandre Montplaisir - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.tracecompass.internal.tmf.ui.viewers.events.columns; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.tracecompass.internal.tmf.ui.Messages; -import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; -import org.eclipse.tracecompass.tmf.core.event.ITmfEventType; -import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn; - -/** - * Column for the event type - */ -public final class TmfTypeColumn extends TmfEventTableColumn { - - @SuppressWarnings("null") - private static final @NonNull String HEADER = Messages.TmfEventsTable_TypeColumnHeader; - - /** - * Constructor - */ - public TmfTypeColumn() { - super(HEADER); - } - - @Override - public String getItemString(ITmfEvent event) { - ITmfEventType type = event.getType(); - if (type == null) { - return EMPTY_STRING; - } - String typeName = type.getName(); - return (typeName == null ? EMPTY_STRING : typeName); - } - - @Override - public String getFilterFieldId() { - return ITmfEvent.EVENT_FIELD_TYPE; - } -} \ No newline at end of file diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/TmfEventsTable.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/TmfEventsTable.java index 0238a4e324..7d63ad8ee5 100644 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/TmfEventsTable.java +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/TmfEventsTable.java @@ -112,6 +112,8 @@ import org.eclipse.tracecompass.internal.tmf.ui.dialogs.MultiLineInputDialog; import org.eclipse.tracecompass.tmf.core.component.ITmfEventProvider; import org.eclipse.tracecompass.tmf.core.component.TmfComponent; import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect; +import org.eclipse.tracecompass.tmf.core.event.aspect.TmfEventFieldAspect; import org.eclipse.tracecompass.tmf.core.event.collapse.ITmfCollapsibleEvent; import org.eclipse.tracecompass.tmf.core.event.lookup.ITmfCallsite; import org.eclipse.tracecompass.tmf.core.event.lookup.ITmfModelLookup; @@ -138,7 +140,6 @@ import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; import org.eclipse.tracecompass.tmf.ui.viewers.events.TmfEventsCache.CachedEvent; import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn; -import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableFieldColumn; import org.eclipse.tracecompass.tmf.ui.views.colors.ColorSetting; import org.eclipse.tracecompass.tmf.ui.views.colors.ColorSettingsManager; import org.eclipse.tracecompass.tmf.ui.views.colors.IColorSettingsListener; @@ -208,9 +209,9 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS * @since 3.2 */ public static final Collection DEFAULT_COLUMNS = ImmutableList.of( - TmfEventTableColumn.BaseColumns.TIMESTAMP, - TmfEventTableColumn.BaseColumns.EVENT_TYPE, - TmfEventTableColumn.BaseColumns.CONTENTS + new TmfEventTableColumn(ITmfEventAspect.BaseAspects.TIMESTAMP), + new TmfEventTableColumn(ITmfEventAspect.BaseAspects.EVENT_TYPE), + new TmfEventTableColumn(ITmfEventAspect.BaseAspects.CONTENTS) ); /** @@ -364,9 +365,9 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS ImmutableList.Builder builder = new ImmutableList.Builder<>(); for (org.eclipse.tracecompass.tmf.ui.widgets.virtualtable.ColumnData col : columnData) { - String header = col.header; - if (header != null) { - builder.add(new TmfEventTableFieldColumn(header)); + String fieldName = col.header; + if (fieldName != null) { + builder.add(new TmfEventTableColumn(new TmfEventFieldAspect(fieldName, fieldName))); } } return builder.build(); @@ -2541,31 +2542,42 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS } /** - * Margin column for images and special text (e.g. collapse count) - */ - private static final class TmfMarginColumn extends TmfEventTableColumn { - - private static final @NonNull String HEADER = EMPTY_STRING; - - /** - * Constructor - */ - public TmfMarginColumn() { - super(HEADER); - } - - @Override - public String getItemString(ITmfEvent event) { - if (!(event instanceof CachedEvent) || ((CachedEvent) event).repeatCount == 0) { - return EMPTY_STRING; - } - return "+" + ((CachedEvent) event).repeatCount; //$NON-NLS-1$ - } - - @Override - public String getFilterFieldId() { - return null; - } - } + * Margin column for images and special text (e.g. collapse count) + */ + private static final class TmfMarginColumn extends TmfEventTableColumn { + + private static final @NonNull ITmfEventAspect MARGIN_ASPECT = new ITmfEventAspect() { + + @Override + public String getName() { + return EMPTY_STRING; + } + + @Override + public String resolve(ITmfEvent event) { + if (!(event instanceof CachedEvent) || ((CachedEvent) event).repeatCount == 0) { + return EMPTY_STRING; + } + return "+" + ((CachedEvent) event).repeatCount; //$NON-NLS-1$ + } + + @Override + public String getHelpText() { + return EMPTY_STRING; + } + + @Override + public String getFilterId() { + return null; + } + }; + + /** + * Constructor + */ + public TmfMarginColumn() { + super(MARGIN_ASPECT); + } + } } diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/columns/TmfEventTableColumn.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/columns/TmfEventTableColumn.java index 80906e8559..781159675f 100644 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/columns/TmfEventTableColumn.java +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/columns/TmfEventTableColumn.java @@ -12,12 +12,11 @@ package org.eclipse.tracecompass.tmf.ui.viewers.events.columns; +import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.tracecompass.internal.tmf.ui.viewers.events.columns.TmfContentsColumn; -import org.eclipse.tracecompass.internal.tmf.ui.viewers.events.columns.TmfTimestampColumn; -import org.eclipse.tracecompass.internal.tmf.ui.viewers.events.columns.TmfTypeColumn; import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect; /** * A column in the @@ -29,70 +28,32 @@ import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; * {@link org.eclipse.tracecompass.tmf.ui.viewers.events.TmfEventsTable#TmfEventsTable(org.eclipse.swt.widgets.Composite, int, java.util.Collection)} * * @author Alexandre Montplaisir + * @noextend This class should not be extended directly. You should instead + * implement an {@link ITmfEventAspect}. * @since 3.1 */ @NonNullByDefault -public abstract class TmfEventTableColumn { - - // ------------------------------------------------------------------------ - // Class attributes - // ------------------------------------------------------------------------ - - /** - * The base set of columns, which can apply to any trace type. - */ - public static interface BaseColumns { - - /** Column showing the event timestamp */ - TmfEventTableColumn TIMESTAMP = new TmfTimestampColumn(); - - /** Column showing the event type */ - TmfEventTableColumn EVENT_TYPE = new TmfTypeColumn(); - - /** Column showing the aggregated event contents (fields) */ - TmfEventTableColumn CONTENTS = new TmfContentsColumn(); - } - - /** - * Static definition of an empty string. Return this instead of returning - * 'null'! - */ - protected static final String EMPTY_STRING = ""; //$NON-NLS-1$ +public class TmfEventTableColumn { // ------------------------------------------------------------------------ // Fields // ------------------------------------------------------------------------ - private final String fHeaderName; - private final @Nullable String fHeaderTooltip; + private final ITmfEventAspect fAspect; // ------------------------------------------------------------------------ // Constructors // ------------------------------------------------------------------------ /** - * Constructor with no tooltip. - * - * @param headerName - * The name (title) of this column. Should ideally be short. - */ - public TmfEventTableColumn(String headerName) { - fHeaderName = headerName; - fHeaderTooltip = null; - } - - /** - * Constructor with a tooltip. + * Constructor * - * @param headerName - * The name (title) of this column. Should ideally be short. - * @param headerTooltip - * The tooltip text for the column header. Use 'null' for no - * tooltip. + * @param aspect + * The {@link ITmfEventAspect} to be used to populate this + * column. */ - public TmfEventTableColumn(String headerName, @Nullable String headerTooltip) { - fHeaderName = headerName; - fHeaderTooltip = headerTooltip; + public TmfEventTableColumn(ITmfEventAspect aspect) { + fAspect = aspect; } // ------------------------------------------------------------------------ @@ -105,7 +66,7 @@ public abstract class TmfEventTableColumn { * @return The column's title */ public String getHeaderName() { - return fHeaderName; + return fAspect.getName(); } /** @@ -114,31 +75,24 @@ public abstract class TmfEventTableColumn { * @return The header's tooltip */ public @Nullable String getHeaderTooltip() { - return fHeaderTooltip; + return fAspect.getHelpText(); } - // ------------------------------------------------------------------------ - // Abstract methods - // ------------------------------------------------------------------------ - /** * Get the string that should be displayed in this column's cell for a given * trace event. Basically, this defines "what to print in this column for * this event". - *

- * Note to implementers: - *

- * This method takes an {@link ITmfEvent}, because any type of event could - * potentially be present in the table at the time. Do not assume that you - * will only receive events of your trace type. You'd probably want to - * return an empty string for event that don't match your expected class - * type here. * * @param event * The trace event whose element we want to display * @return The string to display in the column for this event */ - public abstract String getItemString(ITmfEvent event); + public String getItemString(ITmfEvent event) { + /* resolve() is NonNull. toString() is not, but should never return null */ + @SuppressWarnings("null") + @NonNull String ret = fAspect.resolve(event).toString(); + return ret; + } /** * Return the FILTER_ID used by the filters to search this column. @@ -147,5 +101,38 @@ public abstract class TmfEventTableColumn { * ID (which will mean this column will probably not be * searchable/filterable.) */ - public abstract @Nullable String getFilterFieldId(); + public @Nullable String getFilterFieldId() { + return fAspect.getFilterId(); + } + + // ------------------------------------------------------------------------ + // hashCode/equals (so that equivalent columns can be merged together) + // ------------------------------------------------------------------------ + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + fAspect.hashCode(); + return result; + } + + @Override + public boolean equals(@Nullable Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof TmfEventTableColumn)) { + return false; + } + TmfEventTableColumn other = (TmfEventTableColumn) obj; + if (!fAspect.equals(other.fAspect)) { + /* Aspects can also define how they can be "equal" to one another */ + return false; + } + return true; + } } diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/columns/TmfEventTableFieldColumn.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/columns/TmfEventTableFieldColumn.java deleted file mode 100644 index 7b7eeeaa4c..0000000000 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/columns/TmfEventTableFieldColumn.java +++ /dev/null @@ -1,114 +0,0 @@ -/******************************************************************************* - * 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: - * Alexandre Montplaisir - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.tracecompass.tmf.ui.viewers.events.columns; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; -import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; - -/** - * Event table column that will print the value of a given event field, and - * whose column name is also the same as that field. - * - * @author Alexandre Montplaisir - * @since 3.1 - */ -@NonNullByDefault -public class TmfEventTableFieldColumn extends TmfEventTableColumn { - - private final String fFieldName; - - /** - * Basic constructor, which uses the same name for the field name and the - * column header. - * - * @param headerAndFieldName - * The string that is both the title of the column AND the field - * name to look for. - */ - public TmfEventTableFieldColumn(String headerAndFieldName) { - super(headerAndFieldName); - fFieldName = headerAndFieldName; - } - - /** - * Advanced constructor, which can define different field name and header. - * You can also define a tooltip, optionally. - * - * @param headerName - * The header (title) of the column - * @param fieldName - * The field name to look for in the event content to populate - * this column. - * @param headerTooltip - * The tooltip text for the column header. Use 'null' for no - * tooltip. - */ - public TmfEventTableFieldColumn(String headerName, String fieldName, - @Nullable String headerTooltip) { - super(headerName, headerTooltip); - fFieldName = fieldName; - } - - @Override - public final String getItemString(ITmfEvent event) { - ITmfEventField field = event.getContent().getField(fFieldName); - if (field == null) { - return EMPTY_STRING; - } - String val = field.getFormattedValue(); - return (val == null ? EMPTY_STRING : val); - } - - @Override - public @NonNull String getFilterFieldId() { - return fFieldName; - } - - // ------------------------------------------------------------------------ - // hashCode/equals (so that equivalent columns can be merged together) - // ------------------------------------------------------------------------ - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + fFieldName.hashCode(); - result = prime * result + getHeaderName().hashCode(); - return result; - } - - @Override - public boolean equals(@Nullable Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof TmfEventTableFieldColumn)) { - return false; - } - TmfEventTableFieldColumn other = (TmfEventTableFieldColumn) obj; - if (!fFieldName.equals(other.fFieldName)) { - return false; - } - if (!getHeaderName().equals(other.getHeaderName())) { - return false; - } - return true; - } - -} diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/text/TmfTextEventTable.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/text/TmfTextEventTable.java index 6567141119..a23e95da05 100644 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/text/TmfTextEventTable.java +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/events/text/TmfTextEventTable.java @@ -30,8 +30,6 @@ import org.eclipse.tracecompass.tmf.ui.widgets.virtualtable.ColumnData; * {@link TmfEventsTable#TmfEventsTable(Composite, int, java.util.Collection)} * , by passing * {@link org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn} - * or - * {@link org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableFieldColumn} * . */ @Deprecated -- 2.34.1