This is an automated email from the ASF dual-hosted git repository.

hansva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git


The following commit(s) were added to refs/heads/main by this push:
     new c9b5ee6757 hide rdbms editor fields #5699 (#5751)
c9b5ee6757 is described below

commit c9b5ee6757362a4a904717a2278919f9421af341
Author: Bart Maertens <[email protected]>
AuthorDate: Wed Oct 1 21:27:47 2025 +0200

    hide rdbms editor fields #5699 (#5751)
---
 .../apache/hop/core/database/BaseDatabaseMeta.java |  48 +++
 .../org/apache/hop/core/database/DatabaseMeta.java |  34 ++
 .../org/apache/hop/core/database/IDatabase.java    |  26 ++
 .../databricks/DatabricksDatabaseMeta.java         |  46 +++
 .../hop/ui/core/database/DatabaseMetaEditor.java   | 378 ++++++++++++++-------
 .../hop/ui/core/gui/GuiCompositeWidgets.java       |   2 +
 .../database/messages/messages_en_US.properties    |   5 +
 7 files changed, 419 insertions(+), 120 deletions(-)

diff --git 
a/core/src/main/java/org/apache/hop/core/database/BaseDatabaseMeta.java 
b/core/src/main/java/org/apache/hop/core/database/BaseDatabaseMeta.java
index cd9495b42b..5226ab7637 100644
--- a/core/src/main/java/org/apache/hop/core/database/BaseDatabaseMeta.java
+++ b/core/src/main/java/org/apache/hop/core/database/BaseDatabaseMeta.java
@@ -31,6 +31,8 @@ import java.util.Map;
 import java.util.SortedSet;
 import java.util.TreeSet;
 import java.util.stream.Stream;
+import lombok.Getter;
+import lombok.Setter;
 import org.apache.hop.core.Const;
 import org.apache.hop.core.exception.HopDatabaseException;
 import org.apache.hop.core.exception.HopPluginException;
@@ -48,6 +50,8 @@ import org.apache.hop.metadata.api.HopMetadataProperty;
  * This class contains the basic information on a database connection. It is 
not intended to be used
  * other than the inheriting classes such as OracleDatabaseInfo, ...
  */
+@Getter
+@Setter
 public abstract class BaseDatabaseMeta implements Cloneable, IDatabase {
 
   /** The SQL to execute at connect time (right after connecting) */
@@ -108,6 +112,12 @@ public abstract class BaseDatabaseMeta implements 
Cloneable, IDatabase {
   public static final String ID_PASSWORD_LABEL = "password-label";
   public static final String ID_PASSWORD_WIDGET = "password-widget";
 
+  // Standard UI element IDs that can be excluded from database editors
+  public static final String ELEMENT_ID_DATABASE_NAME = "databaseName";
+  public static final String ELEMENT_ID_MANUAL_URL = "manualUrl";
+  public static final String ELEMENT_ID_USERNAME = "username";
+  public static final String ELEMENT_ID_PASSWORD = "password";
+
   /**
    * Boolean to indicate if savepoints can be released Most databases do, so 
we set it to true.
    * Child classes can overwrite with false if need be.
@@ -1386,6 +1396,22 @@ public abstract class BaseDatabaseMeta implements 
Cloneable, IDatabase {
     return true;
   }
 
+  /**
+   * @return true if this is a relational database you can explore. Return 
false for SAP, PALO, etc.
+   */
+  @Override
+  public boolean isTestable() {
+    return true;
+  }
+
+  /**
+   * @return true if this is a relational database for which exploring is 
disabled
+   */
+  @Override
+  public boolean isExploringDisabled() {
+    return false;
+  }
+
   /**
    * @param string
    * @return A string that is properly quoted for use in a SQL statement 
(insert, update, delete,
@@ -1999,4 +2025,26 @@ public abstract class BaseDatabaseMeta implements 
Cloneable, IDatabase {
     }
     return identifier;
   }
+
+  /**
+   * Returns a list of UI element IDs that should be excluded from the 
database editor. Databricks
+   * doesn't need database name or manual URL fields.
+   *
+   * @return List of element IDs to exclude
+   */
+  @Override
+  public List<String> getRemoveItems() {
+    return new ArrayList<>();
+  }
+
+  /**
+   * Returns whether URL information should be hidden in test connection 
dialogs. Databricks URLs
+   * may contain sensitive authentication tokens.
+   *
+   * @return true to hide URL information in test connection results
+   */
+  @Override
+  public boolean isHideUrlInTestConnection() {
+    return false; // don't hide URLs by default, set to true if the url may 
contain sensitive tokens
+  }
 }
diff --git a/core/src/main/java/org/apache/hop/core/database/DatabaseMeta.java 
b/core/src/main/java/org/apache/hop/core/database/DatabaseMeta.java
index 94f44cb35b..58a8a6d9c6 100644
--- a/core/src/main/java/org/apache/hop/core/database/DatabaseMeta.java
+++ b/core/src/main/java/org/apache/hop/core/database/DatabaseMeta.java
@@ -2212,6 +2212,20 @@ public class DatabaseMeta extends HopMetadataBase 
implements Cloneable, IHopMeta
     return iDatabase.isExplorable();
   }
 
+  /**
+   * @return true if this is a relational database for which the connection 
can be tested.
+   */
+  public boolean isTestable() {
+    return iDatabase.isTestable();
+  }
+
+  /**
+   * @return true if this is a relational database for which exploring is 
allowed
+   */
+  public boolean isExploringDisabled() {
+    return iDatabase.isExploringDisabled();
+  }
+
   /**
    * @return The SQL on this database to get a list of sequences.
    */
@@ -2296,4 +2310,24 @@ public class DatabaseMeta extends HopMetadataBase 
implements Cloneable, IHopMeta
   protected IDatabase getDbInterface(String typeCode) throws 
HopDatabaseException {
     return getIDatabase(typeCode);
   }
+
+  /**
+   * Returns a list of UI element IDs that should be excluded from the 
database editor. Databricks
+   * doesn't need database name or manual URL fields.
+   *
+   * @return List of element IDs to exclude
+   */
+  public List<String> getRemoveItems() {
+    return iDatabase.getRemoveItems();
+  }
+
+  /**
+   * Returns whether URL information should be hidden in test connection 
dialogs. Databricks URLs
+   * may contain sensitive authentication tokens.
+   *
+   * @return true to hide URL information in test connection results
+   */
+  public boolean isHideUrlInTestConnection() {
+    return iDatabase.isHideUrlInTestConnection();
+  }
 }
diff --git a/core/src/main/java/org/apache/hop/core/database/IDatabase.java 
b/core/src/main/java/org/apache/hop/core/database/IDatabase.java
index fc320db5de..3d40f72ae3 100644
--- a/core/src/main/java/org/apache/hop/core/database/IDatabase.java
+++ b/core/src/main/java/org/apache/hop/core/database/IDatabase.java
@@ -829,6 +829,16 @@ public interface IDatabase extends Cloneable {
    */
   boolean isExplorable();
 
+  /**
+   * @return true if this is a relational database for which the connection 
can be tested.
+   */
+  boolean isTestable();
+
+  /**
+   * @return true if this is a relational database for which exploring is 
disabled
+   */
+  boolean isExploringDisabled();
+
   /**
    * @return The SQL on this database to get a list of sequences.
    */
@@ -1183,4 +1193,20 @@ public interface IDatabase extends Cloneable {
    *     the clause for.
    */
   String getSqlInsertClauseBeforeFields(IVariables variables, String 
schemaTable);
+
+  /**
+   * Returns a list of UI element IDs that should be excluded from the 
database editor. Databricks
+   * doesn't need database name or manual URL fields.
+   *
+   * @return List of element IDs to exclude
+   */
+  List<String> getRemoveItems();
+
+  /**
+   * Returns whether URL information should be hidden in test connection 
dialogs. Databricks URLs
+   * may contain sensitive authentication tokens.
+   *
+   * @return true to hide URL information in test connection results
+   */
+  boolean isHideUrlInTestConnection();
 }
diff --git 
a/plugins/tech/databricks/src/main/java/org/apache/hop/database/databricks/DatabricksDatabaseMeta.java
 
b/plugins/tech/databricks/src/main/java/org/apache/hop/database/databricks/DatabricksDatabaseMeta.java
index 5d14082914..dbdc393362 100644
--- 
a/plugins/tech/databricks/src/main/java/org/apache/hop/database/databricks/DatabricksDatabaseMeta.java
+++ 
b/plugins/tech/databricks/src/main/java/org/apache/hop/database/databricks/DatabricksDatabaseMeta.java
@@ -18,6 +18,8 @@
 
 package org.apache.hop.database.databricks;
 
+import java.util.Arrays;
+import java.util.List;
 import lombok.Getter;
 import lombok.Setter;
 import org.apache.commons.lang.StringUtils;
@@ -43,6 +45,31 @@ public class DatabricksDatabaseMeta extends BaseDatabaseMeta 
implements IDatabas
 
   public static final Class<?> PKG = DatabricksDatabaseMeta.class;
 
+  @GuiWidgetElement(
+      id = "port",
+      ignored = true,
+      type = GuiElementType.TEXT,
+      parentId = DatabaseMeta.GUI_PLUGIN_ELEMENT_PARENT_ID)
+  @HopMetadataProperty
+  private String port;
+
+  @GuiWidgetElement(
+      id = "databaseName",
+      ignored = true,
+      type = GuiElementType.TEXT,
+      parentId = DatabaseMeta.GUI_PLUGIN_ELEMENT_PARENT_ID)
+  @HopMetadataProperty
+  private String databaseName;
+
+  // Constructor to set default values for ignored fields
+  public DatabricksDatabaseMeta() {
+    super();
+    // Set default values for fields that are ignored in the UI
+    // but still needed for URL construction
+    this.port = "443"; // Default Databricks port
+    this.databaseName = ""; // Not used for Databricks
+  }
+
   @GuiWidgetElement(
       id = "ucHttpPath",
       order = "10",
@@ -156,4 +183,23 @@ public class DatabricksDatabaseMeta extends 
BaseDatabaseMeta implements IDatabas
       "USING"
     };
   }
+
+  /**
+   * Returns a list of UI element IDs that should be excluded from the 
database editor. Only for
+   * elements created directly in DatabaseMetaEditor (not @GuiWidgetElement). 
Databricks doesn't
+   * need manual URL field.
+   *
+   * @return List of element IDs to exclude
+   */
+  @Override
+  public List<String> getRemoveItems() {
+    return Arrays.asList(
+        BaseDatabaseMeta.ELEMENT_ID_MANUAL_URL // We construct the URL 
automatically
+        );
+  }
+
+  @Override
+  public boolean isRequiresName() {
+    return false;
+  }
 }
diff --git 
a/ui/src/main/java/org/apache/hop/ui/core/database/DatabaseMetaEditor.java 
b/ui/src/main/java/org/apache/hop/ui/core/database/DatabaseMetaEditor.java
index 5832a69086..d97efeadf4 100644
--- a/ui/src/main/java/org/apache/hop/ui/core/database/DatabaseMetaEditor.java
+++ b/ui/src/main/java/org/apache/hop/ui/core/database/DatabaseMetaEditor.java
@@ -111,6 +111,7 @@ public class DatabaseMetaEditor extends 
MetadataEditor<DatabaseMeta> {
   private int margin;
 
   private Map<Class<? extends IDatabase>, IDatabase> metaMap;
+  private List<String> excludedElementIds;
 
   /**
    * @param hopGui The hop GUI
@@ -119,8 +120,24 @@ public class DatabaseMetaEditor extends 
MetadataEditor<DatabaseMeta> {
    */
   public DatabaseMetaEditor(
       HopGui hopGui, MetadataManager<DatabaseMeta> manager, DatabaseMeta 
databaseMeta) {
+    this(hopGui, manager, databaseMeta, databaseMeta.getRemoveItems());
+  }
+
+  /**
+   * @param hopGui The hop GUI
+   * @param manager The metadata
+   * @param databaseMeta The object to edit
+   * @param excludedElementIds List of GUI element IDs to exclude from the 
editor
+   */
+  public DatabaseMetaEditor(
+      HopGui hopGui,
+      MetadataManager<DatabaseMeta> manager,
+      DatabaseMeta databaseMeta,
+      List<String> excludedElementIds) {
     super(hopGui, manager, databaseMeta);
     props = PropsUi.getInstance();
+    this.excludedElementIds =
+        excludedElementIds != null ? excludedElementIds : 
databaseMeta.getRemoveItems();
     metaMap = populateMetaMap();
     metaMap.put(databaseMeta.getIDatabase().getClass(), 
databaseMeta.getIDatabase());
   }
@@ -164,7 +181,7 @@ public class DatabaseMetaEditor extends 
MetadataEditor<DatabaseMeta> {
     wIcon.setLayoutData(fdlicon);
     PropsUi.setLook(wIcon);
 
-    // What's the name
+    // What's the name - always required, never excluded
     Label wlName = new Label(parent, SWT.RIGHT);
     PropsUi.setLook(wlName);
     wlName.setText(BaseMessages.getString(PKG, 
"DatabaseDialog.label.ConnectionName"));
@@ -220,9 +237,15 @@ public class DatabaseMetaEditor extends 
MetadataEditor<DatabaseMeta> {
     wName.addListener(SWT.Modify, modifyListener);
     wConnectionType.addListener(SWT.Modify, modifyListener);
     wConnectionType.addListener(SWT.Modify, event -> changeConnectionType());
-    wUsername.addListener(SWT.Modify, modifyListener);
-    wPassword.addListener(SWT.Modify, modifyListener);
-    wManualUrl.addListener(SWT.Modify, modifyListener);
+    if (wUsername != null) {
+      wUsername.addListener(SWT.Modify, modifyListener);
+    }
+    if (wPassword != null) {
+      wPassword.addListener(SWT.Modify, modifyListener);
+    }
+    if (wManualUrl != null) {
+      wManualUrl.addListener(SWT.Modify, modifyListener);
+    }
     wSupportsBoolean.addListener(SWT.Selection, modifyListener);
     wSupportsTimestamp.addListener(SWT.Selection, modifyListener);
     wQuoteAll.addListener(SWT.Selection, modifyListener);
@@ -302,48 +325,52 @@ public class DatabaseMetaEditor extends 
MetadataEditor<DatabaseMeta> {
     wDriverInfo.setLayoutData(fdDriverInfo);
     lastControl = wDriverInfo;
 
-    // Username field
+    // Username field - only create if not excluded
     //
-    wlUsername = new Label(wGeneralComp, SWT.RIGHT);
-    PropsUi.setLook(wlUsername);
-    wlUsername.setText(BaseMessages.getString(PKG, 
"DatabaseDialog.label.Username"));
-    FormData fdlUsername = new FormData();
-    fdlUsername.top = new FormAttachment(lastControl, margin * 2); // At the 
bottom of this tab
-    fdlUsername.left = new FormAttachment(0, 0); // First one in the left top 
corner
-    fdlUsername.right = new FormAttachment(middle, -margin);
-    wlUsername.setLayoutData(fdlUsername);
-    wUsername =
-        new TextVar(manager.getVariables(), wGeneralComp, SWT.SINGLE | 
SWT.LEFT | SWT.BORDER);
-    PropsUi.setLook(wUsername);
-    FormData fdUsername = new FormData();
-    fdUsername.top = new FormAttachment(wlUsername, 0, SWT.CENTER);
-    fdUsername.left = new FormAttachment(middle, 0); // To the right of the 
label
-    fdUsername.right = new FormAttachment(100, 0);
-    wUsername.setLayoutData(fdUsername);
-    lastControl = wUsername;
-
-    // Password field
+    if (!excludedElementIds.contains(BaseDatabaseMeta.ELEMENT_ID_USERNAME)) {
+      wlUsername = new Label(wGeneralComp, SWT.RIGHT);
+      PropsUi.setLook(wlUsername);
+      wlUsername.setText(BaseMessages.getString(PKG, 
"DatabaseDialog.label.Username"));
+      FormData fdlUsername = new FormData();
+      fdlUsername.top = new FormAttachment(lastControl, margin * 2); // At the 
bottom of this tab
+      fdlUsername.left = new FormAttachment(0, 0); // First one in the left 
top corner
+      fdlUsername.right = new FormAttachment(middle, -margin);
+      wlUsername.setLayoutData(fdlUsername);
+      wUsername =
+          new TextVar(manager.getVariables(), wGeneralComp, SWT.SINGLE | 
SWT.LEFT | SWT.BORDER);
+      PropsUi.setLook(wUsername);
+      FormData fdUsername = new FormData();
+      fdUsername.top = new FormAttachment(wlUsername, 0, SWT.CENTER);
+      fdUsername.left = new FormAttachment(middle, 0); // To the right of the 
label
+      fdUsername.right = new FormAttachment(100, 0);
+      wUsername.setLayoutData(fdUsername);
+      lastControl = wUsername;
+    }
+
+    // Password field - only create if not excluded
     //
-    wlPassword = new Label(wGeneralComp, SWT.RIGHT);
-    PropsUi.setLook(wlPassword);
-    wlPassword.setText(BaseMessages.getString(PKG, 
"DatabaseDialog.label.Password"));
-    FormData fdlPassword = new FormData();
-    fdlPassword.top = new FormAttachment(lastControl, margin * 2); // At the 
bottom of this tab
-    fdlPassword.left = new FormAttachment(0, 0); // First one in the left top 
corner
-    fdlPassword.right = new FormAttachment(middle, -margin);
-    wlPassword.setLayoutData(fdlPassword);
-    wPassword =
-        new TextVar(
-            manager.getVariables(),
-            wGeneralComp,
-            SWT.SINGLE | SWT.LEFT | SWT.BORDER | SWT.PASSWORD);
-    PropsUi.setLook(wPassword);
-    FormData fdPassword = new FormData();
-    fdPassword.top = new FormAttachment(wlPassword, 0, SWT.CENTER);
-    fdPassword.left = new FormAttachment(middle, 0); // To the right of the 
label
-    fdPassword.right = new FormAttachment(100, 0);
-    wPassword.setLayoutData(fdPassword);
-    lastControl = wPassword;
+    if (!excludedElementIds.contains(BaseDatabaseMeta.ELEMENT_ID_PASSWORD)) {
+      wlPassword = new Label(wGeneralComp, SWT.RIGHT);
+      PropsUi.setLook(wlPassword);
+      wlPassword.setText(BaseMessages.getString(PKG, 
"DatabaseDialog.label.Password"));
+      FormData fdlPassword = new FormData();
+      fdlPassword.top = new FormAttachment(lastControl, margin * 2); // At the 
bottom of this tab
+      fdlPassword.left = new FormAttachment(0, 0); // First one in the left 
top corner
+      fdlPassword.right = new FormAttachment(middle, -margin);
+      wlPassword.setLayoutData(fdlPassword);
+      wPassword =
+          new TextVar(
+              manager.getVariables(),
+              wGeneralComp,
+              SWT.SINGLE | SWT.LEFT | SWT.BORDER | SWT.PASSWORD);
+      PropsUi.setLook(wPassword);
+      FormData fdPassword = new FormData();
+      fdPassword.top = new FormAttachment(wlPassword, 0, SWT.CENTER);
+      fdPassword.left = new FormAttachment(middle, 0); // To the right of the 
label
+      fdPassword.right = new FormAttachment(100, 0);
+      wPassword.setLayoutData(fdPassword);
+      lastControl = wPassword;
+    }
 
     // Add a composite area
     //
@@ -380,25 +407,27 @@ public class DatabaseMetaEditor extends 
MetadataEditor<DatabaseMeta> {
 
     addCompositeWidgetsUsernamePassword();
 
-    // manual URL field
+    // manual URL field - only create if not excluded
     //
-    Label wlManualUrl = new Label(wGeneralComp, SWT.RIGHT);
-    PropsUi.setLook(wlManualUrl);
-    wlManualUrl.setText(BaseMessages.getString(PKG, 
"DatabaseDialog.label.ManualUrl"));
-    FormData fdlManualUrl = new FormData();
-    fdlManualUrl.top = new FormAttachment(lastControl, margin * 2); // At the 
bottom of this tab
-    fdlManualUrl.left = new FormAttachment(0, 0); // First one in the left top 
corner
-    fdlManualUrl.right = new FormAttachment(middle, -margin);
-    wlManualUrl.setLayoutData(fdlManualUrl);
-    wManualUrl =
-        new TextVar(manager.getVariables(), wGeneralComp, SWT.SINGLE | 
SWT.LEFT | SWT.BORDER);
-    PropsUi.setLook(wManualUrl);
-    FormData fdManualUrl = new FormData();
-    fdManualUrl.top = new FormAttachment(wlManualUrl, 0, SWT.CENTER);
-    fdManualUrl.left = new FormAttachment(middle, 0); // To the right of the 
label
-    fdManualUrl.right = new FormAttachment(100, 0);
-    wManualUrl.setLayoutData(fdManualUrl);
-    wManualUrl.addListener(SWT.Modify, e -> enableFields());
+    if (!excludedElementIds.contains(BaseDatabaseMeta.ELEMENT_ID_MANUAL_URL)) {
+      Label wlManualUrl = new Label(wGeneralComp, SWT.RIGHT);
+      PropsUi.setLook(wlManualUrl);
+      wlManualUrl.setText(BaseMessages.getString(PKG, 
"DatabaseDialog.label.ManualUrl"));
+      FormData fdlManualUrl = new FormData();
+      fdlManualUrl.top = new FormAttachment(lastControl, margin * 2); // At 
the bottom of this tab
+      fdlManualUrl.left = new FormAttachment(0, 0); // First one in the left 
top corner
+      fdlManualUrl.right = new FormAttachment(middle, -margin);
+      wlManualUrl.setLayoutData(fdlManualUrl);
+      wManualUrl =
+          new TextVar(manager.getVariables(), wGeneralComp, SWT.SINGLE | 
SWT.LEFT | SWT.BORDER);
+      PropsUi.setLook(wManualUrl);
+      FormData fdManualUrl = new FormData();
+      fdManualUrl.top = new FormAttachment(wlManualUrl, 0, SWT.CENTER);
+      fdManualUrl.left = new FormAttachment(middle, 0); // To the right of the 
label
+      fdManualUrl.right = new FormAttachment(100, 0);
+      wManualUrl.setLayoutData(fdManualUrl);
+      wManualUrl.addListener(SWT.Modify, e -> enableFields());
+    }
 
     FormData fdGeneralComp = new FormData();
     fdGeneralComp.left = new FormAttachment(0, 0);
@@ -414,10 +443,18 @@ public class DatabaseMetaEditor extends 
MetadataEditor<DatabaseMeta> {
   private void addCompositeWidgetsUsernamePassword() {
     // Add username and password to the mix so folks can enable/disable those
     //
-    
guiCompositeWidgets.getWidgetsMap().put(BaseDatabaseMeta.ID_USERNAME_LABEL, 
wlUsername);
-    
guiCompositeWidgets.getWidgetsMap().put(BaseDatabaseMeta.ID_USERNAME_WIDGET, 
wUsername);
-    
guiCompositeWidgets.getWidgetsMap().put(BaseDatabaseMeta.ID_PASSWORD_LABEL, 
wlPassword);
-    
guiCompositeWidgets.getWidgetsMap().put(BaseDatabaseMeta.ID_PASSWORD_WIDGET, 
wPassword);
+    if (wlUsername != null) {
+      
guiCompositeWidgets.getWidgetsMap().put(BaseDatabaseMeta.ID_USERNAME_LABEL, 
wlUsername);
+    }
+    if (wUsername != null) {
+      
guiCompositeWidgets.getWidgetsMap().put(BaseDatabaseMeta.ID_USERNAME_WIDGET, 
wUsername);
+    }
+    if (wlPassword != null) {
+      
guiCompositeWidgets.getWidgetsMap().put(BaseDatabaseMeta.ID_PASSWORD_LABEL, 
wlPassword);
+    }
+    if (wPassword != null) {
+      
guiCompositeWidgets.getWidgetsMap().put(BaseDatabaseMeta.ID_PASSWORD_WIDGET, 
wPassword);
+    }
   }
 
   private AtomicBoolean busyChangingConnectionType = new AtomicBoolean(false);
@@ -750,9 +787,12 @@ public class DatabaseMetaEditor extends 
MetadataEditor<DatabaseMeta> {
   }
 
   private void enableFields() {
-    boolean manualUrl =
-        StringUtils.isNotEmpty(wManualUrl.getText())
-            && StringUtils.isNotBlank(wManualUrl.getText());
+    boolean manualUrl = false;
+    if (wManualUrl != null) {
+      manualUrl =
+          StringUtils.isNotEmpty(wManualUrl.getText())
+              && StringUtils.isNotBlank(wManualUrl.getText());
+    }
 
     // Also enable/disable the custom native fields
     //
@@ -763,23 +803,31 @@ public class DatabaseMetaEditor extends 
MetadataEditor<DatabaseMeta> {
   private void test() {
     DatabaseMeta meta = new DatabaseMeta();
     getWidgetsContent(meta);
-    testConnection(getShell(), manager.getVariables(), meta);
+    //    boolean hideUrl = shouldHideUrlForDatabase(meta);
+    testConnection(getShell(), manager.getVariables(), meta, 
meta.isHideUrlInTestConnection());
   }
 
   private void explore() {
-    DatabaseMeta meta = new DatabaseMeta();
-    getWidgetsContent(meta);
-    try {
-      DatabaseExplorerDialog dialog =
-          new DatabaseExplorerDialog(
-              getShell(),
-              SWT.NONE,
-              manager.getVariables(),
-              meta,
-              manager.getSerializer().loadAll());
-      dialog.open();
-    } catch (Exception e) {
-      new ErrorDialog(getShell(), "Error", "Error exploring database", e);
+    if (!getMetadata().isExploringDisabled()) {
+      DatabaseMeta meta = new DatabaseMeta();
+      getWidgetsContent(meta);
+      try {
+        DatabaseExplorerDialog dialog =
+            new DatabaseExplorerDialog(
+                getShell(),
+                SWT.NONE,
+                manager.getVariables(),
+                meta,
+                manager.getSerializer().loadAll());
+        dialog.open();
+      } catch (Exception e) {
+        new ErrorDialog(getShell(), "Error", "Error exploring database", e);
+      }
+    } else {
+      MessageBox mb = new MessageBox(HopGui.getInstance().getShell(), SWT.OK | 
SWT.ICON_ERROR);
+      mb.setText(BaseMessages.getString(PKG, 
"DatabaseDialog.Exploring.Disabled.title"));
+      mb.setMessage(BaseMessages.getString(PKG, 
"DatabaseDialog.Exploring.Disabled.description"));
+      mb.open();
     }
   }
 
@@ -802,15 +850,21 @@ public class DatabaseMetaEditor extends 
MetadataEditor<DatabaseMeta> {
     wName.setText(Const.NVL(databaseMeta.getName(), ""));
     wConnectionType.setText(Const.NVL(databaseMeta.getPluginName(), ""));
 
-    wUsername.setText(Const.NVL(databaseMeta.getUsername(), ""));
-    wPassword.setText(Const.NVL(databaseMeta.getPassword(), ""));
+    if (wUsername != null) {
+      wUsername.setText(Const.NVL(databaseMeta.getUsername(), ""));
+    }
+    if (wPassword != null) {
+      wPassword.setText(Const.NVL(databaseMeta.getPassword(), ""));
+    }
 
     guiCompositeWidgets.setWidgetsContents(
         databaseMeta.getIDatabase(),
         wDatabaseSpecificComp,
         DatabaseMeta.GUI_PLUGIN_ELEMENT_PARENT_ID);
 
-    wManualUrl.setText(Const.NVL(databaseMeta.getManualUrl(), ""));
+    if (wManualUrl != null) {
+      wManualUrl.setText(Const.NVL(databaseMeta.getManualUrl(), ""));
+    }
     wSupportsBoolean.setSelection(databaseMeta.supportsBooleanDataType());
     wSupportsTimestamp.setSelection(databaseMeta.supportsTimestampDataType());
     wQuoteAll.setSelection(databaseMeta.isQuoteAllFields());
@@ -850,9 +904,24 @@ public class DatabaseMetaEditor extends 
MetadataEditor<DatabaseMeta> {
         meta.getIDatabase(), DatabaseMeta.GUI_PLUGIN_ELEMENT_PARENT_ID);
 
     meta.setAccessType(DatabaseMeta.TYPE_ACCESS_NATIVE);
-    meta.setManualUrl(wManualUrl.getText());
-    meta.setUsername(wUsername.getText());
-    meta.setPassword(wPassword.getText());
+    if (wManualUrl != null) {
+      meta.setManualUrl(wManualUrl.getText());
+    } else {
+      // Initialize excluded manual URL field with empty string to prevent 
null pointer exceptions
+      meta.setManualUrl("");
+    }
+    if (wUsername != null) {
+      meta.setUsername(wUsername.getText());
+    } else {
+      // Initialize excluded username field with empty string
+      meta.setUsername("");
+    }
+    if (wPassword != null) {
+      meta.setPassword(wPassword.getText());
+    } else {
+      // Initialize excluded password field with empty string
+      meta.setPassword("");
+    }
     meta.setSupportsBooleanDataType(wSupportsBoolean.getSelection());
     meta.setSupportsTimestampDataType(wSupportsTimestamp.getSelection());
     meta.setQuoteAllFields(wQuoteAll.getSelection());
@@ -897,45 +966,114 @@ public class DatabaseMetaEditor extends 
MetadataEditor<DatabaseMeta> {
   /** Test the database connection */
   public static final void testConnection(
       Shell shell, IVariables variables, DatabaseMeta databaseMeta) {
-    String[] remarks = databaseMeta.checkParameters();
-    if (remarks.length == 0) {
-      // Get a "test" report from this database
-      DatabaseTestResults databaseTestResults = 
databaseMeta.testConnectionSuccess(variables);
-      String message = databaseTestResults.getMessage();
-      boolean success = databaseTestResults.isSuccess();
-      String title =
-          success
-              ? BaseMessages.getString(PKG, 
"DatabaseDialog.DatabaseConnectionTestSuccess.title")
-              : BaseMessages.getString(PKG, 
"DatabaseDialog.DatabaseConnectionTest.title");
-      if (success && message.contains(Const.CR)) {
-        message =
-            message.substring(0, message.indexOf(Const.CR))
-                + Const.CR
-                + message.substring(message.indexOf(Const.CR));
-        message = message.substring(0, message.lastIndexOf(Const.CR));
+    testConnection(shell, variables, databaseMeta, false);
+  }
+
+  /**
+   * Test the database connection with option to hide sensitive URL information
+   *
+   * @param shell The shell for the dialog
+   * @param variables The variables to use
+   * @param databaseMeta The database metadata
+   * @param hideUrl Whether to hide URL information from the test results
+   */
+  public static final void testConnection(
+      Shell shell, IVariables variables, DatabaseMeta databaseMeta, boolean 
hideUrl) {
+    if (databaseMeta.isTestable()) {
+      String[] remarks = databaseMeta.checkParameters();
+      if (remarks.length == 0) {
+        // Get a "test" report from this database
+        DatabaseTestResults databaseTestResults = 
databaseMeta.testConnectionSuccess(variables);
+        String message = databaseTestResults.getMessage();
+
+        // Hide URL information if requested
+        if (hideUrl && message != null) {
+          message = hideUrlInMessage(message, databaseMeta, variables);
+        }
+        boolean success = databaseTestResults.isSuccess();
+        String title =
+            success
+                ? BaseMessages.getString(PKG, 
"DatabaseDialog.DatabaseConnectionTestSuccess.title")
+                : BaseMessages.getString(PKG, 
"DatabaseDialog.DatabaseConnectionTest.title");
+        if (success && message.contains(Const.CR)) {
+          message =
+              message.substring(0, message.indexOf(Const.CR))
+                  + Const.CR
+                  + message.substring(message.indexOf(Const.CR));
+          message = message.substring(0, message.lastIndexOf(Const.CR));
+        }
+        ShowMessageDialog msgDialog =
+            new ShowMessageDialog(
+                shell, SWT.ICON_INFORMATION | SWT.OK, title, message, 
message.length() > 300);
+        msgDialog.setType(
+            success
+                ? Const.SHOW_MESSAGE_DIALOG_DB_TEST_SUCCESS
+                : Const.SHOW_MESSAGE_DIALOG_DB_TEST_DEFAULT);
+        msgDialog.open();
+      } else {
+        String message = "";
+        for (int i = 0; i < remarks.length; i++) {
+          message += "    * " + remarks[i] + Const.CR;
+        }
+
+        MessageBox mb = new MessageBox(shell, SWT.OK | SWT.ICON_ERROR);
+        mb.setText(BaseMessages.getString(PKG, 
"DatabaseDialog.ErrorParameters2.title"));
+        mb.setMessage(
+            BaseMessages.getString(PKG, 
"DatabaseDialog.ErrorParameters2.description", message));
+        mb.open();
       }
-      ShowMessageDialog msgDialog =
-          new ShowMessageDialog(
-              shell, SWT.ICON_INFORMATION | SWT.OK, title, message, 
message.length() > 300);
-      msgDialog.setType(
-          success
-              ? Const.SHOW_MESSAGE_DIALOG_DB_TEST_SUCCESS
-              : Const.SHOW_MESSAGE_DIALOG_DB_TEST_DEFAULT);
-      msgDialog.open();
     } else {
-      String message = "";
-      for (int i = 0; i < remarks.length; i++) {
-        message += "    * " + remarks[i] + Const.CR;
-      }
-
+      String message = databaseMeta.getPluginName();
       MessageBox mb = new MessageBox(shell, SWT.OK | SWT.ICON_ERROR);
-      mb.setText(BaseMessages.getString(PKG, 
"DatabaseDialog.ErrorParameters2.title"));
+      mb.setText(BaseMessages.getString(PKG, 
"DatabaseDialog.Testing.Disabled.title"));
       mb.setMessage(
-          BaseMessages.getString(PKG, 
"DatabaseDialog.ErrorParameters2.description", message));
+          BaseMessages.getString(PKG, 
"DatabaseDialog.Testing.Disabled.description", message));
       mb.open();
     }
   }
 
+  /**
+   * Helper method to hide URL information from connection test messages
+   *
+   * @param message The original message
+   * @param databaseMeta The database metadata
+   * @param variables The variables
+   * @return The message with URL information hidden
+   */
+  private static String hideUrlInMessage(
+      String message, DatabaseMeta databaseMeta, IVariables variables) {
+    if (message == null) {
+      return message;
+    }
+
+    try {
+      // Get the actual URL to replace it
+      String url = databaseMeta.getURL(variables);
+      if (url != null && !url.isEmpty()) {
+        // Replace the full URL with a masked version
+        String maskedUrl = BaseMessages.getString(PKG, 
"DatabaseDialog.Url.Hidden");
+        message = message.replace(url, maskedUrl);
+      }
+
+      // Also hide any manual URL if present
+      String manualUrl = databaseMeta.getManualUrl();
+      if (manualUrl != null && !manualUrl.isEmpty()) {
+        String resolvedManualUrl = variables.resolve(manualUrl);
+        message =
+            message.replace(
+                resolvedManualUrl, BaseMessages.getString(PKG, 
"DatabaseDialog.Url.Hidden"));
+        message =
+            message.replace(manualUrl, BaseMessages.getString(PKG, 
"DatabaseDialog.Url.Hidden"));
+      }
+
+    } catch (Exception e) {
+      // If there's any issue getting the URL, just return the original message
+      // We don't want to break the test connection functionality
+    }
+
+    return message;
+  }
+
   private String[] getConnectionTypes() {
     PluginRegistry registry = PluginRegistry.getInstance();
     List<IPlugin> plugins = registry.getPlugins(DatabasePluginType.class);
diff --git 
a/ui/src/main/java/org/apache/hop/ui/core/gui/GuiCompositeWidgets.java 
b/ui/src/main/java/org/apache/hop/ui/core/gui/GuiCompositeWidgets.java
index b616bff52a..50c472cf88 100644
--- a/ui/src/main/java/org/apache/hop/ui/core/gui/GuiCompositeWidgets.java
+++ b/ui/src/main/java/org/apache/hop/ui/core/gui/GuiCompositeWidgets.java
@@ -693,6 +693,7 @@ public class GuiCompositeWidgets {
     if (guiElements.isIgnored()) {
       return;
     }
+
     // No data to set for a button widget
     if (guiElements.getType() == GuiElementType.BUTTON) {
       return;
@@ -803,6 +804,7 @@ public class GuiCompositeWidgets {
     if (guiElements.isIgnored()) {
       return;
     }
+
     // No data to retrieve from a button widget
     if (guiElements.getType() == GuiElementType.BUTTON) {
       return;
diff --git 
a/ui/src/main/resources/org/apache/hop/ui/core/database/messages/messages_en_US.properties
 
b/ui/src/main/resources/org/apache/hop/ui/core/database/messages/messages_en_US.properties
index 48a4d50bd8..4b39be24ea 100644
--- 
a/ui/src/main/resources/org/apache/hop/ui/core/database/messages/messages_en_US.properties
+++ 
b/ui/src/main/resources/org/apache/hop/ui/core/database/messages/messages_en_US.properties
@@ -53,3 +53,8 @@ DatabaseDialog.OptionsTab.title=Options
 DatabaseExplorerDialog.Toolbar.CollapseAll.Tooltip=Collapse all
 DatabaseExplorerDialog.Toolbar.ExpandAll.Tooltip=Expand all
 DatabaseToolbarItem.ClearDatabaseCache.ToolTip=Clear the database cache
+DatabaseDialog.Url.Hidden=[REDACTED]
+DatabaseDialog.Testing.Disabled.title=Testing not available
+DatabaseDialog.Testing.Disabled.description=Testing is not available for 
connections to {0}
+DatabaseDialog.Exploring.Disabled.title=Exploring disabled
+DatabaseDialog.Exploring.Disabled.description=Exploring is disabled for this 
connection

Reply via email to