From 163060ceeb5c2c80559589c3cd1dea8ca0e8fd2a Mon Sep 17 00:00:00 2001 From: patschuh <46817726+patschuh@users.noreply.github.com> Date: Thu, 18 Nov 2021 14:48:34 +0100 Subject: [PATCH] Add setting to disable code highlighting Add show method to *Alert Classes that accepts an owner Window --- README.md | 5 +- src/main/java/at/esque/kafka/Controller.java | 51 ++++++++++--------- .../kafka/CreateConnectorController.java | 17 ++++--- .../esque/kafka/CreateSchemaController.java | 11 ++-- .../esque/kafka/CrossClusterController.java | 11 ++-- .../InstalledConnectorPluginsController.java | 7 ++- .../kafka/KafkaConnectBrowserController.java | 25 +++++---- .../at/esque/kafka/PublisherController.java | 19 +++++-- .../SchemaCompatibilityCheckController.java | 9 +++- .../SchemaRegistryBrowserController.java | 26 ++++++---- .../esque/kafka/alerts/ConfirmationAlert.java | 9 ++++ .../at/esque/kafka/alerts/ErrorAlert.java | 13 ++++- .../at/esque/kafka/alerts/SuccessAlert.java | 9 ++++ .../alerts/TopicTemplateAppliedAlert.java | 7 ++- .../at/esque/kafka/alerts/WarningAlert.java | 10 ++++ .../kafka/controls/KafkaEsqueCodeArea.java | 36 +++++++------ .../esque/kafka/handlers/ConfigHandler.java | 25 ++++++++- .../at/esque/kafka/handlers/Settings.java | 4 ++ 18 files changed, 210 insertions(+), 84 deletions(-) diff --git a/README.md b/README.md index 7844687..589aa7a 100644 --- a/README.md +++ b/README.md @@ -103,5 +103,8 @@ Check the settings.yaml in the /.kafkaesque directory for cluster ind * default: true * trace.quick.select.duration.list: configures the values of the quick select buttons as a comma separated list of [Duration](https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html) Strings * default: PT2H, P1D, P7D - ![Trace Quick Select](https://kafka.esque.at/images/screenshots/quickselectTrace.png "Trace Quick Select") +* syntax.highlight.threshold.enabled: Enables the syntax highlight threshold, if enabled JSON syntax highlighting will be disabled for if the codearea contains more characters than the threshold (syntax.highlight.threshold.characters). + * default: true +* syntax.highlight.threshold.characters: configures the maximum number of characters allowed in a codeArea before syntax highlighting is disabled if the threshold is enabled (syntax.highlight.threshold.enabled). + * default: 50000 \ No newline at end of file diff --git a/src/main/java/at/esque/kafka/Controller.java b/src/main/java/at/esque/kafka/Controller.java index 6579348..46f0ad7 100644 --- a/src/main/java/at/esque/kafka/Controller.java +++ b/src/main/java/at/esque/kafka/Controller.java @@ -253,6 +253,9 @@ public void setup(Stage controlledStage) { topicListView.getListView().setCellFactory(lv -> topicListCellFactory()); topicListView.setListComparator(String::compareTo); + configHandler.configureKafkaEsqueCodeArea(keyTextArea); + configHandler.configureKafkaEsqueCodeArea(valueTextArea); + setupJsonFormatToggle(); setupClusterCombobox(); @@ -297,7 +300,7 @@ private void openInTextEditor(KafkaMessage value, String suffix) { Desktop.getDesktop().open(temp); } catch (IOException e) { - Platform.runLater(() -> ErrorAlert.show(e)); + Platform.runLater(() -> ErrorAlert.show(e, controlledStage)); } }).start(); } @@ -413,7 +416,7 @@ private ListCell topicListCellFactory() { trace(topicMessageTypeConfig, consumerConfig, (ConsumerRecord cr) -> StringUtils.equals(cr.key().toString(), traceKeyInput.getSearch()), partition, traceKeyInput.getEpoch()); }); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, controlledStage); } }); @@ -443,7 +446,7 @@ private ListCell topicListCellFactory() { }, null, traceInput.getEpoch()); }); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, controlledStage); } }); @@ -456,7 +459,7 @@ private ListCell topicListCellFactory() { adminClient.deleteTopic(cell.itemProperty().get()); SuccessAlert.show("Delete Topic", null, "Topic [" + cell.itemProperty().get() + "] marked for deletion."); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, controlledStage); } } }); @@ -532,7 +535,7 @@ public void getMessagesClick(ActionEvent event) { getMessagesContinuously(topicMessageTypeConfig, consumerConfig); } } catch (IOException e) { - ErrorAlert.show(e); + ErrorAlert.show(e, controlledStage); } } @@ -574,7 +577,7 @@ public void schemaRegistryClick(ActionEvent event) { stage.show(); centerStageOnControlledStage(stage); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, controlledStage); } } @@ -606,7 +609,7 @@ public void kafkaConnectClick(ActionEvent actionEvent) { stage.show(); centerStageOnControlledStage(stage); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, controlledStage); } } @@ -638,7 +641,7 @@ public void kafkaConnectInstalledPluginClick(ActionEvent actionEvent) { stage.show(); centerStageOnControlledStage(stage); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, controlledStage); } } @@ -659,7 +662,7 @@ public void crossClusterClick(ActionEvent actionEvent) { stage.show(); centerStageOnControlledStage(stage); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, controlledStage); } } @@ -686,7 +689,7 @@ public void lagViewerClick(ActionEvent actionEvent) { consumerHandler.deregisterConsumer(consumerId); }); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, controlledStage); } } @@ -710,7 +713,7 @@ public void aclViewer(ActionEvent actionEvent) { controller.stop(); }); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, controlledStage); } } @@ -720,7 +723,7 @@ private void getOldestMessages(TopicMessageTypeConfig topic, Map try { consumerId = consumerHandler.registerConsumer(selectedCluster(), topic, consumerConfig); } catch (MissingSchemaRegistryException e) { - Platform.runLater(() -> ErrorAlert.show(e)); + Platform.runLater(() -> ErrorAlert.show(e, controlledStage)); return; } try { @@ -795,7 +798,7 @@ private void getNewestMessages(TopicMessageTypeConfig topic, Map try { tempconsumerId = consumerHandler.registerConsumer(selectedCluster(), topic, consumerConfig); } catch (MissingSchemaRegistryException e) { - Platform.runLater(() -> ErrorAlert.show(e)); + Platform.runLater(() -> ErrorAlert.show(e, controlledStage)); return; } UUID consumerId = tempconsumerId; @@ -845,7 +848,7 @@ private void getMessagesContinuously(TopicMessageTypeConfig topic, Map< try { tempconsumerId = consumerHandler.registerConsumer(selectedCluster(), topic, consumerConfig); } catch (MissingSchemaRegistryException e) { - Platform.runLater(() -> ErrorAlert.show(e)); + Platform.runLater(() -> ErrorAlert.show(e, controlledStage)); return; } UUID consumerId = tempconsumerId; @@ -880,7 +883,7 @@ private void trace(TopicMessageTypeConfig topic, Map co try { consumerId = consumerHandler.registerConsumer(selectedCluster(), topic, consumerConfig); } catch (MissingSchemaRegistryException e) { - Platform.runLater(() -> ErrorAlert.show(e)); + Platform.runLater(() -> ErrorAlert.show(e, controlledStage)); return; } try { @@ -984,7 +987,7 @@ private void getMessagesFromSpecificOffset(TopicMessageTypeConfig topic, Map>() { }); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, controlledStage); return; } runInDaemonThread(() -> { @@ -1189,12 +1192,12 @@ public void applyTopicTemplatesClick(ActionEvent event) { if (e.getCause() instanceof TopicExistsException) { alreadyExistedTopics.add(currentTopic); } else { - Platform.runLater(() -> ErrorAlert.show(e)); + Platform.runLater(() -> ErrorAlert.show(e, controlledStage)); } } Platform.runLater(() -> backGroundTaskHolder.setProgressMessage("Created Topic " + createdTopics.size() + " of " + topicsToCreate.size() + " (" + alreadyExistedTopics.size() + " already existed)")); }); - Platform.runLater(() -> TopicTemplateAppliedAlert.show(createdTopics, alreadyExistedTopics)); + Platform.runLater(() -> TopicTemplateAppliedAlert.show(createdTopics, alreadyExistedTopics, topicListView.getScene().getWindow())); } finally { backGroundTaskHolder.backgroundTaskStopped(); } @@ -1248,7 +1251,7 @@ public void playMessageBook(ActionEvent event) { } }); } catch (Exception e) { - Platform.runLater(() -> ErrorAlert.show(e)); + Platform.runLater(() -> ErrorAlert.show(e, controlledStage)); } finally { stopWatch.stop(); topicToProducerMap.values().forEach(uuid -> producerHandler.deregisterProducer(uuid)); @@ -1274,7 +1277,7 @@ private void addMessagesToSend(List messagesToSend, File messagesToSend.addAll(messages.stream().map(message -> new KafkaMessagBookWrapper(playFile.getName(), message)) .collect(Collectors.toList())); } catch (FileNotFoundException e) { - Platform.runLater(() -> ErrorAlert.show(e)); + Platform.runLater(() -> ErrorAlert.show(e, controlledStage)); } } diff --git a/src/main/java/at/esque/kafka/CreateConnectorController.java b/src/main/java/at/esque/kafka/CreateConnectorController.java index 3dab05e..b3f63e2 100644 --- a/src/main/java/at/esque/kafka/CreateConnectorController.java +++ b/src/main/java/at/esque/kafka/CreateConnectorController.java @@ -20,6 +20,7 @@ import javafx.scene.control.cell.PropertyValueFactory; import javafx.stage.FileChooser; import javafx.stage.Stage; +import javafx.stage.Window; import org.apache.avro.Schema; import org.apache.commons.lang3.StringUtils; import org.sourcelab.kafka.connect.apiclient.request.dto.ConnectorPluginConfigValidationResults; @@ -139,17 +140,17 @@ public void addConnector(ActionEvent actionEvent) { if(newConnectorMode == true) { kafkaesqueConnectClient.createConnector(connectorName, connectorClass, paramMap); - SuccessAlert.show("Success", null, "Connector added successfully!"); + SuccessAlert.show("Success", null, "Connector added successfully!", getWindow()); } else { kafkaesqueConnectClient.updateConnector(connectorName, connectorClass, paramMap); - SuccessAlert.show("Success", null, "Connector updated successfully!"); + SuccessAlert.show("Success", null, "Connector updated successfully!", getWindow()); } stage.close(); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } } @@ -198,7 +199,7 @@ public void validateConfig(ActionEvent actionEvent) { ValidationResult validationResult = kafkaesqueConnectClient.validateConnectorConfig(connectorName, connectorClass, paramMap); if (validationResult.getErrorCount() == 0) { - SuccessAlert.show("Success", null, "No validation error found!"); + SuccessAlert.show("Success", null, "No validation error found!", getWindow()); } else { StringBuilder errorProtocol = new StringBuilder(); @@ -212,12 +213,16 @@ public void validateConfig(ActionEvent actionEvent) { } } - WarningAlert.show(String.format("%d validation errors found!", validationResult.getErrorCount()), null, errorProtocol.toString()); + WarningAlert.show(String.format("%d validation errors found!", validationResult.getErrorCount()), null, errorProtocol.toString(), getWindow()); } } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } } + + private Window getWindow() { + return connectorConfigTextArea.getScene().getWindow(); + } } diff --git a/src/main/java/at/esque/kafka/CreateSchemaController.java b/src/main/java/at/esque/kafka/CreateSchemaController.java index 4dc5ce1..a4f4b1c 100644 --- a/src/main/java/at/esque/kafka/CreateSchemaController.java +++ b/src/main/java/at/esque/kafka/CreateSchemaController.java @@ -9,6 +9,7 @@ import javafx.scene.control.TextField; import javafx.stage.FileChooser; import javafx.stage.Stage; +import javafx.stage.Window; import org.apache.avro.Schema; import java.io.File; @@ -34,9 +35,9 @@ public void addSchema(ActionEvent actionEvent) { try { parser.parse(schemaTextArea.getText()); restService.registerSchema(schemaTextArea.getText(), subjectTextField.getText()); - SuccessAlert.show("Success", null, "Schema added successfully!"); + SuccessAlert.show("Success", null, "Schema added successfully!", getWindow()); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } } @@ -50,10 +51,14 @@ public void loadSchemaFile(ActionEvent actionEvent) { String schemaString = new String(Files.readAllBytes(Paths.get(selectedFile.getPath()))); schemaTextArea.setText(schemaString); } catch (IOException e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } } + private Window getWindow() { + return schemaTextArea.getScene().getWindow(); + } + public void setup(String selectedSubject, RestService restService, Stage stage) { this.restService = restService; this.stage = stage; diff --git a/src/main/java/at/esque/kafka/CrossClusterController.java b/src/main/java/at/esque/kafka/CrossClusterController.java index 14f77c6..bc81cd8 100644 --- a/src/main/java/at/esque/kafka/CrossClusterController.java +++ b/src/main/java/at/esque/kafka/CrossClusterController.java @@ -26,6 +26,7 @@ import javafx.scene.control.TextField; import javafx.scene.control.ToggleButton; import javafx.scene.control.Tooltip; +import javafx.stage.Window; import org.apache.commons.lang3.StringUtils; import org.apache.kafka.clients.consumer.ConsumerRecord; import org.apache.kafka.clients.consumer.ConsumerRecords; @@ -123,7 +124,7 @@ public void setup() { return FontIcon.of(FontAwesome.STOP_CIRCLE); default: if(cell.getItem().finishedExceptionaly()) { - cell.setOnMouseClicked(mouseEvent -> ErrorAlert.show(cell.getItem().getException())); + cell.setOnMouseClicked(mouseEvent -> ErrorAlert.show(cell.getItem().getException(), getWindow())); } return FontIcon.of(FontAwesome.WARNING); } @@ -166,7 +167,7 @@ private void startOperation(UUID operationId) { consumerHandler.seekToOffset(consumerId, -2); } } catch (IOException | MissingSchemaRegistryException e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); return; } Optional consumer = consumerHandler.getConsumer(consumerId); @@ -246,10 +247,14 @@ public void startOperationClick(ActionEvent actionEvent) { refreshOperationList(null); startOperation(operationId); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } } + private Window getWindow() { + return fromClusterTopicsList.getScene().getWindow(); + } + @FXML public void refreshOperationList(ActionEvent actionEvent) { runningOperationsList.setItems(crossClusterOperationHandler.getOperations()); diff --git a/src/main/java/at/esque/kafka/InstalledConnectorPluginsController.java b/src/main/java/at/esque/kafka/InstalledConnectorPluginsController.java index f9b5230..9593a0c 100644 --- a/src/main/java/at/esque/kafka/InstalledConnectorPluginsController.java +++ b/src/main/java/at/esque/kafka/InstalledConnectorPluginsController.java @@ -8,6 +8,7 @@ import javafx.collections.FXCollections; import javafx.event.ActionEvent; import javafx.fxml.FXML; +import javafx.stage.Window; public class InstalledConnectorPluginsController { @@ -29,8 +30,12 @@ public void refreshConnectorPlugins(ActionEvent actionEvent) { try { connectorPluginListView.setItems(FXCollections.observableArrayList(kafkaesqueConnectClient.getInstalledConnectorPlugins())); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } } + private Window getWindow() { + return connectorPluginListView.getScene().getWindow(); + } + } diff --git a/src/main/java/at/esque/kafka/KafkaConnectBrowserController.java b/src/main/java/at/esque/kafka/KafkaConnectBrowserController.java index 0e16bef..cc88ed8 100644 --- a/src/main/java/at/esque/kafka/KafkaConnectBrowserController.java +++ b/src/main/java/at/esque/kafka/KafkaConnectBrowserController.java @@ -29,6 +29,7 @@ import javafx.scene.image.Image; import javafx.stage.Modality; import javafx.stage.Stage; +import javafx.stage.Window; import javafx.util.Callback; import org.kordamp.ikonli.fontawesome.FontAwesome; import org.kordamp.ikonli.javafx.FontIcon; @@ -115,7 +116,7 @@ public void handle(ActionEvent event) { updateRightPane(selectedConnectorInRightPane); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } } @@ -130,6 +131,10 @@ public void handle(ActionEvent event) { } + private Window getWindow() { + return connectorConfigTextArea.getScene().getWindow(); + } + public void updateRightPane(String selectedConnector) { try { @@ -154,7 +159,7 @@ public void updateRightPane(String selectedConnector) taskTableView.setItems(null); } } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } @@ -171,7 +176,7 @@ public void refreshConnectors(ActionEvent actionEvent) { connectorListView.getListView().getSelectionModel().select(null); connectorListView.setItems(FXCollections.observableArrayList(kafkaesqueConnectClient.getConnectors())); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } } @@ -190,7 +195,7 @@ private void showConnectConfigDialog(String selectedConnector) stage.setOnCloseRequest(event -> controller.cleanup()); stage.show(); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } } @@ -203,18 +208,18 @@ private ListCell connectorListCellFactory() { deleteItem.setGraphic(new FontIcon(FontAwesome.TRASH)); deleteItem.textProperty().set("delete"); deleteItem.setOnAction(event -> { - if (ConfirmationAlert.show("Delete Connector", "Connector [" + cell.itemProperty().get() + "] will deleted.", "Are you sure you want to delete this connector")) { + if (ConfirmationAlert.show("Delete Connector", "Connector [" + cell.itemProperty().get() + "] will be deleted.", "Are you sure you want to delete this connector", getWindow())) { try { boolean result = kafkaesqueConnectClient.deleteConnector(cell.itemProperty().get()); if(result == true) { - SuccessAlert.show("Delete Connector", null, "Connector [" + cell.itemProperty().get() + "] deleted."); + SuccessAlert.show("Delete Connector", null, "Connector [" + cell.itemProperty().get() + "] deleted.", getWindow()); } else { - WarningAlert.show( "Delete Connector", null, "It wasn't possible to delete the connector"); + WarningAlert.show( "Delete Connector", null, "It wasn't possible to delete the connector", getWindow()); } } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } } }); @@ -303,13 +308,13 @@ private void rightPaneConnectorAction(String action) if (result != true) { - WarningAlert.show("Connector Action", null, String.format("Connector action '%s' returned fales from API!",action)); + WarningAlert.show("Connector Action", null, String.format("Connector action '%s' returned fales from API!",action), getWindow()); } //Refresh view updateRightPane(selectedConnectorInRightPane); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } } } diff --git a/src/main/java/at/esque/kafka/PublisherController.java b/src/main/java/at/esque/kafka/PublisherController.java index 03e9913..398a524 100644 --- a/src/main/java/at/esque/kafka/PublisherController.java +++ b/src/main/java/at/esque/kafka/PublisherController.java @@ -22,6 +22,8 @@ import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.cell.TextFieldTableCell; +import javafx.stage.Stage; +import javafx.stage.Window; import org.apache.kafka.clients.producer.RecordMetadata; import org.apache.kafka.common.header.Header; import org.apache.kafka.common.header.internals.RecordHeader; @@ -68,12 +70,15 @@ public class PublisherController { private ProducerWrapper producerWrapper; private TopicMessageTypeConfig configForTopic; private String topic; + private Stage controlledStage; public void setup(ClusterConfig clusterConfig, String topic, ObservableList partitions, KafkaMessage kafkaMessage) throws IOException { this.topic = topic; configForTopic = configHandler.getConfigForTopic(clusterConfig.getIdentifier(), topic); producerId = producerHandler.registerProducer(clusterConfig, topic); producerWrapper = producerHandler.getProducer(producerId).orElse(null); + configHandler.configureKafkaEsqueCodeArea(keyTextArea); + configHandler.configureKafkaEsqueCodeArea(valueTextArea); setupControls(partitions, configForTopic, kafkaMessage); } @@ -109,7 +114,7 @@ private void setupControls(ObservableList partitions, TopicMessageTypeC try { topicMessageTypes = findTypesForTopic(topic, producerWrapper.getSchemaRegistryRestService()); } catch (RestClientException | IOException e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } if(topicMessageTypes != null) { keyTypeSelectCombobox.setItems(topicMessageTypes); @@ -124,7 +129,7 @@ private void setupControls(ObservableList partitions, TopicMessageTypeC try { topicMessageTypes = findTypesForTopic(topic, producerWrapper.getSchemaRegistryRestService()); } catch (RestClientException | IOException e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } } if(topicMessageTypes != null) { @@ -157,10 +162,10 @@ public void publishClick(ActionEvent event) { if (validateMessage(keyText, valueText)) { RecordMetadata metadata = producerHandler.sendMessage(producerId, topic, selectedPartition, keyText, valueText, keyRecordType, valueRecordType, headerTableView.getItems()); String successMessage = String.format("topic [%s] " + System.lineSeparator() + "partition [%s]" + System.lineSeparator() + "offset [%s]", metadata.topic(), metadata.partition(), metadata.offset()); - SuccessAlert.show("Message published", "Message was published successfully", successMessage); + SuccessAlert.show("Message published", "Message was published successfully", successMessage, getWindow()); } } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } } @@ -188,7 +193,11 @@ private boolean validateMessage(String key, String value) { private void showError(String inputName, ValidationResult validationResult) { String message = String.format("%s is not a valid json String: %s ", inputName, validationResult.getValidationError()); - ErrorAlert.show(new ValidationException(message), false); + ErrorAlert.show(new ValidationException(message), getWindow(), false); + } + + private Window getWindow() { + return valueTextArea.getScene().getWindow(); } @FXML diff --git a/src/main/java/at/esque/kafka/SchemaCompatibilityCheckController.java b/src/main/java/at/esque/kafka/SchemaCompatibilityCheckController.java index 3f3a61f..cc09f1a 100644 --- a/src/main/java/at/esque/kafka/SchemaCompatibilityCheckController.java +++ b/src/main/java/at/esque/kafka/SchemaCompatibilityCheckController.java @@ -10,6 +10,7 @@ import javafx.scene.paint.Color; import javafx.stage.FileChooser; import javafx.stage.Stage; +import javafx.stage.Window; import org.apache.avro.Schema; import java.io.File; @@ -53,7 +54,7 @@ public void addSchema(ActionEvent actionEvent) { resultLabel.setText("Schema is incompatible"); } } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } } @@ -67,7 +68,7 @@ public void loadSchemaFile(ActionEvent actionEvent) { String schemaString = new String(Files.readAllBytes(Paths.get(selectedFile.getPath()))); schemaTextArea.setText(schemaString); } catch (IOException e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } } @@ -86,4 +87,8 @@ public void cleanup() { subjectTextField.setDisable(false); stage = null; } + + private Window getWindow() { + return schemaTextArea.getScene().getWindow(); + } } diff --git a/src/main/java/at/esque/kafka/SchemaRegistryBrowserController.java b/src/main/java/at/esque/kafka/SchemaRegistryBrowserController.java index e11e215..ff0c5c2 100644 --- a/src/main/java/at/esque/kafka/SchemaRegistryBrowserController.java +++ b/src/main/java/at/esque/kafka/SchemaRegistryBrowserController.java @@ -19,6 +19,7 @@ import javafx.scene.image.Image; import javafx.stage.Modality; import javafx.stage.Stage; +import javafx.stage.Window; import org.kordamp.ikonli.fontawesome.FontAwesome; import org.kordamp.ikonli.javafx.FontIcon; import io.confluent.kafka.schemaregistry.client.rest.entities.Schema; @@ -65,7 +66,7 @@ public void setup(ClusterConfig selectedConfig, ConfigHandler configHandler) { schemaIdLabel.setText(String.valueOf(schema.getId())); schemaTextArea.setText(JsonUtils.formatJson(schema.getSchema())); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } })); @@ -83,38 +84,38 @@ public void setup(ClusterConfig selectedConfig, ConfigHandler configHandler) { versionComboBox.getSelectionModel().select(versionComboBox.getItems().size() - 1); } } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } }); subjectListView.setItems(FXCollections.observableArrayList(schemaRegistryRestService.getAllSubjects())); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } } public void deleteSchema() { String subject = subjectListView.getListView().getSelectionModel().getSelectedItem(); Integer version = versionComboBox.getSelectionModel().getSelectedItem(); - if (subject != null && version != null && ConfirmationAlert.show("Delete Version", "Version [" + version + "] of subject [" + subject + "] will be deleted.", "Are you sure you want to delete this version?")) { + if (subject != null && version != null && ConfirmationAlert.show("Delete Version", "Version [" + version + "] of subject [" + subject + "] will be deleted.", "Are you sure you want to delete this version?", getWindow())) { try { schemaRegistryRestService.deleteSchemaVersion(Collections.emptyMap(), subject, "" + version); subjectListView.setItems(FXCollections.observableArrayList(schemaRegistryRestService.getAllSubjects())); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } } } public void deleteSubject() { String subject = subjectListView.getListView().getSelectionModel().getSelectedItem(); - if (subject != null && ConfirmationAlert.show("Delete Subject", "Subject [" + subject + "] will be deleted.", "Are you sure you want to delete this subject?")) { + if (subject != null && ConfirmationAlert.show("Delete Subject", "Subject [" + subject + "] will be deleted.", "Are you sure you want to delete this subject?", getWindow())) { try { schemaRegistryRestService.deleteSubject(Collections.emptyMap(), subject); subjectListView.setItems(FXCollections.observableArrayList(schemaRegistryRestService.getAllSubjects())); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } } } @@ -181,7 +182,7 @@ private void showCreateSchemaDialog(String selectedSubject) { stage.setOnCloseRequest(event -> controller.cleanup()); stage.show(); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } } @@ -199,7 +200,7 @@ private void showSchemaCompatibilityCheckDialog(String selectedSubject, Integer stage.setOnCloseRequest(event -> controller.cleanup()); stage.show(); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } } @@ -208,7 +209,12 @@ public void refreshSubjects(ActionEvent actionEvent) { subjectListView.getListView().getSelectionModel().select(null); subjectListView.setItems(FXCollections.observableArrayList(schemaRegistryRestService.getAllSubjects())); } catch (Exception e) { - ErrorAlert.show(e); + ErrorAlert.show(e, getWindow()); } } + + + private Window getWindow() { + return schemaTextArea.getScene().getWindow(); + } } diff --git a/src/main/java/at/esque/kafka/alerts/ConfirmationAlert.java b/src/main/java/at/esque/kafka/alerts/ConfirmationAlert.java index 07bed28..90fc609 100644 --- a/src/main/java/at/esque/kafka/alerts/ConfirmationAlert.java +++ b/src/main/java/at/esque/kafka/alerts/ConfirmationAlert.java @@ -4,11 +4,16 @@ import javafx.scene.Node; import javafx.scene.control.Alert; import javafx.scene.control.ButtonType; +import javafx.stage.Window; import java.util.Optional; public class ConfirmationAlert { public static boolean show(String title, String header, String content) { + return show(title, header, content, null); + } + + public static boolean show(String title, String header, String content, Window owner) { Alert alert = new Alert(Alert.AlertType.CONFIRMATION); alert.setTitle(title); alert.setHeaderText(header); @@ -21,6 +26,10 @@ public static boolean show(String title, String header, String content) { Node okButton = alert.getDialogPane().lookupButton(ButtonType.OK); okButton.getStyleClass().add("primary"); + if (owner != null) { + alert.initOwner(owner); + } + Optional result = alert.showAndWait(); return result.get() == ButtonType.OK; } diff --git a/src/main/java/at/esque/kafka/alerts/ErrorAlert.java b/src/main/java/at/esque/kafka/alerts/ErrorAlert.java index ffea8c2..d96a0db 100644 --- a/src/main/java/at/esque/kafka/alerts/ErrorAlert.java +++ b/src/main/java/at/esque/kafka/alerts/ErrorAlert.java @@ -5,6 +5,7 @@ import javafx.scene.control.TextArea; import javafx.scene.layout.GridPane; import javafx.scene.layout.Priority; +import javafx.stage.Window; import java.io.PrintWriter; import java.io.StringWriter; @@ -12,10 +13,14 @@ public class ErrorAlert { public static void show(Throwable ex){ - show(ex, true); + show(ex, null, true); } - public static void show(Throwable ex, boolean expandable) { + public static void show(Throwable ex, Window owner){ + show(ex, owner, true); + } + + public static void show(Throwable ex, Window owner, boolean expandable) { Alert alert = new Alert(Alert.AlertType.ERROR); alert.setTitle(ex.getClass().getSimpleName()); alert.setHeaderText(ex.getClass().getName()); @@ -46,6 +51,10 @@ public static void show(Throwable ex, boolean expandable) { alert.getDialogPane().setExpandableContent(expContent); } + if(owner != null){ + alert.initOwner(owner); + } + alert.showAndWait(); } } diff --git a/src/main/java/at/esque/kafka/alerts/SuccessAlert.java b/src/main/java/at/esque/kafka/alerts/SuccessAlert.java index 0401894..8c16dfa 100644 --- a/src/main/java/at/esque/kafka/alerts/SuccessAlert.java +++ b/src/main/java/at/esque/kafka/alerts/SuccessAlert.java @@ -2,9 +2,14 @@ import at.esque.kafka.Main; import javafx.scene.control.Alert; +import javafx.stage.Window; public final class SuccessAlert { public static void show(String title, String header, String content) { + show(title, header, content, null); + } + + public static void show(String title, String header, String content, Window owner) { Alert alert = new Alert(Alert.AlertType.INFORMATION); alert.setTitle(title); alert.setHeaderText(header); @@ -12,6 +17,10 @@ public static void show(String title, String header, String content) { Main.applyStylesheet(alert.getDialogPane().getScene()); Main.applyIcon(alert); + if(owner != null){ + alert.initOwner(owner); + } + alert.showAndWait(); } } diff --git a/src/main/java/at/esque/kafka/alerts/TopicTemplateAppliedAlert.java b/src/main/java/at/esque/kafka/alerts/TopicTemplateAppliedAlert.java index 71b2b78..fab93f7 100644 --- a/src/main/java/at/esque/kafka/alerts/TopicTemplateAppliedAlert.java +++ b/src/main/java/at/esque/kafka/alerts/TopicTemplateAppliedAlert.java @@ -5,11 +5,12 @@ import javafx.scene.control.Label; import javafx.scene.control.ListView; import javafx.scene.layout.GridPane; +import javafx.stage.Window; import java.util.List; public class TopicTemplateAppliedAlert { - public static void show(List created, List existed) { + public static void show(List created, List existed, Window owner) { Alert alert = new Alert(Alert.AlertType.INFORMATION); alert.setTitle("Topic Template Applied"); alert.setHeaderText("Result: "); @@ -30,6 +31,10 @@ public static void show(List created, List existed) { alert.getDialogPane().setContent(gridPane); + if (owner != null) { + alert.initOwner(owner); + } + alert.showAndWait(); } } diff --git a/src/main/java/at/esque/kafka/alerts/WarningAlert.java b/src/main/java/at/esque/kafka/alerts/WarningAlert.java index ed42251..c76e458 100644 --- a/src/main/java/at/esque/kafka/alerts/WarningAlert.java +++ b/src/main/java/at/esque/kafka/alerts/WarningAlert.java @@ -2,14 +2,24 @@ import at.esque.kafka.Main; import javafx.scene.control.Alert; +import javafx.stage.Window; public final class WarningAlert { public static void show(String title, String header, String content) { + show(title, header, content, null); + } + + public static void show(String title, String header, String content, Window owner) { Alert alert = new Alert(Alert.AlertType.WARNING); alert.setTitle(title); alert.setHeaderText(header); alert.setContentText(content); Main.applyIcon(alert); + + if(owner != null){ + alert.initOwner(owner); + } + alert.showAndWait(); } } diff --git a/src/main/java/at/esque/kafka/controls/KafkaEsqueCodeArea.java b/src/main/java/at/esque/kafka/controls/KafkaEsqueCodeArea.java index 3a99588..6338866 100644 --- a/src/main/java/at/esque/kafka/controls/KafkaEsqueCodeArea.java +++ b/src/main/java/at/esque/kafka/controls/KafkaEsqueCodeArea.java @@ -3,8 +3,10 @@ import javafx.beans.binding.Bindings; import javafx.beans.property.BooleanProperty; import javafx.beans.property.IntegerProperty; +import javafx.beans.property.LongProperty; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleIntegerProperty; +import javafx.beans.property.SimpleLongProperty; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.collections.ListChangeListener; @@ -86,6 +88,7 @@ public class KafkaEsqueCodeArea extends BorderPane { public BooleanProperty editable = new SimpleBooleanProperty(true); public BooleanProperty searchVisible = new SimpleBooleanProperty(false); + public LongProperty maxCharactersSyntaxHighlighting = new SimpleLongProperty(Long.MAX_VALUE); public KafkaEsqueCodeArea() { FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource( @@ -216,31 +219,34 @@ private void selectAndShowRange(IndexRange indexRange) { private void highlightAndRememberHits(String regex) { clearSearchHits(); if(!StringUtils.isEmpty(codeArea.getText())) { - Matcher syntaxMatcher = SYNTAX_PATTERN.matcher(codeArea.getText()); String text = codeArea.getText(); int lastKwEnd = 0; StyleSpansBuilder> syntaxSpanBuilder = new StyleSpansBuilder<>(); boolean syntaxMatches = false; - while (syntaxMatcher.find()) { - syntaxMatches = true; - String styleClass = - syntaxMatcher.group("PAREN") != null ? "paren" : - syntaxMatcher.group("BRACE") != null ? "brace" : - syntaxMatcher.group("BRACKET") != null ? "bracket" : - syntaxMatcher.group("SEMICOLON") != null ? "semicolon" : - syntaxMatcher.group("FIELDNAME") != null ? "fieldname" : - syntaxMatcher.group("STRING") != null ? "string" : - null; /* never happens */ - assert styleClass != null; - syntaxSpanBuilder.add(Collections.emptyList(), syntaxMatcher.start() - lastKwEnd); - syntaxSpanBuilder.add(Collections.singleton(styleClass), syntaxMatcher.end() - syntaxMatcher.start()); - lastKwEnd = syntaxMatcher.end(); + if(text.length() <= maxCharactersSyntaxHighlighting.get()) { + Matcher syntaxMatcher = SYNTAX_PATTERN.matcher(text); + while (syntaxMatcher.find()) { + syntaxMatches = true; + String styleClass = + syntaxMatcher.group("PAREN") != null ? "paren" : + syntaxMatcher.group("BRACE") != null ? "brace" : + syntaxMatcher.group("BRACKET") != null ? "bracket" : + syntaxMatcher.group("SEMICOLON") != null ? "semicolon" : + syntaxMatcher.group("FIELDNAME") != null ? "fieldname" : + syntaxMatcher.group("STRING") != null ? "string" : + null; /* never happens */ + assert styleClass != null; + syntaxSpanBuilder.add(Collections.emptyList(), syntaxMatcher.start() - lastKwEnd); + syntaxSpanBuilder.add(Collections.singleton(styleClass), syntaxMatcher.end() - syntaxMatcher.start()); + lastKwEnd = syntaxMatcher.end(); + } } StyleSpans> syntaxSpans = null; if(syntaxMatches){ syntaxSpans = syntaxSpanBuilder.create(); } + StyleSpans> searchSpans = null; if (!StringUtils.isEmpty(regex)) { Pattern searchPattern = Pattern.compile(regex, (caseSensitiveButton.isSelected() ? 0 : Pattern.CASE_INSENSITIVE) + Pattern.MULTILINE); diff --git a/src/main/java/at/esque/kafka/handlers/ConfigHandler.java b/src/main/java/at/esque/kafka/handlers/ConfigHandler.java index 237b3c1..007d243 100644 --- a/src/main/java/at/esque/kafka/handlers/ConfigHandler.java +++ b/src/main/java/at/esque/kafka/handlers/ConfigHandler.java @@ -4,6 +4,7 @@ import at.esque.kafka.cluster.ClusterConfig; import at.esque.kafka.cluster.ClusterConfigs; import at.esque.kafka.cluster.TopicMessageTypeConfig; +import at.esque.kafka.controls.KafkaEsqueCodeArea; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLMapper; @@ -135,6 +136,14 @@ private boolean setDefaultsIfMissing() { settings.put(Settings.TRACE_QUICK_SELECT_ENABLED, Settings.TRACE_QUICK_SELECT_ENABLED_DEFAULT); changed = true; } + if (!settings.containsKey(Settings.SYNTAX_HIGHLIGHT_THRESHOLD_ENABLED)) { + settings.put(Settings.SYNTAX_HIGHLIGHT_THRESHOLD_ENABLED, Settings.SYNTAX_HIGHLIGHT_THRESHOLD_ENABLED_DEFAULT); + changed = true; + } + if (!settings.containsKey(Settings.SYNTAX_HIGHLIGHT_THRESHOLD_CHARACTERS)) { + settings.put(Settings.SYNTAX_HIGHLIGHT_THRESHOLD_CHARACTERS, Settings.SYNTAX_HIGHLIGHT_THRESHOLD_CHARACTERS_DEFAULT); + changed = true; + } return changed; } @@ -213,7 +222,7 @@ public Map getSslProperties(ClusterConfig config) { props.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "SSL"); } - if(config.issuppressSslEndPointIdentification()) { + if (config.issuppressSslEndPointIdentification()) { props.put("ssl.endpoint.identification.algorithm", ""); } @@ -291,4 +300,18 @@ private String getJksStoreLocation(String clusterIdentification, String location } return null; } + + public void configureKafkaEsqueCodeArea(KafkaEsqueCodeArea kafkaEsqueCodeArea) { + String s = settings.get(Settings.SYNTAX_HIGHLIGHT_THRESHOLD_ENABLED); + boolean b = Boolean.parseBoolean(s); + if (b) { + try { + String s2 = settings.get(Settings.SYNTAX_HIGHLIGHT_THRESHOLD_CHARACTERS); + long l = Long.parseLong(s2); + kafkaEsqueCodeArea.maxCharactersSyntaxHighlighting.set(l); + } catch (Exception e) { + kafkaEsqueCodeArea.maxCharactersSyntaxHighlighting.set(Long.parseLong(Settings.SYNTAX_HIGHLIGHT_THRESHOLD_CHARACTERS_DEFAULT)); + } + } + } } diff --git a/src/main/java/at/esque/kafka/handlers/Settings.java b/src/main/java/at/esque/kafka/handlers/Settings.java index 2490d97..60cfd20 100644 --- a/src/main/java/at/esque/kafka/handlers/Settings.java +++ b/src/main/java/at/esque/kafka/handlers/Settings.java @@ -20,6 +20,10 @@ private Settings() { public static final String TRACE_QUICK_SELECT_DURATION_LIST_DEFAULT = "PT2H, P1D, P7D"; public static final String TRACE_QUICK_SELECT_ENABLED = "trace.quick.select.enabled"; public static final String TRACE_QUICK_SELECT_ENABLED_DEFAULT = "true"; + public static final String SYNTAX_HIGHLIGHT_THRESHOLD_ENABLED = "syntax.highlight.threshold.enabled"; + public static final String SYNTAX_HIGHLIGHT_THRESHOLD_ENABLED_DEFAULT = "true"; + public static final String SYNTAX_HIGHLIGHT_THRESHOLD_CHARACTERS = "syntax.highlight.threshold.characters"; + public static final String SYNTAX_HIGHLIGHT_THRESHOLD_CHARACTERS_DEFAULT = "50000"; public static List readDurationSetting(Map settings) { return readDurationSetting(settings.get(TRACE_QUICK_SELECT_DURATION_LIST));