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 2012/04/04 13:09:51 UTC
svn commit: r1309329 - in /incubator/jena/Jena2/ARQ/trunk/src:
main/java/com/hp/hpl/jena/sparql/function/CastXSD.java
test/java/com/hp/hpl/jena/sparql/expr/TestExpressions2.java
Author: andy
Date: Wed Apr 4 11:09:51 2012
New Revision: 1309329
URL: http://svn.apache.org/viewvc?rev=1309329&view=rev
Log:
JENA-231 : Fix: NumberFormatException when casting to xsd:int in ARQ
Modified:
incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/function/CastXSD.java
incubator/jena/Jena2/ARQ/trunk/src/test/java/com/hp/hpl/jena/sparql/expr/TestExpressions2.java
Modified: incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/function/CastXSD.java
URL: http://svn.apache.org/viewvc/incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/function/CastXSD.java?rev=1309329&r1=1309328&r2=1309329&view=diff
==============================================================================
--- incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/function/CastXSD.java (original)
+++ incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/function/CastXSD.java Wed Apr 4 11:09:51 2012
@@ -19,13 +19,16 @@
package com.hp.hpl.jena.sparql.function;
import com.hp.hpl.jena.datatypes.xsd.XSDDatatype ;
+import com.hp.hpl.jena.datatypes.xsd.impl.XSDAbstractDateTimeType ;
+import com.hp.hpl.jena.datatypes.xsd.impl.XSDBaseNumericType ;
import com.hp.hpl.jena.graph.Node ;
import com.hp.hpl.jena.sparql.expr.ExprEvalException ;
import com.hp.hpl.jena.sparql.expr.NodeValue ;
-/** General casting : lexcial form must be right.
+/** General casting of XSD datatypes.
* @see CastXSD_DateTime
* @see CastXSD_Numeric
+ * @see CastXSD_Boolean
*/
public class CastXSD implements FunctionFactory
{
@@ -87,13 +90,46 @@ public class CastXSD implements Function
return r ;
}
+ /*
+ * In RDF (2004 at least), whitespace is not legal in lexcial forms of, for example, integers.
+ * http://www.w3.org/TR/rdf-concepts/#section-Datatypes
+ * Whitespace facet processing is part of XML processing, not RDF's lexical to value mapping.
+ */
+ static boolean whitespaceSurroundAllowed = false ; // ! ARQ.isStrictMode() ;
+
protected NodeValue cast(String s, NodeValue nv, XSDDatatype castType2)
{
+ if ( whitespaceSurroundAllowed )
+ // Maybe more convenient, but is not strictly correct.
+ s = s.trim() ;
+ else
+ {
+ // Correct mode. No white space allowed around values types numeric, boolean, dateTime, ...
+ // See also "JenaParameters.enableWhitespaceCheckingOfTypedLiterals" which defaults to false (accept surrounding whitespace)
+ // This CastXSD - not need to check it is an XSD datatype.
+ // if ( castType.getURI().startsWith(XSDDatatype.XSD) &&
+
+ if ( castType instanceof XSDBaseNumericType ||
+ castType.equals(XSDDatatype.XSDfloat) ||
+ castType.equals(XSDDatatype.XSDdouble) ||
+ castType.equals(XSDDatatype.XSDboolean) ||
+ castType instanceof XSDAbstractDateTimeType ) // Includes durations, and Gregorian
+ {
+ if ( s.startsWith(" ") || s.endsWith(" ") )
+ throw new ExprEvalException("CastXSD: Not a valid literal form (has whitespace): '"+s+"'") ;
+ }
+ }
+
// Plain cast.
- if ( ! castType.isValid(s) )
- throw new ExprEvalException("CastXSD: Not a valid literal form: "+s) ;
- // Unfortunately, validity testing happens in NodeValue.makeNode as well.
- return NodeValue.makeNode(s, castType) ;
+ try {
+ if ( ! castType.isValid(s) )
+ throw new ExprEvalException("CastXSD: Not a valid literal form: '"+s+"'") ;
+ // Unfortunately, validity testing happens in NodeValue.makeNode as well.
+ // but better error messages this way.
+ return NodeValue.makeNode(s, castType) ;
+ } catch (RuntimeException ex) {
+ throw new ExprEvalException("CastXSD: Not a strictly valid literal form: '"+s+"'") ;
+ }
}
}
}
Modified: incubator/jena/Jena2/ARQ/trunk/src/test/java/com/hp/hpl/jena/sparql/expr/TestExpressions2.java
URL: http://svn.apache.org/viewvc/incubator/jena/Jena2/ARQ/trunk/src/test/java/com/hp/hpl/jena/sparql/expr/TestExpressions2.java?rev=1309329&r1=1309328&r2=1309329&view=diff
==============================================================================
--- incubator/jena/Jena2/ARQ/trunk/src/test/java/com/hp/hpl/jena/sparql/expr/TestExpressions2.java (original)
+++ incubator/jena/Jena2/ARQ/trunk/src/test/java/com/hp/hpl/jena/sparql/expr/TestExpressions2.java Wed Apr 4 11:09:51 2012
@@ -37,7 +37,7 @@ public class TestExpressions2 extends As
@Test public void gregorian_eq_02() { eval("'1999'^^xsd:gYear != '1999'^^xsd:gYear", false) ; }
@Test (expected=ExprEvalException.class)
- public void gregorian_eq_03() { evalErr("'1999'^^xsd:gYear = '1999Z'^^xsd:gYear") ; }
+ public void gregorian_eq_03() { eval("'1999'^^xsd:gYear = '1999Z'^^xsd:gYear") ; }
@Test public void gregorian_eq_04() { eval("'1999'^^xsd:gYear = '2001Z'^^xsd:gYear", false) ; }
@@ -54,12 +54,12 @@ public class TestExpressions2 extends As
@Test public void gregorian_cmp_03() { eval("'1999'^^xsd:gYear < '2000+01:00'^^xsd:gYear", true) ; }
@Test (expected=ExprEvalException.class)
- public void gregorian_cmp_04() { evalErr("'1999'^^xsd:gYear < '1999+05:00'^^xsd:gYear") ; }
+ public void gregorian_cmp_04() { eval("'1999'^^xsd:gYear < '1999+05:00'^^xsd:gYear") ; }
public void gregorian_cast_01() { eval("xsd:gYear('2010-03-22'^^xsd:date) = '2010'^^xsd:gYear", true ) ; }
@Test (expected=ExprEvalException.class)
- public void coalesce_01() { evalErr("COALESCE()") ; }
+ public void coalesce_01() { eval("COALESCE()") ; }
@Test public void coalesce_02() { eval("COALESCE(1) = 1", true) ; }
@Test public void coalesce_03() { eval("COALESCE(?x,1) = 1", true) ; }
@Test public void coalesce_04() { eval("COALESCE(9,1) = 9", true) ; }
@@ -69,7 +69,7 @@ public class TestExpressions2 extends As
@Test public void if_02() { eval("IF(1+2=4, 'yes', 'no') = 'no'", true) ; }
@Test public void if_03() { eval("IF(true, 'yes', 1/0) = 'yes'", true) ; }
@Test (expected=ExprEvalException.class)
- public void if_04() { evalErr("IF(true, 1/0, 'no') = 'no'") ; }
+ public void if_04() { eval("IF(true, 1/0, 'no') = 'no'") ; }
// NOT IN, IN
@Test public void in_01() { eval("1 IN(1,2,3)", true) ; }
@@ -86,7 +86,7 @@ public class TestExpressions2 extends As
@Test public void term_constructor_iri_01() { eval("IRI('http://example/') = <http://example/>", true) ; }
@Test (expected=ExprEvalException.class)
- public void term_constructor_iri_02() { evalErr("IRI(123)") ; }
+ public void term_constructor_iri_02() { eval("IRI(123)") ; }
@Test public void term_constructor_iri_03() { eval("IRI(<http://example/>) = <http://example/>", true) ; }
@Test public void term_constructor_iri_04() { eval("isIRI(IRI(BNODE()))", true) ; } // SPARQL extension
@Test public void term_constructor_iri_05() { eval("regex(str(IRI(BNODE())), '^_:' )", true) ; } // SPARQL extension
@@ -100,23 +100,38 @@ public class TestExpressions2 extends As
@Test public void term_constructor_strdt_01() { eval("STRDT('123',xsd:integer) = 123", true) ; }
@Test public void term_constructor_strdt_02() { eval("STRDT('123',<http://example/DT>) = '123'^^<http://example/DT>", true) ; }
@Test (expected=ExprEvalException.class)
- public void term_constructor_strdt_03() { evalErr("STRDT('123','abc') = '123'") ; }
+ public void term_constructor_strdt_03() { eval("STRDT('123','abc') = '123'") ; }
@Test (expected=ExprEvalException.class)
- public void term_constructor_strdt_04() { evalErr("STRDT('123'^^xsd:integer,<http://example/DT>) = '123'^^<http://example/DT>") ; }
+ public void term_constructor_strdt_04() { eval("STRDT('123'^^xsd:integer,<http://example/DT>) = '123'^^<http://example/DT>") ; }
@Test public void term_constructor_strlang_01() { eval("STRLANG('abc', 'en') = 'abc'@en", true) ; }
@Test (expected=ExprEvalException.class)
- public void term_constructor_strlang_02() { evalErr("STRLANG(<http://example/>, 'en') = 'abc'@en") ; }
+ public void term_constructor_strlang_02() { eval("STRLANG(<http://example/>, 'en') = 'abc'@en") ; }
@Test (expected=ExprEvalException.class)
- public void term_constructor_strlang_03() { evalErr("STRLANG('abc'@en, 'en') = 'abc'@en") ; }
+ public void term_constructor_strlang_03() { eval("STRLANG('abc'@en, 'en') = 'abc'@en") ; }
+
+ // XSD casts
+
+ @Test public void xsd_cast_01() { eval("xsd:integer('1') = 1", true) ; }
+ @Test public void xsd_cast_02() { eval("xsd:boolean('1') = true", true) ; }
+ @Test public void xsd_cast_03() { eval("sameTerm(xsd:double('1.0e0'),1.0e0)", true) ; }
+ @Test public void xsd_cast_04() { eval("xsd:double('1') = 1", true) ; }
+
+ @Test (expected=ExprEvalException.class)
+ public void xsd_cast_10() { eval("xsd:integer(' 1')") ; }
+ @Test (expected=ExprEvalException.class)
+ public void xsd_cast_11() { eval("xsd:boolean(' 1')") ; }
+ @Test (expected=ExprEvalException.class)
+ public void xsd_cast_12() { eval("xsd:double(' 1.0e0')") ; }
+ @Test (expected=ExprEvalException.class)
+ public void xsd_cast_13() { eval("xsd:double(' 1.0e0')") ; }
// ---- Workers
- private static void evalErr(String string)
+ private static void eval(String string)
{
eval(string, true) ;
- throw new RuntimeException() ;
}
// It's easier to write tests that simple are expected to return true/false