Author: rvesse
Date: Mon Nov 19 19:26:08 2012
New Revision: 1411358
URL: http://svn.apache.org/viewvc?rev=1411358&view=rev
Log:
Initial framework for user defined functions
Added:
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/user/
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/user/Ex
prTransformExpand.java
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/user/Us
erDefinedFunction.java
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/user/Us
erDefinedFunctionDefinition.java
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/user/Us
erDefinedFunctionFactory.java
jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/function/
jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/function/user/
jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/function/user/TS
_UserFunctions.java
jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/function/user/Te
stFunctionExpansion.java
jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/function/user/Te
stUserDefinedFunctionFactory.java
jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/function/user/Te
stUserFunctionsInSparql.java
Modified:
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/Functio
n.java
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/Functio
nFactory.java
Modified:
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/Functio
n.java
URL:
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl
/jena/sparql/function/Function.java?rev=1411358&r1=1411357&r2=1411358&vie
w=diff
=========================================================================
=====
---
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/Functio
n.java (original)
+++
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/Functio
n.java Mon Nov 19 19:26:08 2012
@@ -30,7 +30,7 @@ public interface Function
/** Called during query plan construction immediately after the
* construction of the extension instance.
* Can throw ExprBuildException if something is wrong (like wrong
number of arguments).
- * @param args The parsed arguements
+ * @param args The parsed arguments
*/
public void build(String uri, ExprList args) ;
Modified:
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/Functio
nFactory.java
URL:
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl
/jena/sparql/function/FunctionFactory.java?rev=1411358&r1=1411357&r2=1411
358&view=diff
=========================================================================
=====
---
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/Functio
nFactory.java (original)
+++
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/Functio
nFactory.java Mon Nov 19 19:26:08 2012
@@ -18,10 +18,18 @@
package com.hp.hpl.jena.sparql.function;
+import com.hp.hpl.jena.sparql.sse.builders.ExprBuildException;
-/** Interface for function factories. */
-
+/**
+ * Interface for function factories.
+ */
public interface FunctionFactory
{
+ /**
+ * Create a function with the given URI
+ * @param uri URI
+ * @return Function
+ * @throws ExprBuildException May be thrown if there is a problem
creating a function
+ */
public Function create(String uri) ;
}
Added:
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/user/Ex
prTransformExpand.java
URL:
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl
/jena/sparql/function/user/ExprTransformExpand.java?rev=1411358&view=auto
=========================================================================
=====
---
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/user/Ex
prTransformExpand.java (added)
+++
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/user/Ex
prTransformExpand.java Mon Nov 19 19:26:08 2012
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2012 YarcData LLC All Rights Reserved.
+ */
+
+package com.hp.hpl.jena.sparql.function.user;
+
+import java.util.Map;
+
+import com.hp.hpl.jena.sparql.algebra.Op;
+import com.hp.hpl.jena.sparql.expr.Expr;
+import com.hp.hpl.jena.sparql.expr.ExprFunction;
+import com.hp.hpl.jena.sparql.expr.ExprFunction0;
+import com.hp.hpl.jena.sparql.expr.ExprFunction1;
+import com.hp.hpl.jena.sparql.expr.ExprFunction2;
+import com.hp.hpl.jena.sparql.expr.ExprFunction3;
+import com.hp.hpl.jena.sparql.expr.ExprFunctionN;
+import com.hp.hpl.jena.sparql.expr.ExprFunctionOp;
+import com.hp.hpl.jena.sparql.expr.ExprList;
+import com.hp.hpl.jena.sparql.expr.ExprTransformCopy;
+
+/**
+ * An expression transformer that will expand user defined expressions
so they do not explicitly rely on other user defined functions
+ * @author rvesse
+ *
+ */
+public class ExprTransformExpand extends ExprTransformCopy {
+
+ private Map<String, UserDefinedFunctionDefinition> definitions;
+
+ /**
+ * Creates a new transformer
+ * @param defs User defined function definitions
+ */
+ public ExprTransformExpand(Map<String,
UserDefinedFunctionDefinition> defs) {
+ if (defs == null) throw new IllegalArgumentException("defs
cannot be null");
+ this.definitions = defs;
+ }
+
+ @Override
+ public Expr transform(ExprFunction0 func) {
+ ExprFunction f = func.getFunction();
+ if (this.shouldExpand(f)) {
+ //TODO Need to expand the function
+ return super.transform(func);
+ } else {
+ return super.transform(func);
+ }
+ }
+
+ @Override
+ public Expr transform(ExprFunction1 func, Expr expr1) {
+ // TODO Auto-generated method stub
+ return super.transform(func, expr1);
+ }
+
+ @Override
+ public Expr transform(ExprFunction2 func, Expr expr1, Expr expr2) {
+ // TODO Auto-generated method stub
+ return super.transform(func, expr1, expr2);
+ }
+
+ @Override
+ public Expr transform(ExprFunction3 func, Expr expr1, Expr expr2,
Expr expr3) {
+ // TODO Auto-generated method stub
+ return super.transform(func, expr1, expr2, expr3);
+ }
+
+ @Override
+ public Expr transform(ExprFunctionN func, ExprList args) {
+ // TODO Auto-generated method stub
+ return super.transform(func, args);
+ }
+
+ @Override
+ public Expr transform(ExprFunctionOp funcOp, ExprList args, Op
opArg) {
+ // TODO Auto-generated method stub
+ return super.transform(funcOp, args, opArg);
+ }
+
+ private boolean shouldExpand(ExprFunction func) {
+ return this.definitions.containsKey(func.getFunctionIRI());
+ }
+
+}
Added:
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/user/Us
erDefinedFunction.java
URL:
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl
/jena/sparql/function/user/UserDefinedFunction.java?rev=1411358&view=auto
=========================================================================
=====
---
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/user/Us
erDefinedFunction.java (added)
+++
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/user/Us
erDefinedFunction.java Mon Nov 19 19:26:08 2012
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2012 YarcData LLC All Rights Reserved.
+ */
+
+package com.hp.hpl.jena.sparql.function.user;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import com.hp.hpl.jena.sparql.core.Var;
+import com.hp.hpl.jena.sparql.engine.binding.Binding;
+import com.hp.hpl.jena.sparql.expr.Expr;
+import com.hp.hpl.jena.sparql.expr.ExprList;
+import com.hp.hpl.jena.sparql.expr.ExprTransformSubstitute;
+import com.hp.hpl.jena.sparql.expr.ExprTransformer;
+import com.hp.hpl.jena.sparql.expr.NodeValue;
+import com.hp.hpl.jena.sparql.function.Function;
+import com.hp.hpl.jena.sparql.function.FunctionEnv;
+import com.hp.hpl.jena.sparql.sse.builders.ExprBuildException;
+
+/**
+ * Represents a user defined function
+ * @author rvesse
+ *
+ */
+public class UserDefinedFunction extends UserDefinedFunctionDefinition
implements Function {
+
+ private Expr actualExpr;
+
+ /**
+ * Creates a new user defined function
+ * @param def Function Definition
+ */
+ public UserDefinedFunction(UserDefinedFunctionDefinition def) {
+ super(def.getUri(), def.getBaseExpr(), def.getArgList());
+ }
+
+ /**
+ * Creates a user defined function
+ * @param url Function URL
+ * @param e Expression
+ * @param argList Arguments
+ */
+ public UserDefinedFunction(String url, Expr e, List<Var> argList) {
+ super(url, e, argList);
+ }
+
+ /**
+ * Builds the expression substituting the arguments given into the
base expression to yield the actual expression to evaluate
+ * @throws ExprBuildException Thrown if an expression cannot be
generated
+ */
+ @Override
+ public void build(String uri, ExprList args) {
+ //Substitutes the arguments into the base expression to give
the actual expression to evaluate
+ if (uri == null || !uri.equals(this.getUri())) throw new
ExprBuildException("Incorrect URI passed to build() call, expected <" +
this.getUri() + "> but got <" + uri + ">");
+ if (this.getArgList().size() != args.size()) throw new
ExprBuildException("Incorrect number of arguments for user defined <" +
this.getUri() + "> function");
+
+ Map<String, Expr> substitutions = new HashMap<String, Expr>();
+ for (int i = 0; i < this.getArgList().size(); i++) {
+ substitutions.put(this.getArgList().get(i).getVarName(),
args.get(i));
+ }
+
+ this.actualExpr = ExprTransformer.transform(new
ExprTransformSubstitute(substitutions), this.getBaseExpr());
+ }
+
+ /**
+ * Executes the function
+ */
+ @Override
+ public NodeValue exec(Binding binding, ExprList args, String uri,
FunctionEnv env) {
+ //Evaluate the actual expression
+ return this.actualExpr.eval(binding, env);
+ }
+
+ /**
+ * Gets the actual expression that was built for the function,
assuming {@link #build(String, ExprList)} has been called
+ * @return Expression if built, null otherwise
+ */
+ public Expr getActualExpr() {
+ return this.actualExpr;
+ }
+}
Added:
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/user/Us
erDefinedFunctionDefinition.java
URL:
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl
/jena/sparql/function/user/UserDefinedFunctionDefinition.java?rev=1411358
&view=auto
=========================================================================
=====
---
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/user/Us
erDefinedFunctionDefinition.java (added)
+++
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/user/Us
erDefinedFunctionDefinition.java Mon Nov 19 19:26:08 2012
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2012 YarcData LLC All Rights Reserved.
+ */
+
+package com.hp.hpl.jena.sparql.function.user;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.hp.hpl.jena.sparql.core.Var;
+import com.hp.hpl.jena.sparql.expr.Expr;
+import com.hp.hpl.jena.sparql.function.Function;
+
+/**
+ * Represents the definition of a user defined function
+ * @author rvesse
+ *
+ */
+public class UserDefinedFunctionDefinition {
+
+ private String uri;
+ private Expr expr;
+ private List<Var> argList;
+
+ /**
+ * Creates a user defined function definition
+ * @param uri Function URL
+ * @param e Expression
+ * @param argList Arguments
+ */
+ public UserDefinedFunctionDefinition(String uri, Expr e, List<Var>
argList) {
+ this.uri = uri;
+ this.expr = e;
+ this.argList = new ArrayList<Var>(argList);
+ }
+
+ /**
+ * Gets the base expression
+ * @return Expression
+ */
+ public Expr getBaseExpr() {
+ return this.expr;
+ }
+
+ /**
+ * Gets the argument list
+ * @return Arguments
+ */
+ public List<Var> getArgList() {
+ return this.argList;
+ }
+
+ /**
+ * Gets the function URI
+ * @return URI
+ */
+ public String getUri() {
+ return this.uri;
+ }
+
+ /**
+ * Gets an instance of an actual {@link Function} that can be used
to evaluate this function
+ * @return Function instance
+ */
+ public Function newFunctionInstance() {
+ return new UserDefinedFunction(this);
+ }
+}
Added:
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/user/Us
erDefinedFunctionFactory.java
URL:
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl
/jena/sparql/function/user/UserDefinedFunctionFactory.java?rev=1411358&vi
ew=auto
=========================================================================
=====
---
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/user/Us
erDefinedFunctionFactory.java (added)
+++
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/user/Us
erDefinedFunctionFactory.java Mon Nov 19 19:26:08 2012
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2012 YarcData LLC All Rights Reserved.
+ */
+
+package com.hp.hpl.jena.sparql.function.user;
+
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import com.hp.hpl.jena.sparql.core.Var;
+import com.hp.hpl.jena.sparql.expr.Expr;
+import com.hp.hpl.jena.sparql.function.Function;
+import com.hp.hpl.jena.sparql.function.FunctionFactory;
+import com.hp.hpl.jena.sparql.function.FunctionRegistry;
+import com.hp.hpl.jena.sparql.lang.sparql_11.ParseException;
+import com.hp.hpl.jena.sparql.lang.sparql_11.SPARQLParser11;
+import com.hp.hpl.jena.sparql.sse.builders.ExprBuildException;
+
+/**
+ * A function factory for managing user defined functions
+ * <p>
+ * User defined functions provide a simple mechanism for a user to
inject custom functions into SPARQL processing
+ * without the need to write any code. These functions essentially
act as aliases for another SPARQL expression
+ * and serve as a means to aid users in simplifying their SPARQL
queries.
+ * </p>
+ * <p>
+ * For example we can define a <strong>square</strong> function like
so:
+ * </p>
+ * <pre>
+ * List<Var> args = new ArrayList<Var>(Var.alloc("x"));
+ *
UserDefinedFunctionFactory.getFactory().add("http://example/square", "?x
* ?x", args);
+ * </pre>
+ * <p>
+ * We can then use this in queries like so:
+ * </p>
+ * <pre>
+ * SELECT (<http://example/square>(3) AS ?ThreeSquared) { }
+ * </pre>
+ * <p>
+ * Internally the call to the <strong>square</strong> function is
translated into it's equivalent SPARQL expression and executed in that
form.
+ * </p>
+ * @author rvesse
+ *
+ */
+public class UserDefinedFunctionFactory implements FunctionFactory {
+
+ private static UserDefinedFunctionFactory factory = new
UserDefinedFunctionFactory();
+
+ /**
+ * Gets the static instance of the factory
+ * @return Function Factory
+ */
+ public static UserDefinedFunctionFactory getFactory() {
+ return factory;
+ }
+
+ private Map<String, UserDefinedFunctionDefinition> definitions =
new HashMap<String, UserDefinedFunctionDefinition>();
+
+ /**
+ * Private constructor prevents instantiation
+ */
+ private UserDefinedFunctionFactory() { }
+
+ /**
+ * Creates a function for the given URI
+ * @throws ExprBuildException Thrown if the given URI is not a
known function
+ */
+ @Override
+ public Function create(String uri) {
+ UserDefinedFunctionDefinition def = this.definitions.get(uri);
+ if (def == null) throw new ExprBuildException("Function <" +
uri + "> not known by this function factory");
+ return def.newFunctionInstance();
+ }
+
+ /**
+ * Adds a function
+ * @param uri URI
+ * @param e Expression
+ * @param args Arguments
+ */
+ public void add(String uri, Expr e, List<Var> args) {
+ UserDefinedFunctionDefinition def = new
UserDefinedFunctionDefinition(uri, e, args);
+ this.definitions.put(uri, def);
+ FunctionRegistry.get().put(uri, this);
+ }
+
+ /**
+ * Adds a function
+ * <p>
+ * This method will build the expression to use based on the
expression string given, strings must match the SPARQL expression syntax
e.g.
+ * </p>
+ * <pre>
+ * (?x * ?y) + 5
+ * </pre>
+ * @param uri URI
+ * @param expr Expression String (in SPARQL syntax)
+ * @param args Arguments
+ * @throws ParseException Thrown if the expression string is not
valid syntax
+ */
+ public void add(String uri, String expr, List<Var> args) throws
ParseException {
+ Expr e = new SPARQLParser11(new
StringReader(expr)).Expression();
+ UserDefinedFunctionDefinition def = new
UserDefinedFunctionDefinition(uri, e, args);
+ this.definitions.put(uri, def);
+ FunctionRegistry.get().put(uri, this);
+ }
+
+ /**
+ * Removes a function definition
+ * @param uri URI
+ * @throws NoSuchElementException Thrown if a function with the
given URI does not exist
+ */
+ public void remove(String uri) {
+ if (!this.definitions.containsKey(uri)) throw new
NoSuchElementException("No function definition is associated with the
URI <" + uri + ">");
+ this.definitions.remove(uri);
+ FunctionRegistry.get().remove(uri);
+ }
+
+ /**
+ * Gets the definition of the function (if registered)
+ * @param uri URI
+ * @return Function Definition if registered, null otherwise
+ */
+ public UserDefinedFunctionDefinition get(String uri) {
+ if (!this.definitions.containsKey(uri)) return null;
+ return this.definitions.get(uri);
+ }
+
+ /**
+ * Gets whether a function with the given URI has been registered
+ * @param uri URI
+ * @return True if registered, false otherwise
+ */
+ public boolean isRegistered(String uri) {
+ return this.definitions.containsKey(uri);
+ }
+
+ /**
+ * Clears all function definitions
+ */
+ public void clear() {
+ for (String uri : this.definitions.keySet()) {
+ FunctionRegistry.get().remove(uri);
+ }
+ this.definitions.clear();
+ }
+}
Added:
jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/function/user/TS
_UserFunctions.java
URL:
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/test/java/com/hp/hpl
/jena/sparql/function/user/TS_UserFunctions.java?rev=1411358&view=auto
=========================================================================
=====
---
jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/function/user/TS
_UserFunctions.java (added)
+++
jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/function/user/TS
_UserFunctions.java Mon Nov 19 19:26:08 2012
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2012 YarcData LLC All Rights Reserved.
+ */
+
+package com.hp.hpl.jena.sparql.function.user;
+
+import junit.framework.JUnit4TestAdapter;
+
+import org.junit.BeforeClass;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+import com.hp.hpl.jena.sparql.expr.TS_Expr;
+
+@RunWith(Suite.class)
+@SuiteClasses( {
+ TestUserDefinedFunctionFactory.class,
+ TestFunctionExpansion.class,
+ TestUserFunctionsInSparql.class
+})
+public class TS_UserFunctions {
+
+ public static junit.framework.Test suite() {
+ return new JUnit4TestAdapter(TS_Expr.class);
+ }
+}
Added:
jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/function/user/Te
stFunctionExpansion.java
URL:
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/test/java/com/hp/hpl
/jena/sparql/function/user/TestFunctionExpansion.java?rev=1411358&view=au
to
=========================================================================
=====
---
jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/function/user/Te
stFunctionExpansion.java (added)
+++
jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/function/user/Te
stFunctionExpansion.java Mon Nov 19 19:26:08 2012
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2012 YarcData LLC All Rights Reserved.
+ */
+
+package com.hp.hpl.jena.sparql.function.user;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.hp.hpl.jena.sparql.core.Var;
+import com.hp.hpl.jena.sparql.expr.E_Multiply;
+import com.hp.hpl.jena.sparql.expr.Expr;
+import com.hp.hpl.jena.sparql.expr.ExprList;
+import com.hp.hpl.jena.sparql.expr.ExprVar;
+import com.hp.hpl.jena.sparql.expr.nodevalue.NodeValueBoolean;
+import com.hp.hpl.jena.sparql.expr.nodevalue.NodeValueInteger;
+
+/**
+ * Test for checking that functions are appropriately expanded when
supplied with actual arguments
+ * @author rvesse
+ *
+ */
+public class TestFunctionExpansion {
+
+ @BeforeClass
+ public static void setup() {
+ UserDefinedFunctionFactory.getFactory().clear();
+ }
+
+ @AfterClass
+ public static void teardown() {
+ UserDefinedFunctionFactory.getFactory().clear();
+ }
+
+ @Test
+ public void test_function_expansion_01() {
+ Expr e = new ExprVar("x");
+
UserDefinedFunctionFactory.getFactory().add("http://example/simple", e,
new ArrayList<Var>(e.getVarsMentioned()));
+
+ UserDefinedFunction f = (UserDefinedFunction)
UserDefinedFunctionFactory.getFactory().create("http://example/simple");
+ f.build("http://example/simple", new ExprList(new
NodeValueBoolean(true)));
+
+ Expr actual = f.getActualExpr();
+ Assert.assertFalse(e.equals(actual));
+ Assert.assertEquals(0, actual.getVarsMentioned().size());
+ Assert.assertEquals(new NodeValueBoolean(true), actual);
+ }
+
+ @Test
+ public void test_function_expansion_02() {
+ Expr e = new E_Multiply(new ExprVar("x"), new ExprVar("x"));
+
UserDefinedFunctionFactory.getFactory().add("http://example/square", e,
new ArrayList<Var>(e.getVarsMentioned()));
+
+ UserDefinedFunction f = (UserDefinedFunction)
UserDefinedFunctionFactory.getFactory().create("http://example/square");
+ f.build("http://example/square", new ExprList(new
NodeValueInteger(3)));
+
+ Expr actual = f.getActualExpr();
+ Assert.assertFalse(e.equals(actual));
+ Assert.assertEquals(0, actual.getVarsMentioned().size());
+ Assert.assertEquals(new E_Multiply(new NodeValueInteger(3),
new NodeValueInteger(3)), actual);
+ }
+
+ @Test
+ public void test_function_expansion_03() {
+ Expr e = new E_Multiply(new ExprVar("x"), new ExprVar("y"));
+ List<Var> defArgs = new ArrayList<Var>();
+ defArgs.add(Var.alloc("x"));
+ defArgs.add(Var.alloc("y"));
+
UserDefinedFunctionFactory.getFactory().add("http://example/square", e,
defArgs);
+
+ UserDefinedFunction f = (UserDefinedFunction)
UserDefinedFunctionFactory.getFactory().create("http://example/square");
+ ExprList args = new ExprList();
+ args.add(new NodeValueInteger(3));
+ args.add(new NodeValueInteger(4));
+ f.build("http://example/square", args);
+
+ Expr actual = f.getActualExpr();
+ Assert.assertFalse(e.equals(actual));
+ Assert.assertEquals(0, actual.getVarsMentioned().size());
+ Assert.assertEquals(new E_Multiply(new NodeValueInteger(3),
new NodeValueInteger(4)), actual);
+ }
+}
Added:
jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/function/user/Te
stUserDefinedFunctionFactory.java
URL:
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/test/java/com/hp/hpl
/jena/sparql/function/user/TestUserDefinedFunctionFactory.java?rev=141135
8&view=auto
=========================================================================
=====
---
jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/function/user/Te
stUserDefinedFunctionFactory.java (added)
+++
jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/function/user/Te
stUserDefinedFunctionFactory.java Mon Nov 19 19:26:08 2012
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2012 YarcData LLC All Rights Reserved.
+ */
+
+package com.hp.hpl.jena.sparql.function.user;
+
+import java.util.ArrayList;
+
+import junit.framework.Assert;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.hp.hpl.jena.sparql.core.Var;
+import com.hp.hpl.jena.sparql.expr.E_Multiply;
+import com.hp.hpl.jena.sparql.expr.Expr;
+import com.hp.hpl.jena.sparql.expr.ExprVar;
+import com.hp.hpl.jena.sparql.lang.sparql_11.ParseException;
+
+/**
+ * Tests for the {@link UserDefinedFunctionFactory}
+ * @author rvesse
+ *
+ */
+public class TestUserDefinedFunctionFactory {
+
+ @BeforeClass
+ public static void setup() {
+ UserDefinedFunctionFactory.getFactory().clear();
+ }
+
+ @AfterClass
+ public static void teardown() {
+ UserDefinedFunctionFactory.getFactory().clear();
+ }
+
+ @Test
+ public void test_user_defined_function_factory_instance() {
+ UserDefinedFunctionFactory factory =
UserDefinedFunctionFactory.getFactory();
+ Assert.assertNotNull(factory);
+ }
+
+ @Test
+ public void test_user_defined_function_factory_add_01() {
+ Expr e = new E_Multiply(new ExprVar("x"), new ExprVar("x"));
+
UserDefinedFunctionFactory.getFactory().add("http://example/square", e,
new ArrayList<Var>(e.getVarsMentioned()));
+
Assert.assertTrue(UserDefinedFunctionFactory.getFactory().isRegistered("h
ttp://example/square"));
+ Assert.assertEquals(e,
UserDefinedFunctionFactory.getFactory().get("http://example/square").getB
aseExpr());
+ }
+
+ @Test
+ public void test_user_defined_function_factory_add_02() {
+ Expr e1 = new E_Multiply(new ExprVar("x"), new ExprVar("x"));
+ Expr e2 = new E_Multiply(new ExprVar("y"), new ExprVar("y"));
+
+
UserDefinedFunctionFactory.getFactory().add("http://example/square", e1,
new ArrayList<Var>(e1.getVarsMentioned()));
+
Assert.assertTrue(UserDefinedFunctionFactory.getFactory().isRegistered("h
ttp://example/square"));
+ Assert.assertEquals(e1,
UserDefinedFunctionFactory.getFactory().get("http://example/square").getB
aseExpr());
+
+
UserDefinedFunctionFactory.getFactory().add("http://example/square", e2,
new ArrayList<Var>(e2.getVarsMentioned()));
+
Assert.assertTrue(UserDefinedFunctionFactory.getFactory().isRegistered("h
ttp://example/square"));
+ Assert.assertEquals(e2,
UserDefinedFunctionFactory.getFactory().get("http://example/square").getB
aseExpr());
+ }
+
+ @Test
+ public void test_user_defined_function_factory_add_03() throws
ParseException {
+ Expr e = new E_Multiply(new ExprVar("x"), new ExprVar("x"));
+
+ //Instead of registering the pre-built expression register
using a string for the expression
+
UserDefinedFunctionFactory.getFactory().add("http://example/square", "?x
* ?x", new ArrayList<Var>(e.getVarsMentioned()));
+
+
Assert.assertTrue(UserDefinedFunctionFactory.getFactory().isRegistered("h
ttp://example/square"));
+ Assert.assertEquals(e,
UserDefinedFunctionFactory.getFactory().get("http://example/square").getB
aseExpr());
+ }
+}
Added:
jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/function/user/Te
stUserFunctionsInSparql.java
URL:
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/test/java/com/hp/hpl
/jena/sparql/function/user/TestUserFunctionsInSparql.java?rev=1411358&vie
w=auto
=========================================================================
=====
---
jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/function/user/Te
stUserFunctionsInSparql.java (added)
+++
jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/function/user/Te
stUserFunctionsInSparql.java Mon Nov 19 19:26:08 2012
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2012 YarcData LLC All Rights Reserved.
+ */
+
+package com.hp.hpl.jena.sparql.function.user;
+
+import java.util.ArrayList;
+
+import junit.framework.Assert;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.hp.hpl.jena.graph.Node;
+import com.hp.hpl.jena.query.Query;
+import com.hp.hpl.jena.query.QueryExecution;
+import com.hp.hpl.jena.query.QueryExecutionFactory;
+import com.hp.hpl.jena.query.QueryFactory;
+import com.hp.hpl.jena.query.ResultSet;
+import com.hp.hpl.jena.rdf.model.ModelFactory;
+import com.hp.hpl.jena.sparql.core.Var;
+import com.hp.hpl.jena.sparql.engine.binding.Binding;
+import com.hp.hpl.jena.sparql.expr.E_Multiply;
+import com.hp.hpl.jena.sparql.expr.Expr;
+import com.hp.hpl.jena.sparql.expr.ExprVar;
+import com.hp.hpl.jena.sparql.util.NodeFactory;
+
+/**
+ * Tests that user functions are properly wired in and usable from
SPARQL
+ * @author rvesse
+ *
+ */
+public class TestUserFunctionsInSparql {
+
+ @BeforeClass
+ public static void setup() {
+ UserDefinedFunctionFactory.getFactory().clear();
+
+ //Define a square function
+ Expr square = new E_Multiply(new ExprVar("x"), new
ExprVar("x"));
+
UserDefinedFunctionFactory.getFactory().add("http://example/square",
square, new ArrayList<Var>(square.getVarsMentioned()));
+ }
+
+ @AfterClass
+ public static void teardown() {
+ UserDefinedFunctionFactory.getFactory().clear();
+ }
+
+ @Test
+ public void test_user_functions_in_sparql() {
+
Assert.assertTrue(UserDefinedFunctionFactory.getFactory().isRegistered("h
ttp://example/square"));
+
+ String query = "SELECT (<http://example/square>(2) AS ?square)
{ }";
+ Query q = QueryFactory.create(query);
+
+ QueryExecution qe = QueryExecutionFactory.create(q,
ModelFactory.createDefaultModel());
+ ResultSet rset = qe.execSelect();
+ Assert.assertTrue(rset.hasNext());
+ Binding b = rset.nextBinding();
+ Assert.assertFalse(rset.hasNext());
+ qe.close();
+
+ //Validate returned value
+ Node actual = b.get(Var.alloc("square"));
+ Assert.assertEquals(NodeFactory.intToNode(4), actual);
+ }
+}