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 2025/04/11 07:36:57 UTC
(jena) 02/06: Update result set testing for triple terms
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
commit a3c030c4d8def19017e9da1732c9562285f660ca
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Sun Feb 2 18:19:59 2025 +0000
Update result set testing for triple terms
---
.../org/apache/jena/sparql/exec/RowSetMem.java | 3 +-
.../org/apache/jena/sparql/expr/NodeValue.java | 28 +-
.../jena/sparql/expr/nodevalue/NodeFunctions.java | 38 ++-
.../jena/sparql/resultset/ResultSetCompare.java | 304 ++++--------------
.../jena/sparql/resultset/ResultSetCompare1.java | 346 ++++++++++++++++++++
.../{ResultSetCompare.java => ResultsCompare.java} | 302 +++++++-----------
.../org/apache/jena/sparql/syntax/ElementData.java | 6 +-
.../main/java/org/apache/jena/sparql/util/Iso.java | 214 ++++++-------
.../org/apache/jena/sparql/util/IsoMatcher.java | 24 +-
.../jena/sparql/util/NodeIsomorphismMap.java | 33 +-
.../apache/jena/sparql/util/NodeToLabelMap.java | 92 ++----
.../org/apache/jena/sparql/util/iso/BNodeIso.java | 87 +++++
.../apache/jena/sparql/util/iso/IsoAlgRows.java | 272 ++++++++++++++++
.../util/{IsoAlg.java => iso/IsoAlgTuple.java} | 212 ++++++-------
.../org/apache/jena/sparql/util/iso/IsoLib.java | 125 ++++++++
.../apache/jena/sparql/util/iso/IsoMapping.java | 67 ++++
.../jena/arq/junit/sparql/tests/QueryEvalTest.java | 12 +-
.../apache/jena/atlas/data/DataBagExaminer.java | 17 +-
.../jena/atlas/data/TestDistinctDataBag.java | 88 ++----
.../jena/atlas/data/TestDistinctDataNet.java | 133 +++-----
.../apache/jena/atlas/data/TestSortedDataBag.java | 101 +++---
.../jena/atlas/data/TestThresholdPolicyCount.java | 19 +-
.../jena/riot/protobuf/TestProtobufResultSet.java | 8 +-
.../jena/riot/resultset/TestResultSetIO.java | 6 +-
.../jena/riot/thrift/TestThriftResultSet.java | 8 +-
.../apache/jena/sparql/AbstractTestAdditional.java | 4 +-
.../test/java/org/apache/jena/sparql/TC_ARQ.java | 4 +-
.../algebra/optimize/TestSemanticEquivalence.java | 6 +-
.../sparql/engine/binding/TestBindingStreams.java | 96 +++---
.../jena/sparql/engine/join/AbstractTestJoin.java | 4 +-
.../jena/sparql/engine/join/TestTableJoin.java | 4 +-
.../org/apache/jena/sparql/path/TestPathQuery.java | 9 +-
.../jena/sparql/resultset/TestResultSet.java | 92 +++---
.../sparql/resultset/TestResultSetFormat1.java | 85 +++--
.../java/org/apache/jena/sparql/util/TS_Util.java | 1 -
.../sparql/util/{TS_Util.java => iso/TS_Iso.java} | 14 +-
.../org/apache/jena/sparql/util/iso/TestIso.java | 71 +++++
.../jena/sparql/util/iso/TestIsoAlgRows.java | 351 +++++++++++++++++++++
.../jena/sparql/util/{ => iso}/TestIsoMatcher.java | 24 +-
.../java/org/apache/jena/atlas/lib/ListUtils.java | 6 +-
.../src/main/java/org/apache/jena/graph/Node.java | 7 +-
.../impl/TestServiceEnhancerCachedVsUncached.java | 22 +-
.../org/apache/jena/fuseki/main/TestQuery.java | 7 +-
.../test/service/TestCustomServiceExecutor.java | 17 +-
.../org/apache/jena/tdb1/solver/TestSolverTDB.java | 12 +-
.../org/apache/jena/tdb2/solver/TestSolverTDB.java | 14 +-
46 files changed, 2168 insertions(+), 1227 deletions(-)
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/exec/RowSetMem.java b/jena-arq/src/main/java/org/apache/jena/sparql/exec/RowSetMem.java
index 81fdb73b2d..fbf2e0bbcd 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/exec/RowSetMem.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/exec/RowSetMem.java
@@ -49,8 +49,8 @@ public class RowSetMem implements RowSetRewindable
* @param other The other RowSetMem object
*/
private RowSetMem(RowSetMem other) {
+ // Share vars and rows but not the iterator.
vars = other.vars;
- // Share results (not the iterator).
rows = other.rows;
reset();
}
@@ -61,7 +61,6 @@ public class RowSetMem implements RowSetRewindable
* necessary internal datastructures are shared. This operation destroys
* (uses up) a RowSet object that is not an in-memory one.
*/
-
private RowSetMem(RowSet other) {
if ( other instanceof RowSetMem rsm ) {
// See also the RowSetMem(RowSetMem) constructor.
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java
index 63be42bf31..69c4315fa9 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java
@@ -353,30 +353,28 @@ public abstract class NodeValue extends ExprNode
return makeNode(lexicalForm, XSDdate);
}
- // ----------------------------------------------------------------
- // ---- Expr interface
+ // ----------------------------------------------------------------
+ // ---- Expr interface
- @Override
- public NodeValue eval(Binding binding, FunctionEnv env) {
- return this;
- }
+ @Override
+ public NodeValue eval(Binding binding, FunctionEnv env) {
+ return this;
+ }
- // NodeValues are immutable so no need to duplicate.
- @Override
- public Expr copySubstitute(Binding binding) {
- return this;
- }
+ // NodeValues are immutable so no need to duplicate.
+ @Override
+ public Expr copySubstitute(Binding binding) {
+ return this;
+ }
@Override
- public Expr applyNodeTransform(NodeTransform transform)
- {
+ public Expr applyNodeTransform(NodeTransform transform) {
Node n = asNode();
n = transform.apply(n);
return makeNode(n);
}
- public Node evalNode(Binding binding, ExecutionContext execCxt)
- {
+ public Node evalNode(Binding binding, ExecutionContext execCxt) {
return asNode();
}
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeFunctions.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeFunctions.java
index 52144eccf1..0d04b2021f 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeFunctions.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeFunctions.java
@@ -38,7 +38,6 @@ import org.apache.jena.irix.IRIException;
import org.apache.jena.irix.IRIs;
import org.apache.jena.irix.IRIx;
import org.apache.jena.query.ARQ;
-import org.apache.jena.rdf.model.impl.Util;
import org.apache.jena.riot.out.NodeFmtLib;
import org.apache.jena.riot.system.RiotLib;
import org.apache.jena.sparql.expr.ExprEvalException;
@@ -127,22 +126,31 @@ public class NodeFunctions {
return NodeValue.booleanReturn(sameTerm(nv1.asNode(), nv2.asNode()));
}
+ // Jena - up to Jena 4.
+ // Language tags were kept in the case form they were given as.
+ // Jena5 - language tags are canonicalised.
+
/** sameTerm(x,y) */
public static boolean sameTerm(Node node1, Node node2) {
- if ( node1.equals(node2) )
- return true;
- if ( Util.isLangString(node1) && Util.isLangString(node2) ) {
- String lex1 = node1.getLiteralLexicalForm();
- String lex2 = node2.getLiteralLexicalForm();
- if ( !lex1.equals(lex2) )
- return false;
- return node1.getLiteralLanguage().equalsIgnoreCase(node2.getLiteralLanguage());
- }
- if ( node1.isTripleTerm() && node2.isTripleTerm() ) {
- return sameTriples(node1.getTriple(), node2.getTriple());
- }
- return false;
- }
+ return node1.sameTermAs(node2);
+ }
+
+// /** sameTerm(x,y) */
+// public static boolean sameTerm(Node node1, Node node2) {
+// if ( node1.equals(node2) )
+// return true;
+// if ( Util.isLangString(node1) && Util.isLangString(node2) ) {
+// String lex1 = node1.getLiteralLexicalForm();
+// String lex2 = node2.getLiteralLexicalForm();
+// if ( !lex1.equals(lex2) )
+// return false;
+// return node1.getLiteralLanguage().equalsIgnoreCase(node2.getLiteralLanguage());
+// }
+// if ( node1.isTripleTerm() && node2.isTripleTerm() ) {
+// return sameTriples(node1.getTriple(), node2.getTriple());
+// }
+// return false;
+// }
private static boolean sameTriples(Triple t1, Triple t2) {
return sameTerm(t1.getSubject(), t2.getSubject())
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/resultset/ResultSetCompare.java b/jena-arq/src/main/java/org/apache/jena/sparql/resultset/ResultSetCompare.java
index b18a48fd9f..ebaa375bcc 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/resultset/ResultSetCompare.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/resultset/ResultSetCompare.java
@@ -18,68 +18,23 @@
package org.apache.jena.sparql.resultset;
-import java.util.*;
-
-import org.apache.jena.atlas.iterator.Iter;
-import org.apache.jena.graph.Node;
-import org.apache.jena.graph.Triple;
+import org.apache.jena.atlas.lib.ListUtils;
import org.apache.jena.query.ResultSet;
import org.apache.jena.query.ResultSetFactory;
import org.apache.jena.query.ResultSetRewindable;
import org.apache.jena.rdf.model.Model;
-import org.apache.jena.sparql.core.Var;
-import org.apache.jena.sparql.engine.binding.Binding;
import org.apache.jena.sparql.exec.RowSet;
-import org.apache.jena.sparql.exec.RowSetRewindable;
-import org.apache.jena.sparql.util.EqualityTest;
-import org.apache.jena.sparql.util.Iso;
-import org.apache.jena.sparql.util.NodeIsomorphismMap;
-import org.apache.jena.sparql.util.NodeUtils;
-/** Comparison of ResultSets.
- * Note that reading ResultSets is destructive so consider using {@link ResultSetRewindable}
- * from {@link ResultSetFactory#makeRewindable}
+/**
+ * Comparison of ResultSets.
+ * Note that reading ResultSets is destructive so consider using {@link ResultSetRewindable}
+ * from {@link ResultSetFactory#makeRewindable}.
+ *
+ * @deprecated Use {@link ResultsCompare}.
*/
-
+@Deprecated(forRemoval = true)
public class ResultSetCompare
{
- /* This is from the DAWG test suite.
- * Result set 1:
- * ---------------
- * | x | y |
- * ===============
- * | _:b0 | _:b1 |
- * | _:b2 | _:b3 |
- * | _:b1 | _:b0 |
- * ---------------
- * Result set 2:
- * ---------------
- * | x | y |
- * ===============
- * | _:b1 | _:b0 |
- * | _:b3 | _:b2 |
- * | _:b2 | _:b3 |
- * ---------------
- */
-
-// private static String[] rs1$ = {
-// "(resultset (?x ?y)",
-// " (row (?x _:b0) (?y _:b1))",
-// " (row (?x _:b2) (?y _:b3))",
-// " (row (?x _:b1) (?y _:b0))",
-// ")"};
-// private static String[] rs2$ = {
-// "(resultset (?x ?y)",
-// " (row (?x _:c1) (?y _:c0))",
-// " (row (?x _:c3) (?y _:c2))",
-// " (row (?x _:c2) (?y _:c3))",
-// ")"};
-//
-
- // Limitations:
- // This code does not do compare/isomorphism combined with value testing.
- // It drops to graph isomorphism, which is term based.
-
/** Compare two result sets for equivalence. Equivalence means:
* A row rs1 has one matching row in rs2, and vice versa.
* A row is only matched once.
@@ -98,27 +53,11 @@ public class ResultSetCompare
/** See {@link #equalsByValue(ResultSet, ResultSet)} */
public static boolean equalsByValue(RowSet rs1, RowSet rs2) {
- if ( ! compareHeader(rs1, rs2) ) return false;
-
- RowSetRewindable rs1a = rs1.rewindable();
- RowSetRewindable rs2a = rs2.rewindable();
-
- if ( equivalent(convert(rs1a), convert(rs2a), new BNodeIso(NodeUtils.sameValue)) )
- return true;
- rs1a.reset();
- rs2a.reset();
- return isomorphic(rs1a, rs2a);
- }
-
- public static boolean equalsByTest(Collection<Binding> b1, Collection<Binding> b2, EqualityTest match)
- {
- List<Binding> rows1 = new ArrayList<>(b1);
- List<Binding> rows2 = new ArrayList<>(b2);
- return equivalent(rows1, rows2, match);
+ return ResultsCompare.equalsByValue(rs1, rs2);
}
-
- /** compare two result sets for equivalence. Equivalence means:
+ /**
+ * Compare two result sets for equivalence. Equivalence means:
* A row rs1 has one matching row in rs2, and vice versa.
* A row is only matched once.
* Rows match if they have the same variables with the same values,
@@ -132,22 +71,24 @@ public class ResultSetCompare
*/
public static boolean equalsByTerm(ResultSet rs1, ResultSet rs2) {
- return equalsByTerm(RowSet.adapt(rs1), RowSet.adapt(rs2));
+ return ResultsCompare.equalsByTerm(rs1, rs2);
}
- /** See {@link #equalsByTerm(ResultSet, ResultSet)} */
+ /**
+ * Compare two result sets for equivalence. Equivalence means:
+ * A row rs1 has one matching row in rs2, and vice versa.
+ * A row is only matched once.
+ * Rows match if they have the same variables with the same values,
+ * bNodes must map to a consistent other bNodes.
+ * Term comparisons of nodes.
+ *
+ * Destructive - rs1 and rs2 are both read, possibly to exhaustion.
+ * @param rs1
+ * @param rs2
+ * @return true if they are equivalent
+ */
public static boolean equalsByTerm(RowSet rs1, RowSet rs2) {
- if ( ! compareHeader(rs1, rs2) )
- return false;
-
- RowSetRewindable rs1a = rs1.rewindable();
- RowSetRewindable rs2a = rs2.rewindable();
- // Aligned rows
- if ( equivalent(convert(rs1a), convert(rs2a), new BNodeIso(NodeUtils.sameNode)) )
- return true;
- rs1a.reset();
- rs2a.reset();
- return isomorphic(rs1a, rs2a);
+ return ResultsCompare.equalsByTerm(rs1, rs2);
}
/** Compare two result sets for equivalence. Equivalence means:
@@ -156,206 +97,97 @@ public class ResultSetCompare
* bNodes must map to a consistent other bNodes.
* Value comparisons of nodes.
*
- * Destructive - rs1 and rs2 are both read, possibly to exhaustion.
* @param rs1
* @param rs2
* @return true if they are equivalent
*/
public static boolean equalsByValueAndOrder(ResultSet rs1, ResultSet rs2) {
- return equalsByValueAndOrder(RowSet.adapt(rs1), RowSet.adapt(rs2));
+ return ResultsCompare.equalsByValueAndOrder(rs1, rs2);
}
/** See {@link #equalsByValueAndOrder(ResultSet, ResultSet)} */
public static boolean equalsByValueAndOrder(RowSet rs1, RowSet rs2) {
- if ( ! compareHeader(rs1, rs2) )
- return false;
- return equivalentByOrder(convert(rs1) , convert(rs2), new BNodeIso(NodeUtils.sameValue));
+ return ResultsCompare.equalsByValueAndOrder(rs1, rs2);
}
-
/** compare two result sets for equivalence. Equivalence means:
* Each row in rs1 matches the same index row in rs2.
* Rows match if they have the same variables with the same values,
* bNodes must map to a consistent other bNodes.
* RDF term comparisons of nodes.
*
- * Destructive - rs1 and rs2 are both read, possibly to exhaustion.
* @param rs1
* @param rs2
* @return true if they are equivalent
*/
public static boolean equalsByTermAndOrder(ResultSet rs1, ResultSet rs2) {
- return equalsByTermAndOrder(RowSet.adapt(rs1), RowSet.adapt(rs2));
+ return ResultsCompare.equalsByTermAndOrder(rs1, rs2);
}
/** See {@link #equalsByTermAndOrder(ResultSet, ResultSet)} */
public static boolean equalsByTermAndOrder(RowSet rs1, RowSet rs2) {
- if ( ! compareHeader(rs1, rs2) )
- return false;
- return equivalentByOrder(convert(rs1) , convert(rs2), new BNodeIso(NodeUtils.sameNode));
+ return ResultsCompare.equalsByTermAndOrder(rs1, rs2);
}
- /** compare two result sets for exact equality equivalence.
- * Exact equalitymeans:
- * Each row in rs1 matches the same index row in rs2.
- * Rows match if they have the same variables with the same values,
- * bNodes must have same labels
+ /**
+ * Compare two result sets for exact equality equivalence and order.
+ * Blank nodes must have same labels.
*
- * Destructive - rs1 and rs2 are both read, possibly to exhaustion.
* @param rs1
* @param rs2
* @return true if they are equivalent
*/
public static boolean equalsExact(ResultSet rs1, ResultSet rs2) {
- return equalsExact(RowSet.adapt(rs1), RowSet.adapt(rs2));
+ return ResultsCompare.equalsExact(rs1, rs2);
}
- /** See {@link #equalsExact(ResultSet, ResultSet)} */
- public static boolean equalsExact(RowSet rs1, RowSet rs2) {
- if ( !compareHeader(rs1, rs2) )
- return false;
- return equivalentByOrder(convert(rs1) , convert(rs2), NodeUtils.sameNode);
- }
-
- /** Compare two result sets for bNode isomorphism equivalence.
- * Only does RDF term comparison.
+ /**
+ * Compare two result sets for exact equality equivalence and order.
+ * Blank nodes must have same labels.
+ *
+ * @param rs1
+ * @param rs2
+ * @return true if they are equivalent
*/
- public static boolean isomorphic(ResultSet rs1, ResultSet rs2) {
- Model m1 = RDFOutput.encodeAsModel(rs1);
- Model m2 = RDFOutput.encodeAsModel(rs2);
- return m1.isIsomorphicWith(m2);
- }
-
- /** See {@link #isomorphic(ResultSet, ResultSet)} */
- public static boolean isomorphic(RowSet rs1, RowSet rs2) {
- return isomorphic(ResultSet.adapt(rs1), ResultSet.adapt(rs2));
- }
-
- /** Compare two bindings, use the node equality test provided */
- static public boolean equal(Binding bind1, Binding bind2, EqualityTest test) {
- if ( bind1 == bind2 )
- return true;
- if ( bind1.size() != bind2.size() )
- return false;
- // They are the same size so containment is enough.
- if ( ! containedIn(bind1, bind2, test) ) return false;
- return true;
+ public static boolean equalsExact(RowSet rs1, RowSet rs2) {
+ return ResultsCompare.equalsByTermAndOrder(rs1, rs2);
}
- static private boolean compareHeader(RowSet rs1, RowSet rs2) {
+ private static boolean compareHeader(RowSet rs1, RowSet rs2) {
if ( rs1 == null && rs2 == null )
return true;
if ( rs1 == null )
return false;
if ( rs2 == null )
return false;
- Set<Var> names1 = Set.copyOf(rs1.getResultVars());
- Set<Var> names2 = Set.copyOf(rs2.getResultVars());
- return names1.equals(names2);
- }
-
- static private List<Binding> convert(RowSet rs) {
- return Iter.iter(rs).toList();
+ return ListUtils.equalsUnordered(rs1.getResultVars(), rs2.getResultVars());
}
- static private boolean equivalent(Collection<Binding> rows1, Collection<Binding> rows2, EqualityTest match) {
- if ( rows1.size() != rows2.size() )
- return false;
- for ( Binding row1 : rows1 ) {
- // find in rows2.
- Binding matched = null;
- for ( Binding row2 : rows2 ) {
- // NEED BACKTRACKING
- if ( equal(row1, row2, match) ) {
- matched = row2;
- break;
- }
- }
-
- if ( matched == null )
- return false;
- // Remove matching.
- rows2.remove(matched);
- }
- return true;
- }
-
- static private boolean equivalentByOrder(List<Binding> rows1, List<Binding> rows2, EqualityTest match) {
- if ( rows1.size() != rows2.size() )
- return false;
-
- Iterator<Binding> iter1 = rows1.iterator();
- Iterator<Binding> iter2 = rows2.iterator();
-
- while ( iter1.hasNext() )
- {
- // Does not need backtracking because rows must
- // align and so must variables in a row.
- Binding row1 = iter1.next();
- Binding row2 = iter2.next();
- if ( !equal(row1, row2, match) )
- return false;
- }
- return true;
+ /*
+ * Compare two result sets for blank node isomorphism equivalence. Only does RDF
+ * term comparison.
+ *
+ * This method does not handle triple terms in results.
+ *
+ * @deprecated Use {@link #equalsByTerm(ResultSet, ResultSet)} */
+ @Deprecated(forRemoval = true)
+ public static boolean isomorphic(ResultSet rs1, ResultSet rs2) {
+ Model m1 = RDFOutput.encodeAsModel(rs1);
+ Model m2 = RDFOutput.encodeAsModel(rs2);
+ return m1.isIsomorphicWith(m2);
}
- // Is bind1 contained in bind2? For every (var,value) in bind1, is it in bind2?
- // Maybe more in bind2.
- private static boolean containedIn(Binding bind1, Binding bind2, EqualityTest test) {
- // There are about 100 ways to do this!
- Iterator<Var> iter1 = bind1.vars();
-
- while(iter1.hasNext()) {
- Var v = iter1.next();
- Node n1 = bind1.get(v);
- Node n2 = bind2.get(v);
- if ( n2 == null )
- // v bound in bind1 and not in bind2.
- return false;
- if ( ! test.equal(n1, n2) )
- return false;
- }
- return true;
+ /**
+ * Compare two row sets for blank node isomorphism equivalence. Only does RDF
+ * term comparison.
+ *
+ * This method does not handle triple terms in results.
+ *
+ * @deprecated Use {@link #equalsByTerm(RowSet, RowSet)}
+ */
+ @Deprecated(forRemoval = true)
+ public static boolean isomorphic(RowSet rs1, RowSet rs2) {
+ return isomorphic(ResultSet.adapt(rs1), ResultSet.adapt(rs2));
}
- public static class BNodeIso implements EqualityTest
- {
- private NodeIsomorphismMap mapping;
- private EqualityTest literalTest;
-
- public BNodeIso(EqualityTest literalTest) {
- this.mapping = new NodeIsomorphismMap();
- this.literalTest = literalTest;
- }
-
- @Override
- public boolean equal(Node n1, Node n2) {
- if ( n1 == null && n2 == null )
- return true;
- if ( n1 == null )
- return false;
- if ( n2 == null )
- return false;
-
- if ( n1.isURI() && n2.isURI() )
- return n1.equals(n2);
-
- if ( n1.isLiteral() && n2.isLiteral() )
- return literalTest.equal(n1, n2);
-
- if ( n1.isBlank() && n2.isBlank() )
- return Iso.nodeIso(n1, n2, mapping);
-
- if ( n1.isVariable() && n2.isVariable() )
- return mapping.makeIsomorphic(n1, n2);
-
- if ( n1.isTripleTerm() && n2.isTripleTerm() ) {
- Triple t1 = n1.getTriple();
- Triple t2 = n2.getTriple();
- return Iso.tripleIso(t1, t2, mapping);
- }
-
- return false;
- }
- }
}
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/resultset/ResultSetCompare1.java b/jena-arq/src/main/java/org/apache/jena/sparql/resultset/ResultSetCompare1.java
new file mode 100644
index 0000000000..597a4d6898
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/resultset/ResultSetCompare1.java
@@ -0,0 +1,346 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.sparql.resultset;
+
+public class ResultSetCompare1{}
+//import java.util.Iterator;
+//import java.util.List;
+//import java.util.Set;
+//
+//import org.apache.jena.atlas.iterator.Iter;
+//import org.apache.jena.graph.Node;
+//import org.apache.jena.query.ResultSet;
+//import org.apache.jena.query.ResultSetFactory;
+//import org.apache.jena.query.ResultSetRewindable;
+//import org.apache.jena.sparql.core.Var;
+//import org.apache.jena.sparql.engine.binding.Binding;
+//import org.apache.jena.sparql.exec.RowSet;
+//import org.apache.jena.sparql.util.EqualityTest;
+//import org.apache.jena.sparql.util.NodeUtils;
+//import org.apache.jena.sparql.util.iso.BNodeIso;
+//
+///** Comparison of ResultSets.
+// * Note that reading ResultSets is destructive so consider using {@link ResultSetRewindable}
+// * from {@link ResultSetFactory#makeRewindable}
+// */
+//
+//public class ResultSetCompare1 -- Original.
+//{
+// /** Compare two result sets for equivalence. Equivalence means:
+// * A row rs1 has one matching row in rs2, and vice versa.
+// * A row is only matched once.
+// * Rows match if they have the same variables with the same values.
+// * bNodes must map to a consistent other bNodes. Value comparisons of nodes.
+// *
+// * Destructive - rs1 and rs2 are both read, possibly to exhaustion.
+// * @param rs1
+// * @param rs2
+// * @return true if they are equivalent
+// */
+//
+// public static boolean equalsByValue(ResultSet rs1, ResultSet rs2) {
+// return ResultsCompare.equalsByValue(rs1, rs2);
+// }
+//
+// /** See {@link #equalsByValue(ResultSet, ResultSet)} */
+// public static boolean equalsByValue(RowSet rs1, RowSet rs2) {
+// return ResultsCompare.equalsByValue(rs1, rs2);
+// }
+//
+////
+//// public static boolean equalsByTest(Collection<Binding> b1, Collection<Binding> b2, EqualityTest match)
+//// {
+//// List<Binding> rows1 = new ArrayList<>(b1);
+//// List<Binding> rows2 = new ArrayList<>(b2);
+//// return equivalent(rows1, rows2, match);
+//// }
+////
+// /** compare two result sets for equivalence. Equivalence means:
+// * A row rs1 has one matching row in rs2, and vice versa.
+// * A row is only matched once.
+// * Rows match if they have the same variables with the same values,
+// * bNodes must map to a consistent other bNodes.
+// * Term comparisons of nodes.
+// *
+// * Destructive - rs1 and rs2 are both read, possibly to exhaustion.
+// * @param rs1
+// * @param rs2
+// * @return true if they are equivalent
+// */
+//
+// public static boolean equalsByTerm(ResultSet rs1, ResultSet rs2) {
+// return ResultsCompare.equalsByTerm(rs1, rs2);
+// }
+//
+// /** See {@link #equalsByTerm(ResultSet, ResultSet)} */
+// public static boolean equalsByTerm(RowSet rs1, RowSet rs2) {
+// return ResultsCompare.equalsByTerm(rs1, rs2);
+// }
+//
+// /** Compare two result sets for equivalence. Equivalence means:
+// * Each row in rs1 matches the same index row in rs2.
+// * Rows match if they have the same variables with the same values,
+// * bNodes must map to a consistent other bNodes.
+// * Value comparisons of nodes.
+// *
+// * Destructive - rs1 and rs2 are both read, possibly to exhaustion.
+// * @param rs1
+// * @param rs2
+// * @return true if they are equivalent
+// */
+// public static boolean equalsByValueAndOrder(ResultSet rs1, ResultSet rs2) {
+// return equalsByValueAndOrder(RowSet.adapt(rs1), RowSet.adapt(rs2));
+// }
+//
+// /** See {@link #equalsByValueAndOrder(ResultSet, ResultSet)} */
+// public static boolean equalsByValueAndOrder(RowSet rs1, RowSet rs2) {
+// if ( ! compareHeader(rs1, rs2) )
+// return false;
+// return equivalentByOrder(convert(rs1) , convert(rs2), BNodeIso.bnodeIsoByValue());
+// }
+//
+//
+// /** compare two result sets for equivalence. Equivalence means:
+// * Each row in rs1 matches the same index row in rs2.
+// * Rows match if they have the same variables with the same values,
+// * bNodes must map to a consistent other bNodes.
+// * RDF term comparisons of nodes.
+// *
+// * Destructive - rs1 and rs2 are both read, possibly to exhaustion.
+// * @param rs1
+// * @param rs2
+// * @return true if they are equivalent
+// */
+// public static boolean equalsByTermAndOrder(ResultSet rs1, ResultSet rs2) {
+// return equalsByTermAndOrder(RowSet.adapt(rs1), RowSet.adapt(rs2));
+// }
+//
+// /** See {@link #equalsByTermAndOrder(ResultSet, ResultSet)} */
+// public static boolean equalsByTermAndOrder(RowSet rs1, RowSet rs2) {
+// if ( ! compareHeader(rs1, rs2) )
+// return false;
+// return equivalentByOrder(convert(rs1) , convert(rs2), BNodeIso.bnodeIsoByTerm());
+// }
+//
+// /** compare two result sets for exact equality equivalence.
+// * Exact equality means:
+// * Each row in rs1 matches the same index row in rs2.
+// * Rows match if they have the same variables with the same values,
+// * bNodes must have same labels
+// *
+// * Destructive - rs1 and rs2 are both read, possibly to exhaustion.
+// * @param rs1
+// * @param rs2
+// * @return true if they are equivalent
+// */
+// public static boolean equalsExact(ResultSet rs1, ResultSet rs2) {
+// return equalsExact(RowSet.adapt(rs1), RowSet.adapt(rs2));
+// }
+//
+// /** Compare two list - unordered */
+// public static boolean equalsByTerm(List<Binding> list1, List<Binding> list2) {
+// return ResultsCompare.equalsByTerm(list1, list2);
+// }
+//
+// /** Compare two list - unordered */
+// public static boolean equalsExact(List<Binding> list1, List<Binding> list2) {
+// return ResultsCompare.equalsExact(list1, list2);
+// }
+//
+// /**
+// * Compare two row sets for exact equality equivalence.
+// * Exact equality means:
+// * Each row in rs1 matches the same index row in rs2.
+// * Rows match if they have the same variables with the same values,
+// * bNodes must have same labels
+// *
+// * Destructive - rs1 and rs2 are both read, possibly to exhaustion.
+// * @param rs1
+// * @param rs2
+// * @return true if they are equivalent
+// */
+// public static boolean equalsExact(RowSet rs1, RowSet rs2) {
+// if ( !compareHeader(rs1, rs2) )
+// return false;
+// return equivalentByOrder(convert(rs1) , convert(rs2), NodeUtils.sameNode);
+// }
+//
+////
+//// /**
+//// * Compare two result sets for blank node isomorphism equivalence.
+//// * Only does RDF term comparison.
+//// * @deprecated Use {@link #equalsByTerm(ResultSet, ResultSet)}
+//// */
+//// @Deprecated(forRemoval = true)
+//// public static boolean isomorphic(ResultSet rs1, ResultSet rs2) {
+//// Model m1 = RDFOutput.encodeAsModel(rs1);
+//// Model m2 = RDFOutput.encodeAsModel(rs2);
+//// return m1.isIsomorphicWith(m2);
+//// }
+////
+//// /**
+//// * Compare two row sets for blank node isomorphism equivalence.
+//// * Only does RDF term comparison.
+//// * @deprecated Use {@link #equalsByTerm(RowSet, RowSet)}
+//// */
+//// @Deprecated(forRemoval = true)
+//// public static boolean isomorphic(RowSet rs1, RowSet rs2) {
+//// return isomorphic(ResultSet.adapt(rs1), ResultSet.adapt(rs2));
+//// }
+////
+//
+// static private List<Binding> convert(RowSet rs) {
+// return Iter.iter(rs).toList();
+// }
+//
+//
+// /** Compare two bindings, use the node equality test provided */
+// static public boolean equal(Binding bind1, Binding bind2, EqualityTest test) {
+// if ( bind1 == bind2 )
+// return true;
+// if ( bind1.size() != bind2.size() )
+// return false;
+// // They are the same size so containment is enough.
+// if ( ! containedIn(bind1, bind2, test) )
+// return false;
+// return true;
+// }
+//
+// static private boolean compareHeader(RowSet rs1, RowSet rs2) {
+// if ( rs1 == null && rs2 == null )
+// return true;
+// if ( rs1 == null )
+// return false;
+// if ( rs2 == null )
+// return false;
+// Set<Var> names1 = Set.copyOf(rs1.getResultVars());
+// Set<Var> names2 = Set.copyOf(rs2.getResultVars());
+// return names1.equals(names2);
+// }
+//
+//// private static final boolean DEBUG = false;
+////
+//// static private boolean equivalent(Collection<Binding> rows1, Collection<Binding> rows2, EqualityTest match) {
+//// if ( rows1.size() != rows2.size() )
+//// return false;
+//// for ( Binding row1 : rows1 ) {
+//// if ( DEBUG ) System.out.println(" Row1 = "+row1);
+////
+//// // find in rows2.
+//// Binding matched = null;
+//// int i = 0;
+//// for ( Binding row2 : rows2 ) {
+//// if ( DEBUG ) System.out.printf("%-2d Row2 = %s\n", i++, row2);
+////
+//// // NEED BACKTRACKING
+//// if ( equal(row1, row2, match) ) {
+//// if ( DEBUG ) System.out.println("MATCHES");
+//// matched = row2;
+//// break;
+//// }
+//// }
+////
+//// if ( DEBUG ) System.out.println();
+//// if ( matched == null )
+//// return false;
+//// // Remove matching.
+//// rows2.remove(matched);
+//// }
+//// return true;
+//// }
+////
+// static private boolean equivalentByOrder(List<Binding> rows1, List<Binding> rows2, EqualityTest match) {
+// if ( rows1.size() != rows2.size() )
+// return false;
+//
+// Iterator<Binding> iter1 = rows1.iterator();
+// Iterator<Binding> iter2 = rows2.iterator();
+//
+// while ( iter1.hasNext() )
+// {
+// // Does not need backtracking because rows must
+// // align and so must variables in a row.
+// Binding row1 = iter1.next();
+// Binding row2 = iter2.next();
+// if ( !equal(row1, row2, match) )
+// return false;
+// }
+// return true;
+// }
+//
+// // Is bind1 contained in bind2? For every (var,value) in bind1, is it in bind2?
+// // Maybe more in bind2.
+// private static boolean containedIn(Binding bind1, Binding bind2, EqualityTest test) {
+// // There are about 100 ways to do this!
+// Iterator<Var> iter1 = bind1.vars();
+//
+// while(iter1.hasNext()) {
+// Var v = iter1.next();
+// Node n1 = bind1.get(v);
+// Node n2 = bind2.get(v);
+// if ( n2 == null )
+// // v bound in bind1 and not in bind2.
+// return false;
+// if ( ! test.equal(n1, n2) )
+// return false;
+// }
+// return true;
+// }
+////
+//// public static class BNodeIso implements EqualityTest
+//// {
+//// private NodeIsomorphismMap mapping;
+//// private EqualityTest literalTest;
+////
+//// public BNodeIso(EqualityTest literalTest) {
+//// this.mapping = new NodeIsomorphismMap();
+//// this.literalTest = literalTest;
+//// }
+////
+//// @Override
+//// public boolean equal(Node n1, Node n2) {
+//// if ( n1 == null && n2 == null )
+//// return true;
+//// if ( n1 == null )
+//// return false;
+//// if ( n2 == null )
+//// return false;
+////
+//// if ( n1.isURI() && n2.isURI() )
+//// return n1.equals(n2);
+////
+//// if ( n1.isLiteral() && n2.isLiteral() )
+//// return literalTest.equal(n1, n2);
+////
+//// if ( n1.isBlank() && n2.isBlank() )
+//// return Iso.nodeIso(n1, n2, mapping);
+////
+//// if ( n1.isVariable() && n2.isVariable() )
+//// return mapping.makeIsomorphic(n1, n2);
+////
+//// if ( n1.isTripleTerm() && n2.isTripleTerm() ) {
+//// Triple t1 = n1.getTriple();
+//// Triple t2 = n2.getTriple();
+//// return Iso.tripleIso(t1, t2, mapping);
+//// }
+////
+//// return false;
+//// }
+//// }
+//}
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/resultset/ResultSetCompare.java b/jena-arq/src/main/java/org/apache/jena/sparql/resultset/ResultsCompare.java
similarity index 51%
copy from jena-arq/src/main/java/org/apache/jena/sparql/resultset/ResultSetCompare.java
copy to jena-arq/src/main/java/org/apache/jena/sparql/resultset/ResultsCompare.java
index b18a48fd9f..f5e7726548 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/resultset/ResultSetCompare.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/resultset/ResultsCompare.java
@@ -18,111 +18,70 @@
package org.apache.jena.sparql.resultset;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
import org.apache.jena.atlas.iterator.Iter;
import org.apache.jena.graph.Node;
-import org.apache.jena.graph.Triple;
import org.apache.jena.query.ResultSet;
import org.apache.jena.query.ResultSetFactory;
import org.apache.jena.query.ResultSetRewindable;
-import org.apache.jena.rdf.model.Model;
import org.apache.jena.sparql.core.Var;
import org.apache.jena.sparql.engine.binding.Binding;
import org.apache.jena.sparql.exec.RowSet;
-import org.apache.jena.sparql.exec.RowSetRewindable;
import org.apache.jena.sparql.util.EqualityTest;
-import org.apache.jena.sparql.util.Iso;
-import org.apache.jena.sparql.util.NodeIsomorphismMap;
import org.apache.jena.sparql.util.NodeUtils;
+import org.apache.jena.sparql.util.iso.BNodeIso;
+import org.apache.jena.sparql.util.iso.IsoAlgRows;
/** Comparison of ResultSets.
* Note that reading ResultSets is destructive so consider using {@link ResultSetRewindable}
* from {@link ResultSetFactory#makeRewindable}
*/
-public class ResultSetCompare
-{
- /* This is from the DAWG test suite.
- * Result set 1:
- * ---------------
- * | x | y |
- * ===============
- * | _:b0 | _:b1 |
- * | _:b2 | _:b3 |
- * | _:b1 | _:b0 |
- * ---------------
- * Result set 2:
- * ---------------
- * | x | y |
- * ===============
- * | _:b1 | _:b0 |
- * | _:b3 | _:b2 |
- * | _:b2 | _:b3 |
- * ---------------
- */
-
-// private static String[] rs1$ = {
-// "(resultset (?x ?y)",
-// " (row (?x _:b0) (?y _:b1))",
-// " (row (?x _:b2) (?y _:b3))",
-// " (row (?x _:b1) (?y _:b0))",
-// ")"};
-// private static String[] rs2$ = {
-// "(resultset (?x ?y)",
-// " (row (?x _:c1) (?y _:c0))",
-// " (row (?x _:c3) (?y _:c2))",
-// " (row (?x _:c2) (?y _:c3))",
-// ")"};
-//
-
- // Limitations:
- // This code does not do compare/isomorphism combined with value testing.
- // It drops to graph isomorphism, which is term based.
+public class ResultsCompare {
- /** Compare two result sets for equivalence. Equivalence means:
- * A row rs1 has one matching row in rs2, and vice versa.
- * A row is only matched once.
- * Rows match if they have the same variables with the same values.
- * bNodes must map to a consistent other bNodes. Value comparisons of nodes.
+ /**
+ * Compare two result sets for equivalence where nodes are compared by value. A
+ * row rs1 has one matching row in rs2, and vice versa. A row is only matched
+ * once. Rows match if they have the same variables with the same values. bNodes
+ * must map to a consistent other bNodes. Value comparisons of nodes.
*
- * Destructive - rs1 and rs2 are both read, possibly to exhaustion.
* @param rs1
* @param rs2
* @return true if they are equivalent
*/
-
public static boolean equalsByValue(ResultSet rs1, ResultSet rs2) {
return equalsByValue(RowSet.adapt(rs1), RowSet.adapt(rs2));
}
/** See {@link #equalsByValue(ResultSet, ResultSet)} */
public static boolean equalsByValue(RowSet rs1, RowSet rs2) {
- if ( ! compareHeader(rs1, rs2) ) return false;
-
- RowSetRewindable rs1a = rs1.rewindable();
- RowSetRewindable rs2a = rs2.rewindable();
-
- if ( equivalent(convert(rs1a), convert(rs2a), new BNodeIso(NodeUtils.sameValue)) )
- return true;
- rs1a.reset();
- rs2a.reset();
- return isomorphic(rs1a, rs2a);
+ return IsoAlgRows.isIsomorphic(rs1, rs2, BNodeIso.Match.BNODES_VALUE);
}
- public static boolean equalsByTest(Collection<Binding> b1, Collection<Binding> b2, EqualityTest match)
- {
- List<Binding> rows1 = new ArrayList<>(b1);
- List<Binding> rows2 = new ArrayList<>(b2);
- return equivalent(rows1, rows2, match);
+ /**
+ * Compare two result sets for equivalence where nodes are compared by beign the
+ * same term.. A row rs1 has one matching row in rs2, and vice versa. A row is
+ * only matched once. Rows match if they have the same variables with the same
+ * values, bNodes must map to a consistent other bNodes.
+ *
+ * @param rs1
+ * @param rs2
+ * @return true if they are equivalent
+ */
+ public static boolean equalsByTerm(ResultSet rs1, ResultSet rs2) {
+ return equalsByTerm(RowSet.adapt(rs1), RowSet.adapt(rs2));
}
-
- /** compare two result sets for equivalence. Equivalence means:
+ /**
+ * Compare two row sets for equivalence. Equivalence means:
* A row rs1 has one matching row in rs2, and vice versa.
* A row is only matched once.
* Rows match if they have the same variables with the same values,
- * bNodes must map to a consistent other bNodes.
+ * blank node must map to a consistent blank node in the other row set.
* Term comparisons of nodes.
*
* Destructive - rs1 and rs2 are both read, possibly to exhaustion.
@@ -130,33 +89,21 @@ public class ResultSetCompare
* @param rs2
* @return true if they are equivalent
*/
-
- public static boolean equalsByTerm(ResultSet rs1, ResultSet rs2) {
- return equalsByTerm(RowSet.adapt(rs1), RowSet.adapt(rs2));
- }
-
- /** See {@link #equalsByTerm(ResultSet, ResultSet)} */
public static boolean equalsByTerm(RowSet rs1, RowSet rs2) {
- if ( ! compareHeader(rs1, rs2) )
- return false;
+ return IsoAlgRows.isIsomorphic(rs1, rs2, BNodeIso.Match.BNODES_TERM);
+ }
- RowSetRewindable rs1a = rs1.rewindable();
- RowSetRewindable rs2a = rs2.rewindable();
- // Aligned rows
- if ( equivalent(convert(rs1a), convert(rs2a), new BNodeIso(NodeUtils.sameNode)) )
- return true;
- rs1a.reset();
- rs2a.reset();
- return isomorphic(rs1a, rs2a);
+ /** Compare two list - unordered */
+ public static boolean equalsByTerm(List<Binding> list1, List<Binding> list2) {
+ return IsoAlgRows.isIsomorphic(list1, list2, BNodeIso.Match.BNODES_TERM);
}
- /** Compare two result sets for equivalence. Equivalence means:
- * Each row in rs1 matches the same index row in rs2.
- * Rows match if they have the same variables with the same values,
- * bNodes must map to a consistent other bNodes.
- * Value comparisons of nodes.
- *
+ /**
+ * Compare two result sets for equivalence. Equivalence means: Each row in rs1
+ * matches the same index row in rs2. Rows match if they have the same variables
+ * with the same values, bNodes must map to a consistent other bNodes.
* Destructive - rs1 and rs2 are both read, possibly to exhaustion.
+ *
* @param rs1
* @param rs2
* @return true if they are equivalent
@@ -165,21 +112,30 @@ public class ResultSetCompare
return equalsByValueAndOrder(RowSet.adapt(rs1), RowSet.adapt(rs2));
}
- /** See {@link #equalsByValueAndOrder(ResultSet, ResultSet)} */
+ /**
+ * Compare two result sets for equivalence. Equivalence means: Each row in rs1
+ * matches the same index row in rs2. Rows match if they have the same variables
+ * with the same values, bNodes must map to a consistent other bNodes.
+ * Destructive - rs1 and rs2 are both read, possibly to exhaustion.
+ *
+ * @param rs1
+ * @param rs2
+ * @return true if they are equivalent
+ */
public static boolean equalsByValueAndOrder(RowSet rs1, RowSet rs2) {
if ( ! compareHeader(rs1, rs2) )
return false;
- return equivalentByOrder(convert(rs1) , convert(rs2), new BNodeIso(NodeUtils.sameValue));
+ return equivalentByOrder(convert(rs1) , convert(rs2), BNodeIso.bnodeIsoByValue());
}
-
- /** compare two result sets for equivalence. Equivalence means:
- * Each row in rs1 matches the same index row in rs2.
- * Rows match if they have the same variables with the same values,
- * bNodes must map to a consistent other bNodes.
+ /**
+ * Compare two result sets for equivalence.
+ * Equivalence means: Each row in rs1
+ * matches the same index row in rs2. Rows match if they have the same variables
+ * with the same values, blank nodes must map to a consistent other blank node.
* RDF term comparisons of nodes.
- *
* Destructive - rs1 and rs2 are both read, possibly to exhaustion.
+ *
* @param rs1
* @param rs2
* @return true if they are equivalent
@@ -188,18 +144,30 @@ public class ResultSetCompare
return equalsByTermAndOrder(RowSet.adapt(rs1), RowSet.adapt(rs2));
}
- /** See {@link #equalsByTermAndOrder(ResultSet, ResultSet)} */
+ /**
+ * Compare two row sets for equivalence.
+ * Equivalence means: Each row in rs1
+ * matches the same index row in rs2. Rows match if they have the same variables
+ * with the same values, blank nodes must map to a consistent other blank node.
+ * RDF term comparisons of nodes.
+ * Destructive - rs1 and rs2 are both read, possibly to exhaustion.
+ *
+ * @param rs1
+ * @param rs2
+ * @return true if they are equivalent
+ */
public static boolean equalsByTermAndOrder(RowSet rs1, RowSet rs2) {
if ( ! compareHeader(rs1, rs2) )
return false;
- return equivalentByOrder(convert(rs1) , convert(rs2), new BNodeIso(NodeUtils.sameNode));
+ return equivalentByOrder(convert(rs1) , convert(rs2), BNodeIso.bnodeIsoByTerm());
}
- /** compare two result sets for exact equality equivalence.
- * Exact equalitymeans:
+ /**
+ * Compare two result sets for exact equality equivalence.
+ * Exact equality means:
* Each row in rs1 matches the same index row in rs2.
* Rows match if they have the same variables with the same values,
- * bNodes must have same labels
+ * Blank nodes must have same labels
*
* Destructive - rs1 and rs2 are both read, possibly to exhaustion.
* @param rs1
@@ -210,25 +178,60 @@ public class ResultSetCompare
return equalsExact(RowSet.adapt(rs1), RowSet.adapt(rs2));
}
- /** See {@link #equalsExact(ResultSet, ResultSet)} */
+ /**
+ * Compare two row sets for equivalence where blank nodes must have same labels
+ * Destructive - rs1 and rs2 are both read, possibly to exhaustion.
+ *
+ * @param rs1
+ * @param rs2
+ * @return true if they are equivalent
+ */
public static boolean equalsExact(RowSet rs1, RowSet rs2) {
if ( !compareHeader(rs1, rs2) )
return false;
- return equivalentByOrder(convert(rs1) , convert(rs2), NodeUtils.sameNode);
+ return equalsExact(convert(rs1), convert(rs2));
}
- /** Compare two result sets for bNode isomorphism equivalence.
- * Only does RDF term comparison.
+ /**
+ * Compare two row sets for exact node equality equivalence.
+ * Each row in rs1 matches some other row in rs2.
+ * Rows match if they have the same variables with the same terms.
+ * Blank nodes must have same labels
+ *
+ * @param list1
+ * @param list2
+ * @return true if they are equivalent
*/
- public static boolean isomorphic(ResultSet rs1, ResultSet rs2) {
- Model m1 = RDFOutput.encodeAsModel(rs1);
- Model m2 = RDFOutput.encodeAsModel(rs2);
- return m1.isIsomorphicWith(m2);
+ public static boolean equalsExact(List<Binding> list1, List<Binding> list2) {
+ // Mutable copy used to track matches from list1.
+ // This would also work.
+ // return IsoAlgRows.isIsomorphic(list1, list2, BNodeIso.Match.EXACT);
+ // The code here is simpel and direct.
+
+ list2 = new ArrayList<>(list2);
+ if ( list1.size() != list2.size() )
+ return false;
+ for ( Binding binding : list1 ) {
+ boolean wasPresent = list2.remove(binding);
+ if ( ! wasPresent )
+ return false;
+ }
+ // list2 must be empty.
+ return true;
}
- /** See {@link #isomorphic(ResultSet, ResultSet)} */
- public static boolean isomorphic(RowSet rs1, RowSet rs2) {
- return isomorphic(ResultSet.adapt(rs1), ResultSet.adapt(rs2));
+ /**
+ * Compare two row sets for exact node equality equivalence.
+ * Each row in rs1 matches the same row in rs2.
+ * Rows match if they have the same variables with the same values,
+ * Blank nodes must have same labels
+ *
+ * @param list1
+ * @param list2
+ * @return true if they are equivalent
+ */
+ public static boolean equalsExactAndOrder(List<Binding> list1, List<Binding> list2) {
+ return equivalentByOrder(list1, list2, NodeUtils.sameRdfTerm);
}
/** Compare two bindings, use the node equality test provided */
@@ -238,7 +241,8 @@ public class ResultSetCompare
if ( bind1.size() != bind2.size() )
return false;
// They are the same size so containment is enough.
- if ( ! containedIn(bind1, bind2, test) ) return false;
+ if ( ! containedIn(bind1, bind2, test) )
+ return false;
return true;
}
@@ -258,28 +262,6 @@ public class ResultSetCompare
return Iter.iter(rs).toList();
}
- static private boolean equivalent(Collection<Binding> rows1, Collection<Binding> rows2, EqualityTest match) {
- if ( rows1.size() != rows2.size() )
- return false;
- for ( Binding row1 : rows1 ) {
- // find in rows2.
- Binding matched = null;
- for ( Binding row2 : rows2 ) {
- // NEED BACKTRACKING
- if ( equal(row1, row2, match) ) {
- matched = row2;
- break;
- }
- }
-
- if ( matched == null )
- return false;
- // Remove matching.
- rows2.remove(matched);
- }
- return true;
- }
-
static private boolean equivalentByOrder(List<Binding> rows1, List<Binding> rows2, EqualityTest match) {
if ( rows1.size() != rows2.size() )
return false;
@@ -287,8 +269,7 @@ public class ResultSetCompare
Iterator<Binding> iter1 = rows1.iterator();
Iterator<Binding> iter2 = rows2.iterator();
- while ( iter1.hasNext() )
- {
+ while (iter1.hasNext()) {
// Does not need backtracking because rows must
// align and so must variables in a row.
Binding row1 = iter1.next();
@@ -317,45 +298,4 @@ public class ResultSetCompare
}
return true;
}
-
- public static class BNodeIso implements EqualityTest
- {
- private NodeIsomorphismMap mapping;
- private EqualityTest literalTest;
-
- public BNodeIso(EqualityTest literalTest) {
- this.mapping = new NodeIsomorphismMap();
- this.literalTest = literalTest;
- }
-
- @Override
- public boolean equal(Node n1, Node n2) {
- if ( n1 == null && n2 == null )
- return true;
- if ( n1 == null )
- return false;
- if ( n2 == null )
- return false;
-
- if ( n1.isURI() && n2.isURI() )
- return n1.equals(n2);
-
- if ( n1.isLiteral() && n2.isLiteral() )
- return literalTest.equal(n1, n2);
-
- if ( n1.isBlank() && n2.isBlank() )
- return Iso.nodeIso(n1, n2, mapping);
-
- if ( n1.isVariable() && n2.isVariable() )
- return mapping.makeIsomorphic(n1, n2);
-
- if ( n1.isTripleTerm() && n2.isTripleTerm() ) {
- Triple t1 = n1.getTriple();
- Triple t2 = n2.getTriple();
- return Iso.tripleIso(t1, t2, mapping);
- }
-
- return false;
- }
- }
}
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/syntax/ElementData.java b/jena-arq/src/main/java/org/apache/jena/sparql/syntax/ElementData.java
index c82b967eaf..e58e1a5a98 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/syntax/ElementData.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/syntax/ElementData.java
@@ -27,9 +27,8 @@ import org.apache.jena.sparql.algebra.Table ;
import org.apache.jena.sparql.algebra.table.TableData ;
import org.apache.jena.sparql.core.Var ;
import org.apache.jena.sparql.engine.binding.Binding ;
-import org.apache.jena.sparql.resultset.ResultSetCompare ;
+import org.apache.jena.sparql.resultset.ResultsCompare;
import org.apache.jena.sparql.util.NodeIsomorphismMap ;
-import org.apache.jena.sparql.util.NodeUtils ;
public class ElementData extends Element
{
@@ -81,7 +80,8 @@ public class ElementData extends Element
ElementData f2 = (ElementData)el2 ;
if ( ! vars.equals(f2.vars) )
return false ;
- if ( ! ResultSetCompare.equalsByTest(rows, f2.rows, new ResultSetCompare.BNodeIso(NodeUtils.sameNode)) )
+
+ if ( ! ResultsCompare.equalsByTerm(rows, f2.rows) )
return false ;
return true ;
}
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/Iso.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/Iso.java
index c528fd6220..f8e17f5a99 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/util/Iso.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/Iso.java
@@ -34,165 +34,137 @@ import org.apache.jena.sparql.core.Var;
*/
public class Iso {
- /*
- * Are lists of triples isomorphic?
- * The mapping policy {@link NodeIsomorphismMap} is mutated.
+ /**
+ * Are lists of triples isomorphic? The mapping policy {@link NodeIsomorphismMap}
+ * is mutated.
*/
public static boolean isomorphicTriples(List<Triple> triples1, List<Triple> triples2, NodeIsomorphismMap isoMap) {
if ( triples1.size() != triples2.size() )
- return false ;
+ return false;
for ( int i = 0 ; i < triples1.size() ; i++ ) {
- Triple t1 = triples1.get(i) ;
- Triple t2 = triples2.get(i) ;
- if ( ! tripleIso(t1, t2, isoMap))
- return false ;
+ Triple t1 = triples1.get(i);
+ Triple t2 = triples2.get(i);
+ if ( !tripleIso(t1, t2, isoMap) )
+ return false;
}
- return true ;
+ return true;
}
- /*
- * Are lists of quads isomorphic?
- * The mapping policy {@link NodeIsomorphismMap} is mutated.
+ /**
+ * Are lists of quads isomorphic? The mapping policy {@link NodeIsomorphismMap}
+ * is mutated.
*/
public static boolean isomorphicQuads(List<Quad> quads1, List<Quad> quads2, NodeIsomorphismMap isoMap) {
if ( quads1.size() != quads2.size() )
- return false ;
+ return false;
for ( int i = 0 ; i < quads1.size() ; i++ ) {
- Quad q1 = quads1.get(i) ;
- Quad q2 = quads2.get(i) ;
- if ( ! quadIso(q1, q2, isoMap))
- return false ;
+ Quad q1 = quads1.get(i);
+ Quad q2 = quads2.get(i);
+ if ( !quadIso(q1, q2, isoMap) )
+ return false;
}
- return true ;
+ return true;
}
- /*
- * Are lists of nodes isomorphic?
- * The mapping policy {@link NodeIsomorphismMap} is mutated.
+ /**
+ * Are lists of nodes isomorphic? The mapping policy {@link NodeIsomorphismMap}
+ * is mutated.
*/
public static boolean isomorphicNodes(List<Node> nodes1, List<Node> nodes2, NodeIsomorphismMap isoMap) {
if ( nodes1.size() != nodes2.size() )
- return false ;
+ return false;
for ( int i = 0 ; i < nodes1.size() ; i++ ) {
- Node n1 = nodes1.get(i) ;
- Node n2 = nodes2.get(i) ;
- if ( ! nodeIso(n1, n2, isoMap))
- return false ;
+ Node n1 = nodes1.get(i);
+ Node n2 = nodes2.get(i);
+ if ( !nodeIso(n1, n2, isoMap) )
+ return false;
}
- return true ;
+ return true;
}
- /*
- * Are two triple paths isomorphic?
- * The mapping policy {@link NodeIsomorphismMap} is mutated.
+ /**
+ * Are two triple paths isomorphic? The mapping policy {@link NodeIsomorphismMap}
+ * is mutated.
*/
- public static boolean triplePathIso(TriplePath tp1, TriplePath tp2, NodeIsomorphismMap isoMap)
- {
+ public static boolean triplePathIso(TriplePath tp1, TriplePath tp2, NodeIsomorphismMap isoMap) {
if ( tp1.isTriple() ^ tp2.isTriple() )
- return false ;
+ return false;
if ( tp1.isTriple() )
- return Iso.tripleIso(tp1.asTriple(), tp2.asTriple(), isoMap) ;
+ return Iso.tripleIso(tp1.asTriple(), tp2.asTriple(), isoMap);
else
- return Iso.nodeIso(tp1.getSubject(), tp2.getSubject(), isoMap) &&
- Iso.nodeIso(tp1.getObject(), tp2.getObject(), isoMap) &&
- tp1.getPath().equalTo(tp2.getPath(), isoMap) ;
+ return Iso.nodeIso(tp1.getSubject(), tp2.getSubject(), isoMap) && Iso.nodeIso(tp1.getObject(), tp2.getObject(), isoMap)
+ && tp1.getPath().equalTo(tp2.getPath(), isoMap);
}
- /*
- * Are two triples isomorphic?
- * The mapping policy {@link NodeIsomorphismMap} is mutated.
+ /**
+ * Are two triples isomorphic? The mapping policy {@link NodeIsomorphismMap} is
+ * mutated.
*/
- public static boolean tripleIso(Triple t1, Triple t2, NodeIsomorphismMap labelMap)
- {
- Node s1 = t1.getSubject() ;
- Node p1 = t1.getPredicate() ;
- Node o1 = t1.getObject() ;
-
- Node s2 = t2.getSubject() ;
- Node p2 = t2.getPredicate() ;
- Node o2 = t2.getObject() ;
-
- if ( ! nodeIso(s1, s2, labelMap) )
- return false ;
- if ( ! nodeIso(p1, p2, labelMap) )
- return false ;
- if ( ! nodeIso(o1, o2, labelMap) )
- return false ;
-
- return true ;
+ public static boolean tripleIso(Triple t1, Triple t2, NodeIsomorphismMap labelMap) {
+ Node s1 = t1.getSubject();
+ Node p1 = t1.getPredicate();
+ Node o1 = t1.getObject();
+
+ Node s2 = t2.getSubject();
+ Node p2 = t2.getPredicate();
+ Node o2 = t2.getObject();
+
+ if ( !nodeIso(s1, s2, labelMap) )
+ return false;
+ if ( !nodeIso(p1, p2, labelMap) )
+ return false;
+ if ( !nodeIso(o1, o2, labelMap) )
+ return false;
+
+ return true;
}
- /*
- * Are two quads isomorphic?
- * The mapping policy {@link NodeIsomorphismMap} is mutated.
+ /**
+ * Are two quads isomorphic? The mapping policy {@link NodeIsomorphismMap} is
+ * mutated.
*/
- public static boolean quadIso(Quad t1, Quad t2, NodeIsomorphismMap labelMap)
- {
- Node g1 = t1.getGraph() ;
- Node s1 = t1.getSubject() ;
- Node p1 = t1.getPredicate() ;
- Node o1 = t1.getObject() ;
-
- Node g2 = t2.getGraph() ;
- Node s2 = t2.getSubject() ;
- Node p2 = t2.getPredicate() ;
- Node o2 = t2.getObject() ;
-
- if ( ! nodeIso(g1, g2, labelMap) )
- return false ;
- if ( ! nodeIso(s1, s2, labelMap) )
- return false ;
- if ( ! nodeIso(p1, p2, labelMap) )
- return false ;
- if ( ! nodeIso(o1, o2, labelMap) )
- return false ;
-
- return true ;
+ public static boolean quadIso(Quad t1, Quad t2, NodeIsomorphismMap labelMap) {
+ Node g1 = t1.getGraph();
+ Node s1 = t1.getSubject();
+ Node p1 = t1.getPredicate();
+ Node o1 = t1.getObject();
+
+ Node g2 = t2.getGraph();
+ Node s2 = t2.getSubject();
+ Node p2 = t2.getPredicate();
+ Node o2 = t2.getObject();
+
+ if ( !nodeIso(g1, g2, labelMap) )
+ return false;
+ if ( !nodeIso(s1, s2, labelMap) )
+ return false;
+ if ( !nodeIso(p1, p2, labelMap) )
+ return false;
+ if ( !nodeIso(o1, o2, labelMap) )
+ return false;
+
+ return true;
}
- /*
- * Are two nodes isomorphic?
- * The mapping policy {@link NodeIsomorphismMap} is mutated.
+ /**
+ * Are two nodes isomorphic? The mapping policy {@link NodeIsomorphismMap} is
+ * mutated.
*/
- public static boolean nodeIso(Node n1, Node n2, NodeIsomorphismMap isoMap)
- {
+ public static boolean nodeIso(Node n1, Node n2, NodeIsomorphismMap isoMap) {
if ( isoMap != null ) {
if ( n1.isBlank() && n2.isBlank() )
- return isoMap.makeIsomorphic(n1, n2) ;
+ return isoMap.makeIsomorphic(n1, n2);
if ( Var.isBlankNodeVar(n1) && Var.isBlankNodeVar(n2) )
return isoMap.makeIsomorphic(n1, n2) ;
- }
- return n1.equals(n2) ;
- }
-
- /** Interface for choosing the pairs of node that can be map[ped for isomorphism. */
- public interface Mappable {
- boolean isMappable(Node n);
- boolean mappable(Node n1, Node n2);
- }
-
- /** Blank nodes are mappable in {@link IsoAlg} */
- public static Iso.Mappable mappableBlankNodes = new Mappable() {
- @Override public boolean isMappable(Node n) { return n.isBlank(); }
- @Override public boolean mappable(Node n1, Node n2) { return n1.isBlank() && n2.isBlank(); }
- };
-
- /** Blank nodes and variables are mappable in {@link IsoAlg} */
- public static Iso.Mappable mappableVariables = new Mappable() {
- @Override public boolean isMappable(Node n) { return n.isVariable(); }
- @Override public boolean mappable(Node n1, Node n2) { return n1.isVariable() && n2.isVariable(); }
- };
-
-
- /** Blank nodes and variables are mappable in {@link IsoAlg} */
- public static Iso.Mappable mappableBlankNodesVariables = new Mappable() {
- @Override public boolean isMappable(Node n) { return n.isBlank()|| n.isVariable() ; }
- @Override public boolean mappable(Node n1, Node n2) {
- if ( n1.isBlank() && n2.isBlank() ) return true;
- if ( n1.isVariable() && n2.isVariable() ) return true;
- return false;
+ if ( n1.isTripleTerm() && n2.isTripleTerm() )
+ return tripleIso(n1.getTriple(), n2.getTriple(), isoMap);
+ if ( n1.isNodeGraph() && n2.isNodeGraph() ) {
+ List<Triple> list1 = n1.getGraph().find().toList();
+ List<Triple> list2 = n2.getGraph().find().toList();
+ return isomorphicTriples(list1, list2, isoMap);
+ }
}
- };
+ return n1.equals(n2);
+ }
}
-
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/IsoMatcher.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/IsoMatcher.java
index 6230fd1312..6e3ba9581d 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/util/IsoMatcher.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/IsoMatcher.java
@@ -31,16 +31,19 @@ import org.apache.jena.graph.Node ;
import org.apache.jena.graph.Triple ;
import org.apache.jena.sparql.core.DatasetGraph ;
import org.apache.jena.sparql.core.Quad ;
+import org.apache.jena.sparql.util.iso.IsoAlgRows;
+import org.apache.jena.sparql.util.iso.IsoAlgTuple;
+import org.apache.jena.util.iterator.ExtendedIterator;
/**
* Simple isomorphism testing for on unordered collections.
* This code is simple and slow.
- * For graphs, the Graph isomorphism code in Jena is much better (better tested, better performance)
* This code can work on any tuples of nodes.
*
* See {@link Iso} for isomorphism for ordered lists.
*
- * See {@link IsoAlg} for the isomorphism algorithm.
+ * See {@link IsoAlgTuple} for the isomorphism algorithm.
+ * See {@link IsoAlgRows} for the isomorphism algorithm for rowsets.
*/
public class IsoMatcher
{
@@ -64,20 +67,23 @@ public class IsoMatcher
}
/** Helper - convert to {@code List<Tuple<Node>>} */
- /*package*/ static List<Tuple<Node>> tuplesTriples(Iterator<Triple> iter) {
- return Iter.iter(iter).map(t->tuple(t.getSubject(), t.getPredicate(), t.getObject())).toList();
+ private static List<Tuple<Node>> tuplesQuads(Iterator<Quad> iter) {
+ return Iter.iter(iter).map(q->tuple(q.getGraph(), q.getSubject(), q.getPredicate(), q.getObject())).toList();
}
/** Helper - convert to {@code List<Tuple<Node>>} */
- public static List<Tuple<Node>> tuplesQuads(Iterator<Quad> iter) {
- return Iter.iter(iter).map(q->tuple(q.getGraph(), q.getSubject(), q.getPredicate(), q.getObject())).toList();
+ private static List<Tuple<Node>> tuplesTriples(ExtendedIterator<Triple> iter) {
+ try {
+ return Iter.iter(iter).map(t->tuple(t.getSubject(), t.getPredicate(), t.getObject())).toList();
+ }
+ finally { iter.close(); }
}
/** Collection of tuples isomorphism, with choice of when two nodes are "equal".
- * See also {@link IsoAlg#isIsomorphic(Collection, Collection, org.apache.jena.sparql.util.Iso.Mappable, EqualityTest)}
+ * See also {@link IsoAlgTuple#isIsomorphic(Collection, Collection, org.apache.jena.sparql.util.Iso.Mappable, EqualityTest)}
* for isomorphisms testing for more than just blank nodes.
*/
- public static boolean isomorphic(Collection<Tuple<Node>> x1, Collection<Tuple<Node>> x2, EqualityTest nodeTest) {
- return IsoAlg.isIsomorphic(x1, x2, nodeTest);
+ private static boolean isomorphic(Collection<Tuple<Node>> x1, Collection<Tuple<Node>> x2, EqualityTest nodeTest) {
+ return IsoAlgTuple.isIsomorphic(x1, x2, nodeTest);
}
}
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/NodeIsomorphismMap.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/NodeIsomorphismMap.java
index 7bc86d7645..f80d3b3b2f 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/util/NodeIsomorphismMap.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/NodeIsomorphismMap.java
@@ -18,30 +18,35 @@
package org.apache.jena.sparql.util;
-import java.util.HashMap ;
-import java.util.Map ;
+import java.util.HashMap;
+import java.util.Map;
-import org.apache.jena.graph.Node ;
+import org.apache.jena.graph.Node;
/** Map nodes to nodes. */
public class NodeIsomorphismMap
{
- private Map<Node, Node> map = new HashMap<>() ;
-
+ private Map<Node, Node> map = new HashMap<>();
+
public NodeIsomorphismMap() {}
-
- private Node get(Node key) { return map.get(key) ; }
- private void put(Node key, Node value) { map.put(key, value) ; }
-
+
+ private Node get(Node key) { return map.get(key); }
+ private void put(Node key, Node value) { map.put(key, value); }
+
public boolean makeIsomorphic(Node n1, Node n2) {
if ( n1.isBlank() && n2.isBlank() ) {
- Node other = get(n1) ;
+ Node other = get(n1);
if ( other == null ) {
- put(n1, n2) ;
- return true ;
+ put(n1, n2);
+ return true;
}
- return other.equals(n2) ;
+ return other.equals(n2);
}
- return n1.equals(n2) ;
+ return n1.equals(n2);
+ }
+
+ @Override
+ public String toString() {
+ return "Iso["+map.toString()+"]";
}
}
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/NodeToLabelMap.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/NodeToLabelMap.java
index 52877633e7..ab75c73e07 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/util/NodeToLabelMap.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/NodeToLabelMap.java
@@ -18,85 +18,55 @@
package org.apache.jena.sparql.util;
-import java.util.HashMap ;
-import java.util.Map ;
+import java.util.HashMap;
+import java.util.Map;
-import org.apache.jena.graph.Node ;
+import org.apache.jena.graph.Node;
/** Map nodes to blank node representations. */
-public class NodeToLabelMap
-{
+public class NodeToLabelMap {
// Could abstract again as a node -> label cache + cache miss handler.
- int bNodeCounter = 0 ;
- Map<Node, String> bNodeStrings = new HashMap<>() ;
- boolean bNodesAsFakeURIs = false ;
- String prefixString = "b" ;
+ int bNodeCounter = 0;
+ Map<Node, String> bNodeStrings = new HashMap<>();
+ boolean bNodesAsFakeURIs = false;
+ String prefixString = "b";
- public NodeToLabelMap() { this("b") ; }
+ public NodeToLabelMap() {
+ this("b");
+ }
- public NodeToLabelMap(String prefix) { this(prefix, false) ; }
+ public NodeToLabelMap(String prefix) {
+ this(prefix, false);
+ }
- public NodeToLabelMap(String prefix, boolean bNodesAsFakeURIs)
- {
+ public NodeToLabelMap(String prefix, boolean bNodesAsFakeURIs) {
if ( prefix == null || prefix.equals("") )
- throw new IllegalArgumentException("Must provide a prefix") ;
- this.prefixString = "_:"+prefix ;
- this.bNodesAsFakeURIs = bNodesAsFakeURIs ;
+ throw new IllegalArgumentException("Must provide a prefix");
+ this.prefixString = "_:" + prefix;
+ this.bNodesAsFakeURIs = bNodesAsFakeURIs;
}
// Null means not mapped
- public String asString(Node n)
- {
- if ( ! n.isBlank() )
- return null ;
-
- return mapNode(n) ;
+ public String asString(Node n) {
+ if ( !n.isBlank() )
+ return null;
+ return mapNode(n);
}
// synchronized because this may be used from a static via FmtUtils
- protected synchronized String mapNode(Node n)
- {
- String s = bNodeStrings.get(n) ;
+ protected synchronized String mapNode(Node n) {
+ String s = bNodeStrings.get(n);
if ( s != null )
- return s ;
+ return s;
- s = genStringForNode(n) ;
- bNodeStrings.put(n, s) ;
- return s ;
+ s = genStringForNode(n);
+ bNodeStrings.put(n, s);
+ return s;
}
- protected String genStringForNode(Node n)
- {
+ protected String genStringForNode(Node n) {
if ( bNodesAsFakeURIs && n.isBlank() )
- return "<_:"+n.getBlankNodeLabel()+">" ;
-
- return prefixString+(bNodeCounter++) ;
+ return "<_:" + n.getBlankNodeLabel() + ">";
+ return prefixString + (bNodeCounter++);
}
-
-// /**
-// * @return Returns the prefix.
-// */
-// public String getPrefixString()
-// {
-// return prefixString ;
-// }
-//
-// /**
-// * @param prefix The prefix to set.
-// */
-// public void setPrefixString(String prefix)
-// {
-// if ( prefix == null )
-// {
-// Log.fatal(this,"Prefix string is null") ;
-// throw new ARQInternalErrorException("Prefix string is null") ;
-// }
-// if ( prefix.equals("") )
-// {
-// Log.fatal(this,"Prefix string is the empty string") ;
-// throw new ARQInternalErrorException("Prefix string is the empty string") ;
-// }
-//
-// this.prefixString = prefix ;
-// }
}
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/iso/BNodeIso.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/iso/BNodeIso.java
new file mode 100644
index 0000000000..692c31142a
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/iso/BNodeIso.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.sparql.util.iso;
+
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.sparql.util.EqualityTest;
+import org.apache.jena.sparql.util.Iso;
+import org.apache.jena.sparql.util.NodeIsomorphismMap;
+import org.apache.jena.sparql.util.NodeUtils;
+
+public class BNodeIso implements EqualityTest
+{
+ /** Kind of matching to perform. */
+ // BNODES => blank node isomorphism.
+ public enum Match { BNODES_TERM, BNODES_VALUE, EXACT_TERM, EXACT_VALUE }
+
+ /**
+ * Create a fresh {@link EqualityTest} that provides blank node isomorphism and
+ * comparision by term.
+ */
+ public static EqualityTest bnodeIsoByTerm() {
+ return new BNodeIso(NodeUtils.sameRdfTerm);
+ }
+
+ /**
+ * Create a fresh {@link EqualityTest} that provides blank node isomorphism and
+ * comparision by term.
+ */
+ public static EqualityTest bnodeIsoByValue() {
+ return new BNodeIso(NodeUtils.sameValue);
+ }
+
+ private NodeIsomorphismMap mapping;
+ private EqualityTest literalTest;
+
+ private BNodeIso(EqualityTest literalTest) {
+ this.mapping = new NodeIsomorphismMap();
+ this.literalTest = literalTest;
+ }
+
+ @Override
+ public boolean equal(Node n1, Node n2) {
+ if ( n1 == null && n2 == null )
+ return true;
+ if ( n1 == null )
+ return false;
+ if ( n2 == null )
+ return false;
+
+ if ( n1.isURI() && n2.isURI() )
+ return n1.equals(n2);
+
+ if ( n1.isLiteral() && n2.isLiteral() )
+ return literalTest.equal(n1, n2);
+
+ if ( n1.isBlank() && n2.isBlank() )
+ return Iso.nodeIso(n1, n2, mapping);
+
+ if ( n1.isVariable() && n2.isVariable() )
+ return mapping.makeIsomorphic(n1, n2);
+
+ if ( n1.isTripleTerm() && n2.isTripleTerm() ) {
+ Triple t1 = n1.getTriple();
+ Triple t2 = n2.getTriple();
+ return Iso.tripleIso(t1, t2, mapping);
+ }
+
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/iso/IsoAlgRows.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/iso/IsoAlgRows.java
new file mode 100644
index 0000000000..220de7a008
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/iso/IsoAlgRows.java
@@ -0,0 +1,272 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.sparql.util.iso;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+
+import org.apache.jena.atlas.io.IndentedWriter;
+import org.apache.jena.atlas.iterator.Iter;
+import org.apache.jena.atlas.lib.InternalErrorException;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.sparql.core.Var;
+import org.apache.jena.sparql.engine.binding.Binding;
+import org.apache.jena.sparql.exec.RowSet;
+import org.apache.jena.sparql.util.EqualityTest;
+import org.apache.jena.sparql.util.NodeUtils;
+import org.apache.jena.sparql.util.iso.IsoLib.Mappable;
+
+public class IsoAlgRows {
+
+ private static final boolean DEBUG = false;
+ private static final IndentedWriter out = debugIndentedWriter();
+ private static final IndentedWriter debugIndentedWriter() {
+ IndentedWriter iout = null;
+ if ( DEBUG ) {
+ iout = new IndentedWriter(System.out);
+ iout.setFlushOnNewline(true);
+ }
+ return iout;
+ }
+
+ public static boolean isIsomorphic(RowSet rowset1, RowSet rowset2, BNodeIso.Match matching) {
+ Objects.requireNonNull(rowset1);
+ Objects.requireNonNull(rowset2);
+ if ( rowset1 == rowset2 )
+ return true;
+ if ( ! IsoLib.compareHeader(rowset1, rowset2) )
+ return false;
+ List<Binding> rows1 = toList(rowset1);
+ List<Binding> rows2 = toList(rowset2);
+ if ( rows1.size() != rows2.size() )
+ return false;
+
+ // Could divide into rows with exact matches (no blank nodes) and those with
+ // blank nodes.
+
+ return matcher(rows1, rows2, matching);
+ }
+
+ public static boolean isIsomorphic(List<Binding> list1, List<Binding> list2, BNodeIso.Match matching) {
+ if ( list1.size() != list2.size() )
+ return false;
+ return matcher(list1, list2, matching);
+ }
+
+ private static boolean matcher(List<Binding> list1, List<Binding> list2, BNodeIso.Match matching) {
+ Mappable mapping;
+ EqualityTest equalityTest;
+ switch(matching) {
+ case BNODES_TERM, EXACT_TERM -> equalityTest = NodeUtils.sameRdfTerm;
+ case BNODES_VALUE, EXACT_VALUE -> equalityTest = NodeUtils.sameValue;
+ default -> { throw new InternalErrorException("Unknown equality policy"); }
+ }
+ switch(matching) {
+ case EXACT_VALUE, EXACT_TERM -> mapping = IsoLib.mappableNoMap;
+ case BNODES_TERM, BNODES_VALUE -> mapping = IsoLib.mappableBlankNodes;
+ default -> { throw new InternalErrorException("Unknown matching policy"); }
+ }
+
+ return matcherWorker(list1, 0, list2, IsoMapping.rootMapping, mapping, equalityTest);
+ }
+
+ // Match rows in rows1, starting at idx1, against rows in rows2, starting at idx2
+ private static boolean matcherWorker(List<Binding> rows1, int idx1, List<Binding> rows2,
+ IsoMapping mapping, IsoLib.Mappable mappable, EqualityTest equalityTest) {
+ if ( rows1.size() == 0 )
+ return true;
+
+ for ( int i = idx1 ; i < rows1.size() ; i++ ) {
+ Binding row1 = rows1.get(i);
+ if ( row1 == null )
+ continue;
+ if ( DEBUG )
+ out.println("-- Row1 = "+row1);
+ List<Possibility> possibilities = matcherOneRow(row1, rows2, mapping, mappable, equalityTest);
+ if ( DEBUG )
+ out.println("Possibilities: "+possibilities);
+
+ if ( possibilities.isEmpty() )
+ return false;
+
+ for ( Possibility poss : possibilities ) {
+ if ( DEBUG )
+ out.println("Try: " + poss);
+ // Without this row1, and the possibility row can we map the rest?
+ int iRest = i+1;
+ if ( iRest >= rows1.size() ) {
+ // Last item
+ if ( DEBUG )
+ out.println("Yes (zero left)");
+ return true;
+ }
+ // One element of row2 removed. Not by position.
+ List<Binding> rows2x = new ArrayList<>(rows2);
+ rows2x.remove(poss.row);
+
+ if ( DEBUG )
+ out.incIndent();
+
+ if ( matcherWorker(rows1, iRest, rows2x, poss.mapping, mappable, equalityTest) ) {
+ if ( DEBUG )
+ out.decIndent();
+
+ if ( DEBUG )
+ out.println("Yes");
+ return true;
+ }
+ if ( DEBUG )
+ out.decIndent();
+ if ( DEBUG )
+ out.println("No");
+ }
+ // No possibility
+ return false;
+ }
+ // Maybe a bug in this code
+ return false;
+ }
+
+ private static List<Possibility> matcherOneRow(Binding row1, List<Binding> rows2, IsoMapping mapping, IsoLib.Mappable mappable, EqualityTest equalityTest) {
+ // find in rows2.
+ List<Possibility> possibilities = new ArrayList<>();
+ for ( int j = 0 ; j < rows2.size() ; j++ ) {
+ Binding row2 = rows2.get(j);
+ if ( row2 == null )
+ continue;
+ if ( DEBUG )
+ out.printf("%-2d Row2 = %s\n", j, row2);
+ IsoMapping step = matchOne(row1, row2, mapping, mappable, equalityTest);
+ if ( step == null )
+ continue;
+ Possibility poss = new Possibility(row2, step);
+ if ( DEBUG )
+ out.println(poss.toString());
+ // if row1 all concrete, drop row1 and row2
+ possibilities.add(poss);
+ }
+ return possibilities;
+ }
+
+ /** Can row1 be matched by row2? */
+ private static IsoMapping matchOne(Binding row1, Binding row2, IsoMapping mapping, IsoLib.Mappable mappable, EqualityTest equalityTest) {
+// Set<Var> vars1 = row1.varsMentioned();
+// Set<Var> vars2 = row2.varsMentioned();
+// if ( ! vars1.equals(vars2) )
+// return null;
+
+ Iterator<Var> iter = row1.vars();
+ IsoMapping mapping2 = mapping;
+ while(iter.hasNext()) {
+ Var v = iter.next();
+ Node n1 = row1.get(v);
+ Node n2 = row2.get(v);
+ if ( n2 == null )
+ return null;
+ mapping2 = matchTerms(n1, n2, mapping2, mappable, equalityTest);
+ if ( mapping2 == null )
+ return null;
+ if ( DEBUG )
+ out.println("Mapping: "+mapping2);
+
+ }
+ return mapping2;
+ }
+
+ /*package*/ static IsoMapping matchTermsTest(Node n1, Node n2, EqualityTest nodeTest) {
+ EqualityTest eqtest = BNodeIso.bnodeIsoByTerm();
+ return matchTerms(n1, n2, IsoMapping.rootMapping, IsoLib.mappableBlankNodes, eqtest);
+ }
+
+ static IsoMapping matchTerms(Node n1, Node n2, IsoMapping _mapping, IsoLib.Mappable mappable, EqualityTest nodeTest) {
+ if ( _mapping == null )
+ return null;
+ if ( n1 == null || n2 == null )
+ return null;
+ IsoMapping mapping = _mapping;
+ Node n1m = mapping.map(n1);
+
+ if ( n1m != null ) {
+ // Already mapped
+ if ( DEBUG )
+ out.printf("Existing: %s -> %s for %s\n", n1, n1m, n2);
+ if ( n1m.equals(n2) )
+ // Exact equals after mapping t1 slot.
+ return mapping;
+ // No match.
+ return null;
+ }
+
+ if ( n1.isTripleTerm() ) {
+ if ( n2.isTripleTerm() ) {
+ Triple t1 = n1.getTriple();
+ Triple t2 = n2.getTriple();
+ mapping = matchTerms(t1.getSubject(), t2.getSubject(), mapping, mappable, nodeTest);
+ if ( mapping == null )
+ return null;
+ mapping = matchTerms(t1.getPredicate(), t2.getPredicate(), mapping, mappable, nodeTest);
+ if ( mapping == null )
+ return null;
+ mapping = matchTerms(t1.getObject(), t2.getObject(), mapping, mappable, nodeTest);
+ if ( mapping == null )
+ return null;
+ return mapping;
+ }
+ // n2 not a triple term.
+ return null;
+ } else if ( n2.isTripleTerm() ) {
+ // n1 not a triple term.
+ return null;
+ }
+
+ // Map an atomic term (not triple term)
+ if ( mappable.mappable(n1, n2) ) {
+ if ( mapping.reverseMapped(n2) ) {
+ // Already a target.
+ // but not the same (else n1m != null)
+ return null;
+ }
+ // Add mapping.
+ mapping = new IsoMapping(mapping, n1, n2);
+ return mapping;
+ }
+
+ if ( !nodeTest.equal(n1, n2) )
+ // No isomorphism.
+ return null;
+
+ return mapping;
+ }
+
+
+ static private List<Binding> toList(RowSet rs) {
+ return Iter.iter(rs).toList();
+ }
+
+ private record Possibility(Binding row, IsoMapping mapping) {
+ @Override
+ public String toString() {
+ return String.format("Poss|%s %s|", IsoLib.str(row), mapping);
+ }
+ }
+}
+
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/IsoAlg.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/iso/IsoAlgTuple.java
similarity index 63%
rename from jena-arq/src/main/java/org/apache/jena/sparql/util/IsoAlg.java
rename to jena-arq/src/main/java/org/apache/jena/sparql/util/iso/IsoAlgTuple.java
index 3ce8de4514..9040c3218c 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/util/IsoAlg.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/iso/IsoAlgTuple.java
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-package org.apache.jena.sparql.util;
+package org.apache.jena.sparql.util.iso;
import java.util.ArrayList;
import java.util.Collection;
@@ -29,7 +29,9 @@ import org.apache.jena.atlas.lib.tuple.Tuple;
import org.apache.jena.atlas.lib.tuple.TupleFactory;
import org.apache.jena.graph.Node;
import org.apache.jena.graph.Triple;
-import org.apache.jena.sparql.util.Iso.Mappable;
+import org.apache.jena.sparql.util.EqualityTest;
+import org.apache.jena.sparql.util.Iso;
+import org.apache.jena.sparql.util.NodeUtils;
/**
* Simple isomorphism testing for collections of tuples of nodes. This can be used
@@ -37,75 +39,65 @@ import org.apache.jena.sparql.util.Iso.Mappable;
* better (better tested, better performance) for graph isomorphism. This code is
* simple, easier to understand, and works on collections of tuples, not just graphs.
*/
-public class IsoAlg {
-
- /** Record the mapping of a node. This is a one-way linked list. */
- public static class Mapping {
- final Node node1;
- final Node node2;
- final Mapping parent;
-
- public static final Mapping rootMapping = new Mapping(null, null, null);
-
- public Mapping(Mapping parent, Node node1, Node node2) {
- super();
- this.parent = parent;
- this.node1 = node1;
- this.node2 = node2;
- }
-
- public boolean mapped(Node node) {
- return map(node) != null;
- }
-
- public Node map(Node node) {
- Mapping mapping = this;
- while (mapping != rootMapping) {
- if ( mapping.node1.equals(node) )
- return mapping.node2;
- mapping = mapping.parent;
- }
- return null;
- }
-
- public boolean reverseMapped(Node node) {
- return reverseMap(node) != null;
- }
-
- public Node reverseMap(Node node) {
- Mapping mapping = this;
- while (mapping != rootMapping) {
- if ( mapping.node2.equals(node) )
- return mapping.node1;
- mapping = mapping.parent;
- }
- return null;
- }
-
-
- @Override
- public String toString() {
- StringBuilder sbuff = new StringBuilder();
- Mapping mapping = this;
- while (mapping != rootMapping) {
- sbuff.append("{" + mapping.node1 + " => " + mapping.node2 + "}");
- mapping = mapping.parent;
- }
- sbuff.append("{}");
- return sbuff.toString();
- }
- }
-
- static class Possibility {
- final Tuple<Node> tuple;
- final Mapping mapping;
-
- public Possibility(Tuple<Node> tuple, Mapping mapping) {
- super();
- this.tuple = tuple;
- this.mapping = mapping;
- }
-
+public class IsoAlgTuple {
+
+// /** Record the IsoMapping of a node. This is a one-way linked list. */
+// private static class IsoMapping {
+// final Node node1;
+// final Node node2;
+// final IsoMapping parent;
+//
+// static final IsoMapping rootIsoMapping = new Mapping(null, null, null);
+//
+// Mapping(IsoMapping parent, Node node1, Node node2) {
+// super();
+// this.parent = parent;
+// this.node1 = node1;
+// this.node2 = node2;
+// }
+//
+// boolean mapped(Node node) {
+// return map(node) != null;
+// }
+//
+// Node map(Node node) {
+// IsoMapping IsoMapping = this;
+// while (IsoMapping != rootMapping) {
+// if ( mapping.node1.equals(node) )
+// return mapping.node2;
+// IsoMapping = mapping.parent;
+// }
+// return null;
+// }
+//
+// boolean reverseMapped(Node node) {
+// return reverseMap(node) != null;
+// }
+//
+// Node reverseMap(Node node) {
+// IsoMapping IsoMapping = this;
+// while (IsoMapping != rootMapping) {
+// if ( mapping.node2.equals(node) )
+// return mapping.node1;
+// IsoMapping = mapping.parent;
+// }
+// return null;
+// }
+//
+// @Override
+// public String toString() {
+// StringBuilder sbuff = new StringBuilder();
+// IsoMapping IsoMapping = this;
+// while (IsoMapping != rootMapping) {
+// sbuff.append("{" + mapping.node1 + " => " + mapping.node2 + "}");
+// IsoMapping = mapping.parent;
+// }
+// sbuff.append("{}");
+// return sbuff.toString();
+// }
+// }
+
+ private record Possibility(Tuple<Node> tuple, IsoMapping mapping) {
@Override
public String toString() {
return String.format("Poss|%s %s|", tuple, mapping);
@@ -121,51 +113,55 @@ public class IsoAlg {
* or {@link NodeUtils#sameRdfTerm} (Node.equals, with lang tag insensitive testing).
*/
public static boolean isIsomorphic(Collection<Tuple<Node>> x1, Collection<Tuple<Node>> x2, EqualityTest nodeTest) {
- return isIsomorphic(x1, x2, Iso.mappableBlankNodes, nodeTest);
+ return isIsomorphic(x1, x2, IsoLib.mappableBlankNodes, nodeTest);
}
/**
- * Isomorphism test based on a class of mappable elements (e.g. blank nodes {@linkplain Iso#mappableBlankNodes},
+ * Isomorphism test based on a class of IsoLib.Mappable elements (e.g. blank nodes {@linkplain Iso#mappableBlankNodes},
* or blank nodes and variables {@linkplain Iso#mappableBlankNodesVariables}).
* Two nodes considered "equal" by an equality test such as
* {@link NodeUtils#sameValue} (SPARQL value testing),
* {@link NodeUtils#sameNode} (Node.equals),
* or {@link NodeUtils#sameRdfTerm} (Node.equals, with lang tag insensitive testing).
*/
- public static boolean isIsomorphic(Collection<Tuple<Node>> x1, Collection<Tuple<Node>> x2, Iso.Mappable mappable, EqualityTest nodeTest) {
- return matcher(x1, x2, Mapping.rootMapping, mappable, nodeTest);
+ /*package*/ static boolean isIsomorphic(Collection<Tuple<Node>> x1, Collection<Tuple<Node>> x2, IsoLib.Mappable mappable, EqualityTest nodeTest) {
+ if ( x1.size() != x2.size() )
+ return false;
+ return matcher(x1, x2, IsoMapping.rootMapping, mappable, nodeTest);
}
/**
- * Isomorphism test based on a class of mappable elements (e.g. blank nodes {@linkplain Iso#mappableBlankNodes},
+ * Isomorphism test based on a class of IsoLib.Mappable elements (e.g. blank nodes {@linkplain Iso#mappableBlankNodes},
* or blank nodes and variables {@linkplain Iso#mappableBlankNodesVariables}).
* Two nodes considered "equal" by an equality test such as
* {@link NodeUtils#sameValue} (SPARQL value testing),
* {@link NodeUtils#sameNode} (Node.equals),
* or {@link NodeUtils#sameRdfTerm} (Node.equals, with lang tag insensitive testing).
*/
- public static Mapping isIsomorphic(Tuple<Node> tuple1, Tuple<Node> tuple2, Mapping mapping, Mappable mappable, EqualityTest nodeTest) {
- return gen(tuple1, tuple2, mapping, mappable, nodeTest);
+ private static IsoMapping isIsomorphic(Tuple<Node> tuple1, Tuple<Node> tuple2, IsoMapping mapping, IsoLib.Mappable mappable, EqualityTest nodeTest) {
+ return matchTuples(tuple1, tuple2, mapping, mappable, nodeTest);
}
// Debug.
private static final boolean DEBUG = false;
- private static final IndentedWriter out = new IndentedWriter(System.out);
- static {
- out.setFlushOnNewline(true);
+ private static final IndentedWriter out = debugIndentedWriter();
+ private static final IndentedWriter debugIndentedWriter() {
+ IndentedWriter iout = null;
+ if ( DEBUG ) {
+ iout = new IndentedWriter(System.out);
+ iout.setFlushOnNewline(true);
+ }
+ return iout;
}
- private static boolean matcher(Collection<Tuple<Node>> tuples1, Collection<Tuple<Node>> tuples2, Mapping mapping,
- Iso.Mappable mappable, EqualityTest nodeTest) {
+ private static boolean matcher(Collection<Tuple<Node>> tuples1, Collection<Tuple<Node>> tuples2, IsoMapping mapping,
+ IsoLib.Mappable mappable, EqualityTest nodeTest) {
if ( DEBUG ) {
out.println("match: ");
out.println(" 1: " + tuples1);
out.println(" 2: " + tuples2);
out.println(" M: " + mapping);
}
- if ( tuples1.size() != tuples2.size() )
- return false;
-
// Process the inputs : tuples of all non-mappable terms can be processed here (Node.equals)
// Loop on tuples1:
// if not mappable, remove from tuples2.
@@ -176,6 +172,7 @@ public class IsoAlg {
// Fast path.
if ( true )
{
+ // XXX We can move this out to the caller of matcher.
List<Tuple<Node>> tuples1$ = new ArrayList<>();
// Step one - copy non-mappable tuples or exit now.
for ( Tuple<Node> t1 : tuples1 ) {
@@ -187,7 +184,7 @@ public class IsoAlg {
}
tuples1$.add(t1);
}
- // Tuples for mappable processing.
+ // Tuples for IsoLib.Mappable processing.
tuples1 = tuples1$;
} else
// No pre-process concrete.
@@ -205,10 +202,10 @@ public class IsoAlg {
List<Possibility> causes = matcher(t1, tuples2, mapping, mappable, nodeTest);
- if ( DEBUG )
+ if ( DEBUG ) {
out.println(" Possibilities: Tuple" + t1 + " :: " + causes);
-
- out.incIndent();
+ out.incIndent();
+ }
try {
// Try each possible tuple-tuple matching until one succeeds all the
// way.
@@ -218,9 +215,9 @@ public class IsoAlg {
// Try t1 -> t2
Tuple<Node> t2 = c.tuple;
tuples2.remove(t2);
- // Try without t1 and t2, using the mapping of this cause.
- if ( tuples1.isEmpty() && tuples2.isEmpty() ) // They are the
- // same size.
+ // Try without t1 and t2, using the IsoMapping of this cause.
+ if ( tuples1.isEmpty() && tuples2.isEmpty() )
+ // They are the same size.
return true;
// Recurse
if ( matcher(tuples1, tuples2, c.mapping, mappable, nodeTest) ) {
@@ -235,7 +232,7 @@ public class IsoAlg {
return false;
}
finally {
- out.decIndent();
+ if ( DEBUG ) out.decIndent();
}
}
return true;
@@ -258,11 +255,10 @@ public class IsoAlg {
}
/** Return all possible tuple-tuple matches from tuple t1 to tuples in x2 */
- private static List<Possibility> matcher(Tuple<Node> t1, Collection<Tuple<Node>> g2, Mapping mapping, Iso.Mappable mappable,
- EqualityTest nodeTest) {
+ private static List<Possibility> matcher(Tuple<Node> t1, Collection<Tuple<Node>> g2, IsoMapping mapping, IsoLib.Mappable mappable, EqualityTest nodeTest) {
List<Possibility> matches = new ArrayList<>();
for ( Tuple<Node> t2 : g2 ) {
- Mapping step = gen(t1, t2, mapping, mappable, nodeTest);
+ IsoMapping step = matchTuples(t1, t2, mapping, mappable, nodeTest);
if ( step != null ) {
Possibility c = new Possibility(t2, step);
matches.add(c);
@@ -272,19 +268,19 @@ public class IsoAlg {
}
/**
- * Find a mapping between the tuples, given a start mapping.
- * Return a mapping or null for "no match".
+ * Find a IsoMapping between the tuples, given a start mapping.
+ * Return a IsoMapping or null for "no match".
*/
- private static Mapping gen(Tuple<Node> t1, Tuple<Node> t2, Mapping _mapping, Iso.Mappable mappable, EqualityTest nodeTest) {
+ private static IsoMapping matchTuples(Tuple<Node> t1, Tuple<Node> t2, IsoMapping _mapping, IsoLib.Mappable mappable, EqualityTest nodeTest) {
if ( t1.len() != t2.len() )
return null;
- Mapping mapping = _mapping;
+ IsoMapping mapping = _mapping;
for ( int i = 0 ; i < t1.len() ; i++ ) {
Node n1 = t1.get(i);
Node n2 = t2.get(i);
- Mapping mapping2 = gen(n1, n2, mapping, mappable, nodeTest);
+ IsoMapping mapping2 = matchTerms(n1, n2, mapping, mappable, nodeTest);
if ( mapping2 == null )
return null;
mapping = mapping2;
@@ -297,15 +293,14 @@ public class IsoAlg {
triple.getPredicate(),
triple.getObject());
-
- static Mapping gen(Node n1, Node n2, Mapping _mapping, Iso.Mappable mappable, EqualityTest nodeTest) {
- Mapping mapping = _mapping;
+ static IsoMapping matchTerms(Node n1, Node n2, IsoMapping _mapping, IsoLib.Mappable mappable, EqualityTest nodeTest) {
+ IsoMapping mapping = _mapping;
Node n1m = mapping.map(n1);
if ( n1m != null ) {
// Already mapped
if ( n1m.equals(n2) )
- // Exact equals after mapping t1 slot.
+ // Exact equals after IsoMapping n1.
return mapping;
// No match.
return null;
@@ -317,8 +312,7 @@ public class IsoAlg {
Triple t2 = n2.getTriple();
Tuple<Node> tuple1 = tripleToTuple.apply(t1);
Tuple<Node> tuple2 = tripleToTuple.apply(t2);
- // Whether to records the triple term mapping.
- return gen(tuple1, tuple2, mapping, mappable, nodeTest);
+ return matchTuples(tuple1, tuple2, mapping, mappable, nodeTest);
}
} else if ( n2.isTripleTerm() ) {
return null;
@@ -333,7 +327,7 @@ public class IsoAlg {
}
// **** If n2 not already mapped.
- mapping = new Mapping(mapping, n1, n2);
+ mapping = new IsoMapping(mapping, n1, n2);
return mapping;
}
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/iso/IsoLib.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/iso/IsoLib.java
new file mode 100644
index 0000000000..f0506dd11f
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/iso/IsoLib.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.sparql.util.iso;
+
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.jena.graph.Node;
+import org.apache.jena.riot.out.NodeFmtLib;
+import org.apache.jena.sparql.core.Var;
+import org.apache.jena.sparql.engine.binding.Binding;
+import org.apache.jena.sparql.exec.RowSet;
+import org.apache.jena.sparql.exec.RowSetRewindable;
+import org.apache.jena.sparql.util.EqualityTest;
+
+/**
+ * Shared stuff. Where does this go?
+ */
+class IsoLib {
+ static final boolean DEBUG = false;
+
+ /**
+ * Interface for choosing the pairs of node that can be mapped for isomorphism.
+ */
+ @FunctionalInterface
+ interface Mappable {
+ boolean mappable(Node n1, Node n2);
+ }
+
+ /** Blank nodes are mappable in {@link IsoAlgTuple} */
+ static Mappable mappableBlankNodes = (Node n1, Node n2) -> n1.isBlank() && n2.isBlank();
+
+ static Mappable mappableVariables = (Node n1, Node n2) -> n1.isVariable() && n2.isVariable();
+
+ static Mappable mappableBlankNodesVariables = (Node n1, Node n2) -> {
+ if ( n1.isBlank() && n2.isBlank() ) return true;
+ if ( n1.isVariable() && n2.isVariable() ) return true;
+ return false;
+ };
+
+ /** Exact match only (a separate test), same term, blank nodes have same label. */
+ static Mappable mappableNoMap = (Node n1, Node n2) -> false;
+
+ static boolean compareHeader(RowSet rs1, RowSet rs2) {
+ if ( rs1 == null && rs2 == null )
+ return true;
+ if ( rs1 == null )
+ return false;
+ if ( rs2 == null )
+ return false;
+ Set<Var> names1 = Set.copyOf(rs1.getResultVars());
+ Set<Var> names2 = Set.copyOf(rs2.getResultVars());
+ return names1.equals(names2);
+ }
+
+ static RowSetRewindable print(RowSet rs) {
+ RowSetRewindable rsw = rs.rewindable();
+ rsw.forEach(binding->{
+ String x = str(binding);
+ System.out.print(" ");
+ System.out.print(x);
+ System.out.println();
+ });
+ rsw.reset();
+ return rsw;
+ }
+
+ // String, with blank node ids, not "_:bN"
+ static String str(Binding binding) {
+ StringBuffer sbuff = new StringBuffer();
+ binding.forEach((var, node)-> {
+ String tmp = NodeFmtLib.strNT(node);
+ sbuff.append("( ?" + var.getVarName() + " = " + tmp + " )");
+
+ });
+ return sbuff.toString();
+ }
+
+
+ /** Compare two bindings, use the node equality test provided */
+ static boolean equal(Binding bind1, Binding bind2, EqualityTest test) {
+ if ( bind1 == bind2 )
+ return true;
+ if ( bind1.size() != bind2.size() )
+ return false;
+ // They are the same size so containment is enough.
+ if ( ! containedIn(bind1, bind2, test) )
+ return false;
+ return true;
+ }
+
+ // Is bind1 contained in bind2? For every (var,value) in bind1, is it in bind2?
+ // Maybe more in bind2.
+ private static boolean containedIn(Binding bind1, Binding bind2, EqualityTest test) {
+ Iterator<Var> iter1 = bind1.vars();
+ while(iter1.hasNext()) {
+ Var v = iter1.next();
+ Node n1 = bind1.get(v);
+ Node n2 = bind2.get(v);
+ if ( n2 == null )
+ // v bound in bind1 and not in bind2.
+ return false;
+ if ( ! test.equal(n1, n2) )
+ return false;
+ }
+ return true;
+ }
+
+}
\ No newline at end of file
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/iso/IsoMapping.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/iso/IsoMapping.java
new file mode 100644
index 0000000000..263db14b33
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/iso/IsoMapping.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.sparql.util.iso;
+
+import org.apache.jena.graph.Node;
+
+/** Record the mapping of a node. This is a one-way linked list. */
+/*package*/ record IsoMapping(IsoMapping parent, Node node1, Node node2) {
+
+ static final IsoMapping rootMapping = new IsoMapping(null, null, null);
+
+ boolean mapped(Node node) {
+ return map(node) != null;
+ }
+
+ Node map(Node node) {
+ IsoMapping mapping = this;
+ while (mapping != rootMapping) {
+ if ( mapping.node1.equals(node) )
+ return mapping.node2;
+ mapping = mapping.parent;
+ }
+ return null;
+ }
+
+ boolean reverseMapped(Node node) {
+ return reverseMap(node) != null;
+ }
+
+ Node reverseMap(Node node) {
+ IsoMapping mapping = this;
+ while (mapping != rootMapping) {
+ if ( mapping.node2.equals(node) )
+ return mapping.node1;
+ mapping = mapping.parent;
+ }
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sbuff = new StringBuilder();
+ IsoMapping mapping = this;
+ while (mapping != rootMapping) {
+ sbuff.append("{" + mapping.node1 + " => " + mapping.node2 + "}");
+ mapping = mapping.parent;
+ }
+ sbuff.append("{}");
+ return sbuff.toString();
+ }
+}
\ No newline at end of file
diff --git a/jena-arq/src/test/java/org/apache/jena/arq/junit/sparql/tests/QueryEvalTest.java b/jena-arq/src/test/java/org/apache/jena/arq/junit/sparql/tests/QueryEvalTest.java
index ce1b51a95f..00d3377c52 100644
--- a/jena-arq/src/test/java/org/apache/jena/arq/junit/sparql/tests/QueryEvalTest.java
+++ b/jena-arq/src/test/java/org/apache/jena/arq/junit/sparql/tests/QueryEvalTest.java
@@ -50,7 +50,7 @@ import org.apache.jena.sparql.engine.binding.BindingBuilder;
import org.apache.jena.sparql.engine.iterator.QueryIterPlainWrapper;
import org.apache.jena.sparql.expr.nodevalue.NodeFunctions;
import org.apache.jena.sparql.junit.QueryTestException;
-import org.apache.jena.sparql.resultset.ResultSetCompare;
+import org.apache.jena.sparql.resultset.ResultsCompare;
import org.apache.jena.sparql.resultset.SPARQLResult;
import org.apache.jena.sparql.util.IsoMatcher;
import org.apache.jena.sparql.vocabulary.ResultSetGraphVocab;
@@ -211,7 +211,7 @@ public class QueryEvalTest implements Runnable {
if ( results == null )
return;
- // Assumes resultSetCompare can cope with full isomorphism possibilities.
+ // Assumes ResultsCompare can cope with full isomorphism possibilities.
ResultSetRewindable resultsExpected;
if ( results.isResultSet() )
resultsExpected = ResultSetFactory.makeRewindable(results.getResultSet());
@@ -301,14 +301,14 @@ public class QueryEvalTest implements Runnable {
private static boolean resultSetEquivalent(Query query, ResultSetRewindable resultsExpected, ResultSetRewindable resultsActual) {
if ( compareResultSetsByValue ) {
if ( query.isOrdered() )
- return ResultSetCompare.equalsByValueAndOrder(resultsExpected, resultsActual);
+ return ResultsCompare.equalsByValueAndOrder(resultsExpected, resultsActual);
else
- return ResultSetCompare.equalsByValue(resultsExpected, resultsActual);
+ return ResultsCompare.equalsByValue(resultsExpected, resultsActual);
} else {
if ( query.isOrdered() )
- return ResultSetCompare.equalsByTermAndOrder(resultsExpected, resultsActual);
+ return ResultsCompare.equalsByTermAndOrder(resultsExpected, resultsActual);
else
- return ResultSetCompare.equalsByTerm(resultsExpected, resultsActual);
+ return ResultsCompare.equalsByTerm(resultsExpected, resultsActual);
}
}
diff --git a/jena-arq/src/test/java/org/apache/jena/atlas/data/DataBagExaminer.java b/jena-arq/src/test/java/org/apache/jena/atlas/data/DataBagExaminer.java
index 2c2c4bac16..2a3673b967 100644
--- a/jena-arq/src/test/java/org/apache/jena/atlas/data/DataBagExaminer.java
+++ b/jena-arq/src/test/java/org/apache/jena/atlas/data/DataBagExaminer.java
@@ -18,20 +18,17 @@
package org.apache.jena.atlas.data;
-import java.io.File ;
+import java.io.File;
/**
- * This class exists so that we can examine the internals of a DataBag during testing (which we can do here since it is in the same package).
+ * This class exists so that we can examine the internals of a DataBag during testing
+ * (which we can do here since it is in the same package).
*/
-public class DataBagExaminer
-{
- public static int countTemporaryFiles(AbstractDataBag<?> bag)
- {
+public class DataBagExaminer {
+ public static int countTemporaryFiles(AbstractDataBag<? > bag) {
int count = 0;
- for (File tempFile : bag.getSpillFiles())
- {
- if (tempFile.exists())
- {
+ for ( File tempFile : bag.getSpillFiles() ) {
+ if ( tempFile.exists() ) {
count++;
}
}
diff --git a/jena-arq/src/test/java/org/apache/jena/atlas/data/TestDistinctDataBag.java b/jena-arq/src/test/java/org/apache/jena/atlas/data/TestDistinctDataBag.java
index 734b96d171..a75494a3e3 100644
--- a/jena-arq/src/test/java/org/apache/jena/atlas/data/TestDistinctDataBag.java
+++ b/jena-arq/src/test/java/org/apache/jena/atlas/data/TestDistinctDataBag.java
@@ -24,19 +24,22 @@ import static org.junit.Assert.assertTrue;
import java.io.File ;
import java.util.*;
+import org.junit.Test ;
+
import org.apache.jena.atlas.iterator.Iter ;
import org.apache.jena.datatypes.xsd.XSDDatatype ;
import org.apache.jena.graph.NodeFactory ;
import org.apache.jena.query.SortCondition ;
import org.apache.jena.sparql.core.Var ;
-import org.apache.jena.sparql.engine.binding.*;
-import org.apache.jena.sparql.resultset.ResultSetCompare ;
+import org.apache.jena.sparql.engine.binding.Binding;
+import org.apache.jena.sparql.engine.binding.BindingBuilder;
+import org.apache.jena.sparql.engine.binding.BindingComparator;
+import org.apache.jena.sparql.engine.binding.BindingFactory;
+import org.apache.jena.sparql.resultset.ResultsCompare;
import org.apache.jena.sparql.sse.Item ;
import org.apache.jena.sparql.sse.SSE ;
import org.apache.jena.sparql.sse.builders.BuilderBinding ;
import org.apache.jena.sparql.system.SerializationFactoryFinder;
-import org.apache.jena.sparql.util.NodeUtils ;
-import org.junit.Test ;
public class TestDistinctDataBag
{
@@ -51,8 +54,7 @@ public class TestDistinctDataBag
static Binding bb1 = build("(?a _:XYZ) (?b 1)");
static Binding x10 = build("(?x <http://example/abc>)") ;
- @Test public void testDistinct()
- {
+ @Test public void testDistinct() {
List<Binding> undistinct = new ArrayList<>();
undistinct.add(b12);
undistinct.add(b19);
@@ -71,55 +73,44 @@ public class TestDistinctDataBag
new ThresholdPolicyCount<Binding>(2),
SerializationFactoryFinder.bindingSerializationFactory(),
new BindingComparator(new ArrayList<SortCondition>()));
- try
- {
+ try {
db.addAll(undistinct);
Iterator<Binding> iter = db.iterator();
- while (iter.hasNext())
- {
+ while (iter.hasNext()) {
distinct.add(iter.next());
}
Iter.close(iter);
- }
- finally
- {
+ } finally {
db.close();
}
assertEquals(control.size(), distinct.size());
- assertTrue(ResultSetCompare.equalsByTest(control, distinct, NodeUtils.sameNode));
+ assertTrue(ResultsCompare.equalsExact(control, distinct));
}
- @Test public void testTemporaryFilesAreCleanedUpAfterCompletion()
- {
+ @Test
+ public void testTemporaryFilesAreCleanedUpAfterCompletion() {
List<Binding> undistinct = new ArrayList<>();
random = new Random();
- Var[] vars = new Var[]{
- Var.alloc("1"), Var.alloc("2"), Var.alloc("3"),
- Var.alloc("4"), Var.alloc("5"), Var.alloc("6"),
- Var.alloc("7"), Var.alloc("8"), Var.alloc("9"), Var.alloc("0")
- };
- for(int i = 0; i < 500; i++){
+ Var[] vars = new Var[]{Var.alloc("1"), Var.alloc("2"), Var.alloc("3"), Var.alloc("4"), Var.alloc("5"), Var.alloc("6"),
+ Var.alloc("7"), Var.alloc("8"), Var.alloc("9"), Var.alloc("0")};
+ for ( int i = 0 ; i < 500 ; i++ ) {
undistinct.add(randomBinding(vars));
}
- DistinctDataBag<Binding> db = new DistinctDataBag<>(
- new ThresholdPolicyCount<Binding>(10),
- SerializationFactoryFinder.bindingSerializationFactory(),
- new BindingComparator(new ArrayList<SortCondition>()));
+ DistinctDataBag<Binding> db = new DistinctDataBag<>(new ThresholdPolicyCount<Binding>(10),
+ SerializationFactoryFinder.bindingSerializationFactory(),
+ new BindingComparator(new ArrayList<SortCondition>()));
List<File> spillFiles = new ArrayList<>();
- try
- {
+ try {
db.addAll(undistinct);
spillFiles.addAll(db.getSpillFiles());
int count = 0;
- for (File file : spillFiles)
- {
- if (file.exists())
- {
+ for ( File file : spillFiles ) {
+ if ( file.exists() ) {
count++;
}
}
@@ -127,36 +118,29 @@ public class TestDistinctDataBag
assertEquals(49, count);
Iterator<Binding> iter = db.iterator();
- while (iter.hasNext())
- {
+ while (iter.hasNext()) {
iter.next();
}
Iter.close(iter);
- }
- finally
- {
+ } finally {
db.close();
}
int count = 0;
- for (File file : spillFiles)
- {
- if (file.exists())
- {
+ for ( File file : spillFiles ) {
+ if ( file.exists() ) {
count++;
}
}
assertEquals(0, count);
}
- private static Binding build(String string)
- {
- Item item = SSE.parse("(binding "+string+")") ;
- return BuilderBinding.build(item) ;
+ private static Binding build(String string) {
+ Item item = SSE.parse("(binding " + string + ")");
+ return BuilderBinding.build(item);
}
- private Binding randomBinding(Var[] vars)
- {
+ private Binding randomBinding(Var[] vars) {
BindingBuilder builder = Binding.builder();
builder.add(vars[0], NodeFactory.createBlankNode());
builder.add(vars[1], NodeFactory.createURI(randomURI()));
@@ -171,15 +155,13 @@ public class TestDistinctDataBag
return builder.build();
}
- public String randomURI()
- {
+ public String randomURI() {
return String.format("http://%s.example.com/%s", randomString(10), randomString(10));
}
- public String randomString(int length)
- {
+ public String randomString(int length) {
StringBuilder builder = new StringBuilder();
- for(int i = 0; i < length; i++){
+ for ( int i = 0 ; i < length ; i++ ) {
builder.append(LETTERS.charAt(random.nextInt(LETTERS.length())));
}
return builder.toString();
@@ -215,6 +197,6 @@ public class TestDistinctDataBag
}
assertEquals(control.size(), distinct.size());
- assertTrue(ResultSetCompare.equalsByTest(control, distinct, NodeUtils.sameNode));
+ assertTrue(ResultsCompare.equalsExact(control, distinct));
}
}
diff --git a/jena-arq/src/test/java/org/apache/jena/atlas/data/TestDistinctDataNet.java b/jena-arq/src/test/java/org/apache/jena/atlas/data/TestDistinctDataNet.java
index a84610195d..09c267935f 100644
--- a/jena-arq/src/test/java/org/apache/jena/atlas/data/TestDistinctDataNet.java
+++ b/jena-arq/src/test/java/org/apache/jena/atlas/data/TestDistinctDataNet.java
@@ -24,6 +24,8 @@ import static org.junit.Assert.assertTrue;
import java.io.File ;
import java.util.*;
+import org.junit.Test ;
+
import org.apache.jena.atlas.iterator.Iter ;
import org.apache.jena.datatypes.xsd.XSDDatatype ;
import org.apache.jena.graph.NodeFactory ;
@@ -32,13 +34,11 @@ import org.apache.jena.sparql.core.Var ;
import org.apache.jena.sparql.engine.binding.Binding ;
import org.apache.jena.sparql.engine.binding.BindingBuilder;
import org.apache.jena.sparql.engine.binding.BindingComparator ;
-import org.apache.jena.sparql.resultset.ResultSetCompare ;
+import org.apache.jena.sparql.resultset.ResultsCompare;
import org.apache.jena.sparql.sse.Item ;
import org.apache.jena.sparql.sse.SSE ;
import org.apache.jena.sparql.sse.builders.BuilderBinding ;
import org.apache.jena.sparql.system.SerializationFactoryFinder;
-import org.apache.jena.sparql.util.NodeUtils ;
-import org.junit.Test ;
public class TestDistinctDataNet
{
@@ -54,8 +54,7 @@ public class TestDistinctDataNet
static Binding x10 = build("(?x <http://example/abc>)") ;
@Test
- public void testDistinct()
- {
+ public void testDistinct() {
List<Binding> undistinct = new ArrayList<>();
undistinct.add(b12);
undistinct.add(b19);
@@ -74,29 +73,24 @@ public class TestDistinctDataNet
new ThresholdPolicyCount<Binding>(2),
SerializationFactoryFinder.bindingSerializationFactory(),
new BindingComparator(new ArrayList<SortCondition>()));
- try
- {
+ try {
db.addAll(undistinct);
Iterator<Binding> iter = db.iterator();
- while (iter.hasNext())
- {
+ while (iter.hasNext()) {
distinct.add(iter.next());
}
Iter.close(iter);
- }
- finally
- {
+ } finally {
db.close();
}
assertEquals(control.size(), distinct.size());
- assertTrue(ResultSetCompare.equalsByTest(control, distinct, NodeUtils.sameNode));
+ assertTrue(ResultsCompare.equalsExact(control, distinct));
}
@Test
- public void testDistinct2()
- {
+ public void testDistinct2() {
List<Binding> undistinct = new ArrayList<>();
undistinct.add(b12);
undistinct.add(b19);
@@ -110,67 +104,51 @@ public class TestDistinctDataNet
List<Binding> control = Iter.toList(Iter.distinct(undistinct.iterator()));
List<Binding> distinct = new ArrayList<>();
-
- DistinctDataNet<Binding> db = new DistinctDataNet<>(
- new ThresholdPolicyCount<Binding>(2),
- SerializationFactoryFinder.bindingSerializationFactory(),
- new BindingComparator(new ArrayList<SortCondition>()));
- try
- {
- for (Binding b : undistinct)
- {
- if (db.netAdd(b))
- {
+ DistinctDataNet<Binding> db = new DistinctDataNet<>(new ThresholdPolicyCount<Binding>(2),
+ SerializationFactoryFinder.bindingSerializationFactory(),
+ new BindingComparator(new ArrayList<SortCondition>()));
+ try {
+ for ( Binding b : undistinct ) {
+ if ( db.netAdd(b) ) {
distinct.add(b);
}
}
Iterator<Binding> iter = db.netIterator();
- while (iter.hasNext())
- {
+ while (iter.hasNext()) {
distinct.add(iter.next());
}
Iter.close(iter);
- }
- finally
- {
+ } finally {
db.close();
}
assertEquals(control.size(), distinct.size());
- assertTrue(ResultSetCompare.equalsByTest(control, distinct, NodeUtils.sameNode));
+ assertTrue(ResultsCompare.equalsExact(control, distinct));
}
@Test
- public void testTemporaryFilesAreCleanedUpAfterCompletion()
- {
+ public void testTemporaryFilesAreCleanedUpAfterCompletion() {
List<Binding> undistinct = new ArrayList<>();
random = new Random();
- Var[] vars = new Var[]{
- Var.alloc("1"), Var.alloc("2"), Var.alloc("3"),
- Var.alloc("4"), Var.alloc("5"), Var.alloc("6"),
- Var.alloc("7"), Var.alloc("8"), Var.alloc("9"), Var.alloc("0")
- };
- for(int i = 0; i < 500; i++){
+ Var[] vars = new Var[]{Var.alloc("1"), Var.alloc("2"), Var.alloc("3"), Var.alloc("4"), Var.alloc("5"), Var.alloc("6"),
+ Var.alloc("7"), Var.alloc("8"), Var.alloc("9"), Var.alloc("0")};
+ for ( int i = 0 ; i < 500 ; i++ ) {
undistinct.add(randomBinding(vars));
}
- DistinctDataNet<Binding> db = new DistinctDataNet<>(
- new ThresholdPolicyCount<Binding>(10),
- SerializationFactoryFinder.bindingSerializationFactory(),
- new BindingComparator(new ArrayList<SortCondition>()));
+ DistinctDataNet<Binding> db = new DistinctDataNet<>(new ThresholdPolicyCount<Binding>(10),
+ SerializationFactoryFinder.bindingSerializationFactory(),
+ new BindingComparator(new ArrayList<SortCondition>()));
List<File> spillFiles = new ArrayList<>();
- try
- {
+ try {
db.addAll(undistinct);
spillFiles.addAll(db.getSpillFiles());
int count = 0;
- for (File file : spillFiles)
- {
- if (file.exists())
- {
+ for ( File file : spillFiles ) {
+ if ( file.exists() ) {
count++;
}
}
@@ -178,55 +156,42 @@ public class TestDistinctDataNet
assertEquals(49, count);
Iterator<Binding> iter = db.iterator();
- while (iter.hasNext())
- {
+ while (iter.hasNext()) {
iter.next();
}
Iter.close(iter);
- }
- finally
- {
+ } finally {
db.close();
}
int count = 0;
- for (File file : spillFiles)
- {
- if (file.exists())
- {
+ for ( File file : spillFiles ) {
+ if ( file.exists() ) {
count++;
}
}
assertEquals(0, count);
}
- private void testDiff(String first, String second, String expected)
- {
- DistinctDataNet.SortedDiffIterator.create(
- Arrays.asList(first.split(" ")).iterator(),
- Arrays.asList(second.split(" ")).iterator());
+ private void testDiff(String first, String second, String expected) {
+ DistinctDataNet.SortedDiffIterator.create(Arrays.asList(first.split(" ")).iterator(), Arrays.asList(second.split(" ")).iterator());
}
- private void testDiff(String[] first, String[] second, String expected)
- {
- DistinctDataNet.SortedDiffIterator<String> sdi = DistinctDataNet.SortedDiffIterator.create(
- Arrays.asList(first).iterator(),
- Arrays.asList(second).iterator());
+ private void testDiff(String[] first, String[] second, String expected) {
+ DistinctDataNet.SortedDiffIterator<String> sdi = DistinctDataNet.SortedDiffIterator.create(Arrays.asList(first).iterator(),
+ Arrays.asList(second).iterator());
StringBuilder sb = new StringBuilder();
boolean firstTime = true;
- while (sdi.hasNext())
- {
- if (!firstTime)
- {
+ while (sdi.hasNext()) {
+ if ( !firstTime ) {
sb.append(" ");
}
firstTime = false;
String s = sdi.next();
- if (null == s)
- {
+ if ( null == s ) {
s = "null";
}
sb.append(s);
@@ -254,14 +219,12 @@ public class TestDistinctDataNet
}
- private static Binding build(String string)
- {
- Item item = SSE.parse("(binding "+string+")") ;
- return BuilderBinding.build(item) ;
+ private static Binding build(String string) {
+ Item item = SSE.parse("(binding " + string + ")");
+ return BuilderBinding.build(item);
}
- private Binding randomBinding(Var[] vars)
- {
+ private Binding randomBinding(Var[] vars) {
BindingBuilder builder = Binding.builder();
builder.add(vars[0], NodeFactory.createBlankNode());
builder.add(vars[1], NodeFactory.createURI(randomURI()));
@@ -276,15 +239,13 @@ public class TestDistinctDataNet
return builder.build();
}
- public String randomURI()
- {
+ public String randomURI() {
return String.format("http://%s.example.com/%s", randomString(10), randomString(10));
}
- public String randomString(int length)
- {
+ public String randomString(int length) {
StringBuilder builder = new StringBuilder();
- for(int i = 0; i < length; i++){
+ for ( int i = 0 ; i < length ; i++ ) {
builder.append(LETTERS.charAt(random.nextInt(LETTERS.length())));
}
return builder.toString();
diff --git a/jena-arq/src/test/java/org/apache/jena/atlas/data/TestSortedDataBag.java b/jena-arq/src/test/java/org/apache/jena/atlas/data/TestSortedDataBag.java
index 662a6a4269..68aa27bf02 100644
--- a/jena-arq/src/test/java/org/apache/jena/atlas/data/TestSortedDataBag.java
+++ b/jena-arq/src/test/java/org/apache/jena/atlas/data/TestSortedDataBag.java
@@ -42,13 +42,12 @@ public class TestSortedDataBag
private static final String LETTERS = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
private Random random;
- @Test public void testSorting()
- {
+ @Test
+ public void testSorting() {
testSorting(500, 10);
}
- private void testSorting(int numBindings, int threshold)
- {
+ private void testSorting(int numBindings, int threshold) {
List<Binding> unsorted = randomBindings(numBindings);
List<SortCondition> conditions = new ArrayList<>();
@@ -59,22 +58,16 @@ public class TestSortedDataBag
List<Binding> sorted = new ArrayList<>();
- SortedDataBag<Binding> db = new SortedDataBag<>(
- new ThresholdPolicyCount<Binding>(threshold),
- SerializationFactoryFinder.bindingSerializationFactory(),
- comparator);
- try
- {
+ SortedDataBag<Binding> db = new SortedDataBag<>(new ThresholdPolicyCount<Binding>(threshold),
+ SerializationFactoryFinder.bindingSerializationFactory(), comparator);
+ try {
db.addAll(unsorted);
Iterator<Binding> iter = db.iterator();
- while (iter.hasNext())
- {
+ while (iter.hasNext()) {
sorted.add(iter.next());
}
Iter.close(iter);
- }
- finally
- {
+ } finally {
db.close();
}
@@ -82,13 +75,13 @@ public class TestSortedDataBag
assertEquals(unsorted, sorted);
}
- @Test public void testSortingWithPreMerge()
- {
+ @Test
+ public void testSortingWithPreMerge() {
// Save the original value...
int origMaxSpillFiles = SortedDataBag.MAX_SPILL_FILES;
- try
- {
+ try {
// Vary the number of spill files and bindings so we get a variable number of premerge rounds
+ // @formatter:off
SortedDataBag.MAX_SPILL_FILES = 2; testSorting(1, 1);
SortedDataBag.MAX_SPILL_FILES = 2; testSorting(2, 1);
SortedDataBag.MAX_SPILL_FILES = 2; testSorting(3, 1);
@@ -99,37 +92,31 @@ public class TestSortedDataBag
SortedDataBag.MAX_SPILL_FILES = 100; testSorting(1000, 10);
SortedDataBag.MAX_SPILL_FILES = 2; testSorting(10, 10);
SortedDataBag.MAX_SPILL_FILES = 5; testSorting(10, 10);
- }
- finally
- {
+ // @formatter:on
+ } finally {
SortedDataBag.MAX_SPILL_FILES = origMaxSpillFiles;
}
}
- @Test public void testTemporaryFilesAreCleanedUpAfterCompletion()
- {
+ @Test
+ public void testTemporaryFilesAreCleanedUpAfterCompletion() {
List<Binding> unsorted = randomBindings(500);
List<SortCondition> conditions = new ArrayList<>();
conditions.add(new SortCondition(new ExprVar("8"), Query.ORDER_ASCENDING));
BindingComparator comparator = new BindingComparator(conditions);
- SortedDataBag<Binding> db = new SortedDataBag<>(
- new ThresholdPolicyCount<Binding>(10),
- SerializationFactoryFinder.bindingSerializationFactory(),
- comparator);
+ SortedDataBag<Binding> db = new SortedDataBag<>(new ThresholdPolicyCount<Binding>(10),
+ SerializationFactoryFinder.bindingSerializationFactory(), comparator);
List<File> spillFiles = new ArrayList<>();
- try
- {
+ try {
db.addAll(unsorted);
spillFiles.addAll(db.getSpillFiles());
int count = 0;
- for (File file : spillFiles)
- {
- if (file.exists())
- {
+ for ( File file : spillFiles ) {
+ if ( file.exists() ) {
count++;
}
}
@@ -137,46 +124,36 @@ public class TestSortedDataBag
assertEquals(49, count);
Iterator<Binding> iter = db.iterator();
- while (iter.hasNext())
- {
+ while (iter.hasNext()) {
iter.next();
}
Iter.close(iter);
- }
- finally
- {
+ } finally {
db.close();
}
int count = 0;
- for (File file : spillFiles)
- {
- if (file.exists())
- {
+ for ( File file : spillFiles ) {
+ if ( file.exists() ) {
count++;
}
}
assertEquals(0, count);
}
- private List<Binding> randomBindings(int numBindings)
- {
+ private List<Binding> randomBindings(int numBindings) {
random = new Random();
- Var[] vars = new Var[]{
- Var.alloc("1"), Var.alloc("2"), Var.alloc("3"),
- Var.alloc("4"), Var.alloc("5"), Var.alloc("6"),
- Var.alloc("7"), Var.alloc("8"), Var.alloc("9"), Var.alloc("0")
- };
+ Var[] vars = new Var[]{Var.alloc("1"), Var.alloc("2"), Var.alloc("3"), Var.alloc("4"), Var.alloc("5"), Var.alloc("6"),
+ Var.alloc("7"), Var.alloc("8"), Var.alloc("9"), Var.alloc("0")};
List<Binding> toReturn = new ArrayList<>();
- for(int i = 0; i < numBindings; i++){
+ for ( int i = 0 ; i < numBindings ; i++ ) {
toReturn.add(randomBinding(vars));
}
return toReturn;
}
- private Binding randomBinding(Var[] vars)
- {
+ private Binding randomBinding(Var[] vars) {
BindingBuilder builder = Binding.builder();
builder.add(vars[0], NodeFactory.createBlankNode());
builder.add(vars[1], NodeFactory.createURI(randomURI()));
@@ -191,30 +168,26 @@ public class TestSortedDataBag
return builder.build();
}
- private String randomURI()
- {
+ private String randomURI() {
return String.format("http://%s.example.com/%s", randomString(10), randomString(10));
}
- private String randomString(int length)
- {
+ private String randomString(int length) {
StringBuilder builder = new StringBuilder();
- for(int i = 0; i < length; i++){
+ for ( int i = 0 ; i < length ; i++ ) {
builder.append(LETTERS.charAt(random.nextInt(LETTERS.length())));
}
return builder.toString();
}
- private void getNextAndExpectException(QueryIterator iter)
- {
- try{
+ private void getNextAndExpectException(QueryIterator iter) {
+ try {
iter.hasNext();
fail("Expected an exception here");
- }catch(QueryCancelledException e){
+ } catch (QueryCancelledException e) {
// expected
- }catch(Exception e){
+ } catch (Exception e) {
fail("Unexpected exception");
}
}
-
}
diff --git a/jena-arq/src/test/java/org/apache/jena/atlas/data/TestThresholdPolicyCount.java b/jena-arq/src/test/java/org/apache/jena/atlas/data/TestThresholdPolicyCount.java
index 1c6d5dd325..c45f398c3a 100644
--- a/jena-arq/src/test/java/org/apache/jena/atlas/data/TestThresholdPolicyCount.java
+++ b/jena-arq/src/test/java/org/apache/jena/atlas/data/TestThresholdPolicyCount.java
@@ -21,29 +21,24 @@ package org.apache.jena.atlas.data;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import org.junit.Test ;
+import org.junit.Test;
+public class TestThresholdPolicyCount {
-public class TestThresholdPolicyCount
-{
-
@Test
- public void count_01()
- {
+ public void count_01() {
ThresholdPolicyCount<String> policy = new ThresholdPolicyCount<>(0);
assertTrue(policy.isThresholdExceeded());
}
-
+
@Test
- public void count_02()
- {
+ public void count_02() {
ThresholdPolicyCount<String> policy = new ThresholdPolicyCount<>(1);
assertFalse(policy.isThresholdExceeded());
}
-
+
@Test
- public void count_03()
- {
+ public void count_03() {
ThresholdPolicyCount<String> policy = new ThresholdPolicyCount<>(1);
assertFalse(policy.isThresholdExceeded());
policy.increment("a");
diff --git a/jena-arq/src/test/java/org/apache/jena/riot/protobuf/TestProtobufResultSet.java b/jena-arq/src/test/java/org/apache/jena/riot/protobuf/TestProtobufResultSet.java
index 4f554154c0..5cef3bf5fe 100644
--- a/jena-arq/src/test/java/org/apache/jena/riot/protobuf/TestProtobufResultSet.java
+++ b/jena-arq/src/test/java/org/apache/jena/riot/protobuf/TestProtobufResultSet.java
@@ -33,7 +33,7 @@ import org.apache.jena.query.ResultSetFormatter;
import org.apache.jena.query.ResultSetRewindable;
import org.apache.jena.riot.resultset.ResultSetLang;
import org.apache.jena.sparql.exec.RowSet;
-import org.apache.jena.sparql.resultset.ResultSetCompare;
+import org.apache.jena.sparql.resultset.ResultsCompare;
import org.apache.jena.sparql.sse.Item;
import org.apache.jena.sparql.sse.SSE;
import org.apache.jena.sparql.sse.builders.BuilderRowSet;
@@ -75,7 +75,7 @@ public class TestProtobufResultSet {
// not reordered
r1.reset();
rs2.reset() ;
- assertFalse(ResultSetCompare.equalsByTermAndOrder(r1, rs2)) ;
+ assertFalse(ResultsCompare.equalsByTermAndOrder(r1, rs2)) ;
rs2.reset() ;
}
@@ -84,7 +84,7 @@ public class TestProtobufResultSet {
// not reordered
r2.reset();
rs1.reset() ;
- assertFalse(ResultSetCompare.equalsByTermAndOrder(r2, rs1)) ;
+ assertFalse(ResultsCompare.equalsByTermAndOrder(r2, rs1)) ;
rs1.reset() ;
}
@@ -98,7 +98,7 @@ public class TestProtobufResultSet {
RowSet rs$ = ProtobufRDF.readRowSet(in) ;
ResultSetRewindable resultSet2 = ResultSetFactory.makeRewindable(rs$) ;
// Includes bnode labels.
- ResultSetCompare.equalsExact(resultSet, resultSet2) ;
+ ResultsCompare.equalsExact(resultSet, resultSet2) ;
resultSet.reset();
resultSet2.reset();
return resultSet2 ;
diff --git a/jena-arq/src/test/java/org/apache/jena/riot/resultset/TestResultSetIO.java b/jena-arq/src/test/java/org/apache/jena/riot/resultset/TestResultSetIO.java
index b3f465619d..4fe4f4f5b0 100644
--- a/jena-arq/src/test/java/org/apache/jena/riot/resultset/TestResultSetIO.java
+++ b/jena-arq/src/test/java/org/apache/jena/riot/resultset/TestResultSetIO.java
@@ -39,7 +39,7 @@ import org.apache.jena.query.ResultSetFactory ;
import org.apache.jena.query.ResultSetRewindable ;
import org.apache.jena.riot.Lang ;
import org.apache.jena.riot.ResultSetMgr ;
-import org.apache.jena.sparql.resultset.ResultSetCompare ;
+import org.apache.jena.sparql.resultset.ResultsCompare ;
import org.apache.jena.sparql.sse.SSE ;
import org.apache.jena.sparql.sse.builders.BuilderRowSet;
@@ -97,7 +97,7 @@ public class TestResultSetIO {
ResultSetRewindable rsw = ResultSetFactory.makeRewindable(rs) ;
if ( ! lang.equals(RS_CSV) ) {
// CSV is not faithful
- assertTrue(ResultSetCompare.equalsByTerm(test_rs, rsw)) ;
+ assertTrue(ResultsCompare.equalsByTerm(test_rs, rsw)) ;
}
rsw.reset();
@@ -109,7 +109,7 @@ public class TestResultSetIO {
rsw.reset();
in = new ByteArrayInputStream(out2.toByteArray()) ;
ResultSet rs2 = ResultSetMgr.read(in, lang) ;
- assertTrue(ResultSetCompare.equalsByTerm(rsw, rs2)) ;
+ assertTrue(ResultsCompare.equalsByTerm(rsw, rs2)) ;
}
}
diff --git a/jena-arq/src/test/java/org/apache/jena/riot/thrift/TestThriftResultSet.java b/jena-arq/src/test/java/org/apache/jena/riot/thrift/TestThriftResultSet.java
index c878a96c87..867b87ff8e 100644
--- a/jena-arq/src/test/java/org/apache/jena/riot/thrift/TestThriftResultSet.java
+++ b/jena-arq/src/test/java/org/apache/jena/riot/thrift/TestThriftResultSet.java
@@ -33,7 +33,7 @@ import org.apache.jena.query.ResultSetFormatter;
import org.apache.jena.query.ResultSetRewindable ;
import org.apache.jena.riot.resultset.ResultSetLang;
import org.apache.jena.sparql.exec.RowSet;
-import org.apache.jena.sparql.resultset.ResultSetCompare ;
+import org.apache.jena.sparql.resultset.ResultsCompare ;
import org.apache.jena.sparql.sse.SSE ;
import org.junit.Test ;
@@ -70,7 +70,7 @@ public class TestThriftResultSet {
// not reordered
r1.reset();
rs2.reset() ;
- assertFalse(ResultSetCompare.equalsByTermAndOrder(r1, rs2)) ;
+ assertFalse(ResultsCompare.equalsByTermAndOrder(r1, rs2)) ;
rs2.reset() ;
}
@@ -79,7 +79,7 @@ public class TestThriftResultSet {
// not reordered
r2.reset();
rs1.reset() ;
- assertFalse(ResultSetCompare.equalsByTermAndOrder(r2, rs1)) ;
+ assertFalse(ResultsCompare.equalsByTermAndOrder(r2, rs1)) ;
rs1.reset() ;
}
@@ -93,7 +93,7 @@ public class TestThriftResultSet {
RowSet rs$ = ThriftRDF.readRowSet(in) ;
ResultSetRewindable resultSet2 = ResultSetFactory.makeRewindable(rs$) ;
// Includes bnode labels.
- ResultSetCompare.equalsExact(resultSet, resultSet2) ;
+ ResultsCompare.equalsExact(resultSet, resultSet2) ;
resultSet.reset();
resultSet2.reset();
return resultSet2 ;
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/AbstractTestAdditional.java b/jena-arq/src/test/java/org/apache/jena/sparql/AbstractTestAdditional.java
index 6e558d8364..3d24699111 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/AbstractTestAdditional.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/AbstractTestAdditional.java
@@ -27,7 +27,7 @@ import org.apache.jena.sparql.core.Quad;
import org.apache.jena.sparql.exec.QueryExec;
import org.apache.jena.sparql.exec.RowSetOps;
import org.apache.jena.sparql.exec.RowSetRewindable;
-import org.apache.jena.sparql.resultset.ResultSetCompare;
+import org.apache.jena.sparql.resultset.ResultsCompare;
import org.apache.jena.sparql.sse.SSE;
import org.apache.jena.system.Txn;
import org.junit.Test;
@@ -70,7 +70,7 @@ public abstract class AbstractTestAdditional {
}
private static void testRS(RowSetRewindable rsExpected, RowSetRewindable rsGot) {
- boolean b = ResultSetCompare.equalsByTerm(rsExpected, rsGot);
+ boolean b = ResultsCompare.equalsByTerm(rsExpected, rsGot);
if (! b ) {
rsExpected.reset();
rsGot.reset();
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/TC_ARQ.java b/jena-arq/src/test/java/org/apache/jena/sparql/TC_ARQ.java
index 4048ca23b9..6ef2916344 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/TC_ARQ.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/TC_ARQ.java
@@ -52,6 +52,7 @@ import org.apache.jena.sparql.syntax.TS_Syntax ;
import org.apache.jena.sparql.transaction.TS_Transaction ;
import org.apache.jena.sparql.util.TS_DyadicDatasetGraphs;
import org.apache.jena.sparql.util.TS_Util ;
+import org.apache.jena.sparql.util.iso.TS_Iso ;
import org.apache.jena.sparql.util.compose.TS_DatasetCollectors;
import org.junit.AfterClass ;
import org.junit.BeforeClass ;
@@ -67,6 +68,7 @@ import org.junit.runners.Suite ;
, TS_DyadicDatasetGraphs.class
, TS_DatasetCollectors.class
, TS_Util.class
+ , TS_Iso.class
, TS_Expr.class
, TS_LibraryFunctions.class
@@ -97,7 +99,7 @@ import org.junit.runners.Suite ;
// Outside org.apache.jena.sparql
, TS_Query.class
-
+
// RDF 1.2 tests. These track the working group.
, TS_RDF12.class
// And scripted tests.
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/algebra/optimize/TestSemanticEquivalence.java b/jena-arq/src/test/java/org/apache/jena/sparql/algebra/optimize/TestSemanticEquivalence.java
index 159aff2697..f9a30565a0 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/algebra/optimize/TestSemanticEquivalence.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/algebra/optimize/TestSemanticEquivalence.java
@@ -34,7 +34,7 @@ import org.apache.jena.sparql.engine.QueryIterator ;
import org.apache.jena.sparql.engine.ResultSetStream ;
import org.apache.jena.sparql.engine.binding.BindingFactory ;
import org.apache.jena.sparql.engine.main.QueryEngineMain ;
-import org.apache.jena.sparql.resultset.ResultSetCompare ;
+import org.apache.jena.sparql.resultset.ResultsCompare ;
import org.apache.jena.sparql.sse.SSE ;
import org.apache.jena.sparql.util.Symbol ;
import org.junit.AfterClass ;
@@ -204,7 +204,7 @@ public class TestSemanticEquivalence {
}
Assert.assertEquals(expected, rsOpt.size());
}
- Assert.assertTrue(ResultSetCompare.isomorphic(rs, rsOpt));
+ Assert.assertTrue(ResultsCompare.equalsByTerm(rs, rsOpt));
} finally {
// Restore previous state
if (isEnabled) {
@@ -268,7 +268,7 @@ public class TestSemanticEquivalence {
Assert.assertEquals(expected, rsOpt.size());
iterOpt.close();
- Assert.assertTrue(ResultSetCompare.isomorphic(rs, rsOpt));
+ Assert.assertTrue(ResultsCompare.equalsByTerm(rs, rsOpt));
} finally {
// Restore previous state
if (isEnabled) {
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/engine/binding/TestBindingStreams.java b/jena-arq/src/test/java/org/apache/jena/sparql/engine/binding/TestBindingStreams.java
index 69d787d8c6..8f15f9bf90 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/engine/binding/TestBindingStreams.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/engine/binding/TestBindingStreams.java
@@ -26,6 +26,10 @@ import java.io.ByteArrayOutputStream ;
import java.util.ArrayList ;
import java.util.List ;
+import org.junit.AfterClass ;
+import org.junit.BeforeClass ;
+import org.junit.Test ;
+
import org.apache.jena.atlas.legacy.BaseTest2 ;
import org.apache.jena.graph.Node ;
import org.apache.jena.graph.NodeFactory ;
@@ -36,15 +40,9 @@ import org.apache.jena.riot.tokens.Tokenizer ;
import org.apache.jena.riot.tokens.TokenizerText;
import org.apache.jena.sparql.core.Var ;
import org.apache.jena.sparql.graph.NodeConst ;
-import org.apache.jena.sparql.resultset.ResultSetCompare ;
import org.apache.jena.sparql.sse.Item ;
import org.apache.jena.sparql.sse.SSE ;
import org.apache.jena.sparql.sse.builders.BuilderBinding ;
-import org.apache.jena.sparql.util.NodeUtils ;
-import org.junit.AfterClass ;
-import org.junit.BeforeClass ;
-import org.junit.Test ;
-
public class TestBindingStreams
{
@@ -106,82 +104,70 @@ public class TestBindingStreams
@Test public void bindingStream_60() { testWriteRead(bb1) ; }
@Test
- public void bindingStream_61()
- {
- Node bn = NodeFactory.createBlankNode("unusual") ;
- Binding b = BindingFactory.binding(Var.alloc("v"), bn) ;
- testWriteRead(b) ;
+ public void bindingStream_61() {
+ Node bn = NodeFactory.createBlankNode("unusual");
+ Binding b = BindingFactory.binding(Var.alloc("v"), bn);
+ testWriteRead(b);
}
@Test public void bindingStream_62() { testWriteRead(bb2) ; }
@Test public void bindingStream_63() { testWriteRead(bb3) ; }
+ static void testRead(String x, Binding...bindings) {
+ Tokenizer t = TokenizerText.create().fromString(x).build();;
+ BindingInputStream inStream = new BindingInputStream(t);
- static void testRead(String x, Binding ... bindings)
- {
- Tokenizer t = TokenizerText.create().fromString(x).build(); ;
- BindingInputStream inStream = new BindingInputStream(t) ;
-
- if ( bindings.length == 0 )
- {
+ if ( bindings.length == 0 ) {
for ( ; inStream.hasNext() ; )
- inStream.next() ;
- return ;
+ inStream.next();
+ return;
}
- int i ;
- for ( i = 0 ; inStream.hasNext() ; i++ )
- {
- Binding b = inStream.next() ;
- assertTrue("Bindings do not match: expected="+bindings[i]+" got="+b, equalBindings(bindings[i], b)) ;
+ int i;
+ for ( i = 0 ; inStream.hasNext() ; i++ ) {
+ Binding b = inStream.next();
+ assertTrue("Bindings do not match: expected=" + bindings[i] + " got=" + b, equalBindings(bindings[i], b));
}
- assertEquals("Wrong length: expect= "+bindings.length+" got="+i,bindings.length, i) ;
+ assertEquals("Wrong length: expect= " + bindings.length + " got=" + i, bindings.length, i);
}
static void testWriteRead(Binding ... bindings) { testWriteRead(null, bindings) ; }
- static void testWriteRead(PrefixMap prefixMap, Binding ... bindings)
- {
- ByteArrayOutputStream out = new ByteArrayOutputStream() ;
- BindingOutputStream output = new BindingOutputStream(out, prefixMap) ;
+ static void testWriteRead(PrefixMap prefixMap, Binding...bindings) {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ BindingOutputStream output = new BindingOutputStream(out, prefixMap);
for ( Binding b : bindings )
- output.write(b) ;
- output.flush() ;
+ output.write(b);
+ output.flush();
// When the going gets tough, the tough put in trace statements:
- //System.out.println("T: \n"+out.toString()) ;
+ // System.out.println("T: \n"+out.toString()) ;
- ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()) ;
- BindingInputStream input = new BindingInputStream(in) ;
+ ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+ BindingInputStream input = new BindingInputStream(in);
- List<Binding> results = new ArrayList<>() ;
- for ( ; input.hasNext() ; )
- {
- results.add(input.next()) ;
+ List<Binding> results = new ArrayList<>();
+ for ( ; input.hasNext() ; ) {
+ results.add(input.next());
}
- assertEquals(bindings.length, results.size()) ;
- for ( int i = 0 ; i < bindings.length ; i++ )
- {
- Binding b1 = bindings[i] ;
- Binding b2 = results.get(i) ;
- assertTrue("Bindings do not match: expected="+b1+" got="+b2, equalBindings(b1, b2)) ;
+ assertEquals(bindings.length, results.size());
+ for ( int i = 0 ; i < bindings.length ; i++ ) {
+ Binding b1 = bindings[i];
+ Binding b2 = results.get(i);
+ assertTrue("Bindings do not match: expected=" + b1 + " got=" + b2, equalBindings(b1, b2));
}
}
-
- private static boolean equalBindings(Binding binding1, Binding binding2)
- {
- // Need to have the exact same terms coming back (therefore we can't use BNodeIso to compare values)
- return ResultSetCompare.equal(binding1, binding2, NodeUtils.sameNode) ;
+ private static boolean equalBindings(Binding binding1, Binding binding2) {
+ // Identical
+ return BindingLib.equals(binding1, binding2) ;
}
-
- private static Binding build(String string)
- {
- Item item = SSE.parse("(binding "+string+")") ;
- return BuilderBinding.build(item) ;
+ private static Binding build(String string) {
+ Item item = SSE.parse("(binding " + string + ")");
+ return BuilderBinding.build(item);
}
}
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/engine/join/AbstractTestJoin.java b/jena-arq/src/test/java/org/apache/jena/sparql/engine/join/AbstractTestJoin.java
index 02c84d39f3..b04dfa1a13 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/engine/join/AbstractTestJoin.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/engine/join/AbstractTestJoin.java
@@ -34,7 +34,7 @@ import org.apache.jena.sparql.core.Var ;
import org.apache.jena.sparql.engine.QueryIterator ;
import org.apache.jena.sparql.engine.binding.Binding ;
import org.apache.jena.sparql.expr.ExprList ;
-import org.apache.jena.sparql.resultset.ResultSetCompare ;
+import org.apache.jena.sparql.resultset.ResultsCompare ;
import org.apache.jena.sparql.sse.SSE ;
/** Tests for inner/equi joins */
@@ -340,7 +340,7 @@ public abstract class AbstractTestJoin {
private static boolean equalTables(Table table1, Table table2) {
ResultSet rs1 = ResultSetFactory.create(table1.iterator(null), table1.getVarNames()) ;
ResultSet rs2 = ResultSetFactory.create(table2.iterator(null), table2.getVarNames()) ;
- return ResultSetCompare.equalsByTerm(rs1, rs2) ;
+ return ResultsCompare.equalsByTerm(rs1, rs2) ;
}
}
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/engine/join/TestTableJoin.java b/jena-arq/src/test/java/org/apache/jena/sparql/engine/join/TestTableJoin.java
index 3b206254b1..77a6358073 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/engine/join/TestTableJoin.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/engine/join/TestTableJoin.java
@@ -35,7 +35,7 @@ import org.apache.jena.sparql.engine.ExecutionContext ;
import org.apache.jena.sparql.engine.QueryIterator ;
import org.apache.jena.sparql.engine.ref.TableJoin;
import org.apache.jena.sparql.expr.ExprList ;
-import org.apache.jena.sparql.resultset.ResultSetCompare ;
+import org.apache.jena.sparql.resultset.ResultsCompare ;
import org.apache.jena.sparql.sse.SSE ;
/** Tests on tables and the simple nest loop join (TableJoin) used by the reference query engine */
@@ -115,7 +115,7 @@ public class TestTableJoin
public static boolean equalsByTerm(Table table1, Table table2) {
ResultSet rs1 = ResultSetFactory.create(table1.iterator(null), table1.getVarNames()) ;
ResultSet rs2 = ResultSetFactory.create(table2.iterator(null), table2.getVarNames()) ;
- return ResultSetCompare.equalsByTerm(rs1, rs2) ;
+ return ResultsCompare.equalsByTerm(rs1, rs2) ;
}
}
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/path/TestPathQuery.java b/jena-arq/src/test/java/org/apache/jena/sparql/path/TestPathQuery.java
index 26071d5dc0..26ce2c93ce 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/path/TestPathQuery.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/path/TestPathQuery.java
@@ -27,7 +27,8 @@ import org.apache.jena.query.QueryFactory;
import org.apache.jena.riot.Lang;
import org.apache.jena.riot.RDFParser;
import org.apache.jena.sparql.exec.*;
-import org.apache.jena.sparql.resultset.ResultSetCompare;
+import org.apache.jena.sparql.resultset.ResultsCompare;
+
import org.junit.Test;
/** Path tests using queries. */
@@ -75,7 +76,7 @@ public class TestPathQuery {
}
@Test public void testPathByQuery_unboundEnds_05() {
- String qsPath = "PREFIX : <http://example/> SELECT * { ?s :p{1,3} ?o }";
+ String qsPath = "PREFIX : <http://example/> SELECT ?s ?o { ?s :p{1,3} ?o }";
// Same results for the test data, not in general.
String qsExpected = "PREFIX : <http://example/> SELECT ?s ?o { { ?s :p ?o } UNION { ?s :p [:p ?o]} }";
test(graph1, qsPath, qsExpected);
@@ -91,6 +92,7 @@ public class TestPathQuery {
System.out.println(qsPath);
print("Actual", rs1);
print("Expected", rs2);
+ rowSetEquals(rs1, rs2);
}
assertTrue(same);
}
@@ -102,7 +104,8 @@ public class TestPathQuery {
}
private boolean rowSetEquals(RowSetRewindable rowset1, RowSetRewindable rowset2) {
- return ResultSetCompare.equalsByTerm(rowset1, rowset2);
+ // XXX [ISO] Use exact.
+ return ResultsCompare.equalsExact(rowset1, rowset2);
}
private void print(String label, RowSetRewindable rowset) {
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSet.java b/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSet.java
index 1f2cbd9450..5b2d9b0d56 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSet.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSet.java
@@ -82,7 +82,7 @@ public class TestResultSet {
ByteArrayInputStream ins = new ByteArrayInputStream(arr.toByteArray());
ResultSet rs2 = ResultSetFactory.fromXML(ins);
- assertTrue(ResultSetCompare.equalsByTerm(rs1, rs2));
+ assertTrue(ResultsCompare.equalsByTerm(rs1, rs2));
}
@Test
@@ -92,7 +92,7 @@ public class TestResultSet {
rs1.reset();
InputStream in = new ByteArrayInputStream(StrUtils.asUTF8bytes(x));
ResultSet rs2 = ResultSetFactory.fromXML(in);
- assertTrue(ResultSetCompare.equalsByTerm(rs1, rs2));
+ assertTrue(ResultsCompare.equalsByTerm(rs1, rs2));
}
@Test
@@ -103,7 +103,7 @@ public class TestResultSet {
rs1.reset();
ByteArrayInputStream ins = new ByteArrayInputStream(arr.toByteArray());
ResultSet rs2 = ResultSetFactory.fromXML(ins);
- assertTrue(ResultSetCompare.equalsByTerm(rs1, rs2));
+ assertTrue(ResultsCompare.equalsByTerm(rs1, rs2));
}
@Test
@@ -113,7 +113,7 @@ public class TestResultSet {
rs1.reset();
InputStream in = new ByteArrayInputStream(StrUtils.asUTF8bytes(x));
ResultSet rs2 = ResultSetFactory.fromXML(in);
- assertTrue(ResultSetCompare.equalsByTerm(rs1, rs2));
+ assertTrue(ResultsCompare.equalsByTerm(rs1, rs2));
}
// RDF
@@ -124,7 +124,7 @@ public class TestResultSet {
Model model = RDFOutput.encodeAsModel(rs1);
rs1.reset();
ResultSet rs2 = RDFInput.fromRDF(model);
- assertTrue(ResultSetCompare.equalsByTerm(rs1, rs2));
+ assertTrue(ResultsCompare.equalsByTerm(rs1, rs2));
}
@Test
@@ -133,7 +133,7 @@ public class TestResultSet {
Model model = RDFOutput.encodeAsModel(rs1);
rs1.reset();
ResultSetRewindable rs2 = ResultSetFactory.makeRewindable(RDFInput.fromRDF(model));
- boolean b = ResultSetCompare.equalsByTerm(rs1, rs2);
+ boolean b = ResultsCompare.equalsByTerm(rs1, rs2);
if ( !b ) {
rs1.reset();
rs2.reset();
@@ -154,7 +154,7 @@ public class TestResultSet {
rs1.reset();
ByteArrayInputStream ins = new ByteArrayInputStream(arr.toByteArray());
ResultSet rs2 = ResultSetFactory.fromJSON(ins);
- assertTrue(ResultSetCompare.equalsByTerm(rs1, rs2));
+ assertTrue(ResultsCompare.equalsByTerm(rs1, rs2));
}
@Test
@@ -166,7 +166,7 @@ public class TestResultSet {
ByteArrayInputStream ins = new ByteArrayInputStream(arr.toByteArray());
ResultSet rs2 = ResultSetFactory.fromJSON(ins); // Test using the DAWG
// examples
- assertTrue(ResultSetCompare.equalsByTerm(rs1, rs2));
+ assertTrue(ResultsCompare.equalsByTerm(rs1, rs2));
}
// Into some format.
@@ -225,7 +225,7 @@ public class TestResultSet {
ResultSet rs1 = make("x", org.apache.jena.graph.NodeFactory.createURI("tag:local"));
ResultSet rs2 = make("x", org.apache.jena.graph.NodeFactory.createURI("tag:local"));
ResultSet rs3 = make2("x", org.apache.jena.graph.NodeFactory.createURI("tag:local"));
- assertTrue(ResultSetCompare.equalsByTerm(rs3, ResultSetUtils.merge(rs1, rs2)));
+ assertTrue(ResultsCompare.equalsByTerm(rs3, ResultSetUtils.merge(rs1, rs2)));
}
private void test_RS_fmt(ResultSet rs, ResultsFormat fmt, boolean ordered) {
@@ -238,11 +238,11 @@ public class TestResultSet {
ResultSetRewindable rs2 = ResultSetFactory.makeRewindable(ResultSetFactory.load(ins, fmt));
// Ordered? Unordered?
- boolean b = ResultSetCompare.equalsByTerm(rs1, rs2);
+ boolean b = ResultsCompare.equalsByTerm(rs1, rs2);
if ( ordered ) {
rs1.reset();
rs2.reset();
- b = b & ResultSetCompare.equalsByTerm(rs1, rs2);
+ b = b & ResultsCompare.equalsByTerm(rs1, rs2);
}
if ( !b ) {
@@ -261,17 +261,17 @@ public class TestResultSet {
public void test_RS_cmp_1() {
ResultSetRewindable rs1 = new ResultSetMem();
ResultSetRewindable rs2 = new ResultSetMem();
- assertTrue(ResultSetCompare.equalsByTerm(rs1, rs2));
+ assertTrue(ResultsCompare.equalsByTerm(rs1, rs2));
rs1.reset();
rs2.reset();
- assertTrue(ResultSetCompare.equalsByTerm(rs1, rs2));
+ assertTrue(ResultsCompare.equalsByTerm(rs1, rs2));
}
@Test
public void test_RS_cmp_2() {
ResultSet rs1 = make("x", org.apache.jena.graph.NodeFactory.createURI("tag:local"));
ResultSet rs2 = new ResultSetMem();
- assertFalse(ResultSetCompare.equalsByTerm(rs1, rs2));
+ assertFalse(ResultsCompare.equalsByTerm(rs1, rs2));
}
@@ -279,15 +279,15 @@ public class TestResultSet {
public void test_RS_cmp_3() {
ResultSet rs1 = make("x", org.apache.jena.graph.NodeFactory.createURI("tag:local"));
ResultSet rs2 = new ResultSetMem();
- assertFalse(ResultSetCompare.equalsByTerm(rs1, rs2));
+ assertFalse(ResultsCompare.equalsByTerm(rs1, rs2));
}
@Test
public void test_RS_cmp_4() {
ResultSet rs1 = make("x", org.apache.jena.graph.NodeFactory.createURI("tag:local"));
ResultSet rs2 = make("x", org.apache.jena.graph.NodeFactory.createURI("tag:local"));
- assertTrue(ResultSetCompare.equalsByTerm(rs1, rs2));
- assertTrue(ResultSetCompare.equalsByTerm(rs1, rs2));
+ assertTrue(ResultsCompare.equalsByTerm(rs1, rs2));
+ assertTrue(ResultsCompare.equalsByTerm(rs1, rs2));
}
@Test
@@ -296,13 +296,13 @@ public class TestResultSet {
ResultSetRewindable rs1 = makeRewindable("x", org.apache.jena.graph.NodeFactory.createURI("tag:local:1"));
ResultSetRewindable rs2 = makeRewindable("x", org.apache.jena.graph.NodeFactory.createURI("tag:local:2"));
- assertFalse(ResultSetCompare.equalsByTerm(rs1, rs2));
+ assertFalse(ResultsCompare.equalsByTerm(rs1, rs2));
rs1.reset();
rs2.reset();
assertTrue(rs1.hasNext());
assertTrue(rs2.hasNext());
- assertFalse(ResultSetCompare.equalsByTerm(rs1, rs2));
+ assertFalse(ResultsCompare.equalsByTerm(rs1, rs2));
}
@Test
@@ -310,12 +310,12 @@ public class TestResultSet {
// Different variable, same values
ResultSetRewindable rs1 = makeRewindable("x", org.apache.jena.graph.NodeFactory.createURI("tag:local"));
ResultSetRewindable rs2 = makeRewindable("y", org.apache.jena.graph.NodeFactory.createURI("tag:local"));
- assertFalse(ResultSetCompare.equalsByTermAndOrder(rs1, rs2));
+ assertFalse(ResultsCompare.equalsByTermAndOrder(rs1, rs2));
rs1.reset();
rs2.reset();
assertTrue(rs1.hasNext());
assertTrue(rs2.hasNext());
- assertFalse(ResultSetCompare.equalsByTerm(rs1, rs2));
+ assertFalse(ResultsCompare.equalsByTerm(rs1, rs2));
}
// Value based
@@ -323,8 +323,8 @@ public class TestResultSet {
public void test_RS_cmp_value_1() {
ResultSetRewindable rs1 = makeRewindable("x", NodeFactoryExtra.parseNode("123"));
ResultSetRewindable rs2 = makeRewindable("x", NodeFactoryExtra.parseNode("0123"));
- assertFalse(ResultSetCompare.equalsByTerm(rs1, rs2));
- assertTrue(ResultSetCompare.equalsByValue(rs1, rs2));
+ assertFalse(ResultsCompare.equalsByTerm(rs1, rs2));
+ assertTrue(ResultsCompare.equalsByValue(rs1, rs2));
}
// Peeking
@@ -503,25 +503,19 @@ public class TestResultSet {
// ---- Isomorphism.
- /* This is from the DAWG test suite. Result set 1: --------------- | x | y |
- * =============== | _:b0 | _:b1 | | _:b2 | _:b3 | | _:b1 | _:b0 |
- * --------------- Result set 2: --------------- | x | y | =============== | _:b1
- * | _:b0 | | _:b3 | _:b2 | | _:b2 | _:b3 | --------------- */
-
- // nasty result set.
- // These are the same but the first row of rs2$ throws in a wrong mapping of
- // b0/c1
-
- // Right mapping is:
- // b0->c3, b1->c2, b2->c1, b3->c0
- // Currently we get, working simply top to bottom, no backtracking:
- // b0->c1, b1->c0, b2->c3, b3->c2, then last row fails as _:b1 is mapped to c0,
- // b0 to c1 not (c2, c3)
-
- private static String[] rs1$ = {"(resultset (?x ?y)", " (row (?x _:b0) (?y _:b1))", " (row (?x _:b2) (?y _:b3))",
- " (row (?x _:b1) (?y _:b0))", ")"};
- private static String[] rs2$ = {"(resultset (?x ?y)", " (row (?x _:c1) (?y _:c0))", " (row (?x _:c3) (?y _:c2))",
- " (row (?x _:c2) (?y _:c3))", ")"};
+ private static String[] rs1$ = {
+ "(resultset (?x ?y)",
+ " (row (?x _:b0) (?y _:b1))",
+ " (row (?x _:b2) (?y _:b3))",
+ " (row (?x _:b1) (?y _:b0))",
+ ")"
+ };
+ private static String[] rs2$ = {
+ "(resultset (?x ?y)",
+ " (row (?x _:c1) (?y _:c0))",
+ " (row (?x _:c3) (?y _:c2))",
+ " (row (?x _:c2) (?y _:c3))",
+ ")"};
@Test
public void test_RS_iso_1() {
@@ -531,14 +525,10 @@ public class TestResultSet {
private void isotest(String[] rs1$2, String[] rs2$2) {
ResultSetRewindable rs1 = make(StrUtils.strjoinNL(rs1$));
ResultSetRewindable rs2 = make(StrUtils.strjoinNL(rs2$));
-
- assertTrue(ResultSetCompare.isomorphic(rs1, rs2));
+ assertTrue(ResultsCompare.equalsByTerm(rs1, rs2));
rs1.reset();
rs2.reset();
- assertTrue(ResultSetCompare.equalsByTerm(rs1, rs2));
- rs1.reset();
- rs2.reset();
- assertTrue(ResultSetCompare.equalsByValue(rs1, rs2));
+ assertTrue(ResultsCompare.equalsByValue(rs1, rs2));
}
private static ResultSetRewindable make(String x) {
@@ -580,12 +570,14 @@ public class TestResultSet {
ByteArrayInputStream y = new ByteArrayInputStream(x.toByteArray());
ResultSetRewindable rs2 = ResultSetFactory.copyResults(ResultsReader.create().context(cxt).lang(sparqlresultlang).read(y));
+
rs1.reset();
rs2.reset();
+
if ( same )
- assertTrue(ResultSetCompare.equalsExact(rs1, rs2));
+ assertTrue(ResultsCompare.equalsExact(rs1, rs2));
else
- assertFalse(ResultSetCompare.equalsExact(rs1, rs2));
+ assertFalse(ResultsCompare.equalsExact(rs1, rs2));
}
// -------- Support functions
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetFormat1.java b/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetFormat1.java
index 707f195a7f..2bb6fd23a3 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetFormat1.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetFormat1.java
@@ -112,81 +112,72 @@ public class TestResultSetFormat1
")" } ;
@Parameters
- public static Collection<Object[]> data()
- {
+ public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] { {$rs0}, {$rs1}, {$rs2}, {$rs3}, {$rs4}, {$rs5}, {$rs6}, {$rs7}, {$rs8}, {$rs9}, {$rs10}, {$rs11} } ) ;
}
private final String[] $rs ;
- public TestResultSetFormat1(String[] rs)
- {
- this.$rs = rs ;
+ public TestResultSetFormat1(String[] rs) {
+ this.$rs = rs;
}
- static ResultSet make(String... strings)
- {
+ static ResultSet make(String...strings) {
if ( strings.length == 0 )
- throw new IllegalArgumentException() ;
+ throw new IllegalArgumentException();
- String x = StrUtils.strjoinNL(strings) ;
- Item item = SSE.parse(x) ;
+ String x = StrUtils.strjoinNL(strings);
+ Item item = SSE.parse(x);
return ResultSetFactory.makeRewindable(BuilderRowSet.build(item));
}
- @Test public void resultset_01()
- {
- ResultSet rs = make($rs) ;
- ResultSetFormatter.asText(rs) ;
+ @Test
+ public void resultset_01() {
+ ResultSet rs = make($rs);
+ ResultSetFormatter.asText(rs);
}
- @Test public void resultset_02()
- {
- ResultSet rs = make($rs) ;
- ByteArrayOutputStream out = new ByteArrayOutputStream() ;
- ResultSetFormatter.outputAsXML(out, rs) ;
- ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()) ;
- ResultSet rs2 = ResultSetFactory.fromXML(in) ;
+ @Test
+ public void resultset_02() {
+ ResultSet rs = make($rs);
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ResultSetFormatter.outputAsXML(out, rs);
+ ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+ ResultSet rs2 = ResultSetFactory.fromXML(in);
checkIsomorphic(rs, rs2);
}
- @Test public void resultset_03()
- {
- ResultSet rs = make($rs) ;
- ByteArrayOutputStream out = new ByteArrayOutputStream() ;
- ResultSetFormatter.outputAsJSON(out, rs) ;
- ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()) ;
- ResultSet rs2 = ResultSetFactory.fromJSON(in) ;
+ @Test
+ public void resultset_03() {
+ ResultSet rs = make($rs);
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ResultSetFormatter.outputAsJSON(out, rs);
+ ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+ ResultSet rs2 = ResultSetFactory.fromJSON(in);
checkIsomorphic(rs, rs2);
}
- @Test public void resultset_04()
- {
- ResultSet rs = make($rs) ;
- ByteArrayOutputStream out = new ByteArrayOutputStream() ;
- ResultSetFormatter.outputAsTSV(out, rs) ;
- ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()) ;
+ @Test
+ public void resultset_04() {
+ ResultSet rs = make($rs);
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ResultSetFormatter.outputAsTSV(out, rs);
+ ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
ResultSet rs2 = ResultSetMgr.read(in, ResultSetLang.RS_TSV);
checkIsomorphic(rs, rs2);
}
- @Test public void resultset_05()
- {
- ResultSet rs = make($rs) ;
- ByteArrayOutputStream out = new ByteArrayOutputStream() ;
- ResultSetFormatter.outputAsCSV(out, rs) ;
+ @Test
+ public void resultset_05() {
+ ResultSet rs = make($rs);
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ResultSetFormatter.outputAsCSV(out, rs);
}
- private static void checkIsomorphic(ResultSet x, ResultSet y)
- {
+ private static void checkIsomorphic(ResultSet x, ResultSet y) {
ResultSetRewindable rs1 = x.rewindable();
ResultSetRewindable rs2 = y.rewindable();
-// System.out.println(ResultSetFormatter.asText(rs1));
-// System.out.println();
-// System.out.println(ResultSetFormatter.asText(rs2));
-// rs1.reset();
-// rs2.reset();
- Assert.assertTrue(ResultSetCompare.isomorphic(rs1, rs2)) ;
+ Assert.assertTrue(ResultsCompare.equalsByTerm(rs1, rs2));
}
}
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 248e96e3d9..64e3d9362f 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
@@ -28,7 +28,6 @@ import org.junit.runners.Suite.SuiteClasses ;
TestList.class ,
TestFmtUtils.class,
TestContextUtils.class,
- TestIsoMatcher.class,
TestGraphUtils.class,
TestQueryCheckRW.class
})
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/iso/TS_Iso.java
similarity index 81%
copy from jena-arq/src/test/java/org/apache/jena/sparql/util/TS_Util.java
copy to jena-arq/src/test/java/org/apache/jena/sparql/util/iso/TS_Iso.java
index 248e96e3d9..ee160060dd 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/iso/TS_Iso.java
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-package org.apache.jena.sparql.util;
+package org.apache.jena.sparql.util.iso;
import org.junit.runner.RunWith ;
import org.junit.runners.Suite ;
@@ -24,13 +24,9 @@ import org.junit.runners.Suite.SuiteClasses ;
@RunWith(Suite.class)
@SuiteClasses( {
- TestDateTimeParsing.class ,
- TestList.class ,
- TestFmtUtils.class,
- TestContextUtils.class,
+ TestIso.class,
TestIsoMatcher.class,
- TestGraphUtils.class,
- TestQueryCheckRW.class
+ TestIsoAlgRows.class
})
-public class TS_Util
-{ }
+
+public class TS_Iso { }
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/util/iso/TestIso.java b/jena-arq/src/test/java/org/apache/jena/sparql/util/iso/TestIso.java
new file mode 100644
index 0000000000..0c7dd01d66
--- /dev/null
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/util/iso/TestIso.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.sparql.util.iso;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.sparql.sse.SSE;
+import org.apache.jena.sparql.util.Iso;
+import org.apache.jena.sparql.util.NodeIsomorphismMap;
+
+/** {@link Iso} contains atomic and order list matching. */
+public class TestIso {
+
+ @Test public void iso_terms_iri_01() { testTerms(":s", ":s", true); }
+ @Test public void iso_terms_iri_02() { testTerms(":s", ":x", false); }
+
+ @Test public void iso_terms_bnode_01() { testTerms("_:s", "_:x", true); }
+ @Test public void iso_terms_bnode_02() { testTerms("_:s", "_:s", true); }
+
+ @Test public void iso_terms_literal_01() { testTerms("'abc'", "'abc'", true); }
+ @Test public void iso_terms_literal_02() { testTerms("'abc'", "'xyz'", false); }
+
+ @Test public void iso_terms_tripleTerms_01() { testTerms("<<( :s :p :o )>>", "<<( :s :p :o )>>", true); }
+ @Test public void iso_terms_tripleTerms_02() { testTerms("<<(:s :p :z )>>", "<<( :s :p :o )>>", false); }
+
+ @Test public void iso_terms_tripleTerms_03() { testTerms("<<( _:b :p :o )>>", "<<( _:x :p :o )>>", true); }
+ @Test public void iso_terms_tripleTerms_04() { testTerms("<<( _:b :p _:b )>>", "<<( _:x :p _:z )>>", false); }
+
+ @Test public void iso_terms_50() { testTerms(":s", "_:b", false); }
+
+ @Test public void iso_triples_01() { testTriples("(:s :p :o)", "(:s :p :o)", true); }
+ @Test public void iso_triples_02() { testTriples("(_:b :p :o)", "(_:x :p :o)", true); }
+ @Test public void iso_triples_03() { testTriples("(_:b :p :o)", "(:s :p _:b)", false); }
+ @Test public void iso_triples_04() { testTriples("(_:b :p _:b)", "(_:x1 :p _:x2)", false); }
+
+ private void testTerms(String str1, String str2, boolean expected) {
+ Node n1 = SSE.parseNode(str1);
+ Node n2 = SSE.parseNode(str2);
+ NodeIsomorphismMap isoMap = new NodeIsomorphismMap();
+ boolean result = Iso.nodeIso(n1, n2, isoMap);
+ assertEquals(expected, result);
+ }
+
+ private void testTriples(String str1, String str2, boolean expected) {
+ Triple t1 = SSE.parseTriple(str1);
+ Triple t2 = SSE.parseTriple(str2);
+ NodeIsomorphismMap isoMap = new NodeIsomorphismMap();
+ boolean result = Iso.tripleIso(t1, t2, isoMap);
+ assertEquals(expected, result);
+ }
+}
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/util/iso/TestIsoAlgRows.java b/jena-arq/src/test/java/org/apache/jena/sparql/util/iso/TestIsoAlgRows.java
new file mode 100644
index 0000000000..7dd7dc054e
--- /dev/null
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/util/iso/TestIsoAlgRows.java
@@ -0,0 +1,351 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.sparql.util.iso;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+
+import org.junit.Test;
+
+import org.apache.jena.graph.Node;
+import org.apache.jena.sparql.engine.binding.Binding;
+import org.apache.jena.sparql.exec.RowSet;
+import org.apache.jena.sparql.exec.RowSetMem;
+import org.apache.jena.sparql.exec.RowSetRewindable;
+import org.apache.jena.sparql.resultset.ResultsCompare;
+import org.apache.jena.sparql.sse.SSE;
+import org.apache.jena.sparql.util.EqualityTest;
+import org.apache.jena.sparql.util.NodeUtils;
+
+public class TestIsoAlgRows {
+
+ @Test public void testIsoTerm_01() { testIsoTerm(":s", ":s", true); }
+ @Test public void testIsoTerm_02() { testIsoTerm(":s", "'s'", false); }
+ @Test public void testIsoTerm_03() { testIsoTerm("_:b0", "_:b1", true); }
+ @Test public void testIsoTerm_04() { testIsoTerm("<<(_:b0 :p :o )>>", "<<(_:b1 :p :o )>>", true); }
+
+ @Test
+ public void testIsoTerm_05() {
+ testIsoTerm("<<( _:b0 :p <<( _:b0 _:b0 _:b0 )>> )>>", "<<( _:b1 :p <<( _:b1 _:b1 _:b1 )>> )>>", true);
+ }
+
+ @Test
+ public void testIsoTerm_06() {
+ testIsoTerm("<<( _:b0 :p <<( _:b0 _:b0 _:b0 )>> )>>", "<<( _:b1 :p <<( _:b1 _:b1 _:b2 )>> )>>", false);
+ }
+
+ @Test
+ public void testIsoTerm_07() {
+ testIsoTerm("<<( _:b1 :p <<( _:b0 _:b0 _:b1 )>> )>>", "<<( _:b2 :p <<( _:b3 _:b3 _:b2 )>> )>>", true);
+ }
+
+ @Test public void testIsoRowSet_01() { testIsoRowSet("(rowset (?x))", "(rowset (?x))", true); }
+ @Test public void testIsoRowSet_02() { testIsoRowSet("(rowset (?x))", "(rowset (?y))", false); }
+ @Test public void testIsoRowSet_03() { testIsoRowSet("(rowset (?x))", "(rowset (?x ?y))", false); }
+ @Test public void testIsoRowSet_04() { testIsoRowSet("(rowset (?x ?y))", "(rowset (?y ?x))", true); }
+
+ @Test public void testIsoRowSet_10() { testIsoRowSet("(rowset (?x) (row (?x 'A')) )", "(rowset (?x) (row (?x 'A')) )", true); }
+ @Test public void testIsoRowSet_11() { testIsoRowSet("(rowset (?x) (row (?x 'A')) )", "(rowset (?y) (row (?y 'A')) )", false); }
+ @Test public void testIsoRowSet_12() { testIsoRowSet("(rowset (?x) (row (?x 'A')) )", "(rowset (?x) (row (?x 'A')) )", true); }
+ @Test public void testIsoRowSet_13() { testIsoRowSet("(rowset (?x) (row (?x 'A')) )", "(rowset (?x) (row (?x 'A')) )", true); }
+
+ @Test public void testIsoRowSet_14() { testIsoRowSet("(rowset (?x ?y))", "(rowset (?y ?x) (row) )", false); }
+ @Test public void testIsoRowSet_15() { testIsoRowSet("(rowset (?x) (row (?x 'A')) )", "(rowset (?x) (row (?x 'A')) (row) )", false); }
+
+ @Test public void testIsoRowSet_16() {
+ testIsoRowSet("(rowset (?x ?y) (row (?x 'A') (?y 'B')) )",
+ "(rowset (?x ?y) (row (?y 'B') (?x 'A')) )",
+ true);
+ }
+
+ // Blank nodes, one row
+
+ @Test public void testIsoRowSet_21() {
+ testIsoRowSet("(rowset (?x ?y ?z) (row (?x _:b0) (?y _:b1) (?z _:b2)) )",
+ "(rowset (?x ?y ?z) (row (?x _:c0) (?y _:c1) (?z _:c2)) )",
+ true); }
+
+ @Test public void testIsoRowSet_22() {
+ testIsoRowSet("(rowset (?x ?y ?z) (row (?x _:b0) (?y _:b1) (?z _:b0)) )",
+ "(rowset (?x ?y ?z) (row (?x _:c0) (?y _:c1) (?z _:c0)) )",
+ true); }
+
+ @Test public void testIsoRowSet_23() {
+ testIsoRowSet("(rowset (?x ?y ?z) (row (?x _:b0) (?y _:b1) (?z _:b0)) )",
+ "(rowset (?x ?y ?z) (row (?x _:c0) (?y _:c1) (?z _:c2)) )",
+ false); }
+
+ // Multiple rows
+ @Test public void testIsoRowSet_30() {
+ testIsoRowSet("(rowset (?x ?y) (row (?x 'A')) (row (?y 'B')) )",
+ "(rowset (?x ?y) (row (?y 'B')) (row (?x 'A')) )",
+ true);
+ }
+
+ @Test public void testIsoRowSet_31() {
+ testIsoRowSet("(rowset (?x ?y) (row (?x _:b0)) (row (?y _:b0)) )",
+ "(rowset (?x ?y) (row (?x _:c0)) (row (?y _:c1)) )",
+ false);
+ }
+
+ @Test public void testIsoRowSet_32() {
+ testIsoRowSet("(rowset (?x ?y) (row (?x _:b0)) (row (?y _:b0)) )",
+ "(rowset (?x ?y) (row (?y _:c1)) (row (?x _:c0)) )",
+ false);
+ }
+
+ @Test public void testIsoRowSet_33() {
+ testIsoRowSet("(rowset (?x) (row (?x _:b0)) (row (?x _:b0)) )",
+ "(rowset (?x) (row (?x _:c0)) (row (?x _:c1)) )",
+ false);
+ }
+
+ @Test public void testIsoRowSet_34() {
+ testIsoRowSet("(rowset (?x) (row (?x _:b0)) (row (?x _:b0)) )",
+ "(rowset (?x) (row (?x _:c0)) (row (?x _:c0)) )",
+ true);
+ }
+
+ //ResultsCompare.equalsExact
+
+ @Test public void testIsoExactRowSet_01() {
+ String x = "(rowset (?x) (row (?x _:b0)) )";
+ // Re-parsed - fresh bnodes.s
+ testIsoExactRowSet(x, x, false);
+ }
+
+ @Test public void testIsoExactRowSet_02() {
+ String x = """
+ (rowset (?x ?y)
+ (row (?x _:b0) (?y _:b1))
+ (row (?x _:b2) (?y _:b3))
+ (row (?x _:b1) (?y _:b0))
+ )
+ """;
+ testIsoExactRowSet(x, x, false);
+ }
+
+ @Test public void testIsoExactRowSet_10() {
+
+ String x = """
+ (rowset (?x ?y)
+ (row (?x _:b0) (?y _:b1))
+ (row (?x _:b2) (?y _:b3))
+ (row (?x _:b1) (?y _:b0))
+ )
+ """;
+ RowSetRewindable rowSet1 = SSE.parseRowSet(x).rewindable();
+ RowSetRewindable rowSet2 =RowSetMem.create(rowSet1);
+ rowSet1.reset();
+ rowSet2.reset();
+ testIsoExactRowSet(rowSet1, x, rowSet2, x, true);
+ }
+
+ @Test public void testIsoRowSet_35() {
+ String x = """
+ (rowset (?x ?y)
+ (row (?x _:b0) (?y _:b1))
+ (row (?x _:b2) (?y _:b3))
+ (row (?x _:b1) (?y _:b0))
+ )
+ """;
+ testIsoRowSet(x, x, true);
+ }
+
+ // Term testing
+
+ @Test public void testIsoRowSet_40() {
+ testIsoRowSet("(rowset (?x) (row (?x <<(:s :p _:b)>>)) )",
+ "(rowset (?x) (row (?x <<(:s :p _:b)>>)) )",
+ true);
+ }
+
+ @Test public void testIsoRowSet_41() {
+ testIsoRowSet("(rowset (?x ?y) (row (?x <<(:s :p _:b)>>) (?y <<(:s :p _:b)>>)) )",
+ "(rowset (?x ?y) (row (?x <<(:s :p _:b)>>) (?y <<(:s :p _:b)>>)) )",
+ true);
+ }
+
+ @Test public void testIsoRowSet_42() {
+ testIsoRowSet("(rowset (?x ?y) (row (?x <<(:s :p _:b)>>) (?y <<(:s :p _:b)>>)) )",
+ "(rowset (?x ?y) (row (?x <<(:s :p _:b1)>>) (?y <<(:s :p _:b2)>>)) )",
+ false);
+ }
+
+ @Test public void testIsoRowSet_50() {
+ testIsoRowSet("(rowset (?x) (row (?x <<(_:b :p <<(_:b :p _:b)>> )>>)) )",
+ "(rowset (?x) (row (?x <<(_:b :p <<(_:b :p _:b)>> )>>)) )",
+ true);
+ }
+
+ @Test public void testIsoRowSet_51() {
+ testIsoRowSet("(rowset (?x) (row (?x <<(_:b :p <<(_:b :p _:b)>> )>>)) )",
+ "(rowset (?x) (row (?x <<(_:b :p <<(_:b1 :p _:b)>> )>>)) )",
+ false);
+ }
+
+ // ---- Lists of rows.
+ @FunctionalInterface
+ interface ListTest {
+ boolean test(List<Binding> list1, List<Binding> list2);
+ }
+
+ @Test public void testIsoList_01() {
+ testIsoListRows("(row (?x :x0) (?y :x1)) (row (?x :x2) (?y :x3)) ",
+ "(row (?x :x0) (?y :x1)) (row (?x :x2) (?y :x3)) ",
+ ResultsCompare::equalsExact,
+ true);
+ }
+
+ @Test public void testIsoList_02() {
+ String arg1 = "(row (?x :x0) (?y :x1)) (row (?x :x2) (?y :x3))";
+ String arg2 = "(row (?x :x2) (?y :x3)) (row (?x :x0) (?y :x1))";
+
+ testIsoListRows(arg1, arg2, ResultsCompare::equalsExact, true);
+ testIsoListRows(arg1, arg2, ResultsCompare::equalsExactAndOrder, false);
+ }
+
+ // ---- Machinery
+
+ private static void testIsoTerm(String str1, String str2, boolean expected) {
+ Node n1 = SSE.parseNode(str1);
+ Node n2 = SSE.parseNode(str2);
+
+ testIsoTerm(n1, str1, n2, str2, expected);
+ testIsoTerm(n2, str2, n1, str1, expected);
+
+ boolean b = equalsIsoByTerm(n1, n2);
+ if ( expected != b ) {
+ String msg = expected ? "(expected match)" : "(expected no match)";
+ System.out.println("== ** BAD "+msg);
+ System.out.println("== Term1");
+ System.out.println(" "+str1);
+ System.out.println("== Term2");
+ System.out.println(" "+str2);
+ System.out.println();
+ }
+ assertEquals(expected, b);
+ }
+
+ private static void testIsoTerm(Node n2, String str1, Node n1, String str2, boolean expected) {
+ boolean b = equalsIsoByTerm(n1, n2);
+ if ( expected != b ) {
+ String msg = expected ? "(expected match)" : "(expected no match)";
+ System.out.println("== ** BAD "+msg);
+ System.out.println("== Term1");
+ System.out.println(" "+str1);
+ System.out.println("== Term2");
+ System.out.println(" "+str2);
+ System.out.println();
+ }
+ assertEquals(expected, b);
+ }
+
+ private static boolean equalsIsoByTerm(Node n1, Node n2) {
+ IsoMapping mapping = IsoAlgRows.matchTermsTest(n1, n2, NodeUtils.sameNode);
+ return mapping != null;
+ }
+
+ // RowSet testing.
+
+ private static void testIsoRowSet(String str1, String str2, boolean expected) {
+ RowSetRewindable rowSet1 = SSE.parseRowSet(str1).rewindable();
+ RowSetRewindable rowSet2 = SSE.parseRowSet(str2).rewindable();
+ // Both ways round.
+ testIsoRowSet(rowSet1, str1, rowSet2, str2, expected);
+ rowSet1.reset();
+ rowSet2.reset();
+ testIsoRowSet(rowSet2, str2, rowSet1, str1, expected);
+ }
+
+ private static void testIsoRowSet(RowSet rowSet1, String str1, RowSet rowSet2, String str2, boolean expected) {
+ RowSetRewindable rsw1 = rowSet1.rewindable();
+ RowSetRewindable rsw2 = rowSet2.rewindable();
+ boolean b = equalsIsoByTerm(rsw1, rsw2);
+ if ( expected != b ) {
+ System.out.println("== ** BAD");
+ System.out.println("== rowSet1");
+ System.out.println(str1);
+ System.out.println("== rowSet2");
+ System.out.println(str2);
+ }
+ assertEquals(expected, b);
+ }
+
+ private static boolean equalsIsoByTerm(RowSetRewindable rowSet1, RowSetRewindable rowSet2) {
+ return ResultsCompare.equalsByTerm(rowSet1, rowSet2);
+ }
+
+ private void testIsoExactRowSet(String str1, String str2, boolean expected) {
+ RowSetRewindable rowSet1 = SSE.parseRowSet(str1).rewindable();
+ RowSetRewindable rowSet2 = SSE.parseRowSet(str2).rewindable();
+ // Both ways round.
+ testIsoExactRowSet(rowSet1, str1, rowSet2, str2, expected);
+ rowSet1.reset();
+ rowSet2.reset();
+ testIsoExactRowSet(rowSet2, str2, rowSet1, str1, expected);
+ }
+
+ private void testIsoExactRowSet(RowSet rowSet1, String str1, RowSet rowSet2, String str2, boolean expected) {
+ RowSetRewindable rsw1 = rowSet1.rewindable();
+ RowSetRewindable rsw2 = rowSet2.rewindable();
+ EqualityTest eqtest = NodeUtils.sameRdfTerm;
+ boolean b = ResultsCompare.equalsExact(rowSet1, rowSet2);
+ if ( expected != b ) {
+ System.out.println("== ** BAD");
+ System.out.println("== rowSet1");
+ rsw1.reset();
+ rsw1 = IsoLib.print(rsw1);
+ System.out.println("== rowSet2");
+ rsw2.reset();
+ rsw2 = IsoLib.print(rsw2);
+ }
+ assertEquals(expected, b);
+ }
+
+ // Lists
+
+ private static List<Binding> parseRows(String str) {
+ RowSet rowSet = SSE.parseRowSet("(rowset () "+str+" )");
+ Binding[] x = rowSet.stream().toArray(Binding[]::new);
+ return List.of(x); // Immutable, no nulls.
+ }
+
+ private static void testIsoListRows(String str1, String str2, ListTest predicate, boolean expected) {
+ List<Binding> rows1 = parseRows(str1);
+ List<Binding> rows2 = parseRows(str2);
+ testIsoListRows(rows1, str1, rows2, str2, predicate, expected);
+ testIsoListRows(rows2, str2, rows1, str1, predicate, expected);
+ }
+
+ private static void testIsoListRows(List<Binding> rows1, String str1, List<Binding> rows2, String str2, ListTest predicate, boolean expected) {
+ boolean b = predicate.test(rows1, rows2);
+ if ( expected != b ) {
+ String msg = expected ? "(expected match)" : "(expected no match)";
+ System.out.println("== ** BAD "+msg);
+ System.out.println("== Row list 1");
+ System.out.println(" "+str1);
+ System.out.println("== Row list 12");
+ System.out.println(" "+str2);
+ System.out.println();
+ }
+ assertEquals(expected, b);
+ }
+}
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/util/TestIsoMatcher.java b/jena-arq/src/test/java/org/apache/jena/sparql/util/iso/TestIsoMatcher.java
similarity index 94%
rename from jena-arq/src/test/java/org/apache/jena/sparql/util/TestIsoMatcher.java
rename to jena-arq/src/test/java/org/apache/jena/sparql/util/iso/TestIsoMatcher.java
index 391ba8529d..0d2ff1a911 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/util/TestIsoMatcher.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/util/iso/TestIsoMatcher.java
@@ -16,8 +16,9 @@
* limitations under the License.
*/
-package org.apache.jena.sparql.util;
+package org.apache.jena.sparql.util.iso;
+import static org.apache.jena.atlas.lib.tuple.TupleFactory.tuple;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
@@ -25,15 +26,21 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import org.junit.Test;
+
+import org.apache.jena.atlas.iterator.Iter;
import org.apache.jena.atlas.lib.tuple.Tuple;
import org.apache.jena.atlas.lib.tuple.TupleFactory;
import org.apache.jena.graph.Graph;
import org.apache.jena.graph.Node;
+import org.apache.jena.graph.Triple;
import org.apache.jena.sparql.core.DatasetGraph;
import org.apache.jena.sparql.sse.Item;
import org.apache.jena.sparql.sse.SSE;
import org.apache.jena.sparql.sse.builders.BuilderNode;
-import org.junit.Test;
+import org.apache.jena.sparql.util.IsoMatcher;
+import org.apache.jena.sparql.util.NodeUtils;
+import org.apache.jena.util.iterator.ExtendedIterator;
public class TestIsoMatcher
{
@@ -336,10 +343,10 @@ public class TestIsoMatcher
Graph g1 = SSE.parseGraph(s1);
Graph g2 = SSE.parseGraph(s2);
- Collection<Tuple<Node>> x1 = IsoMatcher.tuplesTriples(g1.find());
- Collection<Tuple<Node>> x2 = IsoMatcher.tuplesTriples(g2.find());
+ Collection<Tuple<Node>> x1 = tuplesTriples(g1.find());
+ Collection<Tuple<Node>> x2 = tuplesTriples(g2.find());
- boolean b = IsoAlg.isIsomorphic(x1, x2, Iso.mappableBlankNodesVariables, NodeUtils.sameRdfTerm);
+ boolean b = IsoAlgTuple.isIsomorphic(x1, x2, IsoLib.mappableBlankNodesVariables, NodeUtils.sameRdfTerm);
if ( b != expected ) {
System.out.println("====");
SSE.write(g1);
@@ -371,4 +378,11 @@ public class TestIsoMatcher
}
assertEquals(iso, b);
}
+
+ /*package*/ static List<Tuple<Node>> tuplesTriples(ExtendedIterator<Triple> iter) {
+ try {
+ return Iter.iter(iter).map(t->tuple(t.getSubject(), t.getPredicate(), t.getObject())).toList();
+ }
+ finally { iter.close(); }
+ }
}
diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/ListUtils.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/ListUtils.java
index bde33c4d61..1eca2b5154 100644
--- a/jena-base/src/main/java/org/apache/jena/atlas/lib/ListUtils.java
+++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/ListUtils.java
@@ -87,9 +87,9 @@ public class ListUtils
List<T> list2a = new ArrayList<>(list2);
for ( T elt : list1 )
list2a.remove(elt);
- if ( list2a.size() != 0 )
- return false;
- return true;
+ if ( list2a.isEmpty() )
+ return true;
+ return false;
}
/**
diff --git a/jena-core/src/main/java/org/apache/jena/graph/Node.java b/jena-core/src/main/java/org/apache/jena/graph/Node.java
index dd68883648..2f34f2ed71 100644
--- a/jena-core/src/main/java/org/apache/jena/graph/Node.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/Node.java
@@ -246,12 +246,15 @@ public abstract class Node implements Serializable {
/*package*/ Node( ) {}
/**
- * Java rules for equals. See also {#sameTermAs} and {#sameValueAs} Nodes only equal
- * other Nodes that have equal labels.
+ * Java rules for equals. See also {#sameTermAs} and {#sameValueAs}.
+ * Nodes only equal other Nodes that have equal labels.
*/
@Override
public abstract boolean equals(Object o);
+ /**
+ * RDF term equality.
+ */
public boolean sameTermAs(Object o)
{ return equals( o ); }
diff --git a/jena-extras/jena-serviceenhancer/src/test/java/org/apache/jena/sparql/service/enhancer/impl/TestServiceEnhancerCachedVsUncached.java b/jena-extras/jena-serviceenhancer/src/test/java/org/apache/jena/sparql/service/enhancer/impl/TestServiceEnhancerCachedVsUncached.java
index 1e93278c63..7558955607 100644
--- a/jena-extras/jena-serviceenhancer/src/test/java/org/apache/jena/sparql/service/enhancer/impl/TestServiceEnhancerCachedVsUncached.java
+++ b/jena-extras/jena-serviceenhancer/src/test/java/org/apache/jena/sparql/service/enhancer/impl/TestServiceEnhancerCachedVsUncached.java
@@ -25,24 +25,20 @@ import java.util.Random;
import java.util.function.Consumer;
import java.util.regex.Pattern;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
import org.apache.jena.atlas.logging.Log;
-import org.apache.jena.query.Query;
-import org.apache.jena.query.QueryExecution;
-import org.apache.jena.query.QueryFactory;
-import org.apache.jena.query.ResultSetFactory;
-import org.apache.jena.query.ResultSetFormatter;
-import org.apache.jena.query.ResultSetRewindable;
+import org.apache.jena.query.*;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.sparql.engine.iterator.QueryIterSlice;
-import org.apache.jena.sparql.resultset.ResultSetCompare;
+import org.apache.jena.sparql.resultset.ResultsCompare;
import org.apache.jena.sparql.service.ServiceExecutorRegistry;
import org.apache.jena.sparql.service.enhancer.init.ServiceEnhancerInit;
import org.apache.jena.sparql.util.Context;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
/**
@@ -90,7 +86,7 @@ public class TestServiceEnhancerCachedVsUncached {
cxtMutator.accept(qeB.getContext());
rsB = ResultSetFactory.makeRewindable(qeB.execSelect());
- boolean isEqual = ResultSetCompare.equalsByValue(rsA, rsB);
+ boolean isEqual = ResultsCompare.equalsByValue(rsA, rsB);
if (!isEqual) {
rsA.reset();
ResultSetFormatter.out(System.out, rsA);
diff --git a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestQuery.java b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestQuery.java
index 60d4c392e3..54f8e8db4a 100644
--- a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestQuery.java
+++ b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestQuery.java
@@ -18,8 +18,9 @@
package org.apache.jena.fuseki.main;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.*;
@@ -47,7 +48,7 @@ import org.apache.jena.sparql.core.Var;
import org.apache.jena.sparql.engine.binding.Binding;
import org.apache.jena.sparql.exec.QueryExec;
import org.apache.jena.sparql.exec.http.*;
-import org.apache.jena.sparql.resultset.ResultSetCompare;
+import org.apache.jena.sparql.resultset.ResultsCompare;
import org.apache.jena.sparql.sse.SSE;
import org.apache.jena.sparql.util.Convert;
@@ -316,7 +317,7 @@ public class TestQuery extends AbstractFusekiTest {
private void execQuery(String queryString, ResultSet expectedResultSet) {
try ( QueryExecution qExec = QueryExecution.service(serviceQuery(), queryString) ) {
ResultSet rs = qExec.execSelect();
- boolean b = ResultSetCompare.equalsByTerm(rs, expectedResultSet);
+ boolean b = ResultsCompare.equalsByTerm(rs, expectedResultSet);
assertTrue(b, "Result sets different");
}
}
diff --git a/jena-integration-tests/src/test/java/org/apache/jena/test/service/TestCustomServiceExecutor.java b/jena-integration-tests/src/test/java/org/apache/jena/test/service/TestCustomServiceExecutor.java
index b02c72f43f..60a93b4692 100644
--- a/jena-integration-tests/src/test/java/org/apache/jena/test/service/TestCustomServiceExecutor.java
+++ b/jena-integration-tests/src/test/java/org/apache/jena/test/service/TestCustomServiceExecutor.java
@@ -23,10 +23,13 @@ import static org.junit.Assert.assertTrue;
import java.util.function.Consumer;
+import org.junit.Assert;
+import org.junit.Test;
+
import org.apache.jena.atlas.logging.LogCtl;
-import org.apache.jena.query.*;
import org.apache.jena.graph.Node;
import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.query.*;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.riot.ResultSetMgr;
@@ -41,20 +44,20 @@ import org.apache.jena.sparql.engine.QueryIterator;
import org.apache.jena.sparql.engine.binding.Binding;
import org.apache.jena.sparql.engine.iterator.QueryIter;
import org.apache.jena.sparql.exec.QueryExec;
-import org.apache.jena.sparql.resultset.ResultSetCompare;
+import org.apache.jena.sparql.resultset.ResultsCompare;
import org.apache.jena.sparql.service.ServiceExec;
import org.apache.jena.sparql.service.ServiceExecutorRegistry;
import org.apache.jena.sparql.service.single.ServiceExecutor;
import org.apache.jena.sparql.sse.SSE;
-import org.junit.Assert;
-import org.junit.Test;
public class TestCustomServiceExecutor {
static Table table = SSE.parseTable("(table (row (?s 1) (?p 2) (?o 3) ) )");
- /** A custom service factory that yields the above table for any request
- * to urn:customService */
+ /**
+ * A custom service factory that yields the above table
+ * for any request to urn:customService
+ */
static ServiceExecutor factory = (op, opOriginal, binding, execCxt) ->
op.getService().getURI().equals("urn:customService")
? table.iterator(execCxt)
@@ -251,7 +254,7 @@ public class TestCustomServiceExecutor {
public static void assertResult(String serviceIri, Consumer<QueryExecution> qePostProcessor, boolean withSilent) {
ResultSetRewindable actual = runTestQuery(serviceIri, qePostProcessor, withSilent);
- boolean isEqual = ResultSetCompare.equalsExact(actual, ResultSet.adapt(table.toRowSet()));
+ boolean isEqual = ResultsCompare.equalsExact(actual, ResultSet.adapt(table.toRowSet()));
if (!isEqual) {
actual.reset();
ResultSetMgr.write(System.err, actual, ResultSetLang.RS_Text);
diff --git a/jena-tdb1/src/test/java/org/apache/jena/tdb1/solver/TestSolverTDB.java b/jena-tdb1/src/test/java/org/apache/jena/tdb1/solver/TestSolverTDB.java
index d8c30237bc..c3f4e444d7 100644
--- a/jena-tdb1/src/test/java/org/apache/jena/tdb1/solver/TestSolverTDB.java
+++ b/jena-tdb1/src/test/java/org/apache/jena/tdb1/solver/TestSolverTDB.java
@@ -24,10 +24,14 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
import org.apache.jena.graph.Graph;
import org.apache.jena.graph.Node;
import org.apache.jena.graph.Triple;
-import org.apache.jena.query.*;
+import org.apache.jena.query.Dataset;
+import org.apache.jena.query.ReadWrite;
import org.apache.jena.riot.RDFDataMgr;
import org.apache.jena.shared.PrefixMapping;
import org.apache.jena.shared.impl.PrefixMappingImpl;
@@ -40,12 +44,10 @@ import org.apache.jena.sparql.engine.binding.Binding;
import org.apache.jena.sparql.exec.RowSet;
import org.apache.jena.sparql.exec.RowSetOps;
import org.apache.jena.sparql.exec.RowSetRewindable;
-import org.apache.jena.sparql.resultset.ResultSetCompare;
+import org.apache.jena.sparql.resultset.ResultsCompare;
import org.apache.jena.sparql.sse.SSE;
import org.apache.jena.tdb1.ConfigTest;
import org.apache.jena.tdb1.TDB1Factory;
-import org.junit.BeforeClass;
-import org.junit.Test;
public class TestSolverTDB {
static String graphData = null;
@@ -131,7 +133,7 @@ public class TestSolverTDB {
RowSetRewindable rsw1 = rs1.rewindable();
RowSetRewindable rsw2 = rs2.rewindable();
- boolean b = ResultSetCompare.equalsByValue(rsw1, rsw2);
+ boolean b = ResultsCompare.equalsByValue(rsw1, rsw2);
if ( b != result ) {
System.out.println("Different: ");
rsw1.reset();
diff --git a/jena-tdb2/src/test/java/org/apache/jena/tdb2/solver/TestSolverTDB.java b/jena-tdb2/src/test/java/org/apache/jena/tdb2/solver/TestSolverTDB.java
index 8ffc94c0f8..1ffa2ef12a 100644
--- a/jena-tdb2/src/test/java/org/apache/jena/tdb2/solver/TestSolverTDB.java
+++ b/jena-tdb2/src/test/java/org/apache/jena/tdb2/solver/TestSolverTDB.java
@@ -24,10 +24,15 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
import org.apache.jena.graph.Graph;
import org.apache.jena.graph.Node;
import org.apache.jena.graph.Triple;
-import org.apache.jena.query.*;
+import org.apache.jena.query.Dataset;
+import org.apache.jena.query.ReadWrite;
import org.apache.jena.riot.RDFDataMgr;
import org.apache.jena.shared.PrefixMapping;
import org.apache.jena.shared.impl.PrefixMappingImpl;
@@ -40,13 +45,10 @@ import org.apache.jena.sparql.engine.binding.Binding;
import org.apache.jena.sparql.exec.RowSet;
import org.apache.jena.sparql.exec.RowSetOps;
import org.apache.jena.sparql.exec.RowSetRewindable;
-import org.apache.jena.sparql.resultset.ResultSetCompare;
+import org.apache.jena.sparql.resultset.ResultsCompare;
import org.apache.jena.sparql.sse.SSE;
import org.apache.jena.tdb2.ConfigTest;
import org.apache.jena.tdb2.junit.TL;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
public class TestSolverTDB {
static Dataset dataset = null;
@@ -137,7 +139,7 @@ public class TestSolverTDB {
RowSetRewindable rsw1 = rs1.rewindable();
RowSetRewindable rsw2 = rs2.rewindable();
- boolean b = ResultSetCompare.equalsByValue(rsw1, rsw2);
+ boolean b = ResultsCompare.equalsByValue(rsw1, rsw2);
if ( b != result ) {
System.out.println("Different: ");
rsw1.reset();