You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by rv...@apache.org on 2014/09/17 13:20:09 UTC
svn commit: r1625517 - in /jena/trunk/jena-arq/src:
main/java/com/hp/hpl/jena/sparql/expr/nodevalue/XSDFuncOp.java
main/java/com/hp/hpl/jena/sparql/function/library/FN_StrLength.java
test/java/com/hp/hpl/jena/sparql/expr/TestFunctions.java
Author: rvesse
Date: Wed Sep 17 11:20:08 2014
New Revision: 1625517
URL: http://svn.apache.org/r1625517
Log:
Fix SUBSTR() and STRLEN() to follow the XPath specification and compute substrings and lengths based on complete code points not Java characters (JENA-785)
Modified:
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/nodevalue/XSDFuncOp.java
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/library/FN_StrLength.java
jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/expr/TestFunctions.java
Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/nodevalue/XSDFuncOp.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/nodevalue/XSDFuncOp.java?rev=1625517&r1=1625516&r2=1625517&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/nodevalue/XSDFuncOp.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/expr/nodevalue/XSDFuncOp.java Wed Sep 17 11:20:08 2014
@@ -357,7 +357,7 @@ public class XSDFuncOp
return NodeValue.makeString(string.substring(start)) ;
int finish = nvFinish.getInteger().intValue() ;
- return NodeValue.makeString(string.substring(start, finish)) ;
+ return NodeValue.makeString(string.substring(start, string.offsetByCodePoints(start, finish - start))) ;
} catch (IndexOutOfBoundsException ex) {
throw new ExprEvalException("IndexOutOfBounds", ex) ;
}
@@ -365,7 +365,8 @@ public class XSDFuncOp
public static NodeValue strlen(NodeValue nvString) {
Node n = checkAndGetStringLiteral("strlen", nvString) ;
- int len = n.getLiteralLexicalForm().length() ;
+ String str = n.getLiteralLexicalForm();
+ int len = str.codePointCount(0, str.length()) ;
return NodeValue.makeInteger(len) ;
}
@@ -475,7 +476,7 @@ public class XSDFuncOp
if ( string.length() == 0 )
return calcReturn("", n) ;
- String lex2 = string.substring(start, finish) ;
+ String lex2 = string.substring(start, string.offsetByCodePoints(start, finish - start)) ;
return calcReturn(lex2, n) ;
} catch (IndexOutOfBoundsException ex) {
throw new ExprEvalException("IndexOutOfBounds", ex) ;
Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/library/FN_StrLength.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/library/FN_StrLength.java?rev=1625517&r1=1625516&r2=1625517&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/library/FN_StrLength.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/library/FN_StrLength.java Wed Sep 17 11:20:08 2014
@@ -19,6 +19,7 @@
package com.hp.hpl.jena.sparql.function.library;
import com.hp.hpl.jena.sparql.expr.NodeValue ;
+import com.hp.hpl.jena.sparql.expr.nodevalue.XSDFuncOp;
import com.hp.hpl.jena.sparql.function.FunctionBase1 ;
/** string length - F&O operation */
@@ -30,6 +31,6 @@ public class FN_StrLength extends Functi
@Override
public NodeValue exec(NodeValue v)
{
- return NodeValue.makeInteger(v.getString().length()) ;
+ return XSDFuncOp.strlen(v);
}
}
Modified: jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/expr/TestFunctions.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/expr/TestFunctions.java?rev=1625517&r1=1625516&r2=1625517&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/expr/TestFunctions.java (original)
+++ jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/expr/TestFunctions.java Wed Sep 17 11:20:08 2014
@@ -33,6 +33,7 @@ public class TestFunctions
{
private static final NodeValue INT_ZERO = NodeValue.makeInteger(0) ;
private static final NodeValue INT_ONE = NodeValue.makeInteger(1) ;
+ @SuppressWarnings("unused")
private static final NodeValue INT_TWO = NodeValue.makeInteger(2) ;
private static final NodeValue TRUE = NodeValue.TRUE ;
private static final NodeValue FALSE = NodeValue.FALSE ;
@@ -41,6 +42,8 @@ public class TestFunctions
@Test public void exprStrLen1() { test("fn:string-length('')", INT_ZERO) ; }
@Test public void exprStrLen2() { test("fn:string-length('a')", INT_ONE) ; }
+ // Test from JENA-785
+ @Test public void exprStrLen3() { test("fn:string-length('ððð»ðªðð¿ð»ð®ð¿ð²')", NodeValue.makeInteger(10l)) ; }
// F&O strings are one-based, and substring takes a length
@Test public void exprSubstring1() { test("fn:substring('',0)", NodeValue.makeString("")) ; }
@@ -58,12 +61,15 @@ public class TestFunctions
@Test public void exprSubstring10() { test("fn:substring('abc',1.6,1.33)", NodeValue.makeString("b")) ; }
// This test was added because the test suite had 1199 tests in.
@Test public void exprSubstring11() { test("fn:substring('abc',-1, -15.3)", NodeValue.makeString("")) ; }
+ // Test from JENA-785
+ @Test public void exprSubstring12() { test("fn:substring('ððð»ðªðð¿ð»ð®ð¿ð²', 1, 1)", NodeValue.makeString("ð")) ; }
@Test public void exprJavaSubstring1() { test("afn:substr('abc',0,0)", NodeValue.makeString("")) ; }
@Test public void exprJavaSubstring2() { test("afn:substr('abc',0,1)", NodeValue.makeString("a")) ; }
-
@Test public void exprJavaSubstring3() { test("<"+ARQConstants.ARQFunctionLibrary+"substr>('abc',0,0)", NodeValue.makeString("")) ; }
@Test public void exprJavaSubstring4() { test("<"+ARQConstants.ARQFunctionLibrary+"substr>('abc',0,1)", NodeValue.makeString("a")) ; }
+ // Test from JENA-785
+ @Test public void exprJavaSubstring5() { test("afn:substr('ððð»ðªðð¿ð»ð®ð¿ð²', 0, 1)", NodeValue.makeString("ð")) ; }
@Test public void exprStrStart0() { test("fn:starts-with('abc', '')", TRUE) ; }
@Test public void exprStrStart1() { test("fn:starts-with('abc', 'a')", TRUE) ; }