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 40b8574209 Add support to extra annotations for disabledGuiElements,
fixes #6660 (#6661)
40b8574209 is described below
commit 40b857420964a5e2ff96a22111f4f1cbfd31956c
Author: Hans Van Akelyen <[email protected]>
AuthorDate: Thu Feb 26 13:33:55 2026 +0100
Add support to extra annotations for disabledGuiElements, fixes #6660
(#6661)
---
.../hop/core/extension/ExtensionPointMap.java | 4 ++
.../apache/hop/core/gui/plugin/GuiRegistry.java | 70 ++++++++++++++++++++++
.../metadata/serializer/BaseMetadataProvider.java | 5 ++
.../modules/ROOT/pages/disable-ui-elements.adoc | 13 +++-
.../main/java/org/apache/hop/ui/hopgui/HopGui.java | 44 +-------------
.../apache/hop/ui/hopgui/HopGuiEnvironment.java | 67 +++++++--------------
.../configuration/tabs/ConfigPluginOptionsTab.java | 6 ++
7 files changed, 118 insertions(+), 91 deletions(-)
diff --git
a/core/src/main/java/org/apache/hop/core/extension/ExtensionPointMap.java
b/core/src/main/java/org/apache/hop/core/extension/ExtensionPointMap.java
index 34f2b78a12..41b0cf9ac7 100644
--- a/core/src/main/java/org/apache/hop/core/extension/ExtensionPointMap.java
+++ b/core/src/main/java/org/apache/hop/core/extension/ExtensionPointMap.java
@@ -23,6 +23,7 @@ import com.google.common.collect.Table;
import java.util.List;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.hop.core.exception.HopException;
+import org.apache.hop.core.gui.plugin.GuiRegistry;
import org.apache.hop.core.logging.ILogChannel;
import org.apache.hop.core.logging.LogChannel;
import org.apache.hop.core.plugins.IPlugin;
@@ -82,6 +83,9 @@ public class ExtensionPointMap {
* @param extensionPointPlugin
*/
public void addExtensionPoint(IPlugin extensionPointPlugin) {
+ if
(GuiRegistry.getDisabledGuiElements().contains(extensionPointPlugin.getIds()[0]))
{
+ return;
+ }
lock.writeLock().lock();
try {
for (String id : extensionPointPlugin.getIds()) {
diff --git a/core/src/main/java/org/apache/hop/core/gui/plugin/GuiRegistry.java
b/core/src/main/java/org/apache/hop/core/gui/plugin/GuiRegistry.java
index de98795e97..ba83c60b93 100644
--- a/core/src/main/java/org/apache/hop/core/gui/plugin/GuiRegistry.java
+++ b/core/src/main/java/org/apache/hop/core/gui/plugin/GuiRegistry.java
@@ -17,6 +17,7 @@
package org.apache.hop.core.gui.plugin;
+import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -29,8 +30,13 @@ import java.util.Set;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang.StringUtils;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemException;
+import org.apache.hop.core.Const;
import org.apache.hop.core.action.GuiContextAction;
import org.apache.hop.core.action.GuiContextActionFilter;
+import org.apache.hop.core.exception.HopFileException;
+import org.apache.hop.core.exception.HopXmlException;
import org.apache.hop.core.gui.plugin.action.GuiAction;
import org.apache.hop.core.gui.plugin.action.GuiActionFilter;
import org.apache.hop.core.gui.plugin.callback.GuiCallback;
@@ -47,6 +53,10 @@ import
org.apache.hop.core.gui.plugin.toolbar.GuiToolbarElementFilter;
import org.apache.hop.core.gui.plugin.toolbar.GuiToolbarItem;
import org.apache.hop.core.gui.plugin.toolbar.GuiToolbarItemFilter;
import org.apache.hop.core.util.TranslateUtil;
+import org.apache.hop.core.vfs.HopVfs;
+import org.apache.hop.core.xml.XmlHandler;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
/**
* This singleton keeps track of the various GUI elements that are made
plug-able by the developers.
@@ -104,6 +114,66 @@ public class GuiRegistry {
return guiRegistry;
}
+ private static List<String> disabledGuiElements;
+
+ /**
+ * Returns the list of GUI element IDs that should be disabled (excluded
from the UI). Loaded from
+ * disabledGuiElements.xml in the application folder and/or config folder.
Used
+ * by @GuiWidgetElement, @GuiToolbarElement, @GuiContextAction,
@HopPerspectivePlugin, @GuiMenuElement, @GuiTab, @GuiKeyboardShortcut,
@HopMetadata, @ExtensionPoint
+ * and @ConfigPlugin.
+ *
+ * @return List of exclusion IDs (never null)
+ */
+ public static List<String> getDisabledGuiElements() {
+ if (disabledGuiElements == null) {
+ disabledGuiElements = loadDisabledGuiElements();
+ }
+ return disabledGuiElements;
+ }
+
+ private static List<String> loadDisabledGuiElements() {
+ List<String> excluded = new ArrayList<>();
+ try {
+ FileObject applicationFolderFile =
HopVfs.getFileObject("./disabledGuiElements.xml");
+ FileObject configFolderFile =
+ HopVfs.getFileObject(
+ Const.HOP_CONFIG_FOLDER + File.separator +
"disabledGuiElements.xml");
+
+ if (applicationFolderFile.exists()) {
+ String path =
applicationFolderFile.getPath().toAbsolutePath().toString();
+ Document document = XmlHandler.loadXmlFile(path);
+ Node exclusionsNode = XmlHandler.getSubNode(document, "exclusions");
+ if (exclusionsNode != null) {
+ List<Node> exclusionNodes = XmlHandler.getNodes(exclusionsNode,
"exclusion");
+ for (Node exclusionNode : exclusionNodes) {
+ String text = exclusionNode.getTextContent();
+ if (text != null && !text.isBlank()) {
+ excluded.add(text.trim());
+ }
+ }
+ }
+ }
+
+ if (configFolderFile.exists()) {
+ String path = configFolderFile.getPath().toAbsolutePath().toString();
+ Document document = XmlHandler.loadXmlFile(path);
+ Node exclusionsNode = XmlHandler.getSubNode(document, "exclusions");
+ if (exclusionsNode != null) {
+ List<Node> exclusionNodes = XmlHandler.getNodes(exclusionsNode,
"exclusion");
+ for (Node exclusionNode : exclusionNodes) {
+ String text = exclusionNode.getTextContent();
+ if (text != null && !text.isBlank()) {
+ excluded.add(text.trim());
+ }
+ }
+ }
+ }
+ } catch (HopXmlException | FileSystemException | HopFileException e) {
+ // ignore - file may not exist
+ }
+ return excluded;
+ }
+
/**
* Add GUI Menu elements under a particular gui root (example:
HopGui-MainMenu) under a particular
* parent element ID
diff --git
a/core/src/main/java/org/apache/hop/metadata/serializer/BaseMetadataProvider.java
b/core/src/main/java/org/apache/hop/metadata/serializer/BaseMetadataProvider.java
index 8dab58efdb..6d49df7b28 100644
---
a/core/src/main/java/org/apache/hop/metadata/serializer/BaseMetadataProvider.java
+++
b/core/src/main/java/org/apache/hop/metadata/serializer/BaseMetadataProvider.java
@@ -20,6 +20,7 @@ package org.apache.hop.metadata.serializer;
import java.util.ArrayList;
import java.util.List;
import org.apache.hop.core.exception.HopException;
+import org.apache.hop.core.gui.plugin.GuiRegistry;
import org.apache.hop.core.plugins.IPlugin;
import org.apache.hop.core.plugins.PluginRegistry;
import org.apache.hop.core.variables.IVariables;
@@ -41,8 +42,12 @@ public class BaseMetadataProvider {
public <T extends IHopMetadata> List<Class<T>> getMetadataClasses() {
try {
PluginRegistry registry = PluginRegistry.getInstance();
+ List<String> disabledIds = GuiRegistry.getDisabledGuiElements();
List<Class<T>> classes = new ArrayList<>();
for (IPlugin plugin : registry.getPlugins(MetadataPluginType.class)) {
+ if (disabledIds.contains(plugin.getIds()[0])) {
+ continue;
+ }
String className = plugin.getClassMap().get(plugin.getMainType());
Class<?> pluginClass =
registry.getClassLoader(plugin).loadClass(className);
classes.add((Class<T>) pluginClass);
diff --git a/docs/hop-tech-manual/modules/ROOT/pages/disable-ui-elements.adoc
b/docs/hop-tech-manual/modules/ROOT/pages/disable-ui-elements.adoc
index d47b0c0935..db45096fbb 100644
--- a/docs/hop-tech-manual/modules/ROOT/pages/disable-ui-elements.adoc
+++ b/docs/hop-tech-manual/modules/ROOT/pages/disable-ui-elements.adoc
@@ -62,6 +62,17 @@ Example to block calls using any System. methods:
</exclusions>
----
-For each element that needs to be disabled, you can add an extra `<exclusion>`
line. The value equals the ID element used in `@GuiWidgetElement`,
`@GuiToolbarElement` , `@GuiContextAction` or `@HopPerspectivePlugin`
+For each element that needs to be disabled, you can add an extra `<exclusion>`
line. The value equals the ID element used in:
+
+* `@GuiWidgetElement` – use the element's `id`
+* `@GuiToolbarElement` – use the element's `id`
+* `@GuiContextAction` – use the action's `id`
+* `@HopPerspectivePlugin` – use the perspective plugin's `id`
+* `@GuiMenuElement` – use the menu element's `id`
+* `@GuiTab` – use the tab's `id`, or `className#methodName` when `id` is empty
+* `@GuiKeyboardShortcut` – use the shortcut's `className#methodName`
+* `@HopMetadata` – use the metadata plugin id (from `key` or `name` in the
annotation)
+* `@ExtensionPoint` – use the extension point plugin's `id`
+* `@ConfigPlugin` – use the config plugin's `id`
diff --git a/ui/src/main/java/org/apache/hop/ui/hopgui/HopGui.java
b/ui/src/main/java/org/apache/hop/ui/hopgui/HopGui.java
index e87f98b96f..5c7d919cb9 100644
--- a/ui/src/main/java/org/apache/hop/ui/hopgui/HopGui.java
+++ b/ui/src/main/java/org/apache/hop/ui/hopgui/HopGui.java
@@ -19,7 +19,6 @@ package org.apache.hop.ui.hopgui;
import static org.apache.hop.core.Const.getDocUrl;
-import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.nio.file.Files;
@@ -36,8 +35,6 @@ import lombok.Getter;
import lombok.Setter;
import org.apache.commons.io.output.TeeOutputStream;
import org.apache.commons.lang.StringUtils;
-import org.apache.commons.vfs2.FileObject;
-import org.apache.commons.vfs2.FileSystemException;
import org.apache.hop.core.Const;
import org.apache.hop.core.DbCache;
import org.apache.hop.core.HopEnvironment;
@@ -46,8 +43,6 @@ import
org.apache.hop.core.config.DescribedVariablesConfigFile;
import org.apache.hop.core.config.HopConfig;
import org.apache.hop.core.database.DatabaseMeta;
import org.apache.hop.core.exception.HopException;
-import org.apache.hop.core.exception.HopFileException;
-import org.apache.hop.core.exception.HopXmlException;
import org.apache.hop.core.extension.ExtensionPointHandler;
import org.apache.hop.core.extension.HopExtensionPoint;
import org.apache.hop.core.gui.IUndo;
@@ -74,8 +69,6 @@ import org.apache.hop.core.util.TranslateUtil;
import org.apache.hop.core.variables.DescribedVariable;
import org.apache.hop.core.variables.IVariables;
import org.apache.hop.core.variables.Variables;
-import org.apache.hop.core.vfs.HopVfs;
-import org.apache.hop.core.xml.XmlHandler;
import org.apache.hop.i18n.BaseMessages;
import org.apache.hop.i18n.LanguageChoice;
import org.apache.hop.metadata.api.IHasHopMetadataProvider;
@@ -157,8 +150,6 @@ import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
@GuiPlugin(name = "Hop Gui", description = "The main hop graphical user
interface")
@SuppressWarnings("java:S1104")
@@ -564,40 +555,7 @@ public class HopGui
}
private void loadPerspectives() {
- List<String> excludedGuiElements = new ArrayList<>();
-
- // Try loading code exclusions
- try {
- FileObject applicationFolderFile =
HopVfs.getFileObject("./disabledGuiElements.xml");
- FileObject configFolderFile =
- HopVfs.getFileObject(
- Const.HOP_CONFIG_FOLDER + File.separator +
"disabledGuiElements.xml");
- String path = null;
-
- if (applicationFolderFile.exists()) {
- path = applicationFolderFile.getPath().toAbsolutePath().toString();
- Document document = XmlHandler.loadXmlFile(path);
- Node exclusionsNode = XmlHandler.getSubNode(document, "exclusions");
- List<Node> exclusionNodes = XmlHandler.getNodes(exclusionsNode,
"exclusion");
-
- for (Node exclusionNode : exclusionNodes) {
- excludedGuiElements.add(exclusionNode.getTextContent());
- }
- }
-
- if (configFolderFile.exists()) {
- path = configFolderFile.getPath().toAbsolutePath().toString();
- Document document = XmlHandler.loadXmlFile(path);
- Node exclusionsNode = XmlHandler.getSubNode(document, "exclusions");
- List<Node> exclusionNodes = XmlHandler.getNodes(exclusionsNode,
"exclusion");
-
- for (Node exclusionNode : exclusionNodes) {
- excludedGuiElements.add(exclusionNode.getTextContent());
- }
- }
- } catch (HopXmlException | FileSystemException | HopFileException e) {
- // ignore
- }
+ List<String> excludedGuiElements = GuiRegistry.getDisabledGuiElements();
try {
// Preload the perspectives and store them in the manager as well as the
GuiRegistry
diff --git a/ui/src/main/java/org/apache/hop/ui/hopgui/HopGuiEnvironment.java
b/ui/src/main/java/org/apache/hop/ui/hopgui/HopGuiEnvironment.java
index d9e6887d7f..222f7ea71e 100644
--- a/ui/src/main/java/org/apache/hop/ui/hopgui/HopGuiEnvironment.java
+++ b/ui/src/main/java/org/apache/hop/ui/hopgui/HopGuiEnvironment.java
@@ -17,20 +17,14 @@
package org.apache.hop.ui.hopgui;
-import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
-import java.util.ArrayList;
import java.util.List;
-import org.apache.commons.vfs2.FileObject;
-import org.apache.commons.vfs2.FileSystemException;
-import org.apache.hop.core.Const;
import org.apache.hop.core.HopClientEnvironment;
import org.apache.hop.core.action.GuiContextAction;
import org.apache.hop.core.action.GuiContextActionFilter;
import org.apache.hop.core.exception.HopException;
import org.apache.hop.core.exception.HopPluginException;
-import org.apache.hop.core.exception.HopXmlException;
import org.apache.hop.core.gui.plugin.GuiElementType;
import org.apache.hop.core.gui.plugin.GuiPluginType;
import org.apache.hop.core.gui.plugin.GuiRegistry;
@@ -46,16 +40,12 @@ import org.apache.hop.core.plugins.IPlugin;
import org.apache.hop.core.plugins.IPluginType;
import org.apache.hop.core.plugins.PluginRegistry;
import org.apache.hop.core.search.SearchableAnalyserPluginType;
-import org.apache.hop.core.vfs.HopVfs;
-import org.apache.hop.core.xml.XmlHandler;
import org.apache.hop.ui.hopgui.file.HopFileTypePluginType;
import org.apache.hop.ui.hopgui.file.HopFileTypeRegistry;
import org.apache.hop.ui.hopgui.file.IHopFileType;
import org.apache.hop.ui.hopgui.perspective.HopPerspectivePluginType;
import org.apache.hop.ui.util.EnvironmentUtils;
import org.eclipse.swt.SWT;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
public class HopGuiEnvironment extends HopClientEnvironment {
@@ -84,40 +74,7 @@ public class HopGuiEnvironment extends HopClientEnvironment {
* @throws HopException
*/
public static void initGuiPlugins() throws HopException {
- List<String> excludedGuiElements = new ArrayList<>();
-
- // Try loading code exclusions
- try {
- FileObject applicationFolderFile =
HopVfs.getFileObject("./disabledGuiElements.xml");
- FileObject configFolderFile =
- HopVfs.getFileObject(
- Const.HOP_CONFIG_FOLDER + File.separator +
"disabledGuiElements.xml");
- String path;
-
- if (applicationFolderFile.exists()) {
- path = applicationFolderFile.getPath().toAbsolutePath().toString();
- Document document = XmlHandler.loadXmlFile(path);
- Node exclusionsNode = XmlHandler.getSubNode(document, "exclusions");
- List<Node> exclusionNodes = XmlHandler.getNodes(exclusionsNode,
"exclusion");
-
- for (Node exclusionNode : exclusionNodes) {
- excludedGuiElements.add(exclusionNode.getTextContent());
- }
- }
-
- if (configFolderFile.exists()) {
- path = configFolderFile.getPath().toAbsolutePath().toString();
- Document document = XmlHandler.loadXmlFile(path);
- Node exclusionsNode = XmlHandler.getSubNode(document, "exclusions");
- List<Node> exclusionNodes = XmlHandler.getNodes(exclusionsNode,
"exclusion");
-
- for (Node exclusionNode : exclusionNodes) {
- excludedGuiElements.add(exclusionNode.getTextContent());
- }
- }
- } catch (HopXmlException | FileSystemException e) {
- // ignore
- }
+ List<String> excludedGuiElements = GuiRegistry.getDisabledGuiElements();
try {
GuiRegistry guiRegistry = GuiRegistry.getInstance();
@@ -148,7 +105,7 @@ public class HopGuiEnvironment extends HopClientEnvironment
{
List<Method> methods = findDeclaredMethods(guiPluginClass);
for (Method method : methods) {
GuiMenuElement menuElement =
method.getAnnotation(GuiMenuElement.class);
- if (menuElement != null) {
+ if (menuElement != null &&
!excludedGuiElements.contains(menuElement.id())) {
guiRegistry.addGuiMenuElement(guiPluginClassName, menuElement,
method, classLoader);
}
GuiToolbarElement toolbarElement =
method.getAnnotation(GuiToolbarElement.class);
@@ -168,6 +125,11 @@ public class HopGuiEnvironment extends
HopClientEnvironment {
if (EnvironmentUtils.getInstance().isWeb() && shortcut.key() ==
SWT.ESC) {
continue;
}
+ // Use id() if set, otherwise className#methodName for
disabledGuiElements.xml
+ String shortcutId = guiPluginClassName + "#" + method.getName();
+ if (excludedGuiElements.contains(shortcutId)) {
+ continue; // Skip: disabled in disabledGuiElements.xml
+ }
guiRegistry.addKeyboardShortcut(guiPluginClassName, method,
shortcut);
}
GuiOsxKeyboardShortcut osxShortcut =
method.getAnnotation(GuiOsxKeyboardShortcut.class);
@@ -176,6 +138,11 @@ public class HopGuiEnvironment extends
HopClientEnvironment {
if (EnvironmentUtils.getInstance().isWeb() && osxShortcut.key() ==
SWT.ESC) {
continue;
}
+ // Osx shortcut has no id(); use className#methodName for
disabledGuiElements.xml
+ String osxShortcutId = guiPluginClassName + "#" + method.getName();
+ if (excludedGuiElements.contains(osxShortcutId)) {
+ continue; // Skip: disabled in disabledGuiElements.xml
+ }
guiRegistry.addKeyboardShortcut(guiPluginClassName, method,
osxShortcut);
}
GuiContextAction contextAction =
method.getAnnotation(GuiContextAction.class);
@@ -204,8 +171,14 @@ public class HopGuiEnvironment extends
HopClientEnvironment {
}
GuiTab guiTab = method.getAnnotation(GuiTab.class);
- if (guiTab != null && !excludedGuiElements.contains(guiTab.id())) {
- guiRegistry.addGuiTab(guiPluginClassName, method, guiTab,
classLoader);
+ if (guiTab != null) {
+ String tabId =
+ (guiTab.id() != null && !guiTab.id().isBlank())
+ ? guiTab.id()
+ : guiPluginClassName + "#" + method.getName();
+ if (!excludedGuiElements.contains(tabId)) {
+ guiRegistry.addGuiTab(guiPluginClassName, method, guiTab,
classLoader);
+ }
}
}
}
diff --git
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/configuration/tabs/ConfigPluginOptionsTab.java
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/configuration/tabs/ConfigPluginOptionsTab.java
index 90726fbfd9..93991041b4 100644
---
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/configuration/tabs/ConfigPluginOptionsTab.java
+++
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/configuration/tabs/ConfigPluginOptionsTab.java
@@ -20,10 +20,12 @@ package
org.apache.hop.ui.hopgui.perspective.configuration.tabs;
import java.lang.reflect.Method;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.apache.hop.core.Const;
import org.apache.hop.core.config.plugin.ConfigPluginType;
import org.apache.hop.core.gui.plugin.GuiPlugin;
+import org.apache.hop.core.gui.plugin.GuiRegistry;
import org.apache.hop.core.gui.plugin.tab.GuiTab;
import org.apache.hop.core.plugins.IPlugin;
import org.apache.hop.core.plugins.PluginRegistry;
@@ -96,8 +98,12 @@ public class ConfigPluginOptionsTab {
//
pluginDataMap.clear();
PluginRegistry pluginRegistry = PluginRegistry.getInstance();
+ List<String> disabledIds = GuiRegistry.getDisabledGuiElements();
java.util.List<IPlugin> configPlugins =
pluginRegistry.getPlugins(ConfigPluginType.class);
for (IPlugin configPlugin : configPlugins) {
+ if (disabledIds.contains(configPlugin.getIds()[0])) {
+ continue;
+ }
try {
Object emptySourceData = pluginRegistry.loadClass(configPlugin);
GuiPlugin annotation =
emptySourceData.getClass().getAnnotation(GuiPlugin.class);