Search in sources :

Example 1 with UpdateColumnsTask

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));
}
Also used : ReadableGraph(au.gov.asd.tac.constellation.graph.ReadableGraph) Platform(javafx.application.Platform) Attribute(au.gov.asd.tac.constellation.graph.Attribute) GraphAttribute(au.gov.asd.tac.constellation.graph.GraphAttribute) UpdateColumnsTask(au.gov.asd.tac.constellation.views.tableview.tasks.UpdateColumnsTask) TableColumn(javafx.scene.control.TableColumn) ListChangeListener(javafx.collections.ListChangeListener) Callback(javafx.util.Callback) ObservableList(javafx.collections.ObservableList) Column(au.gov.asd.tac.constellation.views.tableview.api.Column) TableColumn(javafx.scene.control.TableColumn) TableViewState(au.gov.asd.tac.constellation.views.tableview.state.TableViewState) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) Test(org.testng.annotations.Test)

Example 2 with UpdateColumnsTask

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));
}
Also used : ReadableGraph(au.gov.asd.tac.constellation.graph.ReadableGraph) Platform(javafx.application.Platform) Attribute(au.gov.asd.tac.constellation.graph.Attribute) GraphAttribute(au.gov.asd.tac.constellation.graph.GraphAttribute) UpdateColumnsTask(au.gov.asd.tac.constellation.views.tableview.tasks.UpdateColumnsTask) TableColumn(javafx.scene.control.TableColumn) ListChangeListener(javafx.collections.ListChangeListener) Callback(javafx.util.Callback) ObservableList(javafx.collections.ObservableList) Column(au.gov.asd.tac.constellation.views.tableview.api.Column) TableColumn(javafx.scene.control.TableColumn) TableViewState(au.gov.asd.tac.constellation.views.tableview.state.TableViewState) ThreeTuple(au.gov.asd.tac.constellation.utilities.datastructure.ThreeTuple) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) Test(org.testng.annotations.Test)

Example 3 with UpdateColumnsTask

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);
            }
        }
    }
}
Also used : TableCellFactory(au.gov.asd.tac.constellation.views.tableview.factory.TableCellFactory) IntStream(java.util.stream.IntStream) ReadOnlyObjectProperty(javafx.beans.property.ReadOnlyObjectProperty) ReadableGraph(au.gov.asd.tac.constellation.graph.ReadableGraph) SimpleStringProperty(javafx.beans.property.SimpleStringProperty) FXCollections(javafx.collections.FXCollections) ColumnIndexSort(au.gov.asd.tac.constellation.views.tableview.utilities.ColumnIndexSort) ActiveTableReference(au.gov.asd.tac.constellation.views.tableview.api.ActiveTableReference) VisualConcept(au.gov.asd.tac.constellation.graph.schema.visual.concept.VisualConcept) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) TableColumn(javafx.scene.control.TableColumn) Graph(au.gov.asd.tac.constellation.graph.Graph) SwingUtilities(javax.swing.SwingUtilities) Column(au.gov.asd.tac.constellation.views.tableview.api.Column) Insets(javafx.geometry.Insets) TableViewState(au.gov.asd.tac.constellation.views.tableview.state.TableViewState) ListChangeListener(javafx.collections.ListChangeListener) Pair(org.apache.commons.lang3.tuple.Pair) UpdateDataTask(au.gov.asd.tac.constellation.views.tableview.tasks.UpdateDataTask) AbstractAttributeInteraction(au.gov.asd.tac.constellation.graph.attribute.interaction.AbstractAttributeInteraction) Map(java.util.Map) TableView(javafx.scene.control.TableView) GraphAttribute(au.gov.asd.tac.constellation.graph.GraphAttribute) TablePane(au.gov.asd.tac.constellation.views.tableview.panes.TablePane) MenuItem(javafx.scene.control.MenuItem) GraphElementType(au.gov.asd.tac.constellation.graph.GraphElementType) SelectedOnlySelectionListener(au.gov.asd.tac.constellation.views.tableview.listeners.SelectedOnlySelectionListener) GraphRecordStoreUtilities(au.gov.asd.tac.constellation.graph.processing.GraphRecordStoreUtilities) Logger(java.util.logging.Logger) ImmutableObjectCache(au.gov.asd.tac.constellation.utilities.datastructure.ImmutableObjectCache) Collectors(java.util.stream.Collectors) Platform(javafx.application.Platform) List(java.util.List) SelectionMode(javafx.scene.control.SelectionMode) UpdateColumnsTask(au.gov.asd.tac.constellation.views.tableview.tasks.UpdateColumnsTask) TableSelectionListener(au.gov.asd.tac.constellation.views.tableview.listeners.TableSelectionListener) TABLE_LOCK(au.gov.asd.tac.constellation.views.tableview.TableViewTopComponent.TABLE_LOCK) TableViewUtilities(au.gov.asd.tac.constellation.views.tableview.utilities.TableViewUtilities) ObservableList(javafx.collections.ObservableList) ChangeListener(javafx.beans.value.ChangeListener) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) TableCellFactory(au.gov.asd.tac.constellation.views.tableview.factory.TableCellFactory) ReadableGraph(au.gov.asd.tac.constellation.graph.ReadableGraph) ObservableList(javafx.collections.ObservableList) ColumnIndexSort(au.gov.asd.tac.constellation.views.tableview.utilities.ColumnIndexSort) SimpleStringProperty(javafx.beans.property.SimpleStringProperty) TableColumn(javafx.scene.control.TableColumn)

Aggregations

GraphAttribute (au.gov.asd.tac.constellation.graph.GraphAttribute)3 ReadableGraph (au.gov.asd.tac.constellation.graph.ReadableGraph)3 Column (au.gov.asd.tac.constellation.views.tableview.api.Column)3 TableViewState (au.gov.asd.tac.constellation.views.tableview.state.TableViewState)3 UpdateColumnsTask (au.gov.asd.tac.constellation.views.tableview.tasks.UpdateColumnsTask)3 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)3 Platform (javafx.application.Platform)3 ListChangeListener (javafx.collections.ListChangeListener)3 ObservableList (javafx.collections.ObservableList)3 TableColumn (javafx.scene.control.TableColumn)3 Attribute (au.gov.asd.tac.constellation.graph.Attribute)2 Graph (au.gov.asd.tac.constellation.graph.Graph)1 GraphElementType (au.gov.asd.tac.constellation.graph.GraphElementType)1 AbstractAttributeInteraction (au.gov.asd.tac.constellation.graph.attribute.interaction.AbstractAttributeInteraction)1 GraphRecordStoreUtilities (au.gov.asd.tac.constellation.graph.processing.GraphRecordStoreUtilities)1 VisualConcept (au.gov.asd.tac.constellation.graph.schema.visual.concept.VisualConcept)1 ImmutableObjectCache (au.gov.asd.tac.constellation.utilities.datastructure.ImmutableObjectCache)1 ThreeTuple (au.gov.asd.tac.constellation.utilities.datastructure.ThreeTuple)1 TABLE_LOCK (au.gov.asd.tac.constellation.views.tableview.TableViewTopComponent.TABLE_LOCK)1 ActiveTableReference (au.gov.asd.tac.constellation.views.tableview.api.ActiveTableReference)1