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/06/01 21:04:34 UTC

[jena] branch main updated: GH-1272: IRI functions need equals that considers the internal state

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 <an...@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) ; }