GP-1969: Add 'Model' provider for inspecting object-based traces.

This commit is contained in:
Dan 2022-06-15 15:41:38 -04:00
parent eb0a23aecc
commit 2a4b4f9bcf
59 changed files with 6131 additions and 269 deletions

View file

@ -24,18 +24,17 @@ import ghidra.util.table.column.GColumnRenderer;
import utilities.util.reflection.ReflectionUtilities;
/**
* An Table Column is an interface that should be implemented by each class that provides
* a field (column) of an object based table (each row relates to a particular type of object).
* It determines the appropriate cell object for use by the table column this field represents.
* It can then return the appropriate object to display in the table cell for the indicated
* row object.
* An Table Column is an interface that should be implemented by each class that provides a field
* (column) of an object based table (each row relates to a particular type of object). It
* determines the appropriate cell object for use by the table column this field represents. It can
* then return the appropriate object to display in the table cell for the indicated row object.
*
* Implementations of this interface must provide a public default constructor.
*
* @param <ROW_TYPE> The row object class supported by this column
* @param <COLUMN_TYPE> The column object class supported by this column
* @param <DATA_SOURCE> The object class type that will be passed to
* see <code>getValue(ROW_TYPE, Settings, DATA_SOURCE, ServiceProvider)</code>
* @param <DATA_SOURCE> The object class type that will be passed to see
* <code>getValue(ROW_TYPE, Settings, DATA_SOURCE, ServiceProvider)</code>
*/
public abstract class AbstractDynamicTableColumn<ROW_TYPE, COLUMN_TYPE, DATA_SOURCE>
implements DynamicTableColumn<ROW_TYPE, COLUMN_TYPE, DATA_SOURCE> {
@ -80,11 +79,16 @@ public abstract class AbstractDynamicTableColumn<ROW_TYPE, COLUMN_TYPE, DATA_SOU
return -1;
}
@Override
public Comparator<COLUMN_TYPE> getComparator() {
return null;
}
@Override
public Comparator<COLUMN_TYPE> getComparator(DynamicColumnTableModel<?> model,
int columnIndex) {
return getComparator();
}
@Override
@SuppressWarnings("unchecked")
// enforced by the compiler

View file

@ -24,48 +24,52 @@ import ghidra.framework.plugintool.ServiceProvider;
import ghidra.util.table.column.GColumnRenderer;
/**
* The root interface for defining columns for {@link GDynamicColumnTableModel}s. The
* class allows you to create objects for tables that know how to give a column value for a
* given row.
* The root interface for defining columns for {@link DynamicColumnTableModel}s. The class allows
* you to create objects for tables that know how to give a column value for a given row.
*
* @param <ROW_TYPE> The row object class supported by this column
* @param <COLUMN_TYPE> The column object class supported by this column
* @param <DATA_SOURCE> The object class type that will be passed to
* see <code>getValue(ROW_TYPE, Settings, DATA_SOURCE, ServiceProvider)</code>
* @param <DATA_SOURCE> The object class type that will be passed to see
* <code>getValue(ROW_TYPE, Settings, DATA_SOURCE, ServiceProvider)</code>
*/
public interface DynamicTableColumn<ROW_TYPE, COLUMN_TYPE, DATA_SOURCE> {
/**
* Determines the unique column heading that may be used to identify a column instance.
* This name must be non-changing and is used to save/restore state information.
* Determines the unique column heading that may be used to identify a column instance. This
* name must be non-changing and is used to save/restore state information.
*
* @return the field instance name.
*/
public String getColumnName();
/**
* Determines the class of object that is associated with this field (column).
*
* @return the column class
*/
public Class<COLUMN_TYPE> getColumnClass();
/**
* Returns the preferred width for this column. Column should either return a valid positive
* Returns the preferred width for this column. Column should either return a valid positive
* preferred size or -1.
*
* @return the preferred width for this column.
*/
public int getColumnPreferredWidth();
/**
* Returns the single class type of the data that this table field can use to
* generate columnar data.
* @return the single class type of the data that this table field can use to
* generate columnar data.
* Returns the single class type of the data that this table field can use to generate columnar
* data.
*
* @return the single class type of the data that this table field can use to generate columnar
* data.
*/
public Class<ROW_TYPE> getSupportedRowType();
/**
* Creates an object that is appropriate for this field (table column) and for the
* object that is associated with this row of the table.
* Creates an object that is appropriate for this field (table column) and for the object that
* is associated with this row of the table.
*
* @param rowObject the object associated with the row in the table.
* @param settings field settings
* @param data the expected data object, as defined by the DATA_SOURCE type
@ -79,13 +83,15 @@ public interface DynamicTableColumn<ROW_TYPE, COLUMN_TYPE, DATA_SOURCE> {
/**
* Returns the optional cell renderer for this column; null if no renderer is used.
*
* <P>This method allows columns to define custom rendering. The interface returned here
* ensures that the text used for filtering matches what the users sees (via the
* <P>
* This method allows columns to define custom rendering. The interface returned here ensures
* that the text used for filtering matches what the users sees (via the
* {@link GColumnRenderer#getFilterString(Object, Settings)} method).
*
* <P>Note: some types should not make use of the aforementioned filter string. These types
* include the {@link Number} wrapper types, {@link Date} and {@link Enum}s. (This is
* because the filtering system works naturally with these types.) See {@link GColumnRenderer}.
* <P>
* Note: some types should not make use of the aforementioned filter string. These types include
* the {@link Number} wrapper types, {@link Date} and {@link Enum}s. (This is because the
* filtering system works naturally with these types.) See {@link GColumnRenderer}.
*
* @return the renderer
*/
@ -93,13 +99,15 @@ public interface DynamicTableColumn<ROW_TYPE, COLUMN_TYPE, DATA_SOURCE> {
/**
* Returns a list of settings definitions for this field.
*
* @return list of settings definitions for this field.
*/
public SettingsDefinition[] getSettingsDefinitions();
/**
* Gets the maximum number of text display lines needed for any given cell with the
* specified settings.
* Gets the maximum number of text display lines needed for any given cell with the specified
* settings.
*
* @param settings field settings
* @return maximum number of lines needed
*/
@ -107,28 +115,33 @@ public interface DynamicTableColumn<ROW_TYPE, COLUMN_TYPE, DATA_SOURCE> {
/**
* Determines the column heading that will be displayed.
*
* @param settings the settings
* @return the field name to display as the column heading.
*/
public String getColumnDisplayName(Settings settings);
/**
* Returns a description of this column. This may be used as a tooltip for the column header
* @return a description of this column. This may be used as a tooltip for the column header.
* Returns a description of this column. This may be used as a tooltip for the column header
*
* @return a description of this column. This may be used as a tooltip for the column header.
*/
public String getColumnDescription();
/**
* Returns a value that is unique for this table column. This is different than getting
* the display name, which may be shared by different columns.
* Returns a value that is unique for this table column. This is different than getting the
* display name, which may be shared by different columns.
*
* @return the identifier
*/
public String getUniqueIdentifier();
/**
* If implemented, will return a comparator that knows how to sort values for this column.
* If implemented, will return a comparator that knows how to sort values for this column.
* Implementors should return <code>null</code> if they do not wish to provider a comparator
*
* @return the comparator
*/
public Comparator<COLUMN_TYPE> getComparator();
public Comparator<COLUMN_TYPE> getComparator(DynamicColumnTableModel<?> model,
int columnIndex);
}

View file

@ -31,31 +31,29 @@ import util.CollectionUtils;
import utilities.util.reflection.ReflectionUtilities;
/**
* An abstract table model for showing DynamicTableColumns where each row is based on an
* object of type ROW_TYPE. The client is responsible for implementing
* {@link #createTableColumnDescriptor()}. This method specifies which default columns the
* table should have and whether they should be visible or hidden. Hidden columns can be
* made visible through the UI.
* An abstract table model for showing DynamicTableColumns where each row is based on an object of
* type ROW_TYPE. The client is responsible for implementing {@link #createTableColumnDescriptor()}.
* This method specifies which default columns the table should have and whether they should be
* visible or hidden. Hidden columns can be made visible through the UI.
* <p>
* This model will also discover other system columns that understand how to render
* <code>ROW_TYPE</code> data directly. Also, if you create a {@link TableRowMapper mapper}(s) for
* <code>ROW_TYPE</code> data directly. Also, if you create a {@link TableRowMapper mapper}(s) for
* your row type, then this model will load columns for each type for which a mapper was created,
* all as optional, hidden columns.
* <p>
* The various attributes of the columns of this model (visibility, position, size, etc) are
* saved to disk as tool preferences when the user exits the tool.
* The various attributes of the columns of this model (visibility, position, size, etc) are saved
* to disk as tool preferences when the user exits the tool.
* <p>
* Implementation Note: this model loads all columns, specific and discovered, as being visible.
* Then, during initialization, the {@link TableColumnModelState} class will
* either hide all non-default columns, or reload the column state if any
* previous saved state is found.
* Then, during initialization, the {@link TableColumnModelState} class will either hide all
* non-default columns, or reload the column state if any previous saved state is found.
*
* @param <ROW_TYPE> the row object class for this table model.
* @param <DATA_SOURCE> the type of data that will be returned from {@link #getDataSource()}. This
* object will be given to the {@link DynamicTableColumn} objects used by this
* table model when
* {@link DynamicTableColumn#getValue(Object, ghidra.docking.settings.Settings, Object, ServiceProvider)}
* is called.
* @param <DATA_SOURCE> the type of data that will be returned from {@link #getDataSource()}. This
* object will be given to the {@link DynamicTableColumn} objects used by this table
* model when
* {@link DynamicTableColumn#getValue(Object, ghidra.docking.settings.Settings, Object, ServiceProvider)}
* is called.
*/
public abstract class GDynamicColumnTableModel<ROW_TYPE, DATA_SOURCE>
extends AbstractSortedTableModel<ROW_TYPE>
@ -122,10 +120,10 @@ public abstract class GDynamicColumnTableModel<ROW_TYPE, DATA_SOURCE>
}
/**
* Allows clients to defer column creation until after this parent class's constructor has
* been called. This method will not restore any column settings that have been changed
* after construction. Thus, this method is intended only to be called during the
* construction process.
* Allows clients to defer column creation until after this parent class's constructor has been
* called. This method will not restore any column settings that have been changed after
* construction. Thus, this method is intended only to be called during the construction
* process.
*/
protected void reloadColumns() {
@ -201,9 +199,8 @@ public abstract class GDynamicColumnTableModel<ROW_TYPE, DATA_SOURCE>
}
/**
* This differs from {@link #createSortComparator(int)} in that the other method
* creates a comparator that operates on a full row value, whereas this method operates on
* column values.
* This differs from {@link #createSortComparator(int)} in that the other method creates a
* comparator that operates on a full row value, whereas this method operates on column values.
*
* @param columnIndex the column index
* @return a comparator for the specific column values
@ -211,7 +208,8 @@ public abstract class GDynamicColumnTableModel<ROW_TYPE, DATA_SOURCE>
@SuppressWarnings("unchecked") // the column provides the values itself; safe cast
protected Comparator<Object> createSortComparatorForColumn(int columnIndex) {
DynamicTableColumn<ROW_TYPE, ?, ?> column = getColumn(columnIndex);
Comparator<Object> comparator = (Comparator<Object>) column.getComparator();
Comparator<Object> comparator =
(Comparator<Object>) column.getComparator(this, columnIndex);
return comparator;
}
@ -252,11 +250,13 @@ public abstract class GDynamicColumnTableModel<ROW_TYPE, DATA_SOURCE>
}
/**
* Adds the given column at the end of the list of columns. This method is intended for
* Adds the given column at the end of the list of columns. This method is intended for
* implementations to add custom column objects, rather than relying on generic, discovered
* DynamicTableColumn implementations.
*
* <p><b>Note: this method assumes that the columns have already been sorted</b>
* <p>
* <b>Note: this method assumes that the columns have already been sorted</b>
*
* @param column The field to add
*/
protected void addTableColumn(DynamicTableColumn<ROW_TYPE, ?, ?> column) {
@ -264,11 +264,12 @@ public abstract class GDynamicColumnTableModel<ROW_TYPE, DATA_SOURCE>
}
/**
* Adds the given columns to the end of the list of columns. This method is intended for
* Adds the given columns to the end of the list of columns. This method is intended for
* implementations to add custom column objects, rather than relying on generic, discovered
* DynamicTableColumn implementations.
*
* <p><b>Note: this method assumes that the columns have already been sorted.</b>
* <p>
* <b>Note: this method assumes that the columns have already been sorted.</b>
*
* @param columns The columns to add
*/
@ -280,15 +281,16 @@ public abstract class GDynamicColumnTableModel<ROW_TYPE, DATA_SOURCE>
}
/**
* Adds the given field at the given index to the list of fields in this class.
* This method is intended for implementations to add custom column objects, rather than
* relying on generic, discovered DynamicTableColumn implementations.
* Adds the given field at the given index to the list of fields in this class. This method is
* intended for implementations to add custom column objects, rather than relying on generic,
* discovered DynamicTableColumn implementations.
* <p>
* <b>Note: this method assumes that the columns have already been sorted.</b>
*
* @param column The field to add.
* @param index The index at which to add the field. If the index value is invalid (negative
* or greater than the number of columns), then the column will be added to the
* end of the columns list.
* @param index The index at which to add the field. If the index value is invalid (negative or
* greater than the number of columns), then the column will be added to the end of
* the columns list.
* @param isDefault true if this is a default column
*/
protected void addTableColumn(DynamicTableColumn<ROW_TYPE, ?, ?> column, int index,
@ -324,8 +326,8 @@ public abstract class GDynamicColumnTableModel<ROW_TYPE, DATA_SOURCE>
}
/**
* Removes the given columns from this model. This method allows the client to remove
* multiple columns at once, firing only one event when the work is finished.
* Removes the given columns from this model. This method allows the client to remove multiple
* columns at once, firing only one event when the work is finished.
*
* @param columns the columns to remove
*/
@ -363,6 +365,7 @@ public abstract class GDynamicColumnTableModel<ROW_TYPE, DATA_SOURCE>
/**
* Returns true if the column indicated by the index in the model is a default column (meaning
* that it was specified by the model and not discovered).
*
* @param modelIndex the index of the column in the model.
* @return true if the column is a default.
*/
@ -460,7 +463,8 @@ public abstract class GDynamicColumnTableModel<ROW_TYPE, DATA_SOURCE>
/**
* Returns the table's context for the data.
* @return the table's context for the data.
*
* @return the table's context for the data.
*/
public abstract DATA_SOURCE getDataSource();
@ -524,12 +528,12 @@ public abstract class GDynamicColumnTableModel<ROW_TYPE, DATA_SOURCE>
}
/**
* Gets the special table cell renderer for the specified table field column.
* A null value indicates that this field uses a default cell renderer.
* Gets the special table cell renderer for the specified table field column. A null value
* indicates that this field uses a default cell renderer.
*
* @param index the model column index
* @return a table cell renderer for this field. Otherwise, null if a default
* renderer should be used.
* @return a table cell renderer for this field. Otherwise, null if a default renderer should be
* used.
*/
@Override
public TableCellRenderer getRenderer(int index) {
@ -537,8 +541,9 @@ public abstract class GDynamicColumnTableModel<ROW_TYPE, DATA_SOURCE>
}
/**
* Gets the maximum number of text display lines needed for any given cell within the
* specified column.
* Gets the maximum number of text display lines needed for any given cell within the specified
* column.
*
* @param index column field index
* @return maximum number of lines needed for specified column
*/

View file

@ -23,15 +23,15 @@ import ghidra.framework.plugintool.ServiceProvider;
import ghidra.util.table.column.GColumnRenderer;
/**
* A class that is an Adapter in order to allow for the use of existing
* {@link DynamicTableColumn}s when the actual row type of the table is
* not the same as the row type that the {@link DynamicTableColumn} supports.
* A class that is an Adapter in order to allow for the use of existing {@link DynamicTableColumn}s
* when the actual row type of the table is not the same as the row type that the
* {@link DynamicTableColumn} supports.
*
* @param <ROW_TYPE> The table's actual row type
* @param <EXPECTED_ROW_TYPE> The row type expected by the given {@link DynamicTableColumn}
* @param <COLUMN_TYPE> The column type provided by the given {@link DynamicTableColumn}
* @param <DATA_SOURCE> the type of the data for each column; can be Object for columns that
* do not have a data source
* @param <DATA_SOURCE> the type of the data for each column; can be Object for columns that do not
* have a data source
*/
public class MappedTableColumn<ROW_TYPE, EXPECTED_ROW_TYPE, COLUMN_TYPE, DATA_SOURCE>
extends AbstractDynamicTableColumn<ROW_TYPE, COLUMN_TYPE, DATA_SOURCE> {
@ -110,8 +110,9 @@ public class MappedTableColumn<ROW_TYPE, EXPECTED_ROW_TYPE, COLUMN_TYPE, DATA_SO
}
@Override
public Comparator<COLUMN_TYPE> getComparator() {
return tableColumn.getComparator();
public Comparator<COLUMN_TYPE> getComparator(DynamicColumnTableModel<?> model,
int columnIndex) {
return tableColumn.getComparator(model, columnIndex);
}
@Override