diff --git a/pom.xml b/pom.xml index a150ab144..5e650074f 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ 2.8.2 - 2.5.0-RC-2 + 2.6.0-SNAPSHOT 3.0.2 2.27 diff --git a/src/main/java/com/databasepreservation/main/common/client/BrowserService.java b/src/main/java/com/databasepreservation/main/common/client/BrowserService.java index a3cd86590..daf2dc18e 100644 --- a/src/main/java/com/databasepreservation/main/common/client/BrowserService.java +++ b/src/main/java/com/databasepreservation/main/common/client/BrowserService.java @@ -129,6 +129,8 @@ ViewerDatabase uploadSIARDStatus(String databaseUUID) boolean testConnection(String databaseUUID, ConnectionParameters parameters) throws GenericException; + List> validateCustomViewQuery(String databaseUUID, ConnectionParameters parameters, String query) throws GenericException; + boolean createSIARD(String UUID, ConnectionParameters connectionParameters, TableAndColumnsParameters tableAndColumnsParameters, CustomViewsParameters customViewsParameters, ExportOptionsParameters exportOptionsParameters, MetadataExportOptionsParameters metadataExportOptionsParameters) diff --git a/src/main/java/com/databasepreservation/main/common/client/BrowserServiceAsync.java b/src/main/java/com/databasepreservation/main/common/client/BrowserServiceAsync.java index d191753d4..424a3a7a5 100644 --- a/src/main/java/com/databasepreservation/main/common/client/BrowserServiceAsync.java +++ b/src/main/java/com/databasepreservation/main/common/client/BrowserServiceAsync.java @@ -132,6 +132,8 @@ void editSearch(String databaseUUID, String savedSearchUUID, String name, String void testConnection(String databaseUUID, ConnectionParameters parameters, AsyncCallback async); + void validateCustomViewQuery(String databaseUUID, ConnectionParameters parameters, String query, AsyncCallback>> async); + void createSIARD(String UUID, ConnectionParameters connectionParameters, TableAndColumnsParameters tableAndColumnsParameters, CustomViewsParameters customViewsParameters, ExportOptionsParameters exportOptionsParameters, MetadataExportOptionsParameters metadataExportOptionsParameters, AsyncCallback async); diff --git a/src/main/java/com/databasepreservation/main/common/server/BrowserServiceImpl.java b/src/main/java/com/databasepreservation/main/common/server/BrowserServiceImpl.java index 69a12ca9f..e6b88c42f 100644 --- a/src/main/java/com/databasepreservation/main/common/server/BrowserServiceImpl.java +++ b/src/main/java/com/databasepreservation/main/common/server/BrowserServiceImpl.java @@ -284,6 +284,11 @@ public boolean testConnection(String databaseUUID, ConnectionParameters paramete return SIARDController.testConnection(databaseUUID, parameters); } + @Override + public List> validateCustomViewQuery(String databaseUUID, ConnectionParameters parameters, String query) throws GenericException { + return SIARDController.validateCustomViewQuery(databaseUUID, parameters, query); + } + @Override public boolean createSIARD(String UUID, ConnectionParameters connectionParameters, TableAndColumnsParameters tableAndColumnsParameters, CustomViewsParameters customViewsParameters, diff --git a/src/main/java/com/databasepreservation/main/common/server/controller/SIARDController.java b/src/main/java/com/databasepreservation/main/common/server/controller/SIARDController.java index bb53d4c72..90eec7c89 100644 --- a/src/main/java/com/databasepreservation/main/common/server/controller/SIARDController.java +++ b/src/main/java/com/databasepreservation/main/common/server/controller/SIARDController.java @@ -19,6 +19,8 @@ import java.util.Map; import java.util.Set; +import com.google.gwt.core.client.GWT; +import config.i18n.client.ClientMessages; import org.apache.commons.io.IOUtils; import org.roda.core.data.exceptions.GenericException; import org.roda.core.data.exceptions.NotFoundException; @@ -41,6 +43,7 @@ import com.databasepreservation.main.common.shared.ViewerStructure.ViewerDatabaseFromToolkit; import com.databasepreservation.main.common.shared.ViewerStructure.ViewerMetadata; import com.databasepreservation.main.common.shared.ViewerStructure.ViewerSIARDBundle; +import com.databasepreservation.main.common.shared.exceptions.ViewerException; import com.databasepreservation.main.desktop.shared.models.DBPTKModule; import com.databasepreservation.main.desktop.shared.models.ExternalLobDBPTK; import com.databasepreservation.main.desktop.shared.models.PreservationParameter; @@ -90,6 +93,32 @@ public static String getReportFileContents(String databaseUUID) throws NotFoundE return result; } + public static List> validateCustomViewQuery(String databaseUUID, ConnectionParameters parameters, String query) + throws GenericException { + Reporter reporter = getReporter(databaseUUID); + List> results = new ArrayList<>(); + final DatabaseMigration databaseMigration = initializeDatabaseMigration(reporter); + + setupJDBCConnection(databaseMigration, parameters); + + try { + DatabaseImportModule importModule = databaseMigration.getImportModule(); + importModule.setOnceReporter(reporter); + if (importModule instanceof JDBCImportModule) { + JDBCImportModule jdbcImportModule = (JDBCImportModule) importModule; + try { + results = jdbcImportModule.testCustomViewQuery(query); + } catch (ModuleException e) { + throw new GenericException(e.getMessage()); + } + } + } catch (ModuleException e) { + throw new GenericException(e.getMessage()); + } + + return results; + } + public static boolean testConnection(String databaseUUID, ConnectionParameters parameters) throws GenericException { Reporter reporter = getReporter(databaseUUID); @@ -268,21 +297,30 @@ public static ViewerMetadata getDatabaseMetadata(String databaseUUID, Connection final Reporter reporter = getReporter(databaseUUID); final DatabaseMigration databaseMigration = initializeDatabaseMigration(reporter); setupJDBCConnection(databaseMigration, parameters); + + DatabaseImportModule importModule; + DatabaseStructure schemaInformation = null; try { - DatabaseImportModule importModule = databaseMigration.getImportModule(); + importModule = databaseMigration.getImportModule(); importModule.setOnceReporter(reporter); if (importModule instanceof JDBCImportModule) { JDBCImportModule jdbcImportModule = (JDBCImportModule) importModule; - DatabaseStructure schemaInformation = jdbcImportModule.getSchemaInformation(); + schemaInformation = jdbcImportModule.getSchemaInformation(); jdbcImportModule.closeConnection(); - ViewerDatabaseFromToolkit database = ToolkitStructure2ViewerStructure.getDatabase(schemaInformation); - return database.getMetadata(); } - } catch (ModuleException e) { throw new GenericException(e.getMessage()); } + ViewerDatabaseFromToolkit database = null; + try { + database = ToolkitStructure2ViewerStructure.getDatabase(schemaInformation); + } catch (ViewerException e) { + LOGGER.debug(e.getMessage()); + } + + if (database != null) + return database.getMetadata(); return null; } @@ -360,7 +398,7 @@ public static String loadMetadataFromLocal(String databaseUUID, String localPath } private static void convertSIARDMetadataToSolr(Path siardPath, String databaseUUID) throws GenericException { - LOGGER.info("starting to import metadata database " + siardPath.toAbsolutePath().toString()); + LOGGER.info("starting to import metadata from " + siardPath.toAbsolutePath().toString()); Path reporterPath = ViewerConfiguration.getInstance().getReportPath(databaseUUID).toAbsolutePath(); try (Reporter reporter = new Reporter(reporterPath.getParent().toString(), reporterPath.getFileName().toString())) { @@ -730,7 +768,7 @@ private static String constructCustomViews(CustomViewsParameters customViewsPara outputStream.close(); } } catch (IOException e) { - throw new GenericException("Could not close the custom views temporary file", e); + // DO NOTHING } } } @@ -739,7 +777,6 @@ private static String constructCustomViews(CustomViewsParameters customViewsPara * For Java 8 or below: check * http://robertmaldon.blogspot.com/2007/11/dynamically-add-to-eclipse-junit.html * (last access: 22-07-2019) - * */ private static void addURL(URL url) throws Exception { URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader(); diff --git a/src/main/java/com/databasepreservation/main/common/shared/client/common/dialogs/Dialogs.java b/src/main/java/com/databasepreservation/main/common/shared/client/common/dialogs/Dialogs.java index c77aa9c22..df4d710e3 100644 --- a/src/main/java/com/databasepreservation/main/common/shared/client/common/dialogs/Dialogs.java +++ b/src/main/java/com/databasepreservation/main/common/shared/client/common/dialogs/Dialogs.java @@ -7,7 +7,12 @@ */ package com.databasepreservation.main.common.shared.client.common.dialogs; +import java.util.ArrayList; +import java.util.List; + import com.databasepreservation.main.common.shared.client.common.NoAsyncCallback; +import com.databasepreservation.main.common.shared.client.common.lists.IndexedColumn; +import com.databasepreservation.main.common.shared.client.widgets.MyCellTableResources; import com.databasepreservation.main.desktop.client.common.ComboBoxField; import com.databasepreservation.main.desktop.client.common.FileUploadField; import com.databasepreservation.main.desktop.client.common.GenericField; @@ -23,18 +28,89 @@ import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.regexp.shared.RegExp; +import com.google.gwt.safehtml.shared.SafeHtmlUtils; +import com.google.gwt.user.cellview.client.CellTable; +import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy; +import com.google.gwt.user.cellview.client.TextHeader; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.DialogBox; import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.TextBox; +import com.google.gwt.view.client.ListDataProvider; import config.i18n.client.ClientMessages; public class Dialogs { private static final ClientMessages messages = GWT.create(ClientMessages.class); + public static void showQueryResult(String title, String closeButtonText, List> rows) { + + final DialogBox dialogBox = new DialogBox(false, true); + dialogBox.setText(title); + + FlowPanel layout = new FlowPanel(); + Button closeButton = new Button(closeButtonText); + FlowPanel footer = new FlowPanel(); + + footer.add(closeButton); + + dialogBox.setWidget(layout); + + CellTable> table = new CellTable<>(Integer.MAX_VALUE, + (MyCellTableResources) GWT.create(MyCellTableResources.class)); + table.setKeyboardSelectionPolicy(HasKeyboardSelectionPolicy.KeyboardSelectionPolicy.DISABLED); + table.setLoadingIndicator(new HTML(SafeHtmlUtils.fromSafeConstant( + "
"))); + table.addStyleName("table-info my-asyncdatagrid-display"); + + int nrows = rows.size(); + int ncols = rows.get(0).size(); + ArrayList> rowsL = new ArrayList<>(nrows); + + for (int irow = 1; irow < nrows; irow++) { + List rowL = rows.get(irow); + GWT.log("" + rowL.toString()); + rowsL.add(rowL); + } + + // Create table columns + for (int icol = 0; icol < ncols; icol++) { + table.addColumn(new IndexedColumn(icol), new TextHeader(rows.get(0).get(icol))); + } + + // Create a list data provider. + final ListDataProvider> dataProvider = new ListDataProvider>(rowsL); + + // Add the table to the dataProvider. + dataProvider.addDataDisplay(table); + + layout.add(table); + layout.add(footer); + + dialogBox.setGlassEnabled(true); + dialogBox.setAnimationEnabled(false); + + closeButton.addClickHandler(event -> { + dialogBox.hide(); + }); + + dialogBox.addStyleName("dialog-custom-view-test-result"); + layout.addStyleName("dialog-custom-view-test-result-layout"); + footer.addStyleName("dialog-custom-view-test-result-layout-footer"); + FlowPanel btnItemCloseButton = new FlowPanel(); + btnItemCloseButton.addStyleName("btn-item"); + btnItemCloseButton.add(closeButton); + closeButton.addStyleName("btn btn-link"); + footer.add(btnItemCloseButton); + + dialogBox.setWidget(layout); + dialogBox.center(); + dialogBox.show(); + } + public static void showExternalLobsSetupDialog(String title, ComboBoxField referencesType, GenericField genericField, String cancelButtonText, String confirmButtonText, boolean toDelete, final AsyncCallback callback) { diff --git a/src/main/java/com/databasepreservation/main/common/shared/client/common/lists/IndexedColumn.java b/src/main/java/com/databasepreservation/main/common/shared/client/common/lists/IndexedColumn.java new file mode 100644 index 000000000..6c8218f7d --- /dev/null +++ b/src/main/java/com/databasepreservation/main/common/shared/client/common/lists/IndexedColumn.java @@ -0,0 +1,29 @@ +package com.databasepreservation.main.common.shared.client.common.lists; + +import java.util.List; + +import com.google.gwt.cell.client.TextCell; +import com.google.gwt.user.cellview.client.Column; + +/** + * Column used for dynamic table + * + * @author Miguel Guimarães + */ +public class IndexedColumn extends Column, String> { + private final int index; + + public IndexedColumn(int index) { + super(new TextCell()); + this.index = index; + } + + @Override + public String getValue(List object) { + return object.get(index); + } + + public int getIndex() { + return this.index; + } +} diff --git a/src/main/java/com/databasepreservation/main/desktop/client/dbptk/wizard/upload/CreateWizardManager.java b/src/main/java/com/databasepreservation/main/desktop/client/dbptk/wizard/upload/CreateWizardManager.java index 8e1d11ae6..e9d071892 100644 --- a/src/main/java/com/databasepreservation/main/desktop/client/dbptk/wizard/upload/CreateWizardManager.java +++ b/src/main/java/com/databasepreservation/main/desktop/client/dbptk/wizard/upload/CreateWizardManager.java @@ -193,7 +193,7 @@ private void handleTableAndColumnsPanel() { tableAndColumnsParameters = (TableAndColumnsParameters) wizardInstances.get(position).getValues(); wizardContent.clear(); position = 2; - CustomViews customViews = CustomViews.getInstance(tableAndColumnsParameters.getSelectedSchemas(), btnNext); + CustomViews customViews = CustomViews.getInstance(tableAndColumnsParameters.getSelectedSchemas(), btnNext, connectionParameters, databaseUUID); customViews.refreshCustomButtons(); wizardInstances.add(position, customViews); wizardContent.add(customViews); @@ -209,19 +209,34 @@ private void handleCustomViewsPanel() { final boolean valid = wizardInstances.get(position).validate(); if (!valid) { - Dialogs.showConfirmDialog(messages.customViewsDialogTitle(), messages.customViewsDialogMessage(), messages.customViewsDialogCancel(), messages.customViewsDialogConfirm(), new DefaultAsyncCallback() { + Dialogs.showConfirmDialog(messages.customViewsDialogTitle(), messages.customViewsDialogMessage(), messages.basicActionDiscard(), messages.basicActionConfirm(), new DefaultAsyncCallback() { @Override public void onSuccess(Boolean result) { if (result) { - customViewsParameters = (CustomViewsParameters) wizardInstances.get(position).getValues(); - wizardContent.clear(); - position = 3; - SIARDExportOptions exportOptions = SIARDExportOptions.getInstance(); - wizardInstances.add(position, exportOptions); - wizardContent.add(exportOptions); - updateButtons(); - updateBreadcrumb(); - customButtons.clear(); + if (wizardInstances.get(position) instanceof CustomViews) { + final CustomViews customViewInstance = (CustomViews) wizardInstances.get(position); + + BrowserService.Util.getInstance().validateCustomViewQuery(databaseUUID, connectionParameters, customViewInstance.getCustomViewParameter().getCustomViewQuery(), new DefaultAsyncCallback>>() { + @Override + public void onSuccess(List> result) { + + customViewsParameters = customViewInstance.getValues(); + wizardContent.clear(); + position = 3; + SIARDExportOptions exportOptions = SIARDExportOptions.getInstance(); + wizardInstances.add(position, exportOptions); + wizardContent.add(exportOptions); + updateButtons(); + updateBreadcrumb(); + customButtons.clear(); + } + + @Override + public void onFailure(Throwable caught) { + Toast.showError(messages.customViewToastErrorTitle(), caught.getMessage()); + } + }); + } } else { customViewsParameters = (CustomViewsParameters) wizardInstances.get(position).getValues(); customViewsParameters.getCustomViewsParameter().remove(customViewsParameters.getCustomViewsParameter().size()-1); // DISCARD THE LAST diff --git a/src/main/java/com/databasepreservation/main/desktop/client/dbptk/wizard/upload/CustomViews.java b/src/main/java/com/databasepreservation/main/desktop/client/dbptk/wizard/upload/CustomViews.java index 55604b247..9610d60e0 100644 --- a/src/main/java/com/databasepreservation/main/desktop/client/dbptk/wizard/upload/CustomViews.java +++ b/src/main/java/com/databasepreservation/main/desktop/client/dbptk/wizard/upload/CustomViews.java @@ -4,15 +4,20 @@ import java.util.HashMap; import java.util.List; +import com.databasepreservation.main.common.client.BrowserService; +import com.databasepreservation.main.common.shared.client.common.DefaultAsyncCallback; +import com.databasepreservation.main.common.shared.client.common.dialogs.Dialogs; import com.databasepreservation.main.common.shared.client.tools.HistoryManager; import com.databasepreservation.main.common.shared.client.tools.ViewerStringUtils; import com.databasepreservation.main.common.shared.client.widgets.Toast; import com.databasepreservation.main.desktop.client.common.ComboBoxField; import com.databasepreservation.main.desktop.client.common.sidebar.CustomViewsSidebar; import com.databasepreservation.main.desktop.client.dbptk.wizard.WizardPanel; +import com.databasepreservation.main.desktop.shared.models.wizardParameters.ConnectionParameters; import com.databasepreservation.main.desktop.shared.models.wizardParameters.CustomViewsParameter; import com.databasepreservation.main.desktop.shared.models.wizardParameters.CustomViewsParameters; import com.google.gwt.core.client.GWT; +import com.google.gwt.regexp.shared.RegExp; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Button; @@ -56,18 +61,25 @@ interface CustomViewsUiBinder extends UiBinder { private boolean toSave; private ComboBoxField customViewSchemaName; private Button btnNext; + private ConnectionParameters connectionParameters; + private String databaseUUID; + private boolean queryResult; - public static CustomViews getInstance(List schemas, Button btnNext) { + public static CustomViews getInstance(List schemas, Button btnNext, ConnectionParameters connectionParameters, + String databaseUUID) { if (instance == null) { - instance = new CustomViews(schemas, btnNext); + instance = new CustomViews(schemas, btnNext, connectionParameters, databaseUUID); } return instance; } - private CustomViews(List schemas, Button btnNext) { + private CustomViews(List schemas, Button btnNext, ConnectionParameters connectionParameters, + String databaseUUID) { initWidget(binder.createAndBindUi(this)); this.btnNext = btnNext; + this.connectionParameters = connectionParameters; + this.databaseUUID = databaseUUID; customViewsSidebar = CustomViewsSidebar.getInstance(); customViewsList.add(customViewsSidebar); @@ -84,7 +96,7 @@ private CustomViews(List schemas, Button btnNext) { customViewsButtons.add(createCustomViewButton()); } - public void checkIfHaveCustomViews(){ + void checkIfHaveCustomViews(){ if(customViewsParameters.isEmpty()){ btnNext.setText(messages.skip()); } else { @@ -144,21 +156,31 @@ public CustomViewsParameters getValues() { public void error() { } public void sideBarHighlighter(String customViewUUID, String action) { - customViewsButtons.clear(); final CustomViewsParameter parameter = customViewsParameters.get(customViewUUID); if (action != null && action.equals(HistoryManager.ACTION_DELETE)) { - deleteCustomView(parameter.getCustomViewID()); - setTextboxText("", "", "", ""); - customViewName.getElement().removeAttribute("required"); - customViewQuery.getElement().removeAttribute("required"); - customViewSchemaName.getElement().removeAttribute("required"); - customViewsButtons.clear(); - customViewsButtons.add(createCustomViewButton()); - customViewsSidebar.selectNone(); - HistoryManager.gotoCreateSIARD(); + Dialogs.showConfirmDialog(messages.customViewsTitle(), messages.customViewsDialogConfirmDelete(), messages.basicActionCancel(), messages.basicActionConfirm(), + new DefaultAsyncCallback() { + @Override + public void onSuccess(Boolean result) { + if (result) { + deleteCustomView(parameter.getCustomViewID()); + setTextboxText("", "", "", ""); + customViewName.getElement().removeAttribute("required"); + customViewQuery.getElement().removeAttribute("required"); + customViewSchemaName.getElement().removeAttribute("required"); + customViewsButtons.clear(); + customViewsButtons.add(createCustomViewButton()); + customViewsSidebar.selectNone(); + HistoryManager.gotoCreateSIARD(); + } else { + HistoryManager.gotoCreateSIARD(); + } + } + }); } else { + customViewsButtons.clear(); setTextboxText(parameter.getSchema(), parameter.getCustomViewName(), parameter.getCustomViewDescription(), parameter.getCustomViewQuery()); @@ -175,32 +197,75 @@ public void sideBarHighlighter(String customViewUUID, String action) { customViewsButtons.add(createCustomViewButton()); HistoryManager.gotoCreateSIARD(); }); + + Button btnTest = new Button(); + btnTest.setText(messages.customViewsBtnTest()); + btnTest.addStyleName("btn btn-primary btn-run"); + + btnTest.addClickHandler(event -> { + if (validateCustomViewQueryText()) { + BrowserService.Util.getInstance().validateCustomViewQuery(databaseUUID, connectionParameters, + customViewQuery.getText(), new DefaultAsyncCallback>>() { + @Override + public void onSuccess(List> result) { + Dialogs.showQueryResult(messages.customViewsQueryResultsDialogTitle(), messages.basicActionClose(), + result); + } + + @Override + public void onFailure(Throwable caught) { + Toast.showError(messages.customViewToastErrorTitle(), caught.getMessage()); + } + }); + } else { + Toast.showError(messages.customViewsTestQueryError()); + } + }); + Button btnUpdate = new Button(); btnUpdate.setText(messages.customViewsBtnSave()); btnUpdate.addStyleName("btn btn-primary btn-save"); btnUpdate.addClickHandler(event -> { final int valid = customViewFormValidatorUpdate(parameter.getCustomViewName()); if (valid == -1) { - updateCustomViewParameters(parameter.getCustomViewID(), customViewSchemaName.getSelectedValue(), - customViewName.getText(), - customViewDescription.getText(), customViewQuery.getText()); - Toast.showInfo(messages.customViewsTitle(), messages.customViewsUpdateMessage()); + BrowserService.Util.getInstance().validateCustomViewQuery(databaseUUID, connectionParameters, + customViewQuery.getText(), new DefaultAsyncCallback>>() { + @Override + public void onSuccess(List> result) { + if (!result.isEmpty()) { + updateCustomViewParameters(parameter.getCustomViewID(), customViewSchemaName.getSelectedValue(), + customViewName.getText(), customViewDescription.getText(), customViewQuery.getText()); + Toast.showInfo(messages.customViewsTitle(), messages.customViewsUpdateMessage()); + } else { + Toast.showError("Empty"); + } + } + + @Override + public void onFailure(Throwable caught) { + Toast.showError(messages.customViewToastErrorTitle(), caught.getMessage()); + } + }); } else { Toast.showError(messages.errorMessagesCustomViewsTitle(), messages.errorMessagesCustomViews(valid)); highlightFieldsWhenRequired(); } }); - SimplePanel simplePanelforbtnNew = new SimplePanel(); - simplePanelforbtnNew.addStyleName("btn-item"); - simplePanelforbtnNew.add(btnNew); + SimplePanel simplePanelForUpdateButton = new SimplePanel(); + simplePanelForUpdateButton.addStyleName("btn-item"); + simplePanelForUpdateButton.add(btnUpdate); + customViewsButtons.add(simplePanelForUpdateButton); - SimplePanel simplePanelforbtnUpdate = new SimplePanel(); - simplePanelforbtnUpdate.addStyleName("btn-item"); - simplePanelforbtnUpdate.add(btnUpdate); + SimplePanel simplePanelForTestButton = new SimplePanel(); + simplePanelForTestButton.addStyleName("btn-item"); + simplePanelForTestButton.add(btnTest); + customViewsButtons.add(simplePanelForTestButton); - customViewsButtons.add(simplePanelforbtnUpdate); - customViewsButtons.add(simplePanelforbtnNew); + SimplePanel simplePanelForNewButton = new SimplePanel(); + simplePanelForNewButton.addStyleName("btn-item"); + simplePanelForNewButton.add(btnNew); + customViewsButtons.add(simplePanelForNewButton); customViewsSidebar.select(customViewUUID); } @@ -293,7 +358,7 @@ private void setTextboxText(final String schemaName, final String customViewName customViewQuery.setText(customViewQueryText); } - private SimplePanel createCustomViewButton() { + private FlowPanel createCustomViewButton() { Button btnSave = new Button(); btnSave.setText(messages.customViewsBtnSave()); btnSave.addStyleName("btn btn-primary btn-save"); @@ -301,31 +366,79 @@ private SimplePanel createCustomViewButton() { btnSave.addClickHandler(event -> { final int valid = customViewFormValidator(); if (valid == -1) { - customViewsSidebar.addSideBarHyperLink(customViewName.getText(), - String.valueOf(counter), HistoryManager.linkToCreateWizardCustomViewsDelete(String.valueOf(counter))); - - CustomViewsParameter parameter = new CustomViewsParameter(customViewSchemaName.getSelectedValue(), counter, - customViewName.getText(), - customViewDescription.getText(), customViewQuery.getText()); - customViewsParameters.put(String.valueOf(counter), parameter); - counter++; - setTextboxText("", "", "", ""); - customViewName.getElement().removeAttribute("required"); - customViewQuery.getElement().removeAttribute("required"); - customViewSchemaName.getElement().removeAttribute("required"); - customViewsSidebar.selectNone(); + BrowserService.Util.getInstance().validateCustomViewQuery(databaseUUID, connectionParameters, + customViewQuery.getText(), new DefaultAsyncCallback>>() { + @Override + public void onSuccess(List> result) { + if (!result.isEmpty()) { + customViewsSidebar.addSideBarHyperLink(customViewName.getText(), String.valueOf(counter), + HistoryManager.linkToCreateWizardCustomViewsDelete(String.valueOf(counter))); + + CustomViewsParameter parameter = new CustomViewsParameter(customViewSchemaName.getSelectedValue(), + counter, customViewName.getText(), customViewDescription.getText(), customViewQuery.getText()); + customViewsParameters.put(String.valueOf(counter), parameter); + counter++; + setTextboxText("", "", "", ""); + customViewName.getElement().removeAttribute("required"); + customViewQuery.getElement().removeAttribute("required"); + customViewSchemaName.getElement().removeAttribute("required"); + customViewsSidebar.selectNone(); + } else { + Toast.showError("Empty"); + } + checkIfHaveCustomViews(); + } + + @Override + public void onFailure(Throwable caught) { + Toast.showError(messages.customViewToastErrorTitle(), caught.getMessage()); + checkIfHaveCustomViews(); + } + }); } else { Toast.showError(messages.errorMessagesCustomViewsTitle(), messages.errorMessagesCustomViews(valid)); highlightFieldsWhenRequired(); + checkIfHaveCustomViews(); } - checkIfHaveCustomViews(); }); - SimplePanel simplePanelforbtnSave = new SimplePanel(); - simplePanelforbtnSave.addStyleName("btn-item"); - simplePanelforbtnSave.add(btnSave); + Button btnTest = new Button(); + btnTest.setText(messages.customViewsBtnTest()); + btnTest.addStyleName("btn btn-primary btn-run"); + + btnTest.addClickHandler(event -> { + if (validateCustomViewQueryText()) { + BrowserService.Util.getInstance().validateCustomViewQuery(databaseUUID, connectionParameters, + customViewQuery.getText(), new DefaultAsyncCallback>>() { + @Override + public void onSuccess(List> result) { + Dialogs.showQueryResult(messages.customViewsQueryResultsDialogTitle(), messages.basicActionClose(), + result); + } + + @Override + public void onFailure(Throwable caught) { + Toast.showError(messages.customViewToastErrorTitle(), caught.getMessage()); + } + }); + } else { + Toast.showError(messages.customViewsTestQueryError()); + } + }); + + FlowPanel FlowPanelForSaveButton = new FlowPanel(); + FlowPanelForSaveButton.addStyleName("btn-item"); + FlowPanelForSaveButton.add(btnSave); + + FlowPanel FlowPanelForTestButton = new FlowPanel(); + FlowPanelForTestButton.addStyleName("btn-item"); + FlowPanelForTestButton.add(btnTest); - return simplePanelforbtnSave; + FlowPanel FlowPanelForOptionsButtons = new FlowPanel(); + FlowPanelForOptionsButtons.add(FlowPanelForSaveButton); + FlowPanelForOptionsButtons.add(FlowPanelForTestButton); + + return FlowPanelForOptionsButtons; } private void highlightFieldsWhenRequired() { @@ -344,4 +457,21 @@ private void highlightFieldsWhenRequired() { customViewSchemaName.addStyleName("wizard-connection-validator"); } } + + private boolean validateCustomViewQueryText() { + if (ViewerStringUtils.isBlank(customViewQuery.getText())) { + return false; + } + + final String query = customViewQuery.getText(); + + final RegExp compile = RegExp.compile("^(:>\\s+)?SELECT", "i"); + + return compile.test(query); + } + + public CustomViewsParameter getCustomViewParameter() { + return new CustomViewsParameter(customViewSchemaName.getSelectedValue(), counter, customViewName.getText(), + customViewDescription.getText(), customViewQuery.getText()); + } } diff --git a/src/main/java/com/databasepreservation/main/desktop/client/dbptk/wizard/upload/CustomViews.ui.xml b/src/main/java/com/databasepreservation/main/desktop/client/dbptk/wizard/upload/CustomViews.ui.xml index 88ffc4e2a..fbf3ec620 100644 --- a/src/main/java/com/databasepreservation/main/desktop/client/dbptk/wizard/upload/CustomViews.ui.xml +++ b/src/main/java/com/databasepreservation/main/desktop/client/dbptk/wizard/upload/CustomViews.ui.xml @@ -11,7 +11,6 @@ - diff --git a/src/main/java/config/i18n/client/ClientMessages.java b/src/main/java/config/i18n/client/ClientMessages.java index fe55f4387..5e62ad0e9 100644 --- a/src/main/java/config/i18n/client/ClientMessages.java +++ b/src/main/java/config/i18n/client/ClientMessages.java @@ -592,6 +592,17 @@ public interface ClientMessages extends Messages { String SIARDValidationFailed(); + /******************************************** + * Basic Actions + ********************************************/ + String basicActionClose(); + + String basicActionCancel(); + + String basicActionDiscard(); + + String basicActionConfirm(); + /******************************************** * Edit Metadata ********************************************/ @@ -714,6 +725,16 @@ public interface ClientMessages extends Messages { String errorMessagesCustomViewsTitle(); + String customViewsBtnTest(); + + String customViewsTestQueryError(); + + String customViewsQueryResultsDialogTitle(); + + String customViewToastErrorTitle(); + + String customViewsDialogConfirmDelete(); + String errorMessagesCustomViews(@Select int error); /******************************************** @@ -781,5 +802,6 @@ public interface ClientMessages extends Messages { * Home Page ********************************************/ String poweredBy(); + String financedBy(); } diff --git a/src/main/resources/com/databasepreservation/main/desktop/public/main.css b/src/main/resources/com/databasepreservation/main/desktop/public/main.css index 1f232606b..6be6a3bf8 100644 --- a/src/main/resources/com/databasepreservation/main/desktop/public/main.css +++ b/src/main/resources/com/databasepreservation/main/desktop/public/main.css @@ -256,6 +256,10 @@ p[data-value]:after { content: "\f0c7"; } +.btn-run:after { + content: "\f085"; +} + .btn-manage:after { content: "\f233"; } @@ -1762,6 +1766,23 @@ input[type="checkbox"]:checked:after { padding-right: 10px; } +.dialog-custom-view-test-result { + width: 90%; +} + +.dialog-custom-view-test-result table { + width: 100%; +} + +.dialog-custom-view-test-result-layout { + margin: 10px; +} + +.dialog-custom-view-test-result-layout-footer { + display: flex; + flex-direction: row-reverse; +} + /*********************************************** Progress Panel ***********************************************/ diff --git a/src/main/resources/config/i18n/client/ClientMessages.properties b/src/main/resources/config/i18n/client/ClientMessages.properties index 8506d3b0c..8e1dd191e 100644 --- a/src/main/resources/config/i18n/client/ClientMessages.properties +++ b/src/main/resources/config/i18n/client/ClientMessages.properties @@ -113,6 +113,14 @@ siardMetadata_DescriptionUnavailable=A description for this database is not avai menusidebar_manageDatabases=Manage Databases searchPlaceholder=Search... +############################################################################# +# Basic Actions # +############################################################################# +basicActionClose=Close +basicActionDiscard=Discard +basicActionConfirm=Confirm +basicActionCancel=Cancel + ############################################################################# # Diagram Pages # ############################################################################# @@ -383,13 +391,18 @@ customViewSchemaNameLabel=Schema Name customViewsBtnSave=Save customViewsBtnNew=New customViewsDialogTitle=Custom Views -customViewsDialogMessage=The custom view is not save, do you want to save? +customViewsDialogMessage=The custom view is not saved, do you want to save? customViewsDialogConfirm=Save customViewsDialogCancel=Discard errorMessagesCustomViewsTitle=Custom Views errorMessagesCustomViews= errorMessagesCustomViews[1]=Mandatory fields missing errorMessagesCustomViews[2]=View already exists +customViewsBtnTest=Test +customViewsTestQueryError=Please write a SQL select query +customViewsQueryResultsDialogTitle=Results +customViewToastErrorTitle=Custom Views +customViewsDialogConfirmDelete=Are you sure you want to delete this custom view? ############################################################################# # Export Options # diff --git a/src/main/resources/config/i18n/client/ClientMessages_pt_PT.properties b/src/main/resources/config/i18n/client/ClientMessages_pt_PT.properties index 9c4093e2f..c850065f9 100644 --- a/src/main/resources/config/i18n/client/ClientMessages_pt_PT.properties +++ b/src/main/resources/config/i18n/client/ClientMessages_pt_PT.properties @@ -104,6 +104,15 @@ siardMetadata_DescriptionUnavailable=Esta base de dados não possui uma descriç menusidebar_manageDatabases=Gerir Bases de Dados searchPlaceholder=Pesquisar... + +############################################################################# +# Basic Actions # +############################################################################# +basicActionClose=Fechar +basicActionDiscard=Descartar +basicActionConfirm=Confirmar +basicActionCancel=Cancelar + ############################################################################# # Diagram Pages # ############################################################################# @@ -380,6 +389,11 @@ errorMessagesCustomViewsTitle=Vistas Customizadas errorMessagesCustomViews= errorMessagesCustomViews[1]=Preencha todos os campos obrigatórios errorMessagesCustomViews[2]=A vista já se encontra gravada +customViewsBtnTest=Testar +customViewsTestQueryError=Por favor, escreva uma interrogação SQL de seleção +customViewsQueryResultsDialogTitle=Resultados +customViewToastErrorTitle=Vistas Customizadas +customViewsDialogConfirmDelete=Tem a certeza que deseja eliminar esta vista customizada? ############################################################################# # Export Options #