From 0b84ee367283e52de4c4d19f8e2d0ac90729f257 Mon Sep 17 00:00:00 2001 From: Florian Esser Date: Wed, 24 Apr 2024 16:41:00 +0200 Subject: [PATCH] feat: add binding to service provider for use in Groovy script Add an additional binding for the Service Provider to Groovy scripts. ING-4265 --- .../plugin.xml | 7 ++ .../core/service/DelegateServiceProvider.java | 44 ++++++++ .../cst/functions/groovy/GroovyConstants.java | 5 + .../functions/groovy/internal/GroovyUtil.java | 4 + .../plugin.xml | 1 + ...mboldt.util.service.provider.delegate.exsd | 102 ++++++++++++++++++ .../RestrictiveGroovyInterceptor.java | 39 +++++++ 7 files changed, 202 insertions(+) create mode 100644 common/plugins/eu.esdihumboldt.hale.common.core/src/eu/esdihumboldt/hale/common/core/service/DelegateServiceProvider.java create mode 100644 util/plugins/eu.esdihumboldt.util.groovy.sandbox/schema/eu.esdihumboldt.util.service.provider.delegate.exsd diff --git a/common/plugins/eu.esdihumboldt.hale.common.core/plugin.xml b/common/plugins/eu.esdihumboldt.hale.common.core/plugin.xml index a68c08c8ea..a8ca5d0f76 100644 --- a/common/plugins/eu.esdihumboldt.hale.common.core/plugin.xml +++ b/common/plugins/eu.esdihumboldt.hale.common.core/plugin.xml @@ -190,6 +190,13 @@ id="eu.esdihumboldt.hale.common.core.qname"> + + + + . + * + * Contributors: + * wetransform GmbH + */ + +package eu.esdihumboldt.hale.common.core.service; + +/** + * A DelegateServiceProvider delegates service requests to an underlying + * ServiceProvider. It implements the ServiceProvider interface and forwards + * getService calls to the specified underlying ServiceProvider. + * + * @author EmanuelaEpure + */ +public class DelegateServiceProvider implements ServiceProvider { + + private final ServiceProvider serviceProvider; + + /** + * Constructs a new DelegateServiceProvider with the specified + * ServiceProvider. + * + * @param serviceProvider the underlying ServiceProvider to delegate to + */ + public DelegateServiceProvider(ServiceProvider serviceProvider) { + this.serviceProvider = serviceProvider; + } + + @Override + public T getService(Class serviceInterface) { + return serviceProvider.getService(serviceInterface); + } + +} diff --git a/cst/plugins/eu.esdihumboldt.cst.functions.groovy/src/eu/esdihumboldt/cst/functions/groovy/GroovyConstants.java b/cst/plugins/eu.esdihumboldt.cst.functions.groovy/src/eu/esdihumboldt/cst/functions/groovy/GroovyConstants.java index 3c293ab165..4f0200bb57 100644 --- a/cst/plugins/eu.esdihumboldt.cst.functions.groovy/src/eu/esdihumboldt/cst/functions/groovy/GroovyConstants.java +++ b/cst/plugins/eu.esdihumboldt.cst.functions.groovy/src/eu/esdihumboldt/cst/functions/groovy/GroovyConstants.java @@ -69,6 +69,11 @@ public interface GroovyConstants { */ public static final String BINDING_INSTANCE_INDEX = "_instanceIndex"; + /** + * Name of the service provider in the binding. + */ + public static final String BINDING_SERVICE_PROVIDER = "_serviceProvider"; + /** * Name of the helper functions accessor. */ diff --git a/cst/plugins/eu.esdihumboldt.cst.functions.groovy/src/eu/esdihumboldt/cst/functions/groovy/internal/GroovyUtil.java b/cst/plugins/eu.esdihumboldt.cst.functions.groovy/src/eu/esdihumboldt/cst/functions/groovy/internal/GroovyUtil.java index 66107c00a4..a32c27ccf5 100644 --- a/cst/plugins/eu.esdihumboldt.cst.functions.groovy/src/eu/esdihumboldt/cst/functions/groovy/internal/GroovyUtil.java +++ b/cst/plugins/eu.esdihumboldt.cst.functions.groovy/src/eu/esdihumboldt/cst/functions/groovy/internal/GroovyUtil.java @@ -43,6 +43,7 @@ import eu.esdihumboldt.hale.common.core.io.Text; import eu.esdihumboldt.hale.common.core.io.project.ProjectInfoService; import eu.esdihumboldt.hale.common.core.report.SimpleLog; +import eu.esdihumboldt.hale.common.core.service.DelegateServiceProvider; import eu.esdihumboldt.hale.common.instance.groovy.InstanceBuilder; import eu.esdihumboldt.hale.common.instance.index.InstanceIndexService; import eu.esdihumboldt.hale.common.instance.index.spatial.SpatialIndexService; @@ -305,6 +306,9 @@ public static Binding createBinding(InstanceBuilder builder, Cell cell, Cell typ binding.setVariable(BINDING_INSTANCE_INDEX, executionContext.getService(InstanceIndexService.class)); + binding.setVariable(BINDING_SERVICE_PROVIDER, + new DelegateServiceProvider(executionContext)); + return binding; } } diff --git a/util/plugins/eu.esdihumboldt.util.groovy.sandbox/plugin.xml b/util/plugins/eu.esdihumboldt.util.groovy.sandbox/plugin.xml index 64c1c129ef..a1adb497ed 100644 --- a/util/plugins/eu.esdihumboldt.util.groovy.sandbox/plugin.xml +++ b/util/plugins/eu.esdihumboldt.util.groovy.sandbox/plugin.xml @@ -2,4 +2,5 @@ + diff --git a/util/plugins/eu.esdihumboldt.util.groovy.sandbox/schema/eu.esdihumboldt.util.service.provider.delegate.exsd b/util/plugins/eu.esdihumboldt.util.groovy.sandbox/schema/eu.esdihumboldt.util.service.provider.delegate.exsd new file mode 100644 index 0000000000..702034d5be --- /dev/null +++ b/util/plugins/eu.esdihumboldt.util.groovy.sandbox/schema/eu.esdihumboldt.util.service.provider.delegate.exsd @@ -0,0 +1,102 @@ + + + + + + + + + [Enter description of this extension point.] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Enter the first release in which this extension point appears.] + + + + + + + + + [Enter extension point usage example here.] + + + + + + + + + [Enter API information here.] + + + + + + + + + [Enter information about supplied implementation of this extension point.] + + + + + diff --git a/util/plugins/eu.esdihumboldt.util.groovy.sandbox/src/eu/esdihumboldt/util/groovy/sandbox/internal/RestrictiveGroovyInterceptor.java b/util/plugins/eu.esdihumboldt.util.groovy.sandbox/src/eu/esdihumboldt/util/groovy/sandbox/internal/RestrictiveGroovyInterceptor.java index 3aa23e30b1..fe5050055d 100644 --- a/util/plugins/eu.esdihumboldt.util.groovy.sandbox/src/eu/esdihumboldt/util/groovy/sandbox/internal/RestrictiveGroovyInterceptor.java +++ b/util/plugins/eu.esdihumboldt.util.groovy.sandbox/src/eu/esdihumboldt/util/groovy/sandbox/internal/RestrictiveGroovyInterceptor.java @@ -53,8 +53,13 @@ import org.codehaus.groovy.runtime.GStringImpl; import org.codehaus.groovy.runtime.InvokerHelper; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.Platform; import org.kohsuke.groovy.sandbox.GroovyInterceptor; +import de.fhg.igd.eclipse.util.extension.ExtensionUtil; import eu.esdihumboldt.util.groovy.sandbox.GroovyRestrictionException; import groovy.lang.Closure; import groovy.lang.GString; @@ -107,6 +112,11 @@ public class RestrictiveGroovyInterceptor extends GroovyInterceptor { */ private static final Set disallowedClosureWriteProperties = new HashSet<>(); + /** + * The extension point identifier. + */ + public static final String EXTENSION_ID = "eu.esdihumboldt.util.service.provider.delegate"; + /** * Allowed packages. */ @@ -170,6 +180,7 @@ public class RestrictiveGroovyInterceptor extends GroovyInterceptor { // Binding classes allowedClasses.add(Timestamp.class); allowedClasses.add(java.sql.Date.class); + addAllowedClassesForID(EXTENSION_ID); // Number formatting allowedClasses.add(NumberFormat.class); @@ -206,6 +217,34 @@ public class RestrictiveGroovyInterceptor extends GroovyInterceptor { disallowedClosureWriteProperties.add("directive"); } + /** + * add allowed classes from the extension point ID + * + * @param extension_point ID + */ + private static void addAllowedClassesForID(String extension_point) { + // Get the extension point + IExtensionPoint extensionPoint = Platform.getExtensionRegistry() + .getExtensionPoint(extension_point); + + // Get all extensions contributed to the extension point + IExtension[] extensions = extensionPoint.getExtensions(); + for (IExtension extension : extensions) { + // Get all configuration elements of the extension + IConfigurationElement[] configElements = extension.getConfigurationElements(); + for (IConfigurationElement configElement : configElements) { + try { + for (IConfigurationElement element : configElement.getChildren("delegate")) { + Class loadedClass = ExtensionUtil.loadClass(element, "class"); + allowedClasses.add(loadedClass); + } + } catch (Exception e) { + // Handle any exceptions + } + } + } + } + /** * AllowedPackage saves information to allow the use of all classes with a * given prefix.