You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2022/07/08 13:43:21 UTC

[jena] branch main updated: GH-1374: add Context#withFunctionRegistries(Context) and QueryExecutionFactory#create(Query, Graph, Context) helpers

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

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


The following commit(s) were added to refs/heads/main by this push:
     new 3ca8a33851 GH-1374: add Context#withFunctionRegistries(Context) and QueryExecutionFactory#create(Query, Graph, Context) helpers
     new 8424682a4b Merge pull request #1375 from sszuev/main
3ca8a33851 is described below

commit 3ca8a338516410601c3abd0e48f6c21d9f25c89c
Author: sszuev <ss...@gmail.com>
AuthorDate: Sun Jun 12 09:34:17 2022 +0300

    GH-1374: add Context#withFunctionRegistries(Context) and QueryExecutionFactory#create(Query, Graph, Context) helpers
---
 .../jena/sparql/function/FunctionRegistry.java     |  13 +++
 .../sparql/pfunction/PropertyFunctionRegistry.java |  13 +++
 .../sparql/service/ServiceExecutorRegistry.java    |  14 +++
 .../org/apache/jena/sparql/util/ContextUtils.java  |  30 ++++++
 .../java/org/apache/jena/sparql/util/TS_Util.java  |   3 +-
 .../apache/jena/sparql/util/TestContextUtils.java  | 111 +++++++++++++++++++++
 6 files changed, 183 insertions(+), 1 deletion(-)

diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/function/FunctionRegistry.java b/jena-arq/src/main/java/org/apache/jena/sparql/function/FunctionRegistry.java
index 8f3e0f021c..a0dcddb695 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/function/FunctionRegistry.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/function/FunctionRegistry.java
@@ -70,6 +70,19 @@ public class FunctionRegistry
         context.set(ARQConstants.registryFunctions, reg);
     }
 
+    /**
+     * Copies the origin registry into a new one, or makes a fresh instance if the specified registry is {@code null).
+     * @param from {@link FunctionRegistry } or {@code null}
+     * @return {@link FunctionRegistry} a new instance
+     */
+    public static FunctionRegistry createFrom(FunctionRegistry from) {
+        FunctionRegistry res = new FunctionRegistry();
+        if (from != null) {
+            res.registry.putAll(from.registry);
+        }
+        return res;
+    }
+
     public FunctionRegistry()
     {}
 
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/PropertyFunctionRegistry.java b/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/PropertyFunctionRegistry.java
index e4d07e6d0a..c5fe8612fa 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/PropertyFunctionRegistry.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/PropertyFunctionRegistry.java
@@ -74,6 +74,19 @@ public class PropertyFunctionRegistry
         return reg;
     }
 
+    /**
+     * Copies the origin registry into a new one, or makes a fresh instance if the specified registry is {@code null).
+     * @param from {@link PropertyFunctionRegistry} or {@code null}
+     * @return {@link PropertyFunctionRegistry} a new instance
+     */
+    public static PropertyFunctionRegistry createFrom(PropertyFunctionRegistry from) {
+        PropertyFunctionRegistry res = new PropertyFunctionRegistry();
+        if (from != null) {
+            res.registry.putAll(from.registry);
+        }
+        return res;
+    }
+
     /** Insert an PropertyFunction class.
      *  Re-inserting with the same URI overwrites the old entry.
      *  New instance created on retrieval (auto-factory)
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/service/ServiceExecutorRegistry.java b/jena-arq/src/main/java/org/apache/jena/sparql/service/ServiceExecutorRegistry.java
index 6390889bc9..70b28eb16e 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/service/ServiceExecutorRegistry.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/service/ServiceExecutorRegistry.java
@@ -115,6 +115,20 @@ public class ServiceExecutorRegistry
         context.set(ARQConstants.registryServiceExecutors, reg) ;
     }
 
+    /**
+     * Copies the origin registry into a new one, or makes a fresh instance if the specified registry is {@code null).
+     * @param from {@link ServiceExecutorRegistry} or {@code null}
+     * @return {@link ServiceExecutorRegistry} a new instance
+     */
+    public static ServiceExecutorRegistry createFrom(ServiceExecutorRegistry from) {
+        ServiceExecutorRegistry res = new ServiceExecutorRegistry();
+        if (from != null) {
+            res.bulkChain.addAll(from.bulkChain);
+            res.singleChain.addAll(from.singleChain);
+        }
+        return res;
+    }
+
     public ServiceExecutorRegistry()
     {}
 
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/ContextUtils.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/ContextUtils.java
new file mode 100644
index 0000000000..a5c6073028
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/ContextUtils.java
@@ -0,0 +1,30 @@
+package org.apache.jena.sparql.util;
+
+import org.apache.jena.sparql.function.FunctionRegistry;
+import org.apache.jena.sparql.pfunction.PropertyFunctionRegistry;
+import org.apache.jena.sparql.service.ServiceExecutorRegistry;
+
+/**
+ * Utils to work with {@link Context}.
+ */
+public class ContextUtils {
+
+    /**
+     * Copies the given context also copying its registries
+     * ({@link FunctionRegistry}, {@link PropertyFunctionRegistry} and {@link ServiceExecutorRegistry}).
+     * If the input context is null, then method just creates a new empty instance.
+     *
+     * @param from {@link Context} or {@code null}
+     * @return a new {@link Context} instance
+     */
+    public static Context copyWithRegistries(Context from) {
+        FunctionRegistry fr = FunctionRegistry.createFrom(FunctionRegistry.get(from));
+        PropertyFunctionRegistry pfr = PropertyFunctionRegistry.createFrom(PropertyFunctionRegistry.get(from));
+        ServiceExecutorRegistry ser = ServiceExecutorRegistry.createFrom(ServiceExecutorRegistry.get(from));
+        Context res = from == null ? new Context() : from.copy();
+        FunctionRegistry.set(res, fr);
+        PropertyFunctionRegistry.set(res, pfr);
+        ServiceExecutorRegistry.set(res, ser);
+        return res;
+    }
+}
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/util/TS_Util.java b/jena-arq/src/test/java/org/apache/jena/sparql/util/TS_Util.java
index 05d7212b10..7ecb07a1f6 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/util/TS_Util.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/util/TS_Util.java
@@ -27,7 +27,8 @@ import org.junit.runners.Suite.SuiteClasses ;
     TestDateTimeParsing.class ,
     TestList.class ,
     TestFmtUtils.class,
-    TestVersion.class
+    TestVersion.class,
+    TestContextUtils.class,
 })
 public class TS_Util
 { }
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/util/TestContextUtils.java b/jena-arq/src/test/java/org/apache/jena/sparql/util/TestContextUtils.java
new file mode 100644
index 0000000000..4ea8ba3dd0
--- /dev/null
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/util/TestContextUtils.java
@@ -0,0 +1,111 @@
+package org.apache.jena.sparql.util;
+
+import org.apache.jena.graph.Node;
+import org.apache.jena.sparql.ARQConstants;
+import org.apache.jena.sparql.engine.ExecutionContext;
+import org.apache.jena.sparql.engine.QueryIterator;
+import org.apache.jena.sparql.engine.binding.Binding;
+import org.apache.jena.sparql.expr.NodeValue;
+import org.apache.jena.sparql.function.Function;
+import org.apache.jena.sparql.function.FunctionBase1;
+import org.apache.jena.sparql.function.FunctionFactory;
+import org.apache.jena.sparql.function.FunctionRegistry;
+import org.apache.jena.sparql.pfunction.PFuncSimple;
+import org.apache.jena.sparql.pfunction.PropertyFunction;
+import org.apache.jena.sparql.pfunction.PropertyFunctionFactory;
+import org.apache.jena.sparql.pfunction.PropertyFunctionRegistry;
+import org.apache.jena.sparql.service.ServiceExecutorRegistry;
+import org.apache.jena.sparql.service.bulk.ChainingServiceExecutorBulk;
+import org.apache.jena.sparql.service.single.ChainingServiceExecutor;
+import org.apache.jena.sys.JenaSystem;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * To test utility {@link ContextUtils} methods.
+ */
+public class TestContextUtils {
+    @BeforeClass
+    public static void beforeClass() {
+        JenaSystem.init();
+    }
+
+    private static Function mockFunction() {
+        return new FunctionBase1() {
+            @Override
+            public NodeValue exec(NodeValue v) {
+                return null;
+            }
+        };
+    }
+
+    private static PropertyFunction mockPropertyFunction() {
+        return new PFuncSimple() {
+            @Override
+            public QueryIterator execEvaluated(Binding b, Node s, Node p, Node o, ExecutionContext ec) {
+                return null;
+            }
+        };
+    }
+
+    private static ChainingServiceExecutorBulk mockChainingServiceExecutorBulk() {
+        return (opService, input, execCxt, chain) -> null;
+    }
+
+    private static ChainingServiceExecutor mockChainingServiceExecutor() {
+        return (opExecute, opOriginal, binding, execCxt, chain) -> null;
+    }
+
+    @Test
+    public void testCopyWithRegistries() {
+        Context givenContext = new Context();
+        FunctionFactory givenFunctionFactory = uri -> mockFunction();
+        PropertyFunctionFactory givenPFunctionFactory = uri -> mockPropertyFunction();
+        ChainingServiceExecutorBulk givenServiceExecutionFactory = mockChainingServiceExecutorBulk();
+        ChainingServiceExecutor givenChainingServiceExecutor = mockChainingServiceExecutor();
+
+        PropertyFunctionRegistry givenPFunctionRegistry = new PropertyFunctionRegistry();
+        FunctionRegistry givenFunctionRegistry = new FunctionRegistry();
+        ServiceExecutorRegistry givenServiceExecutorRegistry = new ServiceExecutorRegistry();
+        givenFunctionRegistry.put("x", givenFunctionFactory);
+        givenPFunctionRegistry.put("y", givenPFunctionFactory);
+        givenServiceExecutorRegistry.addBulkLink(givenServiceExecutionFactory);
+        givenServiceExecutorRegistry.addSingleLink(givenChainingServiceExecutor);
+
+        givenContext.put(ARQConstants.registryFunctions, givenFunctionRegistry);
+        givenContext.put(ARQConstants.registryPropertyFunctions, givenPFunctionRegistry);
+        givenContext.put(ARQConstants.registryServiceExecutors, givenServiceExecutorRegistry);
+
+        Context actualContext = ContextUtils.copyWithRegistries(givenContext);
+        Assert.assertNotNull(actualContext);
+        Assert.assertNotSame(givenContext, actualContext);
+
+        PropertyFunctionRegistry actualPFunctionRegistry = PropertyFunctionRegistry.get(actualContext);
+        FunctionRegistry actualFunctionRegistry = FunctionRegistry.get(actualContext);
+        ServiceExecutorRegistry actualServiceExecutorRegistry = ServiceExecutorRegistry.get(actualContext);
+
+        Assert.assertNotNull(actualPFunctionRegistry);
+        Assert.assertNotNull(actualFunctionRegistry);
+        Assert.assertNotNull(actualServiceExecutorRegistry);
+
+        Assert.assertNotSame(givenFunctionRegistry, actualFunctionRegistry);
+        Assert.assertNotSame(givenPFunctionRegistry, actualPFunctionRegistry);
+        Assert.assertNotSame(givenServiceExecutorRegistry, actualServiceExecutorRegistry);
+
+        List<FunctionFactory> actualFunctionFactories = new ArrayList<>();
+        actualFunctionRegistry.keys().forEachRemaining(k -> actualFunctionFactories.add(actualFunctionRegistry.get(k)));
+        List<PropertyFunctionFactory> actualPFunctionFactories = new ArrayList<>();
+        actualPFunctionRegistry.keys().forEachRemaining(k -> actualPFunctionFactories.add(actualPFunctionRegistry.get(k)));
+
+        Assert.assertSame(givenPFunctionFactory, actualPFunctionRegistry.get("y"));
+        Assert.assertSame(givenFunctionFactory, actualFunctionRegistry.get("x"));
+        Assert.assertEquals(List.of(givenPFunctionFactory), actualPFunctionFactories);
+        Assert.assertEquals(List.of(givenFunctionFactory), actualFunctionFactories);
+        Assert.assertEquals(List.of(givenServiceExecutionFactory), actualServiceExecutorRegistry.getBulkChain());
+        Assert.assertEquals(List.of(givenChainingServiceExecutor), actualServiceExecutorRegistry.getSingleChain());
+    }
+}