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 2015/10/12 19:15:51 UTC
[1/4] jena git commit: Rename to have 'Duration' in method name
Repository: jena
Updated Branches:
refs/heads/master 2e18b8cdc -> d3180b5e7
Rename to have 'Duration' in method name
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/b111837a
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/b111837a
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/b111837a
Branch: refs/heads/master
Commit: b111837a8a5375de6a1ea2210b2a3f2cf726b6aa
Parents: 2e18b8c
Author: Andy Seaborne <an...@apache.org>
Authored: Mon Oct 12 16:54:26 2015 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Mon Oct 12 16:54:26 2015 +0100
----------------------------------------------------------------------
.../main/java/org/apache/jena/sparql/expr/NodeValue.java | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/b111837a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java
----------------------------------------------------------------------
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 b83e3ba..ebb6621 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
@@ -914,7 +914,12 @@ public abstract class NodeValue extends ExprNode
public boolean isTime() { return false ; }
public boolean isDuration() { return false ; }
- public boolean isYearMonth()
+ @Deprecated
+ public boolean isYearMonth() {
+ return isYearMonthDuration() ;
+ }
+
+ public boolean isYearMonthDuration()
{
if ( ! isDuration() ) return false ;
Duration dur = getDuration() ;
@@ -922,7 +927,7 @@ public abstract class NodeValue extends ExprNode
! dur.isSet(DAYS) && ! dur.isSet(HOURS) && ! dur.isSet(MINUTES) && ! dur.isSet(SECONDS) ;
}
- boolean isDayTime()
+ public boolean isDayTimeDuration()
{
if ( ! isDuration() ) return false ;
Duration dur = getDuration() ;
[3/4] jena git commit: JENA-1047 : Rewrite casting to XSD datatypes.
Posted by an...@apache.org.
JENA-1047 : Rewrite casting to XSD datatypes.
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/5156ba64
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/5156ba64
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/5156ba64
Branch: refs/heads/master
Commit: 5156ba64fbbc02765f9dda27154124f4f93d555e
Parents: 7aa9af5
Author: Andy Seaborne <an...@apache.org>
Authored: Mon Oct 12 17:46:39 2015 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Mon Oct 12 17:46:39 2015 +0100
----------------------------------------------------------------------
.../jena/sparql/expr/nodevalue/XSDFuncOp.java | 8 +-
.../apache/jena/sparql/function/CastXSD.java | 135 --------
.../apache/jena/sparql/function/CastXSD2.java | 317 +++++++++++++++++++
.../jena/sparql/function/CastXSD_Boolean.java | 82 -----
.../jena/sparql/function/CastXSD_DateTime.java | 54 ----
.../jena/sparql/function/CastXSD_Numeric.java | 64 ----
.../jena/sparql/function/StandardFunctions.java | 43 ++-
.../org/apache/jena/sparql/expr/TS_Expr.java | 1 +
.../apache/jena/sparql/expr/TestCastXSD.java | 136 ++++++++
9 files changed, 480 insertions(+), 360 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/5156ba64/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/XSDFuncOp.java
----------------------------------------------------------------------
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 439948a..57a2497 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
@@ -1071,7 +1071,13 @@ public class XSDFuncOp
*/
public static NodeValue dateTimeCast(NodeValue nv, XSDDatatype xsd) {
- // http://www.w3.org/TR/xpath-functions/#casting-to-datetimes
+ if ( nv.isString() ) {
+ String s = nv.getString() ;
+ if ( ! xsd.isValid(s) )
+ throw new ExprEvalTypeException("Invalid lexical form: '"+s+"' for "+xsd.getURI()) ;
+ return NodeValue.makeNode(s, xsd) ;
+ }
+
if ( !nv.hasDateTime() )
throw new ExprEvalTypeException("Not a date/time type: " + nv) ;
http://git-wip-us.apache.org/repos/asf/jena/blob/5156ba64/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD.java b/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD.java
deleted file mode 100644
index acec663..0000000
--- a/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * 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.function;
-
-import org.apache.jena.datatypes.xsd.XSDDatatype ;
-import org.apache.jena.datatypes.xsd.impl.XSDAbstractDateTimeType ;
-import org.apache.jena.datatypes.xsd.impl.XSDBaseNumericType ;
-import org.apache.jena.graph.Node ;
-import org.apache.jena.sparql.expr.ExprEvalException ;
-import org.apache.jena.sparql.expr.NodeValue ;
-
-/** General casting of XSD datatypes.
- * @see CastXSD_DateTime
- * @see CastXSD_Numeric
- * @see CastXSD_Boolean
- */
-public class CastXSD implements FunctionFactory
-{
- protected final XSDDatatype castType ;
-
- public CastXSD(XSDDatatype dt)
- {
- this.castType = dt ;
- }
-
- @Override
- public Function create(String uri)
- {
- return new Instance(castType) ;
- }
-
- protected static class Instance extends FunctionBase1
- {
- XSDDatatype castType ;
- Instance(XSDDatatype dt) {this.castType = dt ; }
-
- @Override
- public NodeValue exec(NodeValue v)
- {
- // http://www.w3.org/TR/xpath-functions/#casting
- String s = null ;
- Node n = v.asNode() ;
-
- if ( n.isBlank() )
- throw new ExprEvalException("CastXSD: Can't cast blank nodes: "+v) ;
-
- if ( n.isURI() )
- {
- if ( castType.equals(XSDDatatype.XSDstring) )
- s = n.getURI() ;
- else
- throw new ExprEvalException("CastXSD: Can't cast node: "+v+" to "+castType.getURI()) ;
- }
- else if ( n.isLiteral() )
- // What if there is a lang tag?
- s = n.getLiteralLexicalForm() ;
- else
- throw new ExprEvalException("CastXSD: Can't cast node: "+v+ "(not a literal, not URI to string)") ;
-
- if ( s == null && v.isString() )
- s = v.getString() ;
-
- if ( s == null )
- throw new ExprEvalException("CastXSD: Can't cast: "+v+ "(has no string appearance)") ;
-
- // // Special case - non-normalised xsd:booleans use 0 and 1.
- // if ( v.isBoolean() )
- // {
- // if ( s.equals("0") ) s = "false" ;
- // if ( s.equals("1") ) s = "true" ;
- // }
-
- NodeValue r = cast(s, v, castType) ;
- 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.
- 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+"'") ;
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/jena/blob/5156ba64/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD2.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD2.java b/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD2.java
new file mode 100644
index 0000000..6d742b3
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD2.java
@@ -0,0 +1,317 @@
+/**
+ * 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.function;
+
+import java.math.BigDecimal ;
+import java.math.BigInteger ;
+import java.util.Objects ;
+
+import javax.xml.datatype.DatatypeConstants ;
+import javax.xml.datatype.Duration ;
+
+import org.apache.jena.datatypes.xsd.XSDDatatype ;
+import org.apache.jena.datatypes.xsd.impl.XSDAbstractDateTimeType ;
+import org.apache.jena.datatypes.xsd.impl.XSDBaseNumericType ;
+import org.apache.jena.graph.Node ;
+import org.apache.jena.sparql.expr.ExprEvalException ;
+import org.apache.jena.sparql.expr.ExprEvalTypeException ;
+import org.apache.jena.sparql.expr.ExprException ;
+import org.apache.jena.sparql.expr.NodeValue ;
+import org.apache.jena.sparql.expr.nodevalue.XSDFuncOp ;
+
+public class CastXSD2 extends FunctionBase1 implements FunctionFactory {
+
+ protected final XSDDatatype castType ;
+
+ public CastXSD2(XSDDatatype dt)
+ {
+ this.castType = dt ;
+ }
+
+ @Override
+ public Function create(String uri)
+ {
+ return this ;
+ }
+
+ @Override
+ public NodeValue exec(NodeValue v)
+ {
+ return cast(v, castType) ;
+ }
+
+
+ private static boolean isTemporalDatatype(XSDDatatype datatype) {
+ return
+ datatype.equals(XSDDatatype.XSDdateTime) ||
+ datatype.equals(XSDDatatype.XSDtime) ||
+ datatype.equals(XSDDatatype.XSDdate) ||
+ datatype.equals(XSDDatatype.XSDgYear) ||
+ datatype.equals(XSDDatatype.XSDgYearMonth) ||
+ datatype.equals(XSDDatatype.XSDgMonth) ||
+ datatype.equals(XSDDatatype.XSDgMonthDay) ||
+ datatype.equals(XSDDatatype.XSDgDay) ;
+ }
+
+ private static boolean isDurationDatatype(XSDDatatype datatype) {
+ return
+ datatype.equals(XSDDatatype.XSDduration) ||
+ datatype.equals(XSDDatatype.XSDyearMonthDuration) ||
+ datatype.equals(XSDDatatype.XSDdayTimeDuration ) ;
+ }
+
+ /** Cast a NodeValue to an XSD datatype.
+ * This includes "by value" so 1e0 (an xsd:double) casts to 1 (an xsd:intger)
+ * @param nv
+ * @param castType
+ * @return NodeValue
+ * @throws ExprEvalException
+ */
+ public static NodeValue cast(NodeValue nv, XSDDatatype castType) {
+ // http://www.w3.org/TR/xpath-functions/#casting
+ Node n = nv.asNode() ;
+
+ if ( n.isBlank() )
+ throw exception("Can't cast blank nodes: "+nv) ;
+
+ if ( n.isURI() ) {
+ if ( castType.equals(XSDDatatype.XSDstring) )
+ return cast$(n.getURI(), castType) ;
+ else
+ throw exception("Can't cast URIs to "+castType.getURI()) ;
+ }
+
+ if ( ! n.isLiteral() )
+ throw exception("Can't cast (not a literal, nor URI to string) "+nv+" : "+castType.getURI()) ;
+
+ // It's a literal.
+
+ // Cast to self but may be an invalid lexical form.
+ if ( Objects.equals(nv.getNode().getLiteralDatatype(), castType) ) {
+ String lex = nv.getNode().getLiteralLexicalForm() ;
+ if ( castType.isValid(lex) )
+ return nv ;
+ throw exception("Invalid lexical form for "+castType.getURI()) ;
+ }
+
+
+ // Many casts can be done by testing the lexical is valid for the datatype.
+ // But some cases need to consider values.
+ // e.g. boolean -> numeric , double -> integer (doubles have "e" in them)
+
+ // To a temporal
+ if ( isTemporalDatatype(castType) ) {
+ return XSDFuncOp.dateTimeCast(nv, castType) ;
+ }
+
+ if ( isDurationDatatype(castType) ) {
+ // Duration cast.
+ // yearMonthDuration and TT is xs:dayTimeDuration -> 0.0S
+ // xs:dayTimeDuration and TT is yearMonthDuration -> P0M
+
+ if ( nv.isDuration() ) {
+ Duration d = nv.getDuration() ;
+ if ( castType.equals(XSDDatatype.XSDyearMonthDuration) ) {
+
+ // Include xsd:duration only covering year-month.
+ if ( nv.isDayTimeDuration() )
+ return NodeValue.makeNode("P0M", castType) ;
+
+ Duration d2 = NodeValue.xmlDatatypeFactory.newDuration
+ (d.getSign()>=0,
+ (BigInteger)d.getField(DatatypeConstants.YEARS), (BigInteger)d.getField(DatatypeConstants.MONTHS), null,
+ null, null, null) ;
+ return NodeValue.makeNode(d2.toString(), castType) ;
+ }
+ if ( castType.equals(XSDDatatype.XSDdayTimeDuration) ) {
+ if ( nv.isYearMonthDuration() )
+ return NodeValue.makeNode("PT0S", castType) ;
+ Duration d2 = NodeValue.xmlDatatypeFactory.newDuration
+
+ (d.getSign()>=0,
+ null, null, (BigInteger)d.getField(DatatypeConstants.DAYS),
+ (BigInteger)d.getField(DatatypeConstants.HOURS), (BigInteger)d.getField(DatatypeConstants.MINUTES), (BigDecimal)d.getField(DatatypeConstants.SECONDS)) ;
+ // return NodeValue.makeDuration(d2) ;
+ return NodeValue.makeNode(d2.toString(), castType) ;
+ }
+ }
+ }
+
+ // From number, can consider value.
+ if ( nv.isNumber() ) {
+ if ( castType.equals(XSDDatatype.XSDdecimal) ) {
+ // Number to decimal.
+ if ( isDouble(nv) || isFloat(nv) ) {
+ // FP to decimal.
+ double d = nv.getDouble() ;
+ if ( Double.isNaN(d) )
+ throw exception("Can't cast NaN to xsd:decimal") ;
+ if ( Double.isInfinite(d) )
+ throw exception("Can't cast Inf or -Inf to xsd:decimal") ;
+ // BigDecimal.valueOf(d) can lead to trailing zeros
+ // BigDecimal.valueOf(d) goes via strings.
+ String lex = doubleToDecimalString(d) ;
+ return NodeValue.makeDecimal(lex) ;
+ }
+ // Integer, or derived type -> decimal.
+ return castByLex(nv, castType) ;
+ }
+ if ( XSDFuncOp.isIntegerType(castType) ) {
+ // Number to integer
+ if ( isDouble(nv) || isFloat(nv) ) {
+ // FP to integer
+ double d = nv.getDouble() ;
+ boolean isIntegerValue = ( Math.rint(d) == d ) ;
+ if ( isIntegerValue ) {
+ String lex = doubleIntegerToString(d) ;
+ if ( lex != null )
+ return castByLex(lex, castType) ;
+ }
+ throw exception(nv, castType) ;
+ } else if ( isDecimal(nv) ) {
+ // Decimal to integer
+ BigDecimal bd = nv.getDecimal() ;
+ try {
+ // Exception on fraction.
+ BigInteger bi = bd.toBigIntegerExact() ;
+ return castByLex(bi.toString(), castType) ;
+ } catch (ArithmeticException ex) {
+ throw new ExprEvalException("CastXSD: Not a valid cast: '"+nv+"'") ;
+ }
+ } else {
+ // Integer derived type -> integer derived type.
+ return castByLex(nv, castType) ;
+ }
+ }
+ }
+
+ // Boolean -> xsd:
+ if ( nv.isBoolean() ) {
+ boolean b = nv.getBoolean() ;
+ // Boolean to boolean covered above.
+ String lex ;
+ if ( XSDDatatype.XSDfloat.equals(castType) || XSDDatatype.XSDdouble.equals(castType) )
+ return cast$( ( b ? "1.0E0" : "0.0E0" ) , castType) ;
+ else if ( XSDDatatype.XSDdecimal.equals(castType) )
+ return cast$( ( b ? "1.0" : "0.0" ) , castType) ;
+ else if ( XSDFuncOp.isIntegerType(castType))
+ return cast$( ( b ? "1" : "0" ) , castType ) ;
+ else if ( XSDDatatype.XSDstring.equals(castType) )
+ return cast$( nv.getNode().getLiteralLexicalForm(), castType ) ;
+ throw exception("Can't cast xsd:boolean to "+castType) ;
+ }
+
+ // Try by lexical
+ return castByLex(nv, castType) ;
+ }
+
+ /** Presentation form of an XSD datatype URI */
+ private static String xsdName(String datatype) {
+ return datatype.replaceAll(XSDDatatype.XSD+"#", "xsd:") ;
+ }
+
+ /** Test to see if a NodeValue is a valid double value and is of datatype xsd:double. */
+ private static boolean isDouble(NodeValue nv) {
+ return nv.isDouble() && nv.getDatatypeURI().equals(XSDDatatype.XSDdouble.getURI()) ;
+ }
+
+ /** Test to see if a NodeValue is a valid float value and is of datatype float. */
+ private static boolean isFloat(NodeValue nv) {
+ return nv.isFloat() && nv.getDatatypeURI().equals(XSDDatatype.XSDfloat.getURI()) ;
+ }
+
+ /** Test to see if a NodeValue is a valid decimal value and is of datatype decimal. */
+ private static boolean isDecimal(NodeValue nv) {
+ return nv.isDecimal() && nv.getDatatypeURI().equals(XSDDatatype.XSDdecimal.getURI()) ;
+ }
+
+ /** Test to see if a NodeValue is a valid numeric value. */
+ private static boolean isNumeric(NodeValue nv) {
+ return nv.isNumber() ;
+ }
+
+ private static ExprException exception(NodeValue nv, XSDDatatype dt) {
+ return exception("Invalid cast: "+nv+" -> "+xsdName(dt.getURI())) ;
+ }
+
+ private static ExprException exception(String msg) {
+ return new ExprEvalTypeException(msg) ;
+ }
+
+ // Cast by lexical form with checking.
+ private static NodeValue castByLex(NodeValue nv, XSDDatatype castType) {
+ String lex = nv.getNode().getLiteralLexicalForm() ;
+ return castByLex(lex, castType) ;
+ }
+
+ // Cast by lexical form with checking.
+ private static NodeValue castByLex(String lex, XSDDatatype castType) {
+ if ( ! castType.isValid(lex) )
+ throw exception("Invalid lexical form: '"+lex+"' for "+castType.getURI()) ;
+ if ( castType instanceof XSDBaseNumericType ||
+ castType.equals(XSDDatatype.XSDfloat) ||
+ castType.equals(XSDDatatype.XSDdouble) ||
+ castType.equals(XSDDatatype.XSDboolean) ||
+ castType instanceof XSDAbstractDateTimeType ) // Includes durations, and Gregorian
+ {
+ // More helpful error message.
+ if ( lex.startsWith(" ") || lex.endsWith(" ") )
+ throw exception("Not a valid literal form (has whitespace): '"+lex+"'") ;
+ }
+ return NodeValue.makeNode(lex, castType) ;
+
+ }
+
+ // Known to work casts. No checking.
+ private static NodeValue cast$(String lex, XSDDatatype castType) {
+ return NodeValue.makeNode(lex, castType) ;
+ }
+
+ // Return the integer lexical form for a double, where the double is known to be integer valued.
+ private static String doubleIntegerToString(double d) {
+ // Fast path
+ long x = Math.round(d) ;
+ if ( x != Long.MAX_VALUE && x != Long.MIN_VALUE )
+ return Long.toString(x) ;
+
+ String lex = BigDecimal.valueOf(d).toPlainString() ;
+ int i = lex.indexOf('.') ;
+ if ( i >= 0 )
+ // Adds .0 for some (small) doubles.
+ lex = lex.substring(0, i) ;
+ return lex;
+ }
+
+ // Return the decimal lexical form for a double value.
+ // Java big decimal allows "E" forms, XSD does not.
+ private static String doubleToDecimalString(double d) {
+ // BigDecimal.valueOf(d) can lead to trailing zeros.
+ String lex = BigDecimal.valueOf(d).toPlainString() ;
+ // Clean the string.
+ int i = lex.indexOf('.') ;
+ if ( i < 0 )
+ return lex ;
+ // Often one or two
+ while(lex.endsWith("00"))
+ lex = lex.substring(0, lex.length()-2) ;
+ while(lex.endsWith("0"))
+ lex = lex.substring(0, lex.length()-1) ;
+ return lex ;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/jena/blob/5156ba64/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD_Boolean.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD_Boolean.java b/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD_Boolean.java
deleted file mode 100644
index 156c201..0000000
--- a/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD_Boolean.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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.function;
-
-import java.math.BigDecimal ;
-import java.math.BigInteger ;
-
-import org.apache.jena.datatypes.xsd.XSDDatatype ;
-import org.apache.jena.sparql.expr.NodeValue ;
-
-public class CastXSD_Boolean extends CastXSD
-{
- public CastXSD_Boolean(XSDDatatype dt)
- {
- super(dt) ;
- }
-
- @Override
- public Function create(String uri)
- {
- return new Instance(castType) ;
- }
-
-
- protected static class Instance extends CastXSD.Instance
- {
- Instance(XSDDatatype dt)
- {
- super(dt) ;
- }
-
- @Override
- protected NodeValue cast(String s, NodeValue nv, XSDDatatype castType)
- {
- if ( nv.isNumber() )
- {
- if ( nv.isFloat() || nv.isDouble() )
- {
- // 0, +0, -0, 0.0, 0.0E0 or NaN, then TV is false.
- // else true.
- double d = ( nv.isDouble() ? nv.getDouble() : nv.getFloat() ) ;
- if ( d == 0.0e0 || Double.isNaN(d) )
- return NodeValue.FALSE ;
- return NodeValue.TRUE ;
- }
- if ( nv.isDecimal() )
- {
- if ( nv.getDecimal().compareTo(BigDecimal.ZERO) == 0 )
- return NodeValue.FALSE ;
- return NodeValue.TRUE ;
- }
-
- if ( nv.isInteger() )
- {
- if ( nv.getInteger().compareTo(BigInteger.ZERO) == 0 )
- return NodeValue.FALSE ;
- return NodeValue.TRUE ;
- }
- }
-
- if ( nv.isBoolean() )
- return nv ;
- return super.cast(s, nv, castType) ;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/jena/blob/5156ba64/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD_DateTime.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD_DateTime.java b/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD_DateTime.java
deleted file mode 100644
index eab9b96..0000000
--- a/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD_DateTime.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.function;
-
-import org.apache.jena.datatypes.xsd.XSDDatatype ;
-import org.apache.jena.sparql.expr.NodeValue ;
-import org.apache.jena.sparql.expr.nodevalue.XSDFuncOp ;
-import org.apache.jena.sparql.util.NodeUtils ;
-
-
-/** Cast DateTime */
-public class CastXSD_DateTime extends CastXSD implements FunctionFactory
-{
- public CastXSD_DateTime(XSDDatatype dt)
- {
- super(dt) ;
- }
-
- @Override
- public Function create(String uri)
- {
- return new InstanceDT(castType) ;
- }
-
- protected static class InstanceDT extends CastXSD.Instance
- {
- InstanceDT(XSDDatatype dt) { super(dt) ; }
-
- @Override
- protected NodeValue cast(String s, NodeValue nv, XSDDatatype castType)
- {
- // Plain cast.
- if ( nv.isString() || NodeUtils.hasLang(nv.asNode()) )
- return super.cast(s, nv, castType) ;
- return XSDFuncOp.dateTimeCast(nv, castType) ;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/jena/blob/5156ba64/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD_Numeric.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD_Numeric.java b/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD_Numeric.java
deleted file mode 100644
index ce9ee5b..0000000
--- a/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD_Numeric.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.function;
-
-import org.apache.jena.datatypes.xsd.XSDDatatype ;
-import org.apache.jena.sparql.expr.NodeValue ;
-import org.apache.jena.sparql.expr.nodevalue.XSDFuncOp ;
-
-public class CastXSD_Numeric extends CastXSD
-{
- public CastXSD_Numeric(XSDDatatype dt)
- {
- super(dt) ;
- }
-
- @Override
- public Function create(String uri)
- {
- return new Instance(castType) ;
- }
-
-
- protected static class Instance extends CastXSD.Instance
- {
- Instance(XSDDatatype dt)
- {
- super(dt) ;
- }
-
- @Override
- protected NodeValue cast(String s, NodeValue nv, XSDDatatype castType)
- {
- if ( nv.isBoolean() )
- {
- boolean b = nv.getBoolean() ;
- if ( XSDDatatype.XSDfloat.equals(castType) || XSDDatatype.XSDdouble.equals(castType) )
- s = ( b ? "1.0E0" : "0.0E0" ) ;
- else if ( XSDDatatype.XSDdecimal.equals(castType) )
- s = ( b ? "1.0" : "0.0" ) ;
- else if ( XSDFuncOp.isIntegerType(castType))
- s = ( b ? "1" : "0" ) ;
- // else do nothing and hope.
- }
-
- return super.cast(s, nv, castType) ;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/jena/blob/5156ba64/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java b/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java
index 320d9ba..a988bdd 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java
@@ -54,21 +54,21 @@ public class StandardFunctions
addCastNumeric(registry, XSDDatatype.XSDdouble) ;
addCastNumeric(registry, XSDDatatype.XSDfloat) ;
- addCastBoolean(registry, XSDDatatype.XSDboolean) ;
-
- addCast(registry, XSDDatatype.XSDduration) ;
- addCast(registry, XSDDatatype.XSDstring) ;
- addCast(registry, XSDDatatype.XSDanyURI) ;
+ addCastXSD(registry, XSDDatatype.XSDboolean) ;
+ addCastXSD(registry, XSDDatatype.XSDduration) ;
+ addCastXSD(registry, XSDDatatype.XSDdayTimeDuration) ;
+ addCastXSD(registry, XSDDatatype.XSDyearMonthDuration) ;
+ addCastXSD(registry, XSDDatatype.XSDstring) ;
+ addCastXSD(registry, XSDDatatype.XSDanyURI) ;
- // Specialized casting rules
- addCastDT(registry, XSDDatatype.XSDdateTime) ;
- addCastDT(registry, XSDDatatype.XSDdate) ;
- addCastDT(registry, XSDDatatype.XSDtime) ;
- addCastDT(registry, XSDDatatype.XSDgYear) ;
- addCastDT(registry, XSDDatatype.XSDgYearMonth) ;
- addCastDT(registry, XSDDatatype.XSDgMonth) ;
- addCastDT(registry, XSDDatatype.XSDgMonthDay) ;
- addCastDT(registry, XSDDatatype.XSDgDay) ;
+ addCastTemporal(registry, XSDDatatype.XSDdateTime) ;
+ addCastTemporal(registry, XSDDatatype.XSDdate) ;
+ addCastTemporal(registry, XSDDatatype.XSDtime) ;
+ addCastTemporal(registry, XSDDatatype.XSDgYear) ;
+ addCastTemporal(registry, XSDDatatype.XSDgYearMonth) ;
+ addCastTemporal(registry, XSDDatatype.XSDgMonth) ;
+ addCastTemporal(registry, XSDDatatype.XSDgMonthDay) ;
+ addCastTemporal(registry, XSDDatatype.XSDgDay) ;
//TODO op:numeric-greater-than etc.
@@ -114,24 +114,19 @@ public class StandardFunctions
add(registry, xfn+"seconds-from-duration", FN_SecondsFromDuration.class) ;
}
- private static void addCast(FunctionRegistry registry, XSDDatatype dt)
+ private static void addCastXSD(FunctionRegistry registry, XSDDatatype dt)
{
- registry.put(dt.getURI(), new CastXSD(dt) ) ;
+ registry.put(dt.getURI(), new CastXSD2(dt) ) ;
}
private static void addCastNumeric(FunctionRegistry registry, XSDDatatype dt)
{
- registry.put(dt.getURI(), new CastXSD_Numeric(dt) ) ;
- }
-
- private static void addCastBoolean(FunctionRegistry registry, XSDDatatype dt)
- {
- registry.put(dt.getURI(), new CastXSD_Boolean(dt) ) ;
+ registry.put(dt.getURI(), new CastXSD2(dt) ) ;
}
- private static void addCastDT(FunctionRegistry registry, XSDDatatype dt)
+ private static void addCastTemporal(FunctionRegistry registry, XSDDatatype dt)
{
- registry.put(dt.getURI(), new CastXSD_DateTime(dt) ) ;
+ registry.put(dt.getURI(), new CastXSD2(dt) ) ;
}
private static void add(FunctionRegistry registry, String uri, Class<?> funcClass)
http://git-wip-us.apache.org/repos/asf/jena/blob/5156ba64/jena-arq/src/test/java/org/apache/jena/sparql/expr/TS_Expr.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TS_Expr.java b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TS_Expr.java
index f2f3abd..bf0ae6d 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TS_Expr.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TS_Expr.java
@@ -32,6 +32,7 @@ import org.junit.runners.Suite.SuiteClasses ;
, TestExpressions.class
, TestExpressions2.class
, TestExpressions3.class
+ , TestCastXSD.class
, TestNodeFunctions.class
, TestExpressions2.class
, TestFunctions.class
http://git-wip-us.apache.org/repos/asf/jena/blob/5156ba64/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestCastXSD.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestCastXSD.java b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestCastXSD.java
new file mode 100644
index 0000000..d382494
--- /dev/null
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestCastXSD.java
@@ -0,0 +1,136 @@
+/**
+ * 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.expr;
+
+import org.apache.jena.graph.Node ;
+import org.apache.jena.query.ARQ ;
+import org.apache.jena.sparql.ARQConstants ;
+import org.apache.jena.sparql.engine.ExecutionContext ;
+import org.apache.jena.sparql.expr.Expr ;
+import org.apache.jena.sparql.expr.ExprEvalException ;
+import org.apache.jena.sparql.expr.NodeValue ;
+import org.apache.jena.sparql.function.FunctionEnv ;
+import org.apache.jena.sparql.sse.SSE ;
+import org.apache.jena.sparql.util.ExprUtils ;
+import org.apache.jena.sparql.util.NodeFactoryExtra ;
+import org.junit.AfterClass ;
+import org.junit.Assert ;
+import org.junit.BeforeClass ;
+import org.junit.Test ;
+
+public class TestCastXSD {
+
+ private static boolean origValue ;
+ @BeforeClass public static void beforeClass() {
+ origValue = NodeValue.VerboseWarnings;
+ NodeValue.VerboseWarnings = false ;
+ }
+ @AfterClass public static void afterClass() {
+ NodeValue.VerboseWarnings = origValue ;
+ }
+
+ @Test public void cast_to_integer_01() { testCast ("xsd:integer('1e0'^^xsd:double)", "'1'^^xsd:integer") ; }
+ @Test public void cast_to_integer_02() { testCast ("xsd:byte('1e0'^^xsd:double)", "'1'^^xsd:byte") ; }
+ @Test public void cast_to_integer_03() { testNoCast ("xsd:byte('HaHa'^^xsd:double)") ; }
+ @Test public void cast_to_integer_04() { testCast ("xsd:byte('-1'^^xsd:double)", "'-1'^^xsd:byte") ; }
+ @Test public void cast_to_integer_05() { testNoCast ("xsd:unsignedInt('-1'^^xsd:double)") ; }
+ @Test public void cast_to_integer_06() { testNoCast ("xsd:byte('500'^^xsd:float)") ; }
+ @Test public void cast_to_integer_07() { testCast ("xsd:integer('1e20'^^xsd:double)", "100000000000000000000") ; }
+ @Test public void cast_to_integer_08() { testCast ("xsd:integer('1e19'^^xsd:double)", "10000000000000000000") ; }
+ @Test public void cast_to_integer_09() { testCast ("xsd:integer('1e18'^^xsd:double)", "1000000000000000000") ; }
+ @Test public void cast_to_integer_10() { testCast ("xsd:integer('+1'^^xsd:integer)", "'+1'^^xsd:integer") ; }
+ @Test public void cast_to_integer_11() { testCast ("xsd:byte('+1'^^xsd:integer)", "'+1'^^xsd:byte") ; }
+ @Test public void cast_to_integer_12() { testNoCast ("xsd:byte('HaHa'^^xsd:integer)") ; }
+ @Test public void cast_to_integer_13() { testCast ("xsd:byte('-1'^^xsd:integer)", "'-1'^^xsd:byte") ; }
+ @Test public void cast_to_integer_14() { testNoCast ("xsd:unsignedInt('-1'^^xsd:integer)") ; }
+ @Test public void cast_to_integer_15() { testNoCast ("xsd:byte('500'^^xsd:integer)") ; }
+ @Test public void cast_to_integer_16() { testCast ("xsd:decimal('1000000000000'^^xsd:integer)", "'1000000000000'^^xsd:decimal") ; }
+ @Test public void cast_to_integer_17() { testCast ("xsd:int('1000'^^xsd:integer)", "'1000'^^xsd:int") ; }
+ @Test public void cast_to_integer_18() { testCast ("xsd:integer('1000'^^xsd:int)", "'1000'^^xsd:integer") ; }
+ @Test public void cast_to_integer_19() { testNoCast ("xsd:negativeInteger('1000'^^xsd:int)") ; }
+ @Test public void cast_to_integer_20() { testCast ("xsd:integer('+1'^^xsd:decimal)", "'1'^^xsd:integer") ; }
+ @Test public void cast_to_integer_21() { testNoCast ("xsd:integer('1.4'^^xsd:decimal)") ; }
+ @Test public void cast_to_integer_22() { testCast ("xsd:byte('01.0'^^xsd:decimal)", "'1'^^xsd:byte") ; }
+ @Test public void cast_to_integer_23() { testNoCast ("xsd:byte('HaHa'^^xsd:decimal)") ; }
+ @Test public void cast_to_integer_24() { testCast ("xsd:byte('-1'^^xsd:decimal)", "'-1'^^xsd:byte") ; }
+ @Test public void cast_to_integer_25() { testNoCast ("xsd:unsignedInt('-1'^^xsd:decimal)") ; }
+ @Test public void cast_to_integer_26() { testNoCast ("xsd:byte('500'^^xsd:decimal)") ; }
+
+ @Test public void cast_decimal_10() { testCast ("xsd:decimal('1e-20'^^xsd:double)", "0.00000000000000000001") ; }
+ @Test public void cast_decimal_11() { testCast ("xsd:decimal('1e-19'^^xsd:double)", "0.0000000000000000001") ; }
+ @Test public void cast_decimal_12() { testCast ("xsd:decimal('1e-18'^^xsd:double)", "0.000000000000000001") ; }
+
+ @Test public void cast_from_string_01() { testCast ("xsd:integer('+1'^^xsd:string)", "'+1'^^xsd:integer") ; }
+ @Test public void cast_from_string_02() { testNoCast ("xsd:integer('a'^^xsd:string)") ; }
+ @Test public void cast_from_string_03() { testCast ("xsd:integer('11')", "'11'^^xsd:integer") ; }
+ @Test public void cast_from_string_04() { testCast ("xsd:double('12'^^xsd:string)", "'12'^^xsd:double") ; }
+ @Test public void cast_from_string_05() { testNoCast ("xsd:double('abc'^^xsd:string)") ; }
+
+ @Test public void cast_from_boolean_01() { testCast ("xsd:boolean('true'^^xsd:boolean)", "'true'^^xsd:boolean" ) ; }
+ @Test public void cast_from_boolean_02() { testCast ("xsd:boolean('1'^^xsd:boolean)", "'1'^^xsd:boolean" ) ; }
+ @Test public void cast_from_boolean_03() { testCast ("xsd:integer('1'^^xsd:boolean)", "1" ) ; }
+ @Test public void cast_from_boolean_04() { testCast ("xsd:decimal('false'^^xsd:boolean)", "0.0" ) ; }
+ @Test public void cast_from_boolean_05() { testCast ("xsd:double('false'^^xsd:boolean)", "0.0E0" ) ; }
+
+ @Test public void cast_to_duration_01() { testCast ("xsd:duration('PT10S')", "'PT10S'^^xsd:duration") ; }
+ @Test public void cast_to_duration_02() { testCast ("xsd:duration('P1DT10S'^^xsd:dayTimeDuration)", "'P1DT10S'^^xsd:duration") ; }
+
+ @Test public void cast_to_duration_03() { testCast ("xsd:dayTimeDuration('P1Y2M3DT1H2M3S'^^xsd:duration)", "'P3DT1H2M3S'^^xsd:dayTimeDuration") ; }
+ @Test public void cast_to_duration_04() { testCast ("xsd:dayTimeDuration('P1Y'^^xsd:duration)", "'PT0S'^^xsd:dayTimeDuration") ; }
+ @Test public void cast_to_duration_05() { testCast ("xsd:yearMonthDuration('P1Y2M3DT1H2M3S'^^xsd:duration)", "'P1Y2M'^^xsd:yearMonthDuration") ; }
+
+ // This is what the XSD spec says, not "no cast"
+ @Test public void cast_to_duration_06() { testCast ("xsd:dayTimeDuration('P1Y2M'^^xsd:yearMonthDuration)", "'PT0S'^^xsd:dayTimeDuration") ; }
+ @Test public void cast_to_duration_07() { testCast ("xsd:yearMonthDuration('P1DT10H'^^xsd:dayTimeDuration)", "'P0M'^^xsd:yearMonthDuration") ; }
+ @Test public void cast_to_duration_08() { testCast ("xsd:yearMonthDuration('P1Y2M')", "'P1Y2M'^^xsd:yearMonthDuration") ; }
+ @Test public void cast_to_duration_09() { testCast ("xsd:dayTimeDuration('P1DT10H')", "'P1DT10H'^^xsd:dayTimeDuration") ; }
+ @Test public void cast_to_duration_10() { testCast ("xsd:duration('P1Y2M3DT1H2M3S')", "'P1Y2M3DT1H2M3S'^^xsd:duration") ; }
+
+ @Test public void cast_to_temporal_01() { testCast ("xsd:date('2015-10-12T15:00:24'^^xsd:dateTime)", "'2015-10-12'^^xsd:date") ; }
+ @Test public void cast_to_temporal_02() { testCast ("xsd:date('2015-10-12T15:00:24+01:00'^^xsd:dateTime)", "'2015-10-12+01:00'^^xsd:date") ; }
+ @Test public void cast_to_temporal_03() { testCast ("xsd:dateTime('2015-10-12'^^xsd:date)", "'2015-10-12T00:00:00'^^xsd:dateTime") ; }
+ @Test public void cast_to_temporal_04() { testCast ("xsd:dateTime('2015-10-12+01:00'^^xsd:date)", "'2015-10-12T00:00:00+01:00'^^xsd:dateTime") ; }
+ @Test public void cast_to_temporal_05() { testCast ("xsd:time('2015-10-12T15:00:24'^^xsd:dateTime)", "'15:00:24'^^xsd:time") ; }
+ @Test public void cast_to_temporal_06() { testCast ("xsd:dateTime('2015-10-12T15:00:24Z')", "'2015-10-12T15:00:24Z'^^xsd:dateTime") ; }
+
+ @Test public void cast_to_gregorian_01() { testCast ("xsd:gYear('2015-10-12'^^xsd:date)", "'2015'^^xsd:gYear") ; }
+ @Test public void cast_to_gregorian_02() { testCast ("xsd:gMonth('2015-10-12'^^xsd:date)", "'--10'^^xsd:gMonth") ; }
+ @Test public void cast_to_gregorian_03() { testCast ("xsd:gMonthDay('2015-10-12'^^xsd:date)", "'--10-12'^^xsd:gMonthDay") ; }
+ @Test public void cast_to_gregorian_04() { testCast ("xsd:gYearMonth('2015-10-12'^^xsd:date)", "'2015-10'^^xsd:gYearMonth") ; }
+
+ private void testNoCast(String input) {
+ try {
+ cast(input) ;
+ Assert.fail("Expected ExprEvalException") ;
+ } catch (ExprEvalException ex) {}
+ }
+
+ private void testCast(String input, String output) {
+ NodeValue nv2 = cast(input) ;
+ Node expected = SSE.parseNode(output) ;
+ Assert.assertEquals(expected, nv2.asNode()) ;
+ }
+
+ private NodeValue cast(String input$) {
+ Expr input = ExprUtils.parse(input$) ;
+ ARQ.getContext().set(ARQConstants.sysCurrentTime, NodeFactoryExtra.nowAsDateTime()) ;
+ FunctionEnv env = new ExecutionContext(ARQ.getContext(), null, null, null) ;
+ return input.eval(null, env) ;
+ }
+}
\ No newline at end of file
[4/4] jena git commit: JENA-1047: Rename to CastXSD
Posted by an...@apache.org.
JENA-1047: Rename to CastXSD
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/d3180b5e
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/d3180b5e
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/d3180b5e
Branch: refs/heads/master
Commit: d3180b5e75b8842cb201fa2bc73843025957ba70
Parents: 5156ba6
Author: Andy Seaborne <an...@apache.org>
Authored: Mon Oct 12 18:15:34 2015 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Mon Oct 12 18:15:34 2015 +0100
----------------------------------------------------------------------
.../apache/jena/sparql/function/CastXSD.java | 317 +++++++++++++++++++
.../apache/jena/sparql/function/CastXSD2.java | 317 -------------------
.../jena/sparql/function/StandardFunctions.java | 6 +-
3 files changed, 320 insertions(+), 320 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/d3180b5e/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD.java b/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD.java
new file mode 100644
index 0000000..b3c3837
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD.java
@@ -0,0 +1,317 @@
+/**
+ * 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.function;
+
+import java.math.BigDecimal ;
+import java.math.BigInteger ;
+import java.util.Objects ;
+
+import javax.xml.datatype.DatatypeConstants ;
+import javax.xml.datatype.Duration ;
+
+import org.apache.jena.datatypes.xsd.XSDDatatype ;
+import org.apache.jena.datatypes.xsd.impl.XSDAbstractDateTimeType ;
+import org.apache.jena.datatypes.xsd.impl.XSDBaseNumericType ;
+import org.apache.jena.graph.Node ;
+import org.apache.jena.sparql.expr.ExprEvalException ;
+import org.apache.jena.sparql.expr.ExprEvalTypeException ;
+import org.apache.jena.sparql.expr.ExprException ;
+import org.apache.jena.sparql.expr.NodeValue ;
+import org.apache.jena.sparql.expr.nodevalue.XSDFuncOp ;
+
+public class CastXSD extends FunctionBase1 implements FunctionFactory {
+
+ protected final XSDDatatype castType ;
+
+ public CastXSD(XSDDatatype dt)
+ {
+ this.castType = dt ;
+ }
+
+ @Override
+ public Function create(String uri)
+ {
+ return this ;
+ }
+
+ @Override
+ public NodeValue exec(NodeValue v)
+ {
+ return cast(v, castType) ;
+ }
+
+
+ private static boolean isTemporalDatatype(XSDDatatype datatype) {
+ return
+ datatype.equals(XSDDatatype.XSDdateTime) ||
+ datatype.equals(XSDDatatype.XSDtime) ||
+ datatype.equals(XSDDatatype.XSDdate) ||
+ datatype.equals(XSDDatatype.XSDgYear) ||
+ datatype.equals(XSDDatatype.XSDgYearMonth) ||
+ datatype.equals(XSDDatatype.XSDgMonth) ||
+ datatype.equals(XSDDatatype.XSDgMonthDay) ||
+ datatype.equals(XSDDatatype.XSDgDay) ;
+ }
+
+ private static boolean isDurationDatatype(XSDDatatype datatype) {
+ return
+ datatype.equals(XSDDatatype.XSDduration) ||
+ datatype.equals(XSDDatatype.XSDyearMonthDuration) ||
+ datatype.equals(XSDDatatype.XSDdayTimeDuration ) ;
+ }
+
+ /** Cast a NodeValue to an XSD datatype.
+ * This includes "by value" so 1e0 (an xsd:double) casts to 1 (an xsd:intger)
+ * @param nv
+ * @param castType
+ * @return NodeValue
+ * @throws ExprEvalException
+ */
+ public static NodeValue cast(NodeValue nv, XSDDatatype castType) {
+ // http://www.w3.org/TR/xpath-functions/#casting
+ Node n = nv.asNode() ;
+
+ if ( n.isBlank() )
+ throw exception("Can't cast blank nodes: "+nv) ;
+
+ if ( n.isURI() ) {
+ if ( castType.equals(XSDDatatype.XSDstring) )
+ return cast$(n.getURI(), castType) ;
+ else
+ throw exception("Can't cast URIs to "+castType.getURI()) ;
+ }
+
+ if ( ! n.isLiteral() )
+ throw exception("Can't cast (not a literal, nor URI to string) "+nv+" : "+castType.getURI()) ;
+
+ // It's a literal.
+
+ // Cast to self but may be an invalid lexical form.
+ if ( Objects.equals(nv.getNode().getLiteralDatatype(), castType) ) {
+ String lex = nv.getNode().getLiteralLexicalForm() ;
+ if ( castType.isValid(lex) )
+ return nv ;
+ throw exception("Invalid lexical form for "+castType.getURI()) ;
+ }
+
+
+ // Many casts can be done by testing the lexical is valid for the datatype.
+ // But some cases need to consider values.
+ // e.g. boolean -> numeric , double -> integer (doubles have "e" in them)
+
+ // To a temporal
+ if ( isTemporalDatatype(castType) ) {
+ return XSDFuncOp.dateTimeCast(nv, castType) ;
+ }
+
+ if ( isDurationDatatype(castType) ) {
+ // Duration cast.
+ // yearMonthDuration and TT is xs:dayTimeDuration -> 0.0S
+ // xs:dayTimeDuration and TT is yearMonthDuration -> P0M
+
+ if ( nv.isDuration() ) {
+ Duration d = nv.getDuration() ;
+ if ( castType.equals(XSDDatatype.XSDyearMonthDuration) ) {
+
+ // Include xsd:duration only covering year-month.
+ if ( nv.isDayTimeDuration() )
+ return NodeValue.makeNode("P0M", castType) ;
+
+ Duration d2 = NodeValue.xmlDatatypeFactory.newDuration
+ (d.getSign()>=0,
+ (BigInteger)d.getField(DatatypeConstants.YEARS), (BigInteger)d.getField(DatatypeConstants.MONTHS), null,
+ null, null, null) ;
+ return NodeValue.makeNode(d2.toString(), castType) ;
+ }
+ if ( castType.equals(XSDDatatype.XSDdayTimeDuration) ) {
+ if ( nv.isYearMonthDuration() )
+ return NodeValue.makeNode("PT0S", castType) ;
+ Duration d2 = NodeValue.xmlDatatypeFactory.newDuration
+
+ (d.getSign()>=0,
+ null, null, (BigInteger)d.getField(DatatypeConstants.DAYS),
+ (BigInteger)d.getField(DatatypeConstants.HOURS), (BigInteger)d.getField(DatatypeConstants.MINUTES), (BigDecimal)d.getField(DatatypeConstants.SECONDS)) ;
+ // return NodeValue.makeDuration(d2) ;
+ return NodeValue.makeNode(d2.toString(), castType) ;
+ }
+ }
+ }
+
+ // From number, can consider value.
+ if ( nv.isNumber() ) {
+ if ( castType.equals(XSDDatatype.XSDdecimal) ) {
+ // Number to decimal.
+ if ( isDouble(nv) || isFloat(nv) ) {
+ // FP to decimal.
+ double d = nv.getDouble() ;
+ if ( Double.isNaN(d) )
+ throw exception("Can't cast NaN to xsd:decimal") ;
+ if ( Double.isInfinite(d) )
+ throw exception("Can't cast Inf or -Inf to xsd:decimal") ;
+ // BigDecimal.valueOf(d) can lead to trailing zeros
+ // BigDecimal.valueOf(d) goes via strings.
+ String lex = doubleToDecimalString(d) ;
+ return NodeValue.makeDecimal(lex) ;
+ }
+ // Integer, or derived type -> decimal.
+ return castByLex(nv, castType) ;
+ }
+ if ( XSDFuncOp.isIntegerType(castType) ) {
+ // Number to integer
+ if ( isDouble(nv) || isFloat(nv) ) {
+ // FP to integer
+ double d = nv.getDouble() ;
+ boolean isIntegerValue = ( Math.rint(d) == d ) ;
+ if ( isIntegerValue ) {
+ String lex = doubleIntegerToString(d) ;
+ if ( lex != null )
+ return castByLex(lex, castType) ;
+ }
+ throw exception(nv, castType) ;
+ } else if ( isDecimal(nv) ) {
+ // Decimal to integer
+ BigDecimal bd = nv.getDecimal() ;
+ try {
+ // Exception on fraction.
+ BigInteger bi = bd.toBigIntegerExact() ;
+ return castByLex(bi.toString(), castType) ;
+ } catch (ArithmeticException ex) {
+ throw new ExprEvalException("CastXSD: Not a valid cast: '"+nv+"'") ;
+ }
+ } else {
+ // Integer derived type -> integer derived type.
+ return castByLex(nv, castType) ;
+ }
+ }
+ }
+
+ // Boolean -> xsd:
+ if ( nv.isBoolean() ) {
+ boolean b = nv.getBoolean() ;
+ // Boolean to boolean covered above.
+ String lex ;
+ if ( XSDDatatype.XSDfloat.equals(castType) || XSDDatatype.XSDdouble.equals(castType) )
+ return cast$( ( b ? "1.0E0" : "0.0E0" ) , castType) ;
+ else if ( XSDDatatype.XSDdecimal.equals(castType) )
+ return cast$( ( b ? "1.0" : "0.0" ) , castType) ;
+ else if ( XSDFuncOp.isIntegerType(castType))
+ return cast$( ( b ? "1" : "0" ) , castType ) ;
+ else if ( XSDDatatype.XSDstring.equals(castType) )
+ return cast$( nv.getNode().getLiteralLexicalForm(), castType ) ;
+ throw exception("Can't cast xsd:boolean to "+castType) ;
+ }
+
+ // Try by lexical
+ return castByLex(nv, castType) ;
+ }
+
+ /** Presentation form of an XSD datatype URI */
+ private static String xsdName(String datatype) {
+ return datatype.replaceAll(XSDDatatype.XSD+"#", "xsd:") ;
+ }
+
+ /** Test to see if a NodeValue is a valid double value and is of datatype xsd:double. */
+ private static boolean isDouble(NodeValue nv) {
+ return nv.isDouble() && nv.getDatatypeURI().equals(XSDDatatype.XSDdouble.getURI()) ;
+ }
+
+ /** Test to see if a NodeValue is a valid float value and is of datatype float. */
+ private static boolean isFloat(NodeValue nv) {
+ return nv.isFloat() && nv.getDatatypeURI().equals(XSDDatatype.XSDfloat.getURI()) ;
+ }
+
+ /** Test to see if a NodeValue is a valid decimal value and is of datatype decimal. */
+ private static boolean isDecimal(NodeValue nv) {
+ return nv.isDecimal() && nv.getDatatypeURI().equals(XSDDatatype.XSDdecimal.getURI()) ;
+ }
+
+ /** Test to see if a NodeValue is a valid numeric value. */
+ private static boolean isNumeric(NodeValue nv) {
+ return nv.isNumber() ;
+ }
+
+ private static ExprException exception(NodeValue nv, XSDDatatype dt) {
+ return exception("Invalid cast: "+nv+" -> "+xsdName(dt.getURI())) ;
+ }
+
+ private static ExprException exception(String msg) {
+ return new ExprEvalTypeException(msg) ;
+ }
+
+ // Cast by lexical form with checking.
+ private static NodeValue castByLex(NodeValue nv, XSDDatatype castType) {
+ String lex = nv.getNode().getLiteralLexicalForm() ;
+ return castByLex(lex, castType) ;
+ }
+
+ // Cast by lexical form with checking.
+ private static NodeValue castByLex(String lex, XSDDatatype castType) {
+ if ( ! castType.isValid(lex) )
+ throw exception("Invalid lexical form: '"+lex+"' for "+castType.getURI()) ;
+ if ( castType instanceof XSDBaseNumericType ||
+ castType.equals(XSDDatatype.XSDfloat) ||
+ castType.equals(XSDDatatype.XSDdouble) ||
+ castType.equals(XSDDatatype.XSDboolean) ||
+ castType instanceof XSDAbstractDateTimeType ) // Includes durations, and Gregorian
+ {
+ // More helpful error message.
+ if ( lex.startsWith(" ") || lex.endsWith(" ") )
+ throw exception("Not a valid literal form (has whitespace): '"+lex+"'") ;
+ }
+ return NodeValue.makeNode(lex, castType) ;
+
+ }
+
+ // Known to work casts. No checking.
+ private static NodeValue cast$(String lex, XSDDatatype castType) {
+ return NodeValue.makeNode(lex, castType) ;
+ }
+
+ // Return the integer lexical form for a double, where the double is known to be integer valued.
+ private static String doubleIntegerToString(double d) {
+ // Fast path
+ long x = Math.round(d) ;
+ if ( x != Long.MAX_VALUE && x != Long.MIN_VALUE )
+ return Long.toString(x) ;
+
+ String lex = BigDecimal.valueOf(d).toPlainString() ;
+ int i = lex.indexOf('.') ;
+ if ( i >= 0 )
+ // Adds .0 for some (small) doubles.
+ lex = lex.substring(0, i) ;
+ return lex;
+ }
+
+ // Return the decimal lexical form for a double value.
+ // Java big decimal allows "E" forms, XSD does not.
+ private static String doubleToDecimalString(double d) {
+ // BigDecimal.valueOf(d) can lead to trailing zeros.
+ String lex = BigDecimal.valueOf(d).toPlainString() ;
+ // Clean the string.
+ int i = lex.indexOf('.') ;
+ if ( i < 0 )
+ return lex ;
+ // Often one or two
+ while(lex.endsWith("00"))
+ lex = lex.substring(0, lex.length()-2) ;
+ while(lex.endsWith("0"))
+ lex = lex.substring(0, lex.length()-1) ;
+ return lex ;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/jena/blob/d3180b5e/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD2.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD2.java b/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD2.java
deleted file mode 100644
index 6d742b3..0000000
--- a/jena-arq/src/main/java/org/apache/jena/sparql/function/CastXSD2.java
+++ /dev/null
@@ -1,317 +0,0 @@
-/**
- * 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.function;
-
-import java.math.BigDecimal ;
-import java.math.BigInteger ;
-import java.util.Objects ;
-
-import javax.xml.datatype.DatatypeConstants ;
-import javax.xml.datatype.Duration ;
-
-import org.apache.jena.datatypes.xsd.XSDDatatype ;
-import org.apache.jena.datatypes.xsd.impl.XSDAbstractDateTimeType ;
-import org.apache.jena.datatypes.xsd.impl.XSDBaseNumericType ;
-import org.apache.jena.graph.Node ;
-import org.apache.jena.sparql.expr.ExprEvalException ;
-import org.apache.jena.sparql.expr.ExprEvalTypeException ;
-import org.apache.jena.sparql.expr.ExprException ;
-import org.apache.jena.sparql.expr.NodeValue ;
-import org.apache.jena.sparql.expr.nodevalue.XSDFuncOp ;
-
-public class CastXSD2 extends FunctionBase1 implements FunctionFactory {
-
- protected final XSDDatatype castType ;
-
- public CastXSD2(XSDDatatype dt)
- {
- this.castType = dt ;
- }
-
- @Override
- public Function create(String uri)
- {
- return this ;
- }
-
- @Override
- public NodeValue exec(NodeValue v)
- {
- return cast(v, castType) ;
- }
-
-
- private static boolean isTemporalDatatype(XSDDatatype datatype) {
- return
- datatype.equals(XSDDatatype.XSDdateTime) ||
- datatype.equals(XSDDatatype.XSDtime) ||
- datatype.equals(XSDDatatype.XSDdate) ||
- datatype.equals(XSDDatatype.XSDgYear) ||
- datatype.equals(XSDDatatype.XSDgYearMonth) ||
- datatype.equals(XSDDatatype.XSDgMonth) ||
- datatype.equals(XSDDatatype.XSDgMonthDay) ||
- datatype.equals(XSDDatatype.XSDgDay) ;
- }
-
- private static boolean isDurationDatatype(XSDDatatype datatype) {
- return
- datatype.equals(XSDDatatype.XSDduration) ||
- datatype.equals(XSDDatatype.XSDyearMonthDuration) ||
- datatype.equals(XSDDatatype.XSDdayTimeDuration ) ;
- }
-
- /** Cast a NodeValue to an XSD datatype.
- * This includes "by value" so 1e0 (an xsd:double) casts to 1 (an xsd:intger)
- * @param nv
- * @param castType
- * @return NodeValue
- * @throws ExprEvalException
- */
- public static NodeValue cast(NodeValue nv, XSDDatatype castType) {
- // http://www.w3.org/TR/xpath-functions/#casting
- Node n = nv.asNode() ;
-
- if ( n.isBlank() )
- throw exception("Can't cast blank nodes: "+nv) ;
-
- if ( n.isURI() ) {
- if ( castType.equals(XSDDatatype.XSDstring) )
- return cast$(n.getURI(), castType) ;
- else
- throw exception("Can't cast URIs to "+castType.getURI()) ;
- }
-
- if ( ! n.isLiteral() )
- throw exception("Can't cast (not a literal, nor URI to string) "+nv+" : "+castType.getURI()) ;
-
- // It's a literal.
-
- // Cast to self but may be an invalid lexical form.
- if ( Objects.equals(nv.getNode().getLiteralDatatype(), castType) ) {
- String lex = nv.getNode().getLiteralLexicalForm() ;
- if ( castType.isValid(lex) )
- return nv ;
- throw exception("Invalid lexical form for "+castType.getURI()) ;
- }
-
-
- // Many casts can be done by testing the lexical is valid for the datatype.
- // But some cases need to consider values.
- // e.g. boolean -> numeric , double -> integer (doubles have "e" in them)
-
- // To a temporal
- if ( isTemporalDatatype(castType) ) {
- return XSDFuncOp.dateTimeCast(nv, castType) ;
- }
-
- if ( isDurationDatatype(castType) ) {
- // Duration cast.
- // yearMonthDuration and TT is xs:dayTimeDuration -> 0.0S
- // xs:dayTimeDuration and TT is yearMonthDuration -> P0M
-
- if ( nv.isDuration() ) {
- Duration d = nv.getDuration() ;
- if ( castType.equals(XSDDatatype.XSDyearMonthDuration) ) {
-
- // Include xsd:duration only covering year-month.
- if ( nv.isDayTimeDuration() )
- return NodeValue.makeNode("P0M", castType) ;
-
- Duration d2 = NodeValue.xmlDatatypeFactory.newDuration
- (d.getSign()>=0,
- (BigInteger)d.getField(DatatypeConstants.YEARS), (BigInteger)d.getField(DatatypeConstants.MONTHS), null,
- null, null, null) ;
- return NodeValue.makeNode(d2.toString(), castType) ;
- }
- if ( castType.equals(XSDDatatype.XSDdayTimeDuration) ) {
- if ( nv.isYearMonthDuration() )
- return NodeValue.makeNode("PT0S", castType) ;
- Duration d2 = NodeValue.xmlDatatypeFactory.newDuration
-
- (d.getSign()>=0,
- null, null, (BigInteger)d.getField(DatatypeConstants.DAYS),
- (BigInteger)d.getField(DatatypeConstants.HOURS), (BigInteger)d.getField(DatatypeConstants.MINUTES), (BigDecimal)d.getField(DatatypeConstants.SECONDS)) ;
- // return NodeValue.makeDuration(d2) ;
- return NodeValue.makeNode(d2.toString(), castType) ;
- }
- }
- }
-
- // From number, can consider value.
- if ( nv.isNumber() ) {
- if ( castType.equals(XSDDatatype.XSDdecimal) ) {
- // Number to decimal.
- if ( isDouble(nv) || isFloat(nv) ) {
- // FP to decimal.
- double d = nv.getDouble() ;
- if ( Double.isNaN(d) )
- throw exception("Can't cast NaN to xsd:decimal") ;
- if ( Double.isInfinite(d) )
- throw exception("Can't cast Inf or -Inf to xsd:decimal") ;
- // BigDecimal.valueOf(d) can lead to trailing zeros
- // BigDecimal.valueOf(d) goes via strings.
- String lex = doubleToDecimalString(d) ;
- return NodeValue.makeDecimal(lex) ;
- }
- // Integer, or derived type -> decimal.
- return castByLex(nv, castType) ;
- }
- if ( XSDFuncOp.isIntegerType(castType) ) {
- // Number to integer
- if ( isDouble(nv) || isFloat(nv) ) {
- // FP to integer
- double d = nv.getDouble() ;
- boolean isIntegerValue = ( Math.rint(d) == d ) ;
- if ( isIntegerValue ) {
- String lex = doubleIntegerToString(d) ;
- if ( lex != null )
- return castByLex(lex, castType) ;
- }
- throw exception(nv, castType) ;
- } else if ( isDecimal(nv) ) {
- // Decimal to integer
- BigDecimal bd = nv.getDecimal() ;
- try {
- // Exception on fraction.
- BigInteger bi = bd.toBigIntegerExact() ;
- return castByLex(bi.toString(), castType) ;
- } catch (ArithmeticException ex) {
- throw new ExprEvalException("CastXSD: Not a valid cast: '"+nv+"'") ;
- }
- } else {
- // Integer derived type -> integer derived type.
- return castByLex(nv, castType) ;
- }
- }
- }
-
- // Boolean -> xsd:
- if ( nv.isBoolean() ) {
- boolean b = nv.getBoolean() ;
- // Boolean to boolean covered above.
- String lex ;
- if ( XSDDatatype.XSDfloat.equals(castType) || XSDDatatype.XSDdouble.equals(castType) )
- return cast$( ( b ? "1.0E0" : "0.0E0" ) , castType) ;
- else if ( XSDDatatype.XSDdecimal.equals(castType) )
- return cast$( ( b ? "1.0" : "0.0" ) , castType) ;
- else if ( XSDFuncOp.isIntegerType(castType))
- return cast$( ( b ? "1" : "0" ) , castType ) ;
- else if ( XSDDatatype.XSDstring.equals(castType) )
- return cast$( nv.getNode().getLiteralLexicalForm(), castType ) ;
- throw exception("Can't cast xsd:boolean to "+castType) ;
- }
-
- // Try by lexical
- return castByLex(nv, castType) ;
- }
-
- /** Presentation form of an XSD datatype URI */
- private static String xsdName(String datatype) {
- return datatype.replaceAll(XSDDatatype.XSD+"#", "xsd:") ;
- }
-
- /** Test to see if a NodeValue is a valid double value and is of datatype xsd:double. */
- private static boolean isDouble(NodeValue nv) {
- return nv.isDouble() && nv.getDatatypeURI().equals(XSDDatatype.XSDdouble.getURI()) ;
- }
-
- /** Test to see if a NodeValue is a valid float value and is of datatype float. */
- private static boolean isFloat(NodeValue nv) {
- return nv.isFloat() && nv.getDatatypeURI().equals(XSDDatatype.XSDfloat.getURI()) ;
- }
-
- /** Test to see if a NodeValue is a valid decimal value and is of datatype decimal. */
- private static boolean isDecimal(NodeValue nv) {
- return nv.isDecimal() && nv.getDatatypeURI().equals(XSDDatatype.XSDdecimal.getURI()) ;
- }
-
- /** Test to see if a NodeValue is a valid numeric value. */
- private static boolean isNumeric(NodeValue nv) {
- return nv.isNumber() ;
- }
-
- private static ExprException exception(NodeValue nv, XSDDatatype dt) {
- return exception("Invalid cast: "+nv+" -> "+xsdName(dt.getURI())) ;
- }
-
- private static ExprException exception(String msg) {
- return new ExprEvalTypeException(msg) ;
- }
-
- // Cast by lexical form with checking.
- private static NodeValue castByLex(NodeValue nv, XSDDatatype castType) {
- String lex = nv.getNode().getLiteralLexicalForm() ;
- return castByLex(lex, castType) ;
- }
-
- // Cast by lexical form with checking.
- private static NodeValue castByLex(String lex, XSDDatatype castType) {
- if ( ! castType.isValid(lex) )
- throw exception("Invalid lexical form: '"+lex+"' for "+castType.getURI()) ;
- if ( castType instanceof XSDBaseNumericType ||
- castType.equals(XSDDatatype.XSDfloat) ||
- castType.equals(XSDDatatype.XSDdouble) ||
- castType.equals(XSDDatatype.XSDboolean) ||
- castType instanceof XSDAbstractDateTimeType ) // Includes durations, and Gregorian
- {
- // More helpful error message.
- if ( lex.startsWith(" ") || lex.endsWith(" ") )
- throw exception("Not a valid literal form (has whitespace): '"+lex+"'") ;
- }
- return NodeValue.makeNode(lex, castType) ;
-
- }
-
- // Known to work casts. No checking.
- private static NodeValue cast$(String lex, XSDDatatype castType) {
- return NodeValue.makeNode(lex, castType) ;
- }
-
- // Return the integer lexical form for a double, where the double is known to be integer valued.
- private static String doubleIntegerToString(double d) {
- // Fast path
- long x = Math.round(d) ;
- if ( x != Long.MAX_VALUE && x != Long.MIN_VALUE )
- return Long.toString(x) ;
-
- String lex = BigDecimal.valueOf(d).toPlainString() ;
- int i = lex.indexOf('.') ;
- if ( i >= 0 )
- // Adds .0 for some (small) doubles.
- lex = lex.substring(0, i) ;
- return lex;
- }
-
- // Return the decimal lexical form for a double value.
- // Java big decimal allows "E" forms, XSD does not.
- private static String doubleToDecimalString(double d) {
- // BigDecimal.valueOf(d) can lead to trailing zeros.
- String lex = BigDecimal.valueOf(d).toPlainString() ;
- // Clean the string.
- int i = lex.indexOf('.') ;
- if ( i < 0 )
- return lex ;
- // Often one or two
- while(lex.endsWith("00"))
- lex = lex.substring(0, lex.length()-2) ;
- while(lex.endsWith("0"))
- lex = lex.substring(0, lex.length()-1) ;
- return lex ;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/jena/blob/d3180b5e/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java b/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java
index a988bdd..ac0dbe1 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/function/StandardFunctions.java
@@ -116,17 +116,17 @@ public class StandardFunctions
private static void addCastXSD(FunctionRegistry registry, XSDDatatype dt)
{
- registry.put(dt.getURI(), new CastXSD2(dt) ) ;
+ registry.put(dt.getURI(), new CastXSD(dt) ) ;
}
private static void addCastNumeric(FunctionRegistry registry, XSDDatatype dt)
{
- registry.put(dt.getURI(), new CastXSD2(dt) ) ;
+ registry.put(dt.getURI(), new CastXSD(dt) ) ;
}
private static void addCastTemporal(FunctionRegistry registry, XSDDatatype dt)
{
- registry.put(dt.getURI(), new CastXSD2(dt) ) ;
+ registry.put(dt.getURI(), new CastXSD(dt) ) ;
}
private static void add(FunctionRegistry registry, String uri, Class<?> funcClass)
[2/4] jena git commit: Removed deprecated; add float to string
Posted by an...@apache.org.
Removed deprecated; add float to string
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/7aa9af5f
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/7aa9af5f
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/7aa9af5f
Branch: refs/heads/master
Commit: 7aa9af5fe8aeb92b32ff9c8e11a6016dee28787e
Parents: b111837
Author: Andy Seaborne <an...@apache.org>
Authored: Mon Oct 12 16:55:50 2015 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Mon Oct 12 16:55:50 2015 +0100
----------------------------------------------------------------------
.../java/org/apache/jena/sparql/util/Utils.java | 24 +++++---------------
1 file changed, 6 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/7aa9af5f/jena-arq/src/main/java/org/apache/jena/sparql/util/Utils.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/Utils.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/Utils.java
index 617f7d7..0c1a9ea 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/util/Utils.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/Utils.java
@@ -20,27 +20,9 @@ package org.apache.jena.sparql.util ;
import java.math.BigDecimal ;
-import org.apache.jena.atlas.lib.Lib ;
-
/** Miscellaneous operations - not query specific */
public class Utils {
- /**
- * @deprecated Use {@link Lib#className(Object)} instead
- */
- @Deprecated
- static public String className(Object obj) {
- return Lib.className(obj) ;
- }
-
- /**
- * @deprecated Use {@link Lib#classShortName(Class)} instead
- */
- @Deprecated
- static public String classShortName(Class<? > cls) {
- return Lib.classShortName(cls) ;
- }
-
static public String stringForm(BigDecimal decimal) {
return decimal.toPlainString() ;
}
@@ -64,6 +46,12 @@ public class Utils {
}
static public String stringForm(float f) {
+ if ( Float.isInfinite(f) ) {
+ if ( f < 0 )
+ return "-INF" ;
+ return "INF" ;
+ }
+
// No SPARQL short form.
return Float.toString(f) ;
}