From 8fb357705f1a8bcd4a1d3851adc15aae92db3c48 Mon Sep 17 00:00:00 2001 From: stroomdev66 Date: Fri, 11 Oct 2024 17:32:07 +0100 Subject: [PATCH] #4523 Embed queries in dashboards --- .../resources/ui/css/celltable/DataGrid.css | 23 ++- .../src/main/resources/ui/css/components.css | 28 ++++ .../resources/ui/css/stroom-dashboard.css | 16 -- .../resources/ui/noauth/swagger/stroom.json | 31 ++++ .../resources/ui/noauth/swagger/stroom.yaml | 20 +++ .../user/cellview/client/AbstractHasData.java | 26 ++- .../embeddedquery/EmbeddedQueryPresenter.java | 66 +++++++- .../EmbeddedQuerySettingsPresenter.java | 53 ++++-- .../client/query/QueryPresenter.java | 69 ++------ .../client/query/QuerySettingsPresenter.java | 3 +- .../SelectionHandlerExpressionBuilder.java | 50 ++++++ .../query/SelectionHandlerPresenter.java | 5 +- .../query/SelectionHandlersPresenter.java | 33 ++-- .../dashboard/client/table/DynamicStyles.java | 49 ++++++ .../client/table/TablePresenter.java | 21 +-- .../client/table/TableRowStyles.java | 30 ++++ .../DynamicFieldSelectionListModel.java | 19 ++- .../client/presenter/QueryEditPresenter.java | 3 +- .../query/client/presenter/QueryModel.java | 5 +- .../presenter/QueryResultTablePresenter.java | 23 +-- .../query/client/presenter/TableRow.java | 16 +- .../presenter/DataRetentionRulePresenter.java | 5 +- .../ElasticIndexSettingsPresenter.java | 2 +- .../presenter/SolrIndexSettingsPresenter.java | 2 +- .../AbstractQueryComponentSettings.java | 152 ++++++++++++++++++ .../dashboard/shared/ComponentSettings.java | 7 +- .../EmbeddedQueryComponentSettings.java | 101 ++---------- .../KeyValueInputComponentSettings.java | 8 +- .../shared/ListInputComponentSettings.java | 18 ++- .../shared/QueryComponentSettings.java | 98 ++--------- .../shared/TableComponentSettings.java | 32 ++-- .../shared/TextComponentSettings.java | 30 ++-- .../shared/TextInputComponentSettings.java | 10 +- .../shared/VisComponentSettings.java | 14 +- .../stroom/query/shared/QueryContext.java | 28 +++- .../stroom/query/shared/QueryResource.java | 8 + .../stroom/query/api/v2/ExpressionUtil.java | 15 ++ .../stroom/query/impl/QueryResourceImpl.java | 12 ++ .../stroom/query/impl/QueryServiceImpl.java | 16 ++ .../datasource/DataSourceResourceImpl.java | 11 +- 40 files changed, 787 insertions(+), 371 deletions(-) create mode 100644 stroom-core-client/src/main/java/stroom/dashboard/client/query/SelectionHandlerExpressionBuilder.java create mode 100644 stroom-core-client/src/main/java/stroom/dashboard/client/table/DynamicStyles.java create mode 100644 stroom-core-client/src/main/java/stroom/dashboard/client/table/TableRowStyles.java create mode 100644 stroom-core-shared/src/main/java/stroom/dashboard/shared/AbstractQueryComponentSettings.java diff --git a/stroom-app/src/main/resources/ui/css/celltable/DataGrid.css b/stroom-app/src/main/resources/ui/css/celltable/DataGrid.css index e2dbef0e41c..c3519bedf4c 100644 --- a/stroom-app/src/main/resources/ui/css/celltable/DataGrid.css +++ b/stroom-app/src/main/resources/ui/css/celltable/DataGrid.css @@ -182,7 +182,6 @@ } .dataGridKeyboardSelectedRowCell { - } /* @@ -213,7 +212,9 @@ don't want the open link to appear opacity: 0.3; } -.dataGridSelectedRow { +.dataGridSelectedRow, +table .dataGridEvenRow.dataGridSelectedRow, +table .dataGridOddRow.dataGridSelectedRow { background-color: var(--row__background-color--selected); color: var(--row__text-color--selected); } @@ -227,13 +228,27 @@ don't want the open link to appear background-color: var(--row__background-color--selected--hovered); } + +/* +.dataGridOddRow:hover .dataGridCell, +.dataGridEvenRow:hover .dataGridCell { + background-color: rgba(255,255,255,0.1); +} + +.dataGridSelectedRow:hover .dataGridCell { + background-color: rgba(255,255,255,0.1); +} +*/ + .dataGridOddRow:focus-within, .dataGridEvenRow:focus-within { - background-color: var(--row__background-color--focussed); + /*background-color: var(--row__background-color--focussed);*/ + box-shadow: inset 0 0 2px var(--text-color); } .dataGridSelectedRow:focus-within { - background-color: var(--row__background-color--selected--focussed); + /*background-color: var(--row__background-color--selected--focussed);*/ + box-shadow: inset 0 0 2px var(--row__text-color--selected); } .dataGridSelectedRowCell { diff --git a/stroom-app/src/main/resources/ui/css/components.css b/stroom-app/src/main/resources/ui/css/components.css index 621305986d5..a9d790fc703 100644 --- a/stroom-app/src/main/resources/ui/css/components.css +++ b/stroom-app/src/main/resources/ui/css/components.css @@ -1516,6 +1516,7 @@ background-color: var(--navigation__background-color--selected-hovered); } +/* .navigation .cellTableOddRow:focus-within, .navigation .cellTableEvenRow:focus-within { background-color: var(--navigation__background-color--focussed); @@ -1524,6 +1525,20 @@ .navigation .cellTableSelectedRow:focus-within { background-color: var(--navigation__background-color--selected--focussed); } +*/ + +.navigation .cellTableOddRow:focus-within, +.navigation .cellTableEvenRow:focus-within { + /*background-color: var(--row__background-color--focussed);*/ + box-shadow: inset 0 0 2px var(--text-color); +} + +.navigation .cellTableSelectedRow:focus-within { + /*background-color: var(--row__background-color--selected--focussed);*/ + box-shadow: inset 0 0 2px var(--row__text-color--selected); +} + + .navigation-title-bar { display: flex; @@ -2152,6 +2167,7 @@ button.main-menu svg { background-color: var(--row__background-color--selected--hovered); } +/* .selectionList .cellTableOddRow:focus-within, .selectionList .cellTableEvenRow:focus-within { background-color: var(--row__background-color--focussed); @@ -2160,6 +2176,18 @@ button.main-menu svg { .selectionList .cellTableSelectedRow:focus-within { background-color: var(--row__background-color--selected--focussed); } +*/ + +.selectionList .cellTableOddRow:focus-within, +.selectionList .cellTableEvenRow:focus-within { + /*background-color: var(--row__background-color--focussed);*/ + box-shadow: inset 0 0 2px var(--text-color); +} + +.selectionList .cellTableSelectedRow:focus-within { + /*background-color: var(--row__background-color--selected--focussed);*/ + box-shadow: inset 0 0 2px var(--row__text-color--selected); +} .selectionList-links { display: flex; diff --git a/stroom-app/src/main/resources/ui/css/stroom-dashboard.css b/stroom-app/src/main/resources/ui/css/stroom-dashboard.css index c48e0cfacbd..a6322dff12f 100644 --- a/stroom-app/src/main/resources/ui/css/stroom-dashboard.css +++ b/stroom-app/src/main/resources/ui/css/stroom-dashboard.css @@ -82,22 +82,6 @@ text-overflow: ellipsis; } -/* Ensure row selection trumps conditional formatting */ -.stroom-dashboard-table .dataGridSelectedRow .cell { - background-color: var(--row__background-color--selected) !important; - color: var(--row__text-color--selected) !important; -} -.stroom-dashboard-table .dataGridSelectedRow:hover .cell { - background-color: var(--row__background-color--selected--hovered) !important; -} -.stroom-dashboard-table .dataGridOddRow:focus-within .cell, -.stroom-dashboard-table .dataGridEvenRow:focus-within .cell { - background-color: var(--row__background-color--focussed) !important; -} -.stroom-dashboard-table .dataGridSelectedRow:focus-within .cell { - background-color: var(--row__background-color--selected--focussed) !important; -} - .stroom-dashboard-text { width: 100%; height: 100%; diff --git a/stroom-app/src/main/resources/ui/noauth/swagger/stroom.json b/stroom-app/src/main/resources/ui/noauth/swagger/stroom.json index e136b47480a..bd9030e0db2 100644 --- a/stroom-app/src/main/resources/ui/noauth/swagger/stroom.json +++ b/stroom-app/src/main/resources/ui/noauth/swagger/stroom.json @@ -7439,6 +7439,34 @@ "tags" : [ "Queries" ] } }, + "/query/v1/fetchQueryDataSource" : { + "post" : { + "operationId" : "fetchQueryDataSource", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/DocRef" + } + } + } + }, + "responses" : { + "default" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/DocRef" + } + } + }, + "description" : "default response" + } + }, + "summary" : "Fetch the datasource referenced by a query", + "tags" : [ "Queries" ] + } + }, "/query/v1/fetchTimeZones" : { "get" : { "operationId" : "fetchTimeZones", @@ -17669,6 +17697,9 @@ "QueryContext" : { "type" : "object", "properties" : { + "additionalQueryExpression" : { + "$ref" : "#/components/schemas/ExpressionOperator" + }, "dateTimeSettings" : { "$ref" : "#/components/schemas/DateTimeSettings" }, diff --git a/stroom-app/src/main/resources/ui/noauth/swagger/stroom.yaml b/stroom-app/src/main/resources/ui/noauth/swagger/stroom.yaml index 0828082cc7e..9751b525dee 100644 --- a/stroom-app/src/main/resources/ui/noauth/swagger/stroom.yaml +++ b/stroom-app/src/main/resources/ui/noauth/swagger/stroom.yaml @@ -5099,6 +5099,24 @@ paths: summary: Fetch detail for help item tags: - Queries + /query/v1/fetchQueryDataSource: + post: + operationId: fetchQueryDataSource + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/DocRef' + responses: + default: + content: + application/json: + schema: + $ref: '#/components/schemas/DocRef' + description: default response + summary: Fetch the datasource referenced by a query + tags: + - Queries /query/v1/fetchTimeZones: get: operationId: fetchTimeZones @@ -13394,6 +13412,8 @@ components: QueryContext: type: object properties: + additionalQueryExpression: + $ref: '#/components/schemas/ExpressionOperator' dateTimeSettings: $ref: '#/components/schemas/DateTimeSettings' params: diff --git a/stroom-core-client-widget/src/main/java/com/google/gwt/user/cellview/client/AbstractHasData.java b/stroom-core-client-widget/src/main/java/com/google/gwt/user/cellview/client/AbstractHasData.java index 6c1e5c2e5f6..cbcd8f89b83 100644 --- a/stroom-core-client-widget/src/main/java/com/google/gwt/user/cellview/client/AbstractHasData.java +++ b/stroom-core-client-widget/src/main/java/com/google/gwt/user/cellview/client/AbstractHasData.java @@ -747,21 +747,36 @@ public final void onBrowserEvent(Event event) { if (!Element.is(eventTarget)) { return; } - Element target = Element.as(eventTarget); if (!getElement().isOrHasChild(Element.as(eventTarget))) { return; } super.onBrowserEvent(event); - String eventType = event.getType(); + rememberFocus(event); + + Scheduler.get().scheduleDeferred(() -> { + final String eventType = event.getType(); + if (BrowserEvents.FOCUS.equals(eventType) && isFocused) { + onFocus(); + } else if (BrowserEvents.BLUR.equals(eventType) && !isFocused) { + onBlur(); + } + + // Let subclasses handle the event now. + onBrowserEvent2(event); + }); + } + + private void rememberFocus(Event event) { + final String eventType = event.getType(); + final EventTarget eventTarget = event.getEventTarget(); + final Element target = Element.as(eventTarget); if (BrowserEvents.FOCUS.equals(eventType)) { // Remember the focus state. isFocused = true; - onFocus(); } else if (BrowserEvents.BLUR.equals(eventType)) { // Remember the blur state. isFocused = false; - onBlur(); } else if (BrowserEvents.KEYDOWN.equals(eventType)) { // A key event indicates that we already have focus. isFocused = true; @@ -771,9 +786,6 @@ public final void onBrowserEvent(Event event) { // focus. isFocused = true; } - - // Let subclasses handle the event now. - onBrowserEvent2(event); } /** diff --git a/stroom-core-client/src/main/java/stroom/dashboard/client/embeddedquery/EmbeddedQueryPresenter.java b/stroom-core-client/src/main/java/stroom/dashboard/client/embeddedquery/EmbeddedQueryPresenter.java index e3b30dbf67b..a7e74b3f012 100644 --- a/stroom-core-client/src/main/java/stroom/dashboard/client/embeddedquery/EmbeddedQueryPresenter.java +++ b/stroom-core-client/src/main/java/stroom/dashboard/client/embeddedquery/EmbeddedQueryPresenter.java @@ -19,11 +19,14 @@ import stroom.core.client.event.WindowCloseEvent; import stroom.dashboard.client.embeddedquery.EmbeddedQueryPresenter.EmbeddedQueryView; import stroom.dashboard.client.main.AbstractComponentPresenter; +import stroom.dashboard.client.main.Component; import stroom.dashboard.client.main.ComponentRegistry.ComponentType; import stroom.dashboard.client.main.ComponentRegistry.ComponentUse; +import stroom.dashboard.client.main.Components; import stroom.dashboard.client.main.DashboardContext; import stroom.dashboard.client.main.Queryable; import stroom.dashboard.client.query.QueryInfo; +import stroom.dashboard.client.query.SelectionHandlerExpressionBuilder; import stroom.dashboard.client.table.ComponentSelection; import stroom.dashboard.client.table.HasComponentSelection; import stroom.dashboard.client.vis.VisSelectionModel; @@ -67,8 +70,9 @@ import java.util.Collections; import java.util.List; +import java.util.Objects; +import java.util.Optional; import java.util.Set; -import java.util.function.Function; public class EmbeddedQueryPresenter extends AbstractComponentPresenter @@ -108,6 +112,7 @@ public class EmbeddedQueryPresenter private List currentErrors; private boolean initialised; private Timer autoRefreshTimer; + private ExpressionOperator currentDecoration; @Inject public EmbeddedQueryPresenter(final EventBus eventBus, @@ -305,6 +310,58 @@ public void setQueryModel(final QueryModel queryModel) { // } // } + + @Override + public void setComponents(final Components components) { + super.setComponents(components); + + registerHandler(components.addComponentChangeHandler(event -> { + if (initialised) { + final Component component = event.getComponent(); + final Optional optional = SelectionHandlerExpressionBuilder + .create(component, getQuerySettings().getSelectionHandlers()); + +// this.params = params; +// lastUsedQueryInfo = null; + + optional.ifPresent(selectionExpression -> { + if (!Objects.equals(currentDecoration, selectionExpression)) { + currentDecoration = selectionExpression; + queryModel.reset(DestroyReason.NO_LONGER_NEEDED); + run(true, true, selectionExpression); + } + }); + } + +// if (component instanceof HasAbstractFields) { +// final VisPresenter visPresenter = (VisPresenter) component; +// final List> selection = visPresenter.getCurrentSelection(); +// String params = ""; +// if (selection != null) { +// for (final Map map : selection) { +// for (final Entry entry : map.entrySet()) { +// params += entry.getKey() + "=" + entry.getValue() + " "; +// } +// } +// } +// onQuery(params, null); +// } + +// if (getTextSettings().getTableId() == null) { +// if (component instanceof TablePresenter) { +// currentTablePresenter = (TablePresenter) component; +// update(currentTablePresenter); +// } +// } else if (Objects.equals(getTextSettings().getTableId(), event.getComponentId())) { +// if (component instanceof TablePresenter) { +// currentTablePresenter = (TablePresenter) component; +// update(currentTablePresenter); +// } +// } +// } + })); + } + private void updateVisibleResult() { if (currentVisPresenter != null) { getView().setResultView(currentVisPresenter.getView()); @@ -394,12 +451,12 @@ public void stop() { private void run(final boolean incremental, final boolean storeHistory) { // No point running the search if there is no query - run(incremental, storeHistory, Function.identity()); + run(incremental, storeHistory, currentDecoration); } private void run(final boolean incremental, final boolean storeHistory, - final Function expressionDecorator) { + final ExpressionOperator additionalQueryExpression) { if (GwtNullSafe.isNonBlankString(query)) { currentErrors = null; @@ -419,7 +476,8 @@ private void run(final boolean incremental, dashboardContext.getTimeRange(), incremental, storeHistory, - queryInfo.getMessage()); + queryInfo.getMessage(), + additionalQueryExpression); } } diff --git a/stroom-core-client/src/main/java/stroom/dashboard/client/embeddedquery/EmbeddedQuerySettingsPresenter.java b/stroom-core-client/src/main/java/stroom/dashboard/client/embeddedquery/EmbeddedQuerySettingsPresenter.java index ca0076734bf..2b7ed40f2d0 100644 --- a/stroom-core-client/src/main/java/stroom/dashboard/client/embeddedquery/EmbeddedQuerySettingsPresenter.java +++ b/stroom-core-client/src/main/java/stroom/dashboard/client/embeddedquery/EmbeddedQuerySettingsPresenter.java @@ -17,30 +17,63 @@ package stroom.dashboard.client.embeddedquery; import stroom.dashboard.client.main.SettingsPresenter; -import stroom.dashboard.client.query.BasicQuerySettingsPresenter; import stroom.dashboard.client.query.SelectionHandlersPresenter; +import stroom.dispatch.client.DefaultErrorHandler; +import stroom.dispatch.client.RestFactory; +import stroom.docref.DocRef; +import stroom.query.shared.QueryResource; +import stroom.util.shared.GwtNullSafe; import stroom.widget.tab.client.presenter.LinkTabsLayoutView; +import com.google.gwt.core.client.GWT; import com.google.inject.Inject; import com.google.web.bindery.event.shared.EventBus; +import java.util.Objects; + public class EmbeddedQuerySettingsPresenter extends SettingsPresenter { + private static final QueryResource QUERY_RESOURCE = GWT.create(QueryResource.class); + + private DocRef currentQueryReference; + private DocRef currentDataSource; + @Inject - public EmbeddedQuerySettingsPresenter(final EventBus eventBus, final LinkTabsLayoutView view, + public EmbeddedQuerySettingsPresenter(final EventBus eventBus, + final LinkTabsLayoutView view, final BasicEmbeddedQuerySettingsPresenter basicSettingsPresenter, - final SelectionHandlersPresenter selectionHandlersPresenter) { + final SelectionHandlersPresenter selectionHandlersPresenter, + final RestFactory restFactory) { super(eventBus, view); getView().asWidget().addStyleName("settingsPresenter"); -// selectionHandlersPresenter.setBasicQuerySettingsPresenter(basicSettingsPresenter); + selectionHandlersPresenter.setDataSourceRefConsumer(consumer -> { + final DocRef queryDocRef = GwtNullSafe + .get(basicSettingsPresenter, BasicEmbeddedQuerySettingsPresenter::getQuery); + if (Objects.equals(queryDocRef, currentQueryReference)) { + consumer.accept(currentDataSource); + } else if (queryDocRef == null) { + consumer.accept(null); + } else { + restFactory + .create(QUERY_RESOURCE) + .method(res -> res.fetchQueryDataSource(queryDocRef)) + .onSuccess(result -> { + currentDataSource = result; + currentQueryReference = queryDocRef; + consumer.accept(result); + }) + .onFailure(new DefaultErrorHandler(this, () -> { + currentDataSource = null; + currentQueryReference = queryDocRef; + consumer.accept(null); + })) + .taskMonitorFactory(this) + .exec(); + } + }); addTab("Basic", basicSettingsPresenter); -// addTab("Selection Handlers", selectionHandlersPresenter); - } - - @Override - public boolean validate() { - return super.validate(); + addTab("Selection Handlers", selectionHandlersPresenter); } } diff --git a/stroom-core-client/src/main/java/stroom/dashboard/client/query/QueryPresenter.java b/stroom-core-client/src/main/java/stroom/dashboard/client/query/QueryPresenter.java index 6467cce3929..30c64b1d031 100644 --- a/stroom-core-client/src/main/java/stroom/dashboard/client/query/QueryPresenter.java +++ b/stroom-core-client/src/main/java/stroom/dashboard/client/query/QueryPresenter.java @@ -28,11 +28,8 @@ import stroom.dashboard.client.main.IndexLoader; import stroom.dashboard.client.main.Queryable; import stroom.dashboard.client.main.SearchModel; -import stroom.dashboard.client.table.ComponentSelection; -import stroom.dashboard.client.table.HasComponentSelection; import stroom.dashboard.shared.Automate; import stroom.dashboard.shared.ComponentConfig; -import stroom.dashboard.shared.ComponentSelectionHandler; import stroom.dashboard.shared.ComponentSettings; import stroom.dashboard.shared.DashboardDoc; import stroom.dashboard.shared.DashboardResource; @@ -51,7 +48,6 @@ import stroom.processor.shared.QueryData; import stroom.query.api.v2.DestroyReason; import stroom.query.api.v2.ExpressionOperator; -import stroom.query.api.v2.ExpressionOperator.Op; import stroom.query.api.v2.ExpressionUtil; import stroom.query.api.v2.QueryKey; import stroom.query.api.v2.ResultStoreInfo; @@ -94,8 +90,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; -import java.util.function.Function; -import java.util.stream.Collectors; +import java.util.Optional; public class QueryPresenter extends AbstractComponentPresenter @@ -135,6 +130,7 @@ public class QueryPresenter private Timer autoRefreshTimer; private boolean queryOnOpen; private QueryInfo queryInfo; + private ExpressionOperator currentDecoration; @Inject public QueryPresenter(final EventBus eventBus, @@ -299,56 +295,19 @@ public void setComponents(final Components components) { registerHandler(components.addComponentChangeHandler(event -> { if (initialised) { final Component component = event.getComponent(); - if (component instanceof HasComponentSelection) { - final HasComponentSelection hasComponentSelection = (HasComponentSelection) component; - final List selection = hasComponentSelection.getSelection(); - final List selectionHandlers = getQuerySettings().getSelectionHandlers(); - if (selectionHandlers != null) { - final List matchingHandlers = selectionHandlers - .stream() - .filter(ComponentSelectionHandler::isEnabled) - .filter(selectionHandler -> selectionHandler.getComponentId() == null || - selectionHandler.getComponentId().equals(component.getId())) - .collect(Collectors.toList()); - - if (matchingHandlers.size() > 0) { - final Function decorator = (in) -> { - final ExpressionOperator.Builder innerBuilder = ExpressionOperator - .builder(); - boolean added = false; - for (final ComponentSelectionHandler selectionHandler : matchingHandlers) { - for (final ComponentSelection params : selection) { - ExpressionOperator ex = selectionHandler.getExpression(); - ex = ExpressionUtil.replaceExpressionParameters(ex, params.getMap()); - innerBuilder.addOperator(ex); - - if (!added) { - added = true; - } else { - innerBuilder.op(Op.OR); - } - } - } - - if (added) { - return ExpressionOperator - .builder() - .addOperator(in) - .addOperator(innerBuilder.build()) - .build(); - } - - return in; - }; + final Optional optional = SelectionHandlerExpressionBuilder + .create(component, getQuerySettings().getSelectionHandlers()); // this.params = params; // lastUsedQueryInfo = null; - searchModel.reset(DestroyReason.NO_LONGER_NEEDED); - run(true, true, decorator); - } + optional.ifPresent(selectionExpression -> { + if (!Objects.equals(currentDecoration, selectionExpression)) { + currentDecoration = selectionExpression; + searchModel.reset(DestroyReason.NO_LONGER_NEEDED); + run(true, true, selectionExpression); } - } + }); } // if (component instanceof HasAbstractFields) { @@ -453,7 +412,7 @@ private void loadDataSource(final DocRef dataSourceRef) { } private void loadedDataSource(final DocRef dataSourceRef) { - fieldSelectionBoxModel.setDataSourceRef(dataSourceRef); + fieldSelectionBoxModel.setDataSourceRefConsumer(consumer -> consumer.accept(dataSourceRef)); // We only want queryable fields. fieldSelectionBoxModel.setQueryable(true); expressionPresenter.init(restFactory, dataSourceRef, fieldSelectionBoxModel); @@ -628,12 +587,12 @@ public boolean getSearchState() { private void run(final boolean incremental, final boolean storeHistory) { - run(incremental, storeHistory, Function.identity()); + run(incremental, storeHistory, null); } private void run(final boolean incremental, final boolean storeHistory, - final Function expressionDecorator) { + final ExpressionOperator expressionDecorator) { final DocRef dataSourceRef = getQuerySettings().getDataSource(); if (dataSourceRef == null) { @@ -646,7 +605,7 @@ private void run(final boolean incremental, // Write expression. final ExpressionOperator root = expressionPresenter.write(); - final ExpressionOperator decorated = expressionDecorator.apply(root); + final ExpressionOperator decorated = ExpressionUtil.combine(root, expressionDecorator); // Start search. final DashboardContext dashboardContext = getDashboardContext(); diff --git a/stroom-core-client/src/main/java/stroom/dashboard/client/query/QuerySettingsPresenter.java b/stroom-core-client/src/main/java/stroom/dashboard/client/query/QuerySettingsPresenter.java index 464c6ea8f38..ac76a3c3e06 100644 --- a/stroom-core-client/src/main/java/stroom/dashboard/client/query/QuerySettingsPresenter.java +++ b/stroom-core-client/src/main/java/stroom/dashboard/client/query/QuerySettingsPresenter.java @@ -31,7 +31,8 @@ public QuerySettingsPresenter(final EventBus eventBus, final LinkTabsLayoutView super(eventBus, view); getView().asWidget().addStyleName("settingsPresenter"); - selectionHandlersPresenter.setBasicQuerySettingsPresenter(basicSettingsPresenter); + selectionHandlersPresenter.setDataSourceRefConsumer(consumer -> + consumer.accept(basicSettingsPresenter.getDataSource())); addTab("Basic", basicSettingsPresenter); addTab("Selection Handlers", selectionHandlersPresenter); diff --git a/stroom-core-client/src/main/java/stroom/dashboard/client/query/SelectionHandlerExpressionBuilder.java b/stroom-core-client/src/main/java/stroom/dashboard/client/query/SelectionHandlerExpressionBuilder.java new file mode 100644 index 00000000000..1182284777a --- /dev/null +++ b/stroom-core-client/src/main/java/stroom/dashboard/client/query/SelectionHandlerExpressionBuilder.java @@ -0,0 +1,50 @@ +package stroom.dashboard.client.query; + +import stroom.dashboard.client.main.Component; +import stroom.dashboard.client.table.ComponentSelection; +import stroom.dashboard.client.table.HasComponentSelection; +import stroom.dashboard.shared.ComponentSelectionHandler; +import stroom.query.api.v2.ExpressionOperator; +import stroom.query.api.v2.ExpressionOperator.Op; +import stroom.query.api.v2.ExpressionUtil; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +public class SelectionHandlerExpressionBuilder { + + public static Optional create(final Component component, + final List selectionHandlers) { + ExpressionOperator currentSelectionExpression = null; + if (component instanceof HasComponentSelection) { + final HasComponentSelection hasComponentSelection = (HasComponentSelection) component; + final List selection = hasComponentSelection.getSelection(); + if (selectionHandlers != null) { + final List matchingHandlers = selectionHandlers + .stream() + .filter(ComponentSelectionHandler::isEnabled) + .filter(selectionHandler -> selectionHandler.getComponentId() == null || + selectionHandler.getComponentId().equals(component.getId())) + .collect(Collectors.toList()); + + if (matchingHandlers.size() > 0) { + final ExpressionOperator.Builder innerBuilder = ExpressionOperator + .builder() + .op(Op.OR); + for (final ComponentSelectionHandler selectionHandler : matchingHandlers) { + for (final ComponentSelection params : selection) { + ExpressionOperator ex = selectionHandler.getExpression(); + ex = ExpressionUtil.replaceExpressionParameters(ex, params.getMap()); + innerBuilder.addOperator(ex); + } + } + + currentSelectionExpression = innerBuilder.build(); + } + } + } + + return Optional.ofNullable(currentSelectionExpression); + } +} diff --git a/stroom-core-client/src/main/java/stroom/dashboard/client/query/SelectionHandlerPresenter.java b/stroom-core-client/src/main/java/stroom/dashboard/client/query/SelectionHandlerPresenter.java index fe3e2f670ce..22753d363e0 100644 --- a/stroom-core-client/src/main/java/stroom/dashboard/client/query/SelectionHandlerPresenter.java +++ b/stroom-core-client/src/main/java/stroom/dashboard/client/query/SelectionHandlerPresenter.java @@ -36,6 +36,7 @@ import java.util.List; import java.util.Optional; +import java.util.function.Consumer; public class SelectionHandlerPresenter extends MyPresenterWidget @@ -64,7 +65,7 @@ public void focus() { void read(final ComponentSelectionHandler componentSelectionHandler, final List componentList, - final DocRef dataSourceRef) { + final Consumer> dataSourceRefConsumer) { getView().setComponentList(componentList); final Optional optionalComponent = componentList .stream() @@ -73,7 +74,7 @@ void read(final ComponentSelectionHandler componentSelectionHandler, getView().setComponent(optionalComponent.orElse(null)); this.originalHandler = componentSelectionHandler; - fieldSelectionBoxModel.setDataSourceRef(dataSourceRef); + fieldSelectionBoxModel.setDataSourceRefConsumer(dataSourceRefConsumer); editExpressionPresenter.init(null, null, fieldSelectionBoxModel); this.originalHandler = componentSelectionHandler; if (componentSelectionHandler.getExpression() == null) { diff --git a/stroom-core-client/src/main/java/stroom/dashboard/client/query/SelectionHandlersPresenter.java b/stroom-core-client/src/main/java/stroom/dashboard/client/query/SelectionHandlersPresenter.java index 42dcd3fdd6d..18b5a74b3b8 100644 --- a/stroom-core-client/src/main/java/stroom/dashboard/client/query/SelectionHandlersPresenter.java +++ b/stroom-core-client/src/main/java/stroom/dashboard/client/query/SelectionHandlersPresenter.java @@ -22,9 +22,11 @@ import stroom.dashboard.client.main.Component; import stroom.dashboard.client.query.SelectionHandlersPresenter.SelectionHandlersView; import stroom.dashboard.client.table.HasComponentSelection; +import stroom.dashboard.shared.AbstractQueryComponentSettings; import stroom.dashboard.shared.ComponentConfig; import stroom.dashboard.shared.ComponentSelectionHandler; -import stroom.dashboard.shared.QueryComponentSettings; +import stroom.dashboard.shared.ComponentSettings; +import stroom.dashboard.shared.ComponentSettings.AbstractBuilder; import stroom.docref.DocRef; import stroom.document.client.event.DirtyEvent; import stroom.document.client.event.DirtyEvent.DirtyHandler; @@ -46,6 +48,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.function.Consumer; import java.util.stream.Collectors; public class SelectionHandlersPresenter @@ -66,7 +69,7 @@ public class SelectionHandlersPresenter private boolean dirty; private List componentList; - private BasicQuerySettingsPresenter basicQuerySettingsPresenter; + private Consumer> dataSourceRefConsumer; @Inject public SelectionHandlersPresenter(final EventBus eventBus, @@ -102,8 +105,8 @@ public void focus() { addButton.focus(); } - public void setBasicQuerySettingsPresenter(final BasicQuerySettingsPresenter basicQuerySettingsPresenter) { - this.basicQuerySettingsPresenter = basicQuerySettingsPresenter; + public void setDataSourceRefConsumer(final Consumer> dataSourceRefConsumer) { + this.dataSourceRefConsumer = dataSourceRefConsumer; } @Override @@ -201,14 +204,13 @@ protected void onBind() { } private void add() { - final DocRef dataSource = basicQuerySettingsPresenter.getDataSource(); final ComponentSelectionHandler newRule = ComponentSelectionHandler .builder() .id(RandomId.createId(5)) .enabled(true) .build(); final SelectionHandlerPresenter editSelectionHandlerPresenter = editRulePresenterProvider.get(); - editSelectionHandlerPresenter.read(newRule, componentList, dataSource); + editSelectionHandlerPresenter.read(newRule, componentList, dataSourceRefConsumer); final PopupSize popupSize = PopupSize.resizable(800, 400); ShowPopupEvent.builder(editSelectionHandlerPresenter) @@ -230,10 +232,9 @@ private void add() { } private void edit(final ComponentSelectionHandler existingRule) { - final DocRef dataSource = basicQuerySettingsPresenter.getDataSource(); final SelectionHandlerPresenter editSelectionHandlerPresenter = editRulePresenterProvider.get(); - editSelectionHandlerPresenter.read(existingRule, componentList, dataSource); + editSelectionHandlerPresenter.read(existingRule, componentList, dataSourceRefConsumer); final PopupSize popupSize = PopupSize.resizable(800, 400); ShowPopupEvent.builder(editSelectionHandlerPresenter) @@ -263,7 +264,7 @@ private void edit(final ComponentSelectionHandler existingRule) { @Override public void read(final ComponentConfig componentConfig) { - final QueryComponentSettings settings = (QueryComponentSettings) componentConfig.getSettings(); + final AbstractQueryComponentSettings settings = (AbstractQueryComponentSettings) componentConfig.getSettings(); if (settings.getSelectionHandlers() != null) { this.selectionHandlers = settings.getSelectionHandlers(); } else { @@ -283,11 +284,15 @@ public void read(final ComponentConfig componentConfig) { @Override public ComponentConfig write(final ComponentConfig componentConfig) { - final QueryComponentSettings oldSettings = (QueryComponentSettings) componentConfig.getSettings(); - final QueryComponentSettings newSettings = oldSettings - .copy() - .selectionHandlers(selectionHandlers) - .build(); + final AbstractQueryComponentSettings oldSettings = + (AbstractQueryComponentSettings) componentConfig.getSettings(); + final AbstractBuilder builder = oldSettings.copy(); + if (builder instanceof AbstractQueryComponentSettings.AbstractBuilder) { + final AbstractQueryComponentSettings.AbstractBuilder abstractBuilder = + (AbstractQueryComponentSettings.AbstractBuilder) builder; + abstractBuilder.selectionHandlers(selectionHandlers); + } + final ComponentSettings newSettings = builder.build(); return componentConfig.copy().settings(newSettings).build(); } diff --git a/stroom-core-client/src/main/java/stroom/dashboard/client/table/DynamicStyles.java b/stroom-core-client/src/main/java/stroom/dashboard/client/table/DynamicStyles.java new file mode 100644 index 00000000000..dd259964301 --- /dev/null +++ b/stroom-core-client/src/main/java/stroom/dashboard/client/table/DynamicStyles.java @@ -0,0 +1,49 @@ +package stroom.dashboard.client.table; + +import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.Element; +import com.google.gwt.user.client.ui.RootPanel; + +import java.util.HashMap; +import java.util.Map; + +public class DynamicStyles { + + private static final Map styles = new HashMap<>(); + private static Element styleElement; + + public static DynamicStyle create(final String style) { + if (styleElement == null) { + styleElement = DOM.createElement("style"); + RootPanel.getBodyElement().appendChild(styleElement); + } + + return styles.computeIfAbsent(style, k -> { + final String dynamicName = "dynamic" + styles.size() + 1; + final String css = ".dataGridEvenRow." + dynamicName + "," + + " .dataGridOddRow." + dynamicName + " " + + "{" + style + "}\n\n"; + styleElement.setInnerHTML(styleElement.getInnerHTML() + css); + return new DynamicStyle(dynamicName, css); + }); + } + + public static class DynamicStyle { + + private final String name; + private final String css; + + public DynamicStyle(final String name, final String css) { + this.name = name; + this.css = css; + } + + public String getName() { + return name; + } + + public String getCss() { + return css; + } + } +} diff --git a/stroom-core-client/src/main/java/stroom/dashboard/client/table/TablePresenter.java b/stroom-core-client/src/main/java/stroom/dashboard/client/table/TablePresenter.java index e11a92663fc..6ee6e0c0a3c 100644 --- a/stroom-core-client/src/main/java/stroom/dashboard/client/table/TablePresenter.java +++ b/stroom-core-client/src/main/java/stroom/dashboard/client/table/TablePresenter.java @@ -571,18 +571,6 @@ private List processData(final List columns, final List v final List processed = new ArrayList<>(values.size()); for (final Row row : values) { - SafeStylesBuilder rowStyle = new SafeStylesBuilder(); - - // Row styles. - if (row.getBackgroundColor() != null - && !row.getBackgroundColor().isEmpty()) { - rowStyle.trustedBackgroundColor(row.getBackgroundColor()); - } - if (row.getTextColor() != null - && !row.getTextColor().isEmpty()) { - rowStyle.trustedColor(row.getTextColor()); - } - final Map cellsMap = new HashMap<>(); for (int i = 0; i < columns.size() && i < row.getValues().size(); i++) { final Column column = columns.get(i); @@ -591,7 +579,6 @@ private List processData(final List columns, final List v : ""; SafeStylesBuilder stylesBuilder = new SafeStylesBuilder(); - stylesBuilder.append(rowStyle.toSafeStyles()); // Wrap if (column.getFormat() != null && @@ -620,12 +607,18 @@ private List processData(final List columns, final List v expander = new Expander(row.getDepth(), false, true); } - processed.add(new TableRow(expander, row.getGroupKey(), cellsMap)); + processed.add(new TableRow( + expander, + row.getGroupKey(), + cellsMap, + row.getBackgroundColor(), + row.getTextColor())); } // Set the expander column width. expanderColumnWidth = ExpanderCell.getColumnWidth(maxDepth); dataGrid.setColumnWidth(expanderColumn, expanderColumnWidth, Unit.PX); + dataGrid.setRowStyles(new TableRowStyles()); return processed; } diff --git a/stroom-core-client/src/main/java/stroom/dashboard/client/table/TableRowStyles.java b/stroom-core-client/src/main/java/stroom/dashboard/client/table/TableRowStyles.java new file mode 100644 index 00000000000..a9c4edcf96a --- /dev/null +++ b/stroom-core-client/src/main/java/stroom/dashboard/client/table/TableRowStyles.java @@ -0,0 +1,30 @@ +package stroom.dashboard.client.table; + +import stroom.dashboard.client.table.DynamicStyles.DynamicStyle; +import stroom.query.client.presenter.TableRow; +import stroom.util.shared.GwtNullSafe; + +import com.google.gwt.safecss.shared.SafeStylesBuilder; +import com.google.gwt.user.cellview.client.RowStyles; + +public class TableRowStyles implements RowStyles { + + @Override + public String getStyleNames(final TableRow row, final int rowIndex) { + // Row styles. + if (GwtNullSafe.isNonBlankString(row.getBackgroundColor()) || + GwtNullSafe.isNonBlankString(row.getTextColor())) { + final SafeStylesBuilder rowStyle = new SafeStylesBuilder(); + if (GwtNullSafe.isNonBlankString(row.getBackgroundColor())) { + rowStyle.trustedBackgroundColor(row.getBackgroundColor()); + } + if (GwtNullSafe.isNonBlankString(row.getTextColor())) { + rowStyle.trustedColor(row.getTextColor()); + } + final DynamicStyle dynamicStyle = DynamicStyles.create(rowStyle.toSafeStyles().asString()); + return dynamicStyle.getName(); + } + + return ""; + } +} diff --git a/stroom-core-client/src/main/java/stroom/query/client/presenter/DynamicFieldSelectionListModel.java b/stroom-core-client/src/main/java/stroom/query/client/presenter/DynamicFieldSelectionListModel.java index e71984548a0..e5017c9dfaa 100644 --- a/stroom-core-client/src/main/java/stroom/query/client/presenter/DynamicFieldSelectionListModel.java +++ b/stroom-core-client/src/main/java/stroom/query/client/presenter/DynamicFieldSelectionListModel.java @@ -27,7 +27,7 @@ public class DynamicFieldSelectionListModel private final EventBus eventBus; private final DataSourceClient dataSourceClient; - private DocRef dataSourceRef; + private Consumer> dataSourceRefConsumer; private Boolean queryable; private FindFieldCriteria lastCriteria; private TaskMonitorFactory taskMonitorFactory = new DefaultTaskMonitorFactory(this); @@ -45,7 +45,7 @@ public void onRangeChange(final FieldInfoSelectionItem parent, final boolean filterChange, final PageRequest pageRequest, final Consumer> consumer) { - if (dataSourceRef != null) { + consumeDataSource(dataSourceRef -> { final StringMatch stringMatch = StringMatch.contains(filter); final FindFieldCriteria findFieldInfoCriteria = new FindFieldCriteria( pageRequest, @@ -79,11 +79,11 @@ public void onRangeChange(final FieldInfoSelectionItem parent, } }, taskMonitorFactory); } - } + }); } - public void setDataSourceRef(final DocRef dataSourceRef) { - this.dataSourceRef = dataSourceRef; + public void setDataSourceRefConsumer(final Consumer> dataSourceRefConsumer) { + this.dataSourceRefConsumer = dataSourceRefConsumer; } public void setQueryable(final Boolean queryable) { @@ -97,7 +97,14 @@ public void reset() { @Override public void findFieldByName(final String fieldName, final Consumer consumer) { - dataSourceClient.findFieldByName(dataSourceRef, fieldName, queryable, consumer, taskMonitorFactory); + consumeDataSource(dataSourceRef -> + dataSourceClient.findFieldByName(dataSourceRef, fieldName, queryable, consumer, taskMonitorFactory)); + } + + private void consumeDataSource(final Consumer dsc) { + if (dataSourceRefConsumer != null) { + dataSourceRefConsumer.accept(dsc); + } } @Override diff --git a/stroom-core-client/src/main/java/stroom/query/client/presenter/QueryEditPresenter.java b/stroom-core-client/src/main/java/stroom/query/client/presenter/QueryEditPresenter.java index b359d33d72e..bcd6e2fe813 100644 --- a/stroom-core-client/src/main/java/stroom/query/client/presenter/QueryEditPresenter.java +++ b/stroom-core-client/src/main/java/stroom/query/client/presenter/QueryEditPresenter.java @@ -365,7 +365,8 @@ private void run(final boolean incremental, queryToolbarPresenter.getTimeRange(), incremental, storeHistory, - queryInfo.getMessage()); + queryInfo.getMessage(), + null); } public TimeRange getTimeRange() { diff --git a/stroom-core-client/src/main/java/stroom/query/client/presenter/QueryModel.java b/stroom-core-client/src/main/java/stroom/query/client/presenter/QueryModel.java index 6d53bd73b33..6caa496b964 100644 --- a/stroom-core-client/src/main/java/stroom/query/client/presenter/QueryModel.java +++ b/stroom-core-client/src/main/java/stroom/query/client/presenter/QueryModel.java @@ -19,6 +19,7 @@ import stroom.dashboard.shared.DashboardSearchResponse; import stroom.dispatch.client.RestFactory; import stroom.query.api.v2.DestroyReason; +import stroom.query.api.v2.ExpressionOperator; import stroom.query.api.v2.OffsetRange; import stroom.query.api.v2.Param; import stroom.query.api.v2.QueryKey; @@ -144,7 +145,8 @@ public void startNewSearch(final String query, final TimeRange timeRange, final boolean incremental, final boolean storeHistory, - final String queryInfo) { + final String queryInfo, + final ExpressionOperator additionalQueryExpression) { GWT.log("SearchModel - startNewSearch()"); // Destroy the previous search and ready all components for a new search to begin. @@ -163,6 +165,7 @@ public void startNewSearch(final String query, .timeRange(timeRange) .queryInfo(queryInfo) .dateTimeSettings(dateTimeSettingsFactory.getDateTimeSettings()) + .additionalQueryExpression(additionalQueryExpression) .build(); currentSearch = QuerySearchRequest diff --git a/stroom-core-client/src/main/java/stroom/query/client/presenter/QueryResultTablePresenter.java b/stroom-core-client/src/main/java/stroom/query/client/presenter/QueryResultTablePresenter.java index 16b87730a89..bb3632c8437 100644 --- a/stroom-core-client/src/main/java/stroom/query/client/presenter/QueryResultTablePresenter.java +++ b/stroom-core-client/src/main/java/stroom/query/client/presenter/QueryResultTablePresenter.java @@ -22,6 +22,7 @@ import stroom.dashboard.client.table.ComponentSelection; import stroom.dashboard.client.table.DownloadPresenter; import stroom.dashboard.client.table.HasComponentSelection; +import stroom.dashboard.client.table.TableRowStyles; import stroom.data.grid.client.DataGridSelectionEventManager; import stroom.data.grid.client.MyDataGrid; import stroom.data.grid.client.PagerView; @@ -402,7 +403,6 @@ private void setDataInternal(final Result componentResult) { dataGrid.setRowData(0, new ArrayList<>()); dataGrid.setRowCount(0, true); - selectionModel.clear(); } } catch (final RuntimeException e) { @@ -489,18 +489,6 @@ private List processData(final List columns, final List v final List processed = new ArrayList<>(values.size()); for (final Row row : values) { - SafeStylesBuilder rowStyle = new SafeStylesBuilder(); - - // Row styles. - if (row.getBackgroundColor() != null - && !row.getBackgroundColor().isEmpty()) { - rowStyle.trustedBackgroundColor(row.getBackgroundColor()); - } - if (row.getTextColor() != null - && !row.getTextColor().isEmpty()) { - rowStyle.trustedColor(row.getTextColor()); - } - final Map cellsMap = new HashMap<>(); for (int i = 0; i < columns.size() && i < row.getValues().size(); i++) { final Column column = columns.get(i); @@ -509,7 +497,6 @@ private List processData(final List columns, final List v : ""; SafeStylesBuilder stylesBuilder = new SafeStylesBuilder(); - stylesBuilder.append(rowStyle.toSafeStyles()); // Wrap if (column.getFormat() != null && @@ -538,12 +525,18 @@ private List processData(final List columns, final List v expander = new Expander(row.getDepth(), false, true); } - processed.add(new TableRow(expander, row.getGroupKey(), cellsMap)); + processed.add(new TableRow( + expander, + row.getGroupKey(), + cellsMap, + row.getBackgroundColor(), + row.getTextColor())); } // Set the expander column width. expanderColumnWidth = ExpanderCell.getColumnWidth(maxDepth); dataGrid.setColumnWidth(expanderColumn, expanderColumnWidth, Unit.PX); + dataGrid.setRowStyles(new TableRowStyles()); return processed; } diff --git a/stroom-core-client/src/main/java/stroom/query/client/presenter/TableRow.java b/stroom-core-client/src/main/java/stroom/query/client/presenter/TableRow.java index 857cfc1c5b5..942251e9511 100644 --- a/stroom-core-client/src/main/java/stroom/query/client/presenter/TableRow.java +++ b/stroom-core-client/src/main/java/stroom/query/client/presenter/TableRow.java @@ -18,13 +18,19 @@ public class TableRow { private final Expander expander; private final String groupKey; private final Map cells; + private final String backgroundColor; + private final String textColor; public TableRow(final Expander expander, final String groupKey, - final Map cells) { + final Map cells, + final String backgroundColor, + final String textColor) { this.expander = expander; this.groupKey = groupKey; this.cells = cells; + this.backgroundColor = backgroundColor; + this.textColor = textColor; } public Expander getExpander() { @@ -45,6 +51,14 @@ public SafeHtml getValue(final String fieldId) { } } + public String getBackgroundColor() { + return backgroundColor; + } + + public String getTextColor() { + return textColor; + } + private SafeHtml decorateValue(final Cell cell) { final SafeHtmlBuilder safeHtmlBuilder = new SafeHtmlBuilder(); diff --git a/stroom-core-client/src/main/java/stroom/receive/rules/client/presenter/DataRetentionRulePresenter.java b/stroom-core-client/src/main/java/stroom/receive/rules/client/presenter/DataRetentionRulePresenter.java index 2cacaff6a39..4ebc9f2175e 100644 --- a/stroom-core-client/src/main/java/stroom/receive/rules/client/presenter/DataRetentionRulePresenter.java +++ b/stroom-core-client/src/main/java/stroom/receive/rules/client/presenter/DataRetentionRulePresenter.java @@ -34,8 +34,9 @@ import com.gwtplatform.mvp.client.View; public class DataRetentionRulePresenter extends MyPresenterWidget implements Focus { + private final EditExpressionPresenter editExpressionPresenter; - private final DynamicFieldSelectionListModel fieldSelectionBoxModel; + private final DynamicFieldSelectionListModel fieldSelectionBoxModel; private DataRetentionRule originalRule; @Inject @@ -49,7 +50,7 @@ public DataRetentionRulePresenter(final EventBus eventBus, this.editExpressionPresenter = editExpressionPresenter; view.setExpressionView(editExpressionPresenter.getView()); - fieldSelectionBoxModel.setDataSourceRef(MetaFields.STREAM_STORE_DOC_REF); + fieldSelectionBoxModel.setDataSourceRefConsumer(consumer -> consumer.accept(MetaFields.STREAM_STORE_DOC_REF)); editExpressionPresenter.init(restFactory, MetaFields.STREAM_STORE_DOC_REF, fieldSelectionBoxModel); } diff --git a/stroom-core-client/src/main/java/stroom/search/elastic/client/presenter/ElasticIndexSettingsPresenter.java b/stroom-core-client/src/main/java/stroom/search/elastic/client/presenter/ElasticIndexSettingsPresenter.java index 1e600f42806..bf39a162b18 100644 --- a/stroom-core-client/src/main/java/stroom/search/elastic/client/presenter/ElasticIndexSettingsPresenter.java +++ b/stroom-core-client/src/main/java/stroom/search/elastic/client/presenter/ElasticIndexSettingsPresenter.java @@ -122,7 +122,7 @@ protected void onRead(final DocRef docRef, final ElasticIndexDoc index, final bo index.setRetentionExpression(ExpressionOperator.builder().op(Op.AND).build()); } - fieldSelectionBoxModel.setDataSourceRef(docRef); + fieldSelectionBoxModel.setDataSourceRefConsumer(consumer -> consumer.accept(docRef)); editExpressionPresenter.init(restFactory, docRef, fieldSelectionBoxModel); editExpressionPresenter.read(index.getRetentionExpression()); pipelinePresenter.setSelectedEntityReference(index.getDefaultExtractionPipeline(), true); diff --git a/stroom-core-client/src/main/java/stroom/search/solr/client/presenter/SolrIndexSettingsPresenter.java b/stroom-core-client/src/main/java/stroom/search/solr/client/presenter/SolrIndexSettingsPresenter.java index 7b2a866470a..94efa972721 100644 --- a/stroom-core-client/src/main/java/stroom/search/solr/client/presenter/SolrIndexSettingsPresenter.java +++ b/stroom-core-client/src/main/java/stroom/search/solr/client/presenter/SolrIndexSettingsPresenter.java @@ -124,7 +124,7 @@ protected void onRead(final DocRef docRef, final SolrIndexDoc index, final boole index.setRetentionExpression(ExpressionOperator.builder().build()); } - fieldSelectionBoxModel.setDataSourceRef(docRef); + fieldSelectionBoxModel.setDataSourceRefConsumer(consumer -> consumer.accept(docRef)); editExpressionPresenter.init(restFactory, docRef, fieldSelectionBoxModel); editExpressionPresenter.read(index.getRetentionExpression()); pipelinePresenter.setSelectedEntityReference(index.getDefaultExtractionPipeline(), true); diff --git a/stroom-core-shared/src/main/java/stroom/dashboard/shared/AbstractQueryComponentSettings.java b/stroom-core-shared/src/main/java/stroom/dashboard/shared/AbstractQueryComponentSettings.java new file mode 100644 index 00000000000..b348030efaf --- /dev/null +++ b/stroom-core-shared/src/main/java/stroom/dashboard/shared/AbstractQueryComponentSettings.java @@ -0,0 +1,152 @@ +/* + * Copyright 2017 Crown Copyright + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package stroom.dashboard.shared; + +import stroom.query.api.v2.QueryKey; +import stroom.query.api.v2.TableSettings; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public abstract class AbstractQueryComponentSettings implements ComponentSettings { + + @JsonProperty + private final Automate automate; + @JsonProperty + private final List selectionHandlers; + @JsonProperty + private final QueryKey lastQueryKey; + @JsonProperty + private final String lastQueryNode; + + @SuppressWarnings("checkstyle:LineLength") + @JsonCreator + public AbstractQueryComponentSettings(@JsonProperty("automate") final Automate automate, + @JsonProperty("selectionHandlers") final List selectionHandlers, + @JsonProperty("lastQueryKey") final QueryKey lastQueryKey, + @JsonProperty("lastQueryNode") final String lastQueryNode) { + this.automate = automate; + this.selectionHandlers = selectionHandlers; + this.lastQueryKey = lastQueryKey; + this.lastQueryNode = lastQueryNode; + } + + public Automate getAutomate() { + return automate; + } + + public List getSelectionHandlers() { + return selectionHandlers; + } + + public QueryKey getLastQueryKey() { + return lastQueryKey; + } + + public String getLastQueryNode() { + return lastQueryNode; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final AbstractQueryComponentSettings that = (AbstractQueryComponentSettings) o; + return Objects.equals(automate, that.automate) && + Objects.equals(selectionHandlers, that.selectionHandlers) && + Objects.equals(lastQueryKey, that.lastQueryKey) && + Objects.equals(lastQueryNode, that.lastQueryNode); + } + + @Override + public int hashCode() { + return Objects.hash(automate, selectionHandlers, lastQueryKey, lastQueryNode); + } + + @Override + public String toString() { + return "AbstractQueryComponentSettings{" + + "automate=" + automate + + ", selectionHandlers=" + selectionHandlers + + ", lastQueryKey=" + lastQueryKey + + ", lastQueryNode='" + lastQueryNode + '\'' + + '}'; + } + + /** + * Builder for constructing a {@link TableSettings tableSettings} + */ + public abstract static class AbstractBuilder + > + extends ComponentSettings.AbstractBuilder { + + Automate automate; + List selectionHandlers; + QueryKey lastQueryKey; + String lastQueryNode; + + AbstractBuilder() { + } + + AbstractBuilder(final AbstractQueryComponentSettings settings) { + this.automate = settings.automate == null + ? null + : settings.automate.copy().build(); + this.selectionHandlers = settings.selectionHandlers == null + ? null + : new ArrayList<>(settings.selectionHandlers); + this.lastQueryKey = settings.lastQueryKey; + this.lastQueryNode = settings.lastQueryNode; + } + + public B automate(final Automate automate) { + this.automate = automate; + return self(); + } + + public B selectionHandlers(final List selectionHandlers) { + this.selectionHandlers = selectionHandlers; + return self(); + } + + public B addSelectionHandler(final ComponentSelectionHandler selectionHandler) { + if (this.selectionHandlers == null) { + this.selectionHandlers = new ArrayList<>(); + } + this.selectionHandlers.add(selectionHandler); + return self(); + } + + public B lastQueryKey(final QueryKey lastQueryKey) { + this.lastQueryKey = lastQueryKey; + return self(); + } + + public B lastQueryNode(final String lastQueryNode) { + this.lastQueryNode = lastQueryNode; + return self(); + } + } +} diff --git a/stroom-core-shared/src/main/java/stroom/dashboard/shared/ComponentSettings.java b/stroom-core-shared/src/main/java/stroom/dashboard/shared/ComponentSettings.java index cd5bb0eb92c..9284dfa540e 100644 --- a/stroom-core-shared/src/main/java/stroom/dashboard/shared/ComponentSettings.java +++ b/stroom-core-shared/src/main/java/stroom/dashboard/shared/ComponentSettings.java @@ -37,11 +37,12 @@ }) @JsonInclude(Include.NON_NULL) public interface ComponentSettings { + AbstractBuilder copy(); - Builder copy(); + abstract class AbstractBuilder> { - interface Builder { + protected abstract B self(); - ComponentSettings build(); + public abstract T build(); } } diff --git a/stroom-core-shared/src/main/java/stroom/dashboard/shared/EmbeddedQueryComponentSettings.java b/stroom-core-shared/src/main/java/stroom/dashboard/shared/EmbeddedQueryComponentSettings.java index 4a32b607a71..aab06ee527e 100644 --- a/stroom-core-shared/src/main/java/stroom/dashboard/shared/EmbeddedQueryComponentSettings.java +++ b/stroom-core-shared/src/main/java/stroom/dashboard/shared/EmbeddedQueryComponentSettings.java @@ -26,7 +26,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -38,18 +37,10 @@ "lastQueryNode" }) @JsonInclude(Include.NON_NULL) -public class EmbeddedQueryComponentSettings implements ComponentSettings { +public class EmbeddedQueryComponentSettings extends AbstractQueryComponentSettings { @JsonProperty private final DocRef queryRef; - @JsonProperty - private final Automate automate; - @JsonProperty - private final List selectionHandlers; - @JsonProperty - private final QueryKey lastQueryKey; - @JsonProperty - private final String lastQueryNode; @SuppressWarnings("checkstyle:LineLength") @JsonCreator @@ -58,33 +49,14 @@ public EmbeddedQueryComponentSettings(@JsonProperty("queryRef") final DocRef que @JsonProperty("selectionHandlers") final List selectionHandlers, @JsonProperty("lastQueryKey") final QueryKey lastQueryKey, @JsonProperty("lastQueryNode") final String lastQueryNode) { + super(automate, selectionHandlers, lastQueryKey, lastQueryNode); this.queryRef = queryRef; - this.automate = automate; - this.selectionHandlers = selectionHandlers; - this.lastQueryKey = lastQueryKey; - this.lastQueryNode = lastQueryNode; } public DocRef getQueryRef() { return queryRef; } - public Automate getAutomate() { - return automate; - } - - public List getSelectionHandlers() { - return selectionHandlers; - } - - public QueryKey getLastQueryKey() { - return lastQueryKey; - } - - public String getLastQueryNode() { - return lastQueryNode; - } - @Override public boolean equals(final Object o) { if (this == o) { @@ -93,28 +65,16 @@ public boolean equals(final Object o) { if (o == null || getClass() != o.getClass()) { return false; } + if (!super.equals(o)) { + return false; + } final EmbeddedQueryComponentSettings that = (EmbeddedQueryComponentSettings) o; - return Objects.equals(queryRef, that.queryRef) && - Objects.equals(automate, that.automate) && - Objects.equals(selectionHandlers, that.selectionHandlers) && - Objects.equals(lastQueryKey, that.lastQueryKey) && - Objects.equals(lastQueryNode, that.lastQueryNode); + return Objects.equals(queryRef, that.queryRef); } @Override public int hashCode() { - return Objects.hash(queryRef, automate, selectionHandlers, lastQueryKey, lastQueryNode); - } - - @Override - public String toString() { - return "EmbeddedQueryComponentSettings{" + - "queryRef=" + queryRef + - ", automate=" + automate + - ", selectionHandlers=" + selectionHandlers + - ", lastQueryKey=" + lastQueryKey + - ", lastQueryNode='" + lastQueryNode + '\'' + - '}'; + return Objects.hash(super.hashCode(), queryRef); } public static Builder builder() { @@ -129,60 +89,27 @@ public Builder copy() { /** * Builder for constructing a {@link TableSettings tableSettings} */ - public static final class Builder implements ComponentSettings.Builder { + public static final class Builder + extends AbstractBuilder { private DocRef queryRef; - private Automate automate; - private List selectionHandlers; - private QueryKey lastQueryKey; - private String lastQueryNode; private Builder() { + super(); } private Builder(final EmbeddedQueryComponentSettings settings) { + super(settings); this.queryRef = settings.queryRef; - this.automate = settings.automate == null - ? null - : settings.automate.copy().build(); - this.selectionHandlers = settings.selectionHandlers == null - ? null - : new ArrayList<>(settings.selectionHandlers); - this.lastQueryKey = settings.lastQueryKey; - this.lastQueryNode = settings.lastQueryNode; } public Builder queryRef(final DocRef queryRef) { this.queryRef = queryRef; - return this; - } - - - public Builder automate(final Automate automate) { - this.automate = automate; - return this; - } - - public Builder selectionHandlers(final List selectionHandlers) { - this.selectionHandlers = selectionHandlers; - return this; - } - - public Builder addSelectionHandler(final ComponentSelectionHandler selectionHandler) { - if (this.selectionHandlers == null) { - this.selectionHandlers = new ArrayList<>(); - } - this.selectionHandlers.add(selectionHandler); - return this; + return self(); } - public Builder lastQueryKey(final QueryKey lastQueryKey) { - this.lastQueryKey = lastQueryKey; - return this; - } - - public Builder lastQueryNode(final String lastQueryNode) { - this.lastQueryNode = lastQueryNode; + @Override + protected Builder self() { return this; } diff --git a/stroom-core-shared/src/main/java/stroom/dashboard/shared/KeyValueInputComponentSettings.java b/stroom-core-shared/src/main/java/stroom/dashboard/shared/KeyValueInputComponentSettings.java index c607d09a7e9..bc7f49d8407 100644 --- a/stroom-core-shared/src/main/java/stroom/dashboard/shared/KeyValueInputComponentSettings.java +++ b/stroom-core-shared/src/main/java/stroom/dashboard/shared/KeyValueInputComponentSettings.java @@ -73,7 +73,8 @@ public Builder copy() { return new Builder(this); } - public static final class Builder implements ComponentSettings.Builder { + public static final class Builder extends ComponentSettings + .AbstractBuilder { private String text; @@ -86,6 +87,11 @@ private Builder(final KeyValueInputComponentSettings keyValueInputComponentSetti public Builder text(final String text) { this.text = text; + return self(); + } + + @Override + protected Builder self() { return this; } diff --git a/stroom-core-shared/src/main/java/stroom/dashboard/shared/ListInputComponentSettings.java b/stroom-core-shared/src/main/java/stroom/dashboard/shared/ListInputComponentSettings.java index 4ec36c423e1..a8d6b089d9b 100644 --- a/stroom-core-shared/src/main/java/stroom/dashboard/shared/ListInputComponentSettings.java +++ b/stroom-core-shared/src/main/java/stroom/dashboard/shared/ListInputComponentSettings.java @@ -134,7 +134,8 @@ public Builder copy() { return new Builder(this); } - public static final class Builder implements ComponentSettings.Builder { + public static final class Builder extends ComponentSettings + .AbstractBuilder { private String key; private String value; @@ -159,31 +160,36 @@ private Builder(final ListInputComponentSettings listInputComponentSettings) { public Builder key(final String key) { this.key = key; - return this; + return self(); } public Builder value(final String value) { this.value = value; - return this; + return self(); } public Builder values(final List values) { this.values = values; - return this; + return self(); } public Builder dictionary(final DocRef dictionary) { this.dictionary = dictionary; - return this; + return self(); } public Builder useDictionary(final boolean useDictionary) { this.useDictionary = useDictionary; - return this; + return self(); } public Builder allowTextEntry(final boolean allowTextEntry) { this.allowTextEntry = allowTextEntry; + return self(); + } + + @Override + protected Builder self() { return this; } diff --git a/stroom-core-shared/src/main/java/stroom/dashboard/shared/QueryComponentSettings.java b/stroom-core-shared/src/main/java/stroom/dashboard/shared/QueryComponentSettings.java index cd749c78e05..979983e15ae 100644 --- a/stroom-core-shared/src/main/java/stroom/dashboard/shared/QueryComponentSettings.java +++ b/stroom-core-shared/src/main/java/stroom/dashboard/shared/QueryComponentSettings.java @@ -26,7 +26,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -39,21 +38,12 @@ "lastQueryNode" }) @JsonInclude(Include.NON_NULL) -public class QueryComponentSettings implements ComponentSettings { +public class QueryComponentSettings extends AbstractQueryComponentSettings { @JsonProperty("dataSource") private final DocRef dataSource; @JsonProperty("expression") private final ExpressionOperator expression; - @JsonProperty("automate") - private final Automate automate; - @JsonProperty("selectionHandlers") - private final List selectionHandlers; - @JsonProperty("lastQueryKey") - private final QueryKey lastQueryKey; - @JsonProperty("lastQueryNode") - private final String lastQueryNode; - @SuppressWarnings("checkstyle:LineLength") @JsonCreator @@ -63,12 +53,9 @@ public QueryComponentSettings(@JsonProperty("dataSource") final DocRef dataSourc @JsonProperty("selectionHandlers") final List selectionHandlers, @JsonProperty("lastQueryKey") final QueryKey lastQueryKey, @JsonProperty("lastQueryNode") final String lastQueryNode) { + super(automate, selectionHandlers, lastQueryKey, lastQueryNode); this.dataSource = dataSource; this.expression = expression; - this.automate = automate; - this.selectionHandlers = selectionHandlers; - this.lastQueryKey = lastQueryKey; - this.lastQueryNode = lastQueryNode; } public DocRef getDataSource() { @@ -79,22 +66,6 @@ public ExpressionOperator getExpression() { return expression; } - public Automate getAutomate() { - return automate; - } - - public List getSelectionHandlers() { - return selectionHandlers; - } - - public QueryKey getLastQueryKey() { - return lastQueryKey; - } - - public String getLastQueryNode() { - return lastQueryNode; - } - @Override public boolean equals(final Object o) { if (this == o) { @@ -103,18 +74,17 @@ public boolean equals(final Object o) { if (o == null || getClass() != o.getClass()) { return false; } + if (!super.equals(o)) { + return false; + } final QueryComponentSettings that = (QueryComponentSettings) o; - return Objects.equals(dataSource, that.dataSource) && - Objects.equals(expression, that.expression) && - Objects.equals(automate, that.automate) && - Objects.equals(selectionHandlers, that.selectionHandlers) && - Objects.equals(lastQueryKey, that.lastQueryKey) && - Objects.equals(lastQueryNode, that.lastQueryNode); + return Objects.equals(dataSource, that.dataSource) && Objects.equals(expression, + that.expression); } @Override public int hashCode() { - return Objects.hash(dataSource, expression, automate, selectionHandlers, lastQueryKey, lastQueryNode); + return Objects.hash(super.hashCode(), dataSource, expression); } @Override @@ -122,14 +92,9 @@ public String toString() { return "QueryComponentSettings{" + "dataSource=" + dataSource + ", expression=" + expression + - ", automate=" + automate + - ", selectionHandlers=" + selectionHandlers + - ", lastQueryKey=" + lastQueryKey + - ", lastQueryNode='" + lastQueryNode + '\'' + '}'; } - public static Builder builder() { return new Builder(); } @@ -139,68 +104,35 @@ public Builder copy() { return new Builder(this); } - public static final class Builder implements ComponentSettings.Builder { + public static final class Builder + extends AbstractBuilder { private DocRef dataSource; private ExpressionOperator expression; - private Automate automate; - private List selectionHandlers; - private QueryKey lastQueryKey; - private String lastQueryNode; private Builder() { } private Builder(final QueryComponentSettings queryComponentSettings) { + super(queryComponentSettings); this.dataSource = queryComponentSettings.dataSource; this.expression = queryComponentSettings.expression == null ? null : queryComponentSettings.expression.copy().build(); - this.automate = queryComponentSettings.automate == null - ? null - : queryComponentSettings.automate.copy().build(); - this.selectionHandlers = queryComponentSettings.selectionHandlers == null - ? null - : new ArrayList<>(queryComponentSettings.selectionHandlers); - this.lastQueryKey = queryComponentSettings.lastQueryKey; - this.lastQueryNode = queryComponentSettings.lastQueryNode; } public Builder dataSource(final DocRef dataSource) { this.dataSource = dataSource; - return this; + return self(); } public Builder expression(final ExpressionOperator expression) { this.expression = expression; - return this; - } - - public Builder automate(final Automate automate) { - this.automate = automate; - return this; - } - - public Builder selectionHandlers(final List selectionHandlers) { - this.selectionHandlers = selectionHandlers; - return this; + return self(); } - public Builder addSelectionHandler(final ComponentSelectionHandler selectionHandler) { - if (this.selectionHandlers == null) { - this.selectionHandlers = new ArrayList<>(); - } - this.selectionHandlers.add(selectionHandler); - return this; - } - - public Builder lastQueryKey(final QueryKey lastQueryKey) { - this.lastQueryKey = lastQueryKey; - return this; - } - - public Builder lastQueryNode(final String lastQueryNode) { - this.lastQueryNode = lastQueryNode; + @Override + protected Builder self() { return this; } diff --git a/stroom-core-shared/src/main/java/stroom/dashboard/shared/TableComponentSettings.java b/stroom-core-shared/src/main/java/stroom/dashboard/shared/TableComponentSettings.java index cb826d0a6c6..e2a56f2f50d 100644 --- a/stroom-core-shared/src/main/java/stroom/dashboard/shared/TableComponentSettings.java +++ b/stroom-core-shared/src/main/java/stroom/dashboard/shared/TableComponentSettings.java @@ -266,7 +266,8 @@ public Builder copy() { /** * Builder for constructing a {@link TableSettings tableSettings} */ - public static final class Builder implements ComponentSettings.Builder { + public static final class Builder extends ComponentSettings + .AbstractBuilder { private String queryId; private DocRef dataSourceRef; @@ -309,17 +310,17 @@ private Builder(final TableComponentSettings tableSettings) { */ public Builder queryId(final String value) { this.queryId = value; - return this; + return self(); } public Builder dataSourceRef(final DocRef dataSourceRef) { this.dataSourceRef = dataSourceRef; - return this; + return self(); } public Builder columns(final List columns) { this.columns = columns; - return this; + return self(); } /** @@ -342,7 +343,7 @@ public Builder addColumn(final Collection values) { } else { this.columns.addAll(values); } - return this; + return self(); } /** @@ -355,7 +356,7 @@ public Builder extractValues(final Boolean value) { } else { this.extractValues = Boolean.FALSE; } - return this; + return self(); } public Builder useDefaultExtractionPipeline(final Boolean value) { @@ -364,7 +365,7 @@ public Builder useDefaultExtractionPipeline(final Boolean value) { } else { this.useDefaultExtractionPipeline = Boolean.TRUE; } - return this; + return self(); } @@ -374,7 +375,7 @@ public Builder useDefaultExtractionPipeline(final Boolean value) { */ public Builder extractionPipeline(final DocRef value) { this.extractionPipeline = value; - return this; + return self(); } /** @@ -388,17 +389,17 @@ public Builder extractionPipeline(final DocRef value) { public Builder extractionPipeline(final String type, final String uuid, final String name) { - return this.extractionPipeline(DocRef.builder().type(type).uuid(uuid).name(name).build()); + return self().extractionPipeline(DocRef.builder().type(type).uuid(uuid).name(name).build()); } public Builder maxResults(final List maxResults) { this.maxResults = maxResults; - return this; + return self(); } public Builder pageSize(final Integer pageSize) { this.pageSize = pageSize; - return this; + return self(); } /** @@ -409,16 +410,21 @@ public Builder pageSize(final Integer pageSize) { */ public Builder showDetail(final Boolean value) { this.showDetail = value; - return this; + return self(); } public Builder conditionalFormattingRules(final List conditionalFormattingRules) { this.conditionalFormattingRules = conditionalFormattingRules; - return this; + return self(); } public Builder modelVersion(final String modelVersion) { this.modelVersion = modelVersion; + return self(); + } + + @Override + protected Builder self() { return this; } diff --git a/stroom-core-shared/src/main/java/stroom/dashboard/shared/TextComponentSettings.java b/stroom-core-shared/src/main/java/stroom/dashboard/shared/TextComponentSettings.java index d756d134572..89236a9e7dc 100644 --- a/stroom-core-shared/src/main/java/stroom/dashboard/shared/TextComponentSettings.java +++ b/stroom-core-shared/src/main/java/stroom/dashboard/shared/TextComponentSettings.java @@ -253,7 +253,8 @@ public Builder copy() { return new Builder(this); } - public static final class Builder implements ComponentSettings.Builder { + public static final class Builder extends ComponentSettings + .AbstractBuilder { private String tableId; private ColumnRef streamIdField; @@ -288,61 +289,66 @@ private Builder(final TextComponentSettings textComponentSettings) { public Builder tableId(final String tableId) { this.tableId = tableId; - return this; + return self(); } public Builder streamIdField(final ColumnRef streamIdField) { this.streamIdField = streamIdField; - return this; + return self(); } public Builder partNoField(final ColumnRef partNoField) { this.partNoField = partNoField; - return this; + return self(); } public Builder recordNoField(final ColumnRef recordNoField) { this.recordNoField = recordNoField; - return this; + return self(); } public Builder lineFromField(final ColumnRef lineFromField) { this.lineFromField = lineFromField; - return this; + return self(); } public Builder colFromField(final ColumnRef colFromField) { this.colFromField = colFromField; - return this; + return self(); } public Builder lineToField(final ColumnRef lineToField) { this.lineToField = lineToField; - return this; + return self(); } public Builder colToField(final ColumnRef colToField) { this.colToField = colToField; - return this; + return self(); } public Builder pipeline(final DocRef pipeline) { this.pipeline = pipeline; - return this; + return self(); } public Builder showAsHtml(final boolean showAsHtml) { this.showAsHtml = showAsHtml; - return this; + return self(); } public Builder showStepping(final boolean showStepping) { this.showStepping = showStepping; - return this; + return self(); } public Builder modelVersion(final String modelVersion) { this.modelVersion = modelVersion; + return self(); + } + + @Override + protected Builder self() { return this; } diff --git a/stroom-core-shared/src/main/java/stroom/dashboard/shared/TextInputComponentSettings.java b/stroom-core-shared/src/main/java/stroom/dashboard/shared/TextInputComponentSettings.java index 6638c18d68f..170b1a09e5a 100644 --- a/stroom-core-shared/src/main/java/stroom/dashboard/shared/TextInputComponentSettings.java +++ b/stroom-core-shared/src/main/java/stroom/dashboard/shared/TextInputComponentSettings.java @@ -86,7 +86,8 @@ public Builder copy() { return new Builder(this); } - public static final class Builder implements ComponentSettings.Builder { + public static final class Builder extends ComponentSettings + .AbstractBuilder { private String key; private String value; @@ -101,11 +102,16 @@ private Builder(final TextInputComponentSettings keyValueInputComponentSettings) public Builder key(final String key) { this.key = key; - return this; + return self(); } public Builder value(final String value) { this.value = value; + return self(); + } + + @Override + protected Builder self() { return this; } diff --git a/stroom-core-shared/src/main/java/stroom/dashboard/shared/VisComponentSettings.java b/stroom-core-shared/src/main/java/stroom/dashboard/shared/VisComponentSettings.java index cbf04d8e0e5..177b00a471e 100644 --- a/stroom-core-shared/src/main/java/stroom/dashboard/shared/VisComponentSettings.java +++ b/stroom-core-shared/src/main/java/stroom/dashboard/shared/VisComponentSettings.java @@ -105,7 +105,8 @@ public Builder copy() { return new Builder(this); } - public static final class Builder implements ComponentSettings.Builder { + public static final class Builder extends ComponentSettings + .AbstractBuilder { private String tableId; private DocRef visualisation; @@ -126,21 +127,26 @@ private Builder(final VisComponentSettings visComponentSettings) { public Builder tableId(final String tableId) { this.tableId = tableId; - return this; + return self(); } public Builder visualisation(final DocRef visualisation) { this.visualisation = visualisation; - return this; + return self(); } public Builder json(final String json) { this.json = json; - return this; + return self(); } public Builder tableSettings(final TableComponentSettings tableSettings) { this.tableSettings = tableSettings; + return self(); + } + + @Override + protected Builder self() { return this; } diff --git a/stroom-core-shared/src/main/java/stroom/query/shared/QueryContext.java b/stroom-core-shared/src/main/java/stroom/query/shared/QueryContext.java index e0185b0b78c..7e4ec02d2c5 100644 --- a/stroom-core-shared/src/main/java/stroom/query/shared/QueryContext.java +++ b/stroom-core-shared/src/main/java/stroom/query/shared/QueryContext.java @@ -10,6 +10,7 @@ package stroom.query.shared; import stroom.expression.api.DateTimeSettings; +import stroom.query.api.v2.ExpressionOperator; import stroom.query.api.v2.Param; import stroom.query.api.v2.TimeRange; @@ -34,16 +35,21 @@ public class QueryContext { private final String queryInfo; @JsonProperty private final DateTimeSettings dateTimeSettings; + @JsonProperty + private final ExpressionOperator additionalQueryExpression; + @SuppressWarnings("checkstyle:LineLength") @JsonCreator public QueryContext(@JsonProperty("params") final List params, @JsonProperty("timeRange") final TimeRange timeRange, @JsonProperty("queryInfo") final String queryInfo, - @JsonProperty("dateTimeSettings") final DateTimeSettings dateTimeSettings) { + @JsonProperty("dateTimeSettings") final DateTimeSettings dateTimeSettings, + @JsonProperty("additionalQueryExpression") final ExpressionOperator additionalQueryExpression) { this.params = params; this.timeRange = timeRange; this.queryInfo = queryInfo; this.dateTimeSettings = dateTimeSettings; + this.additionalQueryExpression = additionalQueryExpression; } public List getParams() { @@ -62,6 +68,10 @@ public DateTimeSettings getDateTimeSettings() { return dateTimeSettings; } + public ExpressionOperator getAdditionalQueryExpression() { + return additionalQueryExpression; + } + @Override public boolean equals(final Object o) { if (this == o) { @@ -74,12 +84,13 @@ public boolean equals(final Object o) { return Objects.equals(params, that.params) && Objects.equals(timeRange, that.timeRange) && Objects.equals(queryInfo, that.queryInfo) && - Objects.equals(dateTimeSettings, that.dateTimeSettings); + Objects.equals(dateTimeSettings, that.dateTimeSettings) && + Objects.equals(additionalQueryExpression, that.additionalQueryExpression); } @Override public int hashCode() { - return Objects.hash(params, timeRange, queryInfo, dateTimeSettings); + return Objects.hash(params, timeRange, queryInfo, dateTimeSettings, additionalQueryExpression); } @Override @@ -89,6 +100,7 @@ public String toString() { ", timeRange=" + timeRange + ", queryInfo='" + queryInfo + '\'' + ", dateTimeSettings=" + dateTimeSettings + + ", currentSelectionExpression=" + additionalQueryExpression + '}'; } @@ -106,6 +118,7 @@ public static final class Builder { private TimeRange timeRange; private String queryInfo; private DateTimeSettings dateTimeSettings; + private ExpressionOperator additionalQueryExpression; private Builder() { } @@ -115,6 +128,7 @@ private Builder(final QueryContext queryContext) { this.timeRange = queryContext.timeRange; this.queryInfo = queryContext.queryInfo; this.dateTimeSettings = queryContext.dateTimeSettings; + this.additionalQueryExpression = queryContext.additionalQueryExpression; } public Builder params(final List params) { @@ -137,12 +151,18 @@ public Builder dateTimeSettings(final DateTimeSettings dateTimeSettings) { return this; } + public Builder additionalQueryExpression(final ExpressionOperator additionalQueryExpression) { + this.additionalQueryExpression = additionalQueryExpression; + return this; + } + public QueryContext build() { return new QueryContext( params, timeRange, queryInfo, - dateTimeSettings); + dateTimeSettings, + additionalQueryExpression); } } } diff --git a/stroom-core-shared/src/main/java/stroom/query/shared/QueryResource.java b/stroom-core-shared/src/main/java/stroom/query/shared/QueryResource.java index b8f412a2164..1e6088b4390 100644 --- a/stroom-core-shared/src/main/java/stroom/query/shared/QueryResource.java +++ b/stroom-core-shared/src/main/java/stroom/query/shared/QueryResource.java @@ -18,6 +18,7 @@ import stroom.dashboard.shared.DashboardSearchResponse; import stroom.dashboard.shared.ValidateExpressionResult; +import stroom.docref.DocRef; import stroom.util.shared.FetchWithUuid; import stroom.util.shared.ResourceGeneration; import stroom.util.shared.ResourcePaths; @@ -140,4 +141,11 @@ ResultPage fetchQueryHelpItems( summary = "Fetch detail for help item", operationId = "fetchDetail") QueryHelpDetail fetchDetail(QueryHelpRow row); + + @POST + @Path("/fetchQueryDataSource") + @Operation( + summary = "Fetch the datasource referenced by a query", + operationId = "fetchQueryDataSource") + DocRef fetchQueryDataSource(DocRef queryDocRef); } diff --git a/stroom-query/stroom-query-api/src/main/java/stroom/query/api/v2/ExpressionUtil.java b/stroom-query/stroom-query-api/src/main/java/stroom/query/api/v2/ExpressionUtil.java index f7ea702a9c9..7339409b27b 100644 --- a/stroom-query/stroom-query-api/src/main/java/stroom/query/api/v2/ExpressionUtil.java +++ b/stroom-query/stroom-query-api/src/main/java/stroom/query/api/v2/ExpressionUtil.java @@ -365,6 +365,21 @@ private static ExpressionItem simplifyExpressionItem(final ExpressionItem item) return item; } + public static ExpressionOperator combine(final ExpressionOperator in, + final ExpressionOperator decoration) { + if (in == null) { + return decoration; + } else if (decoration == null) { + return in; + } + + return ExpressionOperator + .builder() + .addOperator(in) + .addOperator(decoration) + .build(); + } + public interface ExpressionItemVisitor { /** diff --git a/stroom-query/stroom-query-impl/src/main/java/stroom/query/impl/QueryResourceImpl.java b/stroom-query/stroom-query-impl/src/main/java/stroom/query/impl/QueryResourceImpl.java index ebbdcbeed13..09ad42764b1 100644 --- a/stroom-query/stroom-query-impl/src/main/java/stroom/query/impl/QueryResourceImpl.java +++ b/stroom-query/stroom-query-impl/src/main/java/stroom/query/impl/QueryResourceImpl.java @@ -88,6 +88,18 @@ public QueryDoc fetch(final String uuid) { return queryServiceProvider.get().read(getDocRef(uuid)); } + @Override + public DocRef fetchQueryDataSource(final DocRef queryDocRef) { + final QueryDoc doc = queryServiceProvider.get().read(queryDocRef); + try { + final Optional optional = queryServiceProvider.get().getReferencedDataSource(doc.getQuery()); + return optional.orElse(null); + } catch (final RuntimeException e) { + LOGGER.debug(e::getMessage, e); + } + return null; + } + @Override public QueryDoc update(final String uuid, final QueryDoc doc) { if (doc.getUuid() == null || !doc.getUuid().equals(uuid)) { diff --git a/stroom-query/stroom-query-impl/src/main/java/stroom/query/impl/QueryServiceImpl.java b/stroom-query/stroom-query-impl/src/main/java/stroom/query/impl/QueryServiceImpl.java index 3e403ab41cf..11257f26a49 100644 --- a/stroom-query/stroom-query-impl/src/main/java/stroom/query/impl/QueryServiceImpl.java +++ b/stroom-query/stroom-query-impl/src/main/java/stroom/query/impl/QueryServiceImpl.java @@ -32,6 +32,8 @@ import stroom.expression.api.DateTimeSettings; import stroom.node.api.NodeInfo; import stroom.query.api.v2.Column; +import stroom.query.api.v2.ExpressionOperator; +import stroom.query.api.v2.ExpressionUtil; import stroom.query.api.v2.Param; import stroom.query.api.v2.Query; import stroom.query.api.v2.QueryKey; @@ -415,6 +417,20 @@ private SearchRequest mapRequest(final QuerySearchRequest searchRequest) { final ExpressionContext expressionContext = expressionContextFactory.createContext(sampleRequest); SearchRequest mappedRequest = searchRequestFactory.create(query, sampleRequest, expressionContext); + // Mutate expression with selection expression. + Query qry = mappedRequest.getQuery(); + ExpressionOperator expression = qry.getExpression(); + expression = ExpressionUtil.combine( + expression, + NullSafe.get(queryContext, QueryContext::getAdditionalQueryExpression)); + mappedRequest = mappedRequest + .copy() + .query(qry + .copy() + .expression(expression) + .build()) + .build(); + // Fix table result requests. final List resultRequests = mappedRequest.getResultRequests(); if (resultRequests != null) { diff --git a/stroom-query/stroom-query-impl/src/main/java/stroom/query/impl/datasource/DataSourceResourceImpl.java b/stroom-query/stroom-query-impl/src/main/java/stroom/query/impl/datasource/DataSourceResourceImpl.java index 62ba50f1513..7697b461384 100644 --- a/stroom-query/stroom-query-impl/src/main/java/stroom/query/impl/datasource/DataSourceResourceImpl.java +++ b/stroom-query/stroom-query-impl/src/main/java/stroom/query/impl/datasource/DataSourceResourceImpl.java @@ -23,6 +23,8 @@ import stroom.docstore.shared.Documentation; import stroom.event.logging.rs.api.AutoLogged; import stroom.query.impl.QueryService; +import stroom.util.logging.LambdaLogger; +import stroom.util.logging.LambdaLoggerFactory; import stroom.util.shared.ResultPage; import jakarta.inject.Inject; @@ -31,6 +33,8 @@ @AutoLogged class DataSourceResourceImpl implements DataSourceResource { + private static final LambdaLogger LOGGER = LambdaLoggerFactory.getLogger(DataSourceResourceImpl.class); + private final Provider queryServiceProvider; @Inject @@ -50,6 +54,11 @@ public Documentation fetchDocumentation(final DocRef dataSourceRef) { @Override public DocRef fetchDefaultExtractionPipeline(final DocRef dataSourceRef) { - return queryServiceProvider.get().fetchDefaultExtractionPipeline(dataSourceRef); + try { + return queryServiceProvider.get().fetchDefaultExtractionPipeline(dataSourceRef); + } catch (final RuntimeException e) { + LOGGER.debug(e::getMessage, e); + } + return null; } }