use of au.gov.asd.tac.constellation.views.tableview.tasks.UpdateColumnsTask in project constellation by constellation-app.
the class TableNGTest method updateColumns.
@Test
public void updateColumns() {
final ChangeListener<ObservableList<String>> tableSelectionListener = mock(ChangeListener.class);
final ListChangeListener selectedOnlySelectionListener = mock(ListChangeListener.class);
doReturn(tableSelectionListener).when(table).getTableSelectionListener();
doReturn(selectedOnlySelectionListener).when(table).getSelectedOnlySelectionListener();
final ReadableGraph readableGraph = mock(ReadableGraph.class);
when(graph.getReadableGraph()).thenReturn(readableGraph);
// Set up the initial column index. Column 4 will not be found in the graph and
// dropped in the column index created by the update call
final String columnType1 = "source.";
final Attribute attribute1 = mock(Attribute.class);
final TableColumn<ObservableList<String>, String> column1 = mock(TableColumn.class);
when(column1.getText()).thenReturn("source.COLUMN_A");
final String columnType2 = "destination.";
final Attribute attribute2 = mock(Attribute.class);
final TableColumn<ObservableList<String>, String> column2 = mock(TableColumn.class);
when(column2.getText()).thenReturn("destination.COLUMN_A");
final String columnType3 = "transaction.";
final Attribute attribute3 = mock(Attribute.class);
final TableColumn<ObservableList<String>, String> column3 = mock(TableColumn.class);
when(column3.getText()).thenReturn("transaction.COLUMN_B");
final String columnType4 = "source.";
final Attribute attribute4 = mock(Attribute.class);
final TableColumn<ObservableList<String>, String> column4 = mock(TableColumn.class);
when(column4.getText()).thenReturn("source.COLUMN_C");
final CopyOnWriteArrayList<Column> columnIndex = new CopyOnWriteArrayList<>();
columnIndex.add(new Column(columnType1, attribute1, column1));
columnIndex.add(new Column(columnType2, attribute2, column2));
columnIndex.add(new Column(columnType3, attribute3, column3));
columnIndex.add(new Column(columnType4, attribute4, column4));
when(activeTableReference.getColumnIndex()).thenReturn(columnIndex);
// This is a reference of the old column index that will be used whilst the new
// index is being created. Because that creation is mocked this is used only as a
// vertification that the parameter is being correctly constructed.
final Map<String, TableColumn<ObservableList<String>, String>> columnReferenceMap = Map.of("source.COLUMN_A", column1, "destination.COLUMN_A", column2, "transaction.COLUMN_B", column3, "source.COLUMN_C", column4);
// Mock out the re-population of the column index from the graph. This excludes column 4.
final CopyOnWriteArrayList<Column> sourceColumnIndex = new CopyOnWriteArrayList<>();
sourceColumnIndex.add(new Column(columnType1, attribute1, column1));
final CopyOnWriteArrayList<Column> destinationColumnIndex = new CopyOnWriteArrayList<>();
destinationColumnIndex.add(new Column(columnType2, attribute2, column2));
final CopyOnWriteArrayList<Column> transactionColumnIndex = new CopyOnWriteArrayList<>();
transactionColumnIndex.add(new Column(columnType3, attribute3, column3));
doReturn(sourceColumnIndex).when(table).createColumnIndexPart(readableGraph, GraphElementType.VERTEX, "source.", columnReferenceMap);
doReturn(destinationColumnIndex).when(table).createColumnIndexPart(readableGraph, GraphElementType.VERTEX, "destination.", columnReferenceMap);
doReturn(transactionColumnIndex).when(table).createColumnIndexPart(readableGraph, GraphElementType.TRANSACTION, "transaction.", columnReferenceMap);
// Set up the table state
final TableViewState tableViewState = new TableViewState();
tableViewState.setElementType(GraphElementType.TRANSACTION);
// This is used by the sort comparator. This will order the columnIndex
// in a certain way that we can then verify below
tableViewState.setColumnAttributes(List.of(Tuple.create("source.", attribute1), Tuple.create("transaction.", attribute3), Tuple.create("destination.", attribute2)));
try (final MockedStatic<Platform> platformMockedStatic = Mockito.mockStatic(Platform.class)) {
platformMockedStatic.when(Platform::isFxApplicationThread).thenReturn(false);
platformMockedStatic.when(() -> Platform.runLater(any(Runnable.class))).then(mockInvocation -> {
assertTrue(mockInvocation.getArgument(0) instanceof UpdateColumnsTask);
return null;
});
table.updateColumns(graph, tableViewState);
}
// Verify the new column index
final CopyOnWriteArrayList<Column> expectedColumnIndex = new CopyOnWriteArrayList<>();
expectedColumnIndex.add(new Column(columnType1, attribute1, column1));
expectedColumnIndex.add(new Column(columnType3, attribute3, column3));
expectedColumnIndex.add(new Column(columnType2, attribute2, column2));
assertEquals(expectedColumnIndex, columnIndex);
verify(column1, times(1)).setCellValueFactory(any(Callback.class));
verify(column2, times(1)).setCellValueFactory(any(Callback.class));
verify(column3, times(1)).setCellValueFactory(any(Callback.class));
verify(column1, times(1)).setCellFactory(any(Callback.class));
verify(column2, times(1)).setCellFactory(any(Callback.class));
verify(column3, times(1)).setCellFactory(any(Callback.class));
}
use of au.gov.asd.tac.constellation.views.tableview.tasks.UpdateColumnsTask in project constellation by constellation-app.
the class TableNGTest method updateColumnsStateColumnsNotSet.
@Test
public void updateColumnsStateColumnsNotSet() {
final ChangeListener<ObservableList<String>> tableSelectionListener = mock(ChangeListener.class);
final ListChangeListener selectedOnlySelectionListener = mock(ListChangeListener.class);
doReturn(tableSelectionListener).when(table).getTableSelectionListener();
doReturn(selectedOnlySelectionListener).when(table).getSelectedOnlySelectionListener();
final ReadableGraph readableGraph = mock(ReadableGraph.class);
when(graph.getReadableGraph()).thenReturn(readableGraph);
// Set up the initial column index.
final String columnType1 = "source.";
final Attribute attribute1 = mock(Attribute.class);
final TableColumn<ObservableList<String>, String> column1 = mock(TableColumn.class);
when(column1.getText()).thenReturn("source.COLUMN_A");
final CopyOnWriteArrayList<Column> columnIndex = new CopyOnWriteArrayList<>();
columnIndex.add(new Column(columnType1, attribute1, column1));
when(activeTableReference.getColumnIndex()).thenReturn(columnIndex);
// This is a reference of the old column index that will be used whilst the new
// index is being created. Because that creation is mocked this is used only as a
// vertification that the parameter is being correctly constructed.
final Map<String, TableColumn<ObservableList<String>, String>> columnReferenceMap = Map.of("source.COLUMN_A", column1);
// Mock out the re-population of the column index from the graph
final CopyOnWriteArrayList<ThreeTuple<String, Attribute, TableColumn<ObservableList<String>, String>>> sourceColumnIndex = new CopyOnWriteArrayList<>();
sourceColumnIndex.add(ThreeTuple.create(columnType1, attribute1, column1));
doReturn(sourceColumnIndex).when(table).createColumnIndexPart(readableGraph, GraphElementType.VERTEX, "source.", columnReferenceMap);
// Set up the table state
final TableViewState tableViewState = new TableViewState();
tableViewState.setElementType(GraphElementType.VERTEX);
// When this is null, the update is interrupted and the user is asked to select
// which columns they want visible
tableViewState.setColumnAttributes(null);
// Don't want it trying to open the menu to select which columns to show
doNothing().when(table).openColumnVisibilityMenu();
try (final MockedStatic<Platform> platformMockedStatic = Mockito.mockStatic(Platform.class)) {
platformMockedStatic.when(Platform::isFxApplicationThread).thenReturn(false);
platformMockedStatic.when(() -> Platform.runLater(any(Runnable.class))).then(mockInvocation -> {
assertTrue(mockInvocation.getArgument(0) instanceof UpdateColumnsTask);
return null;
});
table.updateColumns(graph, tableViewState);
}
// Verify the new column index
final CopyOnWriteArrayList<ThreeTuple<String, Attribute, TableColumn<ObservableList<String>, String>>> expectedColumnIndex = new CopyOnWriteArrayList<>();
expectedColumnIndex.add(ThreeTuple.create(columnType1, attribute1, column1));
assertEquals(expectedColumnIndex, columnIndex);
// Because the state element type is set to vertex, only the source columns are populated
verify(table, times(0)).createColumnIndexPart(readableGraph, GraphElementType.VERTEX, "destination.", columnReferenceMap);
verify(table, times(0)).createColumnIndexPart(readableGraph, GraphElementType.TRANSACTION, "transaction.", columnReferenceMap);
// Verify the menu open method was called
verify(table).openColumnVisibilityMenu();
// Verify that the new column index did not have its factories set
verify(column1, times(0)).setCellValueFactory(any(Callback.class));
verify(column1, times(0)).setCellFactory(any(Callback.class));
}
use of au.gov.asd.tac.constellation.views.tableview.tasks.UpdateColumnsTask in project constellation by constellation-app.
the class Table method updateColumns.
/**
* Update the columns in the table using the graph and state. This will
* clear and refresh the column index and then trigger a refresh of the
* table view, populating from the new column index.
* <p/>
* If the table's state has an element type of VERTEX then all the columns
* will be prefixed with ".source".
* <p/>
* If the element type is TRANSACTION then the attributes belonging to
* transactions will be prefixed with ".transaction". The vertex attributes
* will also be added as columns in this case. When the state's element type
* is TRANSACTION the vertex attributes will be prefixed with both ".source"
* and ".destination" so that it is distinguishable on which end of the
* transaction those values are present.
* <p/>
* Note that column references are reused where possible to ensure certain
* toolbar/menu operations to work correctly.
* <p/>
* The entire method is synchronized so it should be thread safe and keeps
* the locking logic simpler. Maybe this method could be broken out further.
*
* @param graph the graph to retrieve data from.
* @param state the current table view state.
*/
public void updateColumns(final Graph graph, final TableViewState state) {
synchronized (TABLE_LOCK) {
if (graph != null && state != null) {
if (Platform.isFxApplicationThread()) {
throw new IllegalStateException(ATTEMPT_PROCESS_JAVAFX);
}
if (SwingUtilities.isEventDispatchThread()) {
throw new IllegalStateException(ATTEMPT_PROCESS_EDT);
}
// Clear current columnIndex, but cache the column objects for reuse
final Map<String, TableColumn<ObservableList<String>, String>> columnReferenceMap = getColumnIndex().stream().collect(Collectors.toMap(column -> column.getTableColumn().getText(), column -> column.getTableColumn(), (e1, e2) -> e1));
getColumnIndex().clear();
// Update columnIndex based on graph attributes
final ReadableGraph readableGraph = graph.getReadableGraph();
try {
// Creates "source." columns from vertex attributes
getColumnIndex().addAll(createColumnIndexPart(readableGraph, GraphElementType.VERTEX, GraphRecordStoreUtilities.SOURCE, columnReferenceMap));
if (state.getElementType() == GraphElementType.TRANSACTION) {
// Creates "transaction." columns from transaction attributes
getColumnIndex().addAll(createColumnIndexPart(readableGraph, GraphElementType.TRANSACTION, GraphRecordStoreUtilities.TRANSACTION, columnReferenceMap));
// Creates "destination." columns from vertex attributes
getColumnIndex().addAll(createColumnIndexPart(readableGraph, GraphElementType.VERTEX, GraphRecordStoreUtilities.DESTINATION, columnReferenceMap));
}
} finally {
readableGraph.release();
}
// If there are no visible columns specified, write the key columns to the state
if (state.getColumnAttributes() == null) {
openColumnVisibilityMenu();
return;
}
// Sort columns in columnIndex by state, prefix and attribute name
getColumnIndex().sort(new ColumnIndexSort(state));
// Style and format columns in columnIndex
getColumnIndex().forEach(columnTuple -> {
final TableColumn<ObservableList<String>, String> column = columnTuple.getTableColumn();
// assign cells to columns
column.setCellValueFactory(cellData -> {
final int cellIndex = tableView.getColumns().indexOf(cellData.getTableColumn());
if (cellIndex < cellData.getValue().size()) {
return new SimpleStringProperty(cellData.getValue().get(cellIndex));
} else {
return null;
}
});
// Assign values and styles to cells
column.setCellFactory(cellColumn -> new TableCellFactory(cellColumn, this));
});
// calculated column changes
if (!Thread.currentThread().isInterrupted()) {
// The update columns task holds state between executions. So we need to
// reset some fields each time before it is run.
updateColumnsTask.reset(columnReferenceMap, state);
Platform.runLater(updateColumnsTask);
}
}
}
}
Aggregations