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 b09cb4ed8e GH-1272: IRI functions need equals that considers the internal state new 68b29536e2 Merge pull request #1359 from afs/func-iri-equals b09cb4ed8e is described below commit b09cb4ed8e6405d9cb5d9f456ff25d9019c84f2f Author: Andy Seaborne <a...@apache.org> AuthorDate: Wed Jun 1 20:38:32 2022 +0100 GH-1272: IRI functions need equals that considers the internal state --- .../java/org/apache/jena/sparql/expr/E_IRI.java | 21 ++++++ .../java/org/apache/jena/sparql/expr/E_IRI2.java | 22 ++++++ .../java/org/apache/jena/sparql/expr/E_URI.java | 14 ++++ .../java/org/apache/jena/sparql/expr/E_URI2.java | 15 ++++ .../org/apache/jena/sparql/util/ExprUtils.java | 9 +++ .../apache/jena/sparql/expr/TestExpressions2.java | 80 +++++++++++++++++++++- 6 files changed, 160 insertions(+), 1 deletion(-) diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_IRI.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_IRI.java index 05de07dace..9d7cabcd2e 100644 --- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_IRI.java +++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_IRI.java @@ -18,6 +18,8 @@ package org.apache.jena.sparql.expr; +import java.util.Objects; + import org.apache.jena.query.Query; import org.apache.jena.sparql.ARQConstants; import org.apache.jena.sparql.ARQInternalErrorException; @@ -125,4 +127,23 @@ public class E_IRI extends ExprFunction1 { public Expr getRelExpr() { return relExpr; } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + Objects.hash(parserBase); + return result; + } + + @Override + public boolean equals(Expr obj, boolean bySyntax) { + if ( this == obj ) + return true; + if ( getClass() != obj.getClass() ) + return false; + E_IRI other = (E_IRI)obj; + return Objects.equals(parserBase, other.parserBase) && + Objects.equals(relExpr, other.relExpr); + } } diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_IRI2.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_IRI2.java index b1a8521015..d5b7fa2c0d 100644 --- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_IRI2.java +++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_IRI2.java @@ -20,6 +20,8 @@ package org.apache.jena.sparql.expr; import static org.apache.jena.sparql.expr.E_IRI.resolve; +import java.util.Objects; + import org.apache.jena.sparql.ARQInternalErrorException; import org.apache.jena.sparql.engine.binding.Binding; import org.apache.jena.sparql.function.FunctionEnv; @@ -127,4 +129,24 @@ public class E_IRI2 extends ExprFunction2 { public Expr getBaseExpr() { return baseExpr; } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + Objects.hash(parserBase); + return result; + } + + @Override + public boolean equals(Expr obj, boolean bySyntax) { + if ( this == obj ) + return true; + if ( getClass() != obj.getClass() ) + return false; + E_IRI2 other = (E_IRI2)obj; + return Objects.equals(parserBase, other.parserBase) && + Objects.equals(baseExpr, other.baseExpr) && + Objects.equals(relExpr, other.relExpr); + } } diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_URI.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_URI.java index 8b86c12512..162b001584 100644 --- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_URI.java +++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_URI.java @@ -45,4 +45,18 @@ public class E_URI extends E_IRI { public Expr copy(Expr expr) { return new E_URI(parserBase, expr); } + + @Override + public int hashCode() { + return super.hashCode()+1; + } + + @Override + public boolean equals(Expr obj, boolean bySyntax) { + if ( this == obj ) + return true; + if ( getClass() != obj.getClass() ) + return false; + return super.equals(obj, bySyntax); + } } diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_URI2.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_URI2.java index 904008c91a..5c9f33d813 100644 --- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_URI2.java +++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_URI2.java @@ -45,4 +45,19 @@ public class E_URI2 extends E_IRI2 { public Expr copy(Expr expr1, Expr expr2) { return new E_URI2(expr1, parserBase, expr2); } + + @Override + public int hashCode() { + return super.hashCode()+1; + } + + @Override + public boolean equals(Expr obj, boolean bySyntax) { + if ( this == obj ) + return true; + if ( getClass() != obj.getClass() ) + return false; + return super.equals(obj, bySyntax); + } + } diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/ExprUtils.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/ExprUtils.java index 05657275fb..413ed08822 100644 --- a/jena-arq/src/main/java/org/apache/jena/sparql/util/ExprUtils.java +++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/ExprUtils.java @@ -67,6 +67,15 @@ public class ExprUtils return parse(query, s, true); } + public static Expr parse(String s, PrefixMapping pmap, String baseURI) { + Query query = QueryFactory.make(); + if ( pmap != null ) + query.setPrefixMapping(pmap); + if ( baseURI != null ) + query.setBaseURI(baseURI); + return parse(query, s, true); + } + public static Expr parse(Query query, String s, boolean checkAllUsed) { try { Reader in = new StringReader(s); diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions2.java b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions2.java index bd6f0e0006..632f9c613a 100644 --- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions2.java +++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions2.java @@ -20,8 +20,13 @@ package org.apache.jena.sparql.expr; import static org.junit.Assert.assertEquals; +import org.apache.jena.graph.Node; import org.apache.jena.query.QueryParseException ; +import org.apache.jena.shared.PrefixMapping; +import org.apache.jena.sparql.engine.binding.BindingFactory; import org.apache.jena.sparql.expr.nodevalue.XSDFuncOp ; +import org.apache.jena.sparql.function.FunctionEnvBase; +import org.apache.jena.sparql.sse.SSE; import org.apache.jena.sparql.util.ExprUtils ; import org.junit.Test ; @@ -93,7 +98,80 @@ public class TestExpressions2 // BNODE -> IRI (<_:....>) => string => IRI @Test public void term_constructor_iri_06() { eval("isIRI(IRI(str(IRI(BNODE()))))", true); } - @Test public void term_constructor_bnode_01() { eval("isBlank(BNODE())", true) ; } + @Test public void iri_base_01() { + parseEqualsTest("http://example/", "IRI('x')", "http://base/", "IRI('x')", false); + } + @Test public void iri_base_02() { + parseEqualsTest("http://example/", "IRI('x')", "http://example/", "IRI('x')", true); + } + @Test public void iri_base_03() { + parseEqualsTest("http://example/", "IRI('x1')", "http://example/", "IRI('x2')", false); + } + @Test public void iri_base_04() { + parseEqualsTest("http://example/", "IRI('x')", "http://example/", "URI('x')", false); + } + @Test public void iri_base_05() { + parseEqualsTest("http://example/", "IRI(<base>, 'x')", "http://base/", "IRI(<base>, 'x')", false); + } + @Test public void iri_base_06() { + parseEqualsTest("http://example/", "IRI(<base>, 'x')", "http://example/", "IRI(<base>, 'x')", true); + } + @Test public void iri_base_07() { + parseEqualsTest("http://example/", "IRI(<base>, 'x1')", "http://example/", "IRI(<base>, 'x2')", false); + } + @Test public void iri_base_08() { + parseEqualsTest("http://example/", "IRI(<base>, 'x')", "http://example/", "URI(<base>, 'x')", false); + } + @Test public void iri_base_09() { + parseEqualsTest("http://example/", "IRI(<base1>, 'x')", "http://example/", "IRI(<base2>, 'x')", false); + } + @Test public void iri_base_10() { + parseEqualsTest("http://example/", "IRI(<a/b/c>, 'x')", "http://example/", "IRI(<a/b/c>, <x>)", false); + } + // One arg form. + @Test public void iri_base_20() { + evalTest("http://example/", "IRI('x')", "<http://example/x>"); + } + @Test public void iri_base_21() { + evalTest("http://example/", "IRI(<x>)", "<http://example/x>"); + } + @Test public void iri_base_22() { + evalTest("http://example/", "IRI(<http://host/x>)", "<http://host/x>"); + } + // 2 arg foirm. + @Test public void iri_base_30() { + evalTest("http://example/", "IRI(<base>, 'x')", "<http://example/x>"); + } + @Test public void iri_base_31() { + evalTest("http://example/", "IRI(<http://base/>, 'x')", "<http://base/x>"); + } + @Test public void iri_base_32() { + evalTest("http://example/", "IRI(<a/b/c>, 'x')", "<http://example/a/b/x>"); + } + + private static void evalTest(String parserBase, String exprStr, String result) { + Node expected = SSE.parseNode(result); + Expr expr = expr(parserBase, exprStr); + NodeValue nv = expr.eval(BindingFactory.binding(), new FunctionEnvBase()); + Node actual = nv.asNode(); + assertEquals(expected, actual); + } + + private static void parseEqualsTest(String parserBase1, String exprStr1, + String parserBase2, String exprStr2, + boolean expected) { + Expr expr1 = expr(parserBase1, exprStr1); + Expr expr2 = expr(parserBase2, exprStr2); + boolean b = expr1.equals(expr2); + assertEquals(exprStr1+" equals "+exprStr2, expected, b); + } + + private static Expr expr(String parserBase, String exprStr) { + return ExprUtils.parse(exprStr, (PrefixMapping)null, parserBase); + } + // end IRI and base + + @Test public void term_constructor_bnode_01() { eval("isBlank(BNODE())", true) ; } @Test public void term_constructor_bnode_02() { eval("isBlank(BNODE('abc'))", true) ; } @Test public void term_constructor_bnode_03() { eval("isBlank(BNODE('abc'))", true) ; } @Test public void term_constructor_bnode_04() { eval("BNODE('abc') = BNODE('abc')", true) ; }