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 ad4f7f23787424d462836af2c650a2cbd6b453d4
Author: Andy Seaborne <[email protected]>
AuthorDate: Sun Apr 20 11:27:49 2025 +0100

    Move argument checking library code to NodeValueOps
---
 .../java/org/apache/jena/sparql/expr/E_Regex.java  |  4 +-
 .../org/apache/jena/sparql/expr/E_Subtract.java    |  1 -
 .../jena/sparql/expr/nodevalue/NodeFunctions.java  | 67 ------------------
 .../jena/sparql/expr/nodevalue/NodeValueOps.java   | 80 +++++++++++++++++++++-
 .../jena/sparql/expr/nodevalue/XSDFuncOp.java      | 32 ++++-----
 .../apache/jena/sparql/expr/TestNodeFunctions.java | 31 +--------
 .../apache/jena/sparql/expr/TestNodeValueOps.java  | 31 +++++++++
 7 files changed, 128 insertions(+), 118 deletions(-)

diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_Regex.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_Regex.java
index 94f14e752f..eaa58e299a 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_Regex.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_Regex.java
@@ -24,7 +24,7 @@ import org.apache.commons.lang3.StringUtils ;
 import org.apache.jena.atlas.logging.Log ;
 import org.apache.jena.graph.Node ;
 import org.apache.jena.query.ARQ ;
-import org.apache.jena.sparql.expr.nodevalue.NodeFunctions ;
+import org.apache.jena.sparql.expr.nodevalue.NodeValueOps;
 import org.apache.jena.sparql.sse.Tags ;
 import org.apache.jena.sparql.util.FmtUtils ;
 
@@ -62,7 +62,7 @@ public class E_Regex extends ExprFunctionN
 
     @Override
     public NodeValue eval(List<NodeValue> args) {
-        Node arg = NodeFunctions.checkAndGetStringLiteral("REGEX", 
args.get(0));
+        Node arg = NodeValueOps.checkAndGetStringLiteral("REGEX", args.get(0));
         NodeValue vPattern = args.get(1);
         NodeValue vFlags = (args.size() == 2 ? null : args.get(2));
 
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_Subtract.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_Subtract.java
index 846a981e4c..904e692286 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_Subtract.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_Subtract.java
@@ -38,7 +38,6 @@ public class E_Subtract extends ExprFunction2
     {
         if ( ARQ.isStrictMode() )
             return XSDFuncOp.numSubtract(x, y) ;
-
         return NodeValueOps.subtractionNV(x, y) ;
     }
     
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 0d04b2021f..4dfef10acc 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
@@ -53,73 +53,6 @@ import org.apache.jena.vocabulary.XSD;
  */
 public class NodeFunctions {
 
-    /**
-     * check and get a string (may be a simple literal, literal with language
-     * tag or an XSD string).
-     */
-    public static Node checkAndGetStringLiteral(String label, NodeValue nv) {
-        Node n = nv.asNode();
-        if ( !n.isLiteral() )
-            throw new ExprEvalException(label + ": Not a literal: " + nv);
-        String lang = n.getLiteralLanguage();
-
-        if ( NodeUtils.isLangString(n) )
-            // Language tag.  Legal.
-            return n;
-
-        // No language tag : either no datatype or a datatype of xsd:string
-        // Includes the case of rdf:langString and no language ==> Illegal as 
a compatible string.
-
-        if ( nv.isString() )
-                return n;
-        throw new ExprEvalException(label + ": Not a string literal: " + nv);
-    }
-
-    /**
-     * Check for string operations with primary first arg and second arg
-     * (e.g. CONTAINS).  The arguments are not used in the same way and the 
check
-     * operation is not symmetric.
-     * <ul>
-     * <li> "abc"@en is compatible with "abc"
-     * <li> "abc" is NOT compatible with "abc"@en
-     * </ul>
-     */
-    public static void checkTwoArgumentStringLiterals(String label, NodeValue 
arg1, NodeValue arg2) {
-
-        /* Quote the spec:
-         * Compatibility of two arguments is defined as:
-         *    The arguments are simple literals or literals typed as xsd:string
-         *    The arguments are plain literals with identical language tags
-         *    The first argument is a plain literal with language tag and the 
second argument is a simple literal or literal typed as xsd:string
-         */
-
-        Node n1 = checkAndGetStringLiteral(label, arg1);
-        Node n2 = checkAndGetStringLiteral(label, arg2);
-        String lang1 = n1.getLiteralLanguage();
-        String lang2 = n2.getLiteralLanguage();
-        if ( lang1 == null )
-            lang1 = "";
-        if ( lang2 == null )
-            lang2 = "";
-
-        // Case 1
-        if ( lang1.equals("") ) {
-            if ( lang2.equals("") )
-                return;
-            throw new ExprEvalException(label + ": Incompatible: " + arg1 + " 
and " + arg2);
-        }
-
-        // Case 2
-        if ( lang1.equalsIgnoreCase(lang2) )
-            return;
-
-        // Case 3
-        if ( lang2.equals("") )
-            return;
-
-        throw new ExprEvalException(label + ": Incompatible: " + arg1 + " and 
" + arg2);
-    }
-
     // -------- sameTerm
 
     public static NodeValue sameTerm(NodeValue nv1, NodeValue nv2) {
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueOps.java
 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueOps.java
index f1fc4a2ad5..b76ddf2460 100644
--- 
a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueOps.java
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueOps.java
@@ -30,11 +30,20 @@ import javax.xml.datatype.XMLGregorianCalendar;
 import org.apache.jena.datatypes.xsd.XSDDatatype;
 import org.apache.jena.graph.Node;
 import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.sparql.expr.ExprEvalException;
 import org.apache.jena.sparql.expr.ExprEvalTypeException;
 import org.apache.jena.sparql.expr.NodeValue;
 import org.apache.jena.sparql.expr.ValueSpace;
-
-/** The code parts of arithmetic operations on {@link NodeValue}s.
+import org.apache.jena.sparql.util.NodeUtils;
+
+/**
+ * Operations relating to {@link NodeValue NodeValues}.
+ * <ul>
+ * <li>The code parts of arithmetic operations on {@link NodeValue}s.
+ * <li>Library code such as Argument testing
+ * </ul>
+ * <p>
+ * This class is not considered to be part of the ARQ API.
  */
 public class NodeValueOps
 {
@@ -284,4 +293,71 @@ public class NodeValueOps
         long x2 = gcal2.getTimeInMillis();
         return NodeValue.xmlDatatypeFactory.newDuration(x1 - x2);
     }
+
+    /**
+     * check and get a string (may be a simple literal, literal with language
+     * tag or an XSD string).
+     */
+    public static Node checkAndGetStringLiteral(String label, NodeValue nv) {
+        Node n = nv.asNode();
+        if ( !n.isLiteral() )
+            throw new ExprEvalException(label + ": Not a literal: " + nv);
+        String lang = n.getLiteralLanguage();
+
+        if ( NodeUtils.isLangString(n) )
+            // Language tag.  Legal.
+            return n;
+
+        // No language tag : either no datatype or a datatype of xsd:string
+        // Includes the case of rdf:langString and no language ==> Illegal as 
a compatible string.
+
+        if ( nv.isString() )
+                return n;
+        throw new ExprEvalException(label + ": Not a string literal: " + nv);
+    }
+
+    /**
+     * Check for string operations with primary first arg and second arg
+     * (e.g. CONTAINS).  The arguments are not used in the same way and the 
check
+     * operation is not symmetric.
+     * <ul>
+     * <li> "abc"@en is compatible with "abc"
+     * <li> "abc" is NOT compatible with "abc"@en
+     * </ul>
+     */
+    public static void checkTwoArgumentStringLiterals(String label, NodeValue 
arg1, NodeValue arg2) {
+
+        /* Quote the spec:
+         * Compatibility of two arguments is defined as:
+         *    The arguments are simple literals or literals typed as xsd:string
+         *    The arguments are plain literals with identical language tags
+         *    The first argument is a plain literal with language tag and the 
second argument is a simple literal or literal typed as xsd:string
+         */
+
+        Node n1 = checkAndGetStringLiteral(label, arg1);
+        Node n2 = checkAndGetStringLiteral(label, arg2);
+        String lang1 = n1.getLiteralLanguage();
+        String lang2 = n2.getLiteralLanguage();
+        if ( lang1 == null )
+            lang1 = "";
+        if ( lang2 == null )
+            lang2 = "";
+
+        // Case 1
+        if ( lang1.equals("") ) {
+            if ( lang2.equals("") )
+                return;
+            throw new ExprEvalException(label + ": Incompatible: " + arg1 + " 
and " + arg2);
+        }
+
+        // Case 2
+        if ( lang1.equalsIgnoreCase(lang2) )
+            return;
+
+        // Case 3
+        if ( lang2.equals("") )
+            return;
+
+        throw new ExprEvalException(label + ": Incompatible: " + arg1 + " and 
" + arg2);
+    }
 }
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/XSDFuncOp.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/XSDFuncOp.java
index fa049da431..4a17dbc04c 100644
--- 
a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/XSDFuncOp.java
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/XSDFuncOp.java
@@ -19,8 +19,6 @@
 package org.apache.jena.sparql.expr.nodevalue;
 
 import static javax.xml.datatype.DatatypeConstants.*;
-import static 
org.apache.jena.sparql.expr.nodevalue.NodeFunctions.checkAndGetStringLiteral;
-import static 
org.apache.jena.sparql.expr.nodevalue.NodeFunctions.checkTwoArgumentStringLiterals;
 import static org.apache.jena.sparql.expr.nodevalue.NumericType.OP_DECIMAL;
 import static org.apache.jena.sparql.expr.nodevalue.NumericType.OP_DOUBLE;
 import static org.apache.jena.sparql.expr.nodevalue.NumericType.OP_FLOAT;
@@ -63,7 +61,7 @@ public class XSDFuncOp
 {
     private XSDFuncOp() {}
 
-    // The choice of "24" is arbitrary but more than 18 (XSD 1.0) or 16 XSD 
1.1) as required by F&O
+    // The choice of "24" is arbitrary but more than 18 (XSD 1.0) or 16 (XSD 
1.1) as required by F&O
     //   F&O 3.1: section 4.2 (end intro)
     //   https://www.w3.org/TR/xpath-functions/#op.numeric section 4.2
     private static final int DIVIDE_PRECISION = 24;
@@ -556,23 +554,23 @@ public class XSDFuncOp
     }
 
     public static NodeValue strlen(NodeValue nvString) {
-        Node n = checkAndGetStringLiteral("strlen", nvString);
+        Node n = NodeValueOps.checkAndGetStringLiteral("strlen", nvString);
         String str = n.getLiteralLexicalForm();
         int len = str.codePointCount(0, str.length());
         return NodeValue.makeInteger(len);
     }
 
     public static NodeValue strReplace(NodeValue nvStr, NodeValue nvPattern, 
NodeValue nvReplacement, NodeValue nvFlags) {
-        String pat = checkAndGetStringLiteral("replace", 
nvPattern).getLiteralLexicalForm();
+        String pat = NodeValueOps.checkAndGetStringLiteral("replace", 
nvPattern).getLiteralLexicalForm();
         String flagsStr = null;
         if ( nvFlags != null )
-            flagsStr = checkAndGetStringLiteral("replace", 
nvFlags).getLiteralLexicalForm();
+            flagsStr = NodeValueOps.checkAndGetStringLiteral("replace", 
nvFlags).getLiteralLexicalForm();
         return strReplace(nvStr, RegexEngine.makePattern("replace", pat, 
flagsStr), nvReplacement);
     }
 
     public static NodeValue strReplace(NodeValue nvStr, Pattern pattern, 
NodeValue nvReplacement) {
-        String n = checkAndGetStringLiteral("replace", 
nvStr).getLiteralLexicalForm();
-        String rep = checkAndGetStringLiteral("replace", 
nvReplacement).getLiteralLexicalForm();
+        String n = NodeValueOps.checkAndGetStringLiteral("replace", 
nvStr).getLiteralLexicalForm();
+        String rep = NodeValueOps.checkAndGetStringLiteral("replace", 
nvReplacement).getLiteralLexicalForm();
         String x = replaceAll(pattern.matcher(n), rep);
         if ( x == null )
             // No replacement.
@@ -621,7 +619,7 @@ public class XSDFuncOp
     }
 
     public static NodeValue substring(NodeValue nvString, NodeValue nvStart, 
NodeValue nvLength) {
-        Node n = checkAndGetStringLiteral("substring", nvString);
+        Node n = NodeValueOps.checkAndGetStringLiteral("substring", nvString);
         RDFDatatype dt = n.getLiteralDatatype();
         // XSD F&O:
         try {
@@ -708,7 +706,7 @@ public class XSDFuncOp
     }
 
     public static NodeValue strContains(NodeValue string, NodeValue match) {
-        checkTwoArgumentStringLiterals("contains", string, match);
+        NodeValueOps.checkTwoArgumentStringLiterals("contains", string, match);
         String lex1 = string.asNode().getLiteralLexicalForm();
         String lex2 = match.asNode().getLiteralLexicalForm();
         boolean x = StrUtils.contains(lex1, lex2);
@@ -716,14 +714,14 @@ public class XSDFuncOp
     }
 
     public static NodeValue strStartsWith(NodeValue string, NodeValue match) {
-        checkTwoArgumentStringLiterals("strStarts", string, match);
+        NodeValueOps.checkTwoArgumentStringLiterals("strStarts", string, 
match);
         String lex1 = string.asNode().getLiteralLexicalForm();
         String lex2 = match.asNode().getLiteralLexicalForm();
         return NodeValue.booleanReturn(lex1.startsWith(lex2));
     }
 
     public static NodeValue strEndsWith(NodeValue string, NodeValue match) {
-        checkTwoArgumentStringLiterals("strEnds", string, match);
+        NodeValueOps.checkTwoArgumentStringLiterals("strEnds", string, match);
         String lex1 = string.asNode().getLiteralLexicalForm();
         String lex2 = match.asNode().getLiteralLexicalForm();
         return NodeValue.booleanReturn(lex1.endsWith(lex2));
@@ -736,7 +734,7 @@ public class XSDFuncOp
     }
 
     public static NodeValue strBefore(NodeValue string, NodeValue match) {
-        checkTwoArgumentStringLiterals("strBefore", string, match);
+        NodeValueOps.checkTwoArgumentStringLiterals("strBefore", string, 
match);
         String lex1 = string.asNode().getLiteralLexicalForm();
         String lex2 = match.asNode().getLiteralLexicalForm();
         Node mainArg = string.asNode();
@@ -753,7 +751,7 @@ public class XSDFuncOp
     }
 
     public static NodeValue strAfter(NodeValue string, NodeValue match) {
-        checkTwoArgumentStringLiterals("strAfter", string, match);
+        NodeValueOps.checkTwoArgumentStringLiterals("strAfter", string, match);
         String lex1 = string.asNode().getLiteralLexicalForm();
         String lex2 = match.asNode().getLiteralLexicalForm();
         Node mainArg = string.asNode();
@@ -770,14 +768,14 @@ public class XSDFuncOp
     }
 
     public static NodeValue strLowerCase(NodeValue string) {
-        Node n = checkAndGetStringLiteral("lcase", string);
+        Node n = NodeValueOps.checkAndGetStringLiteral("lcase", string);
         String lex = n.getLiteralLexicalForm();
         String lex2 = lex.toLowerCase();
         return calcReturn(lex2, string.asNode());
     }
 
     public static NodeValue strUpperCase(NodeValue string) {
-        Node n = checkAndGetStringLiteral("ucase", string);
+        Node n = NodeValueOps.checkAndGetStringLiteral("ucase", string);
         String lex = n.getLiteralLexicalForm();
         String lex2 = lex.toUpperCase();
         return calcReturn(lex2, string.asNode());
@@ -820,7 +818,7 @@ public class XSDFuncOp
         StringBuilder sb = new StringBuilder();
 
         for (NodeValue nv : args) {
-            Node n = checkAndGetStringLiteral("CONCAT", nv);
+            Node n = NodeValueOps.checkAndGetStringLiteral("CONCAT", nv);
             String lang1 = n.getLiteralLanguage();
             if ( !lang1.equals("") ) {
                 if ( lang != null && !lang1.equals(lang) )
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeFunctions.java 
b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeFunctions.java
index ab46dbb938..1491c3c96d 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeFunctions.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeFunctions.java
@@ -20,6 +20,8 @@ package org.apache.jena.sparql.expr;
 
 import static org.junit.Assert.*;
 
+import org.junit.Test;
+
 import org.apache.jena.datatypes.xsd.XSDDatatype;
 import org.apache.jena.graph.Node;
 import org.apache.jena.graph.NodeFactory;
@@ -28,9 +30,7 @@ import org.apache.jena.query.ARQ;
 import org.apache.jena.sparql.expr.nodevalue.NodeFunctions;
 import org.apache.jena.sparql.graph.NodeConst;
 import org.apache.jena.sparql.sse.SSE;
-import org.apache.jena.vocabulary.RDF;
 import org.apache.jena.vocabulary.XSD;
-import org.junit.Test;
 
 public class TestNodeFunctions {
     private static final double accuracyExact = 0.0d;
@@ -396,31 +396,4 @@ public class TestNodeFunctions {
         NodeValue r = NodeFunctions.isLiteral(nv);
         assertEquals(NodeValue.FALSE, r);
     }
-
-    @Test public void testCheckAndGetStringLiteral1() {
-        NodeValue nv = NodeValue.makeNode("abc", XSDDatatype.XSDstring);
-        Node n = NodeFunctions.checkAndGetStringLiteral("Test", nv);
-        assertEquals( "abc", n.getLiteralLexicalForm());
-    }
-
-    @Test public void testCheckAndGetStringLiteral2() {
-        NodeValue nv = NodeValue.makeNode("abc", 
XSDDatatype.XSDnormalizedString);
-        Node n = NodeFunctions.checkAndGetStringLiteral("Test", nv);
-        assertEquals( "abc", n.getLiteralLexicalForm());
-    }
-
-    @Test public void testCheckAndGetStringLiteral3() {
-        NodeValue nv = NodeValue.makeString("abc");
-        Node n = NodeFunctions.checkAndGetStringLiteral("Test", nv);
-        assertEquals( "abc", n.getLiteralLexicalForm());
-    }
-
-    @Test(expected=ExprEvalException.class)
-    public void testCheckAndGetStringLiteral4() {
-        // The form "abc"^^rdf:langString (no lang tag) is not derived from 
xsd:string.
-        NodeValue nv = NodeValue.makeNode("abc", RDF.dtLangString);
-        Node n = NodeFunctions.checkAndGetStringLiteral("Test", nv);
-        assertEquals( "abc", n.getLiteralLexicalForm());
-    }
-
 }
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeValueOps.java 
b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeValueOps.java
index 7651c9a37f..ff64564e64 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeValueOps.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeValueOps.java
@@ -20,10 +20,41 @@ package org.apache.jena.sparql.expr;
 
 import static org.junit.Assert.assertEquals;
 
+import org.apache.jena.datatypes.xsd.XSDDatatype;
+import org.apache.jena.graph.Node;
 import org.apache.jena.sparql.expr.nodevalue.NodeValueOps;
+import org.apache.jena.vocabulary.RDF;
+
 import org.junit.Test;
 
 public class TestNodeValueOps {
+
+    @Test public void testCheckAndGetStringLiteral1() {
+        NodeValue nv = NodeValue.makeNode("abc", XSDDatatype.XSDstring);
+        Node n = NodeValueOps.checkAndGetStringLiteral("Test", nv);
+        assertEquals( "abc", n.getLiteralLexicalForm());
+    }
+
+    @Test public void testCheckAndGetStringLiteral2() {
+        NodeValue nv = NodeValue.makeNode("abc", 
XSDDatatype.XSDnormalizedString);
+        Node n = NodeValueOps.checkAndGetStringLiteral("Test", nv);
+        assertEquals( "abc", n.getLiteralLexicalForm());
+    }
+
+    @Test public void testCheckAndGetStringLiteral3() {
+        NodeValue nv = NodeValue.makeString("abc");
+        Node n = NodeValueOps.checkAndGetStringLiteral("Test", nv);
+        assertEquals( "abc", n.getLiteralLexicalForm());
+    }
+
+    @Test(expected=ExprEvalException.class)
+    public void testCheckAndGetStringLiteral4() {
+        // The form "abc"^^rdf:langString (no lang tag) is not derived from 
xsd:string.
+        NodeValue nv = NodeValue.makeNode("abc", RDF.dtLangString);
+        Node n = NodeValueOps.checkAndGetStringLiteral("Test", nv);
+        assertEquals( "abc", n.getLiteralLexicalForm());
+    }
+
     // ** Addition
     // Numerics
     @Test

Reply via email to