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/05/05 22:36:25 UTC
svn commit: r1334490 - in
/incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/projects/nodevalue:
Dispatch.java NV2.java TestDateTimeOps.java
Author: andy
Date: Sat May 5 20:36:25 2012
New Revision: 1334490
URL: http://svn.apache.org/viewvc?rev=1334490&view=rev
Log:
Code for date/time arthimetic.
Added:
incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/projects/nodevalue/TestDateTimeOps.java
Removed:
incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/projects/nodevalue/Dispatch.java
Modified:
incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/projects/nodevalue/NV2.java
Modified: incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/projects/nodevalue/NV2.java
URL: http://svn.apache.org/viewvc/incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/projects/nodevalue/NV2.java?rev=1334490&r1=1334489&r2=1334490&view=diff
==============================================================================
--- incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/projects/nodevalue/NV2.java (original)
+++ incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/projects/nodevalue/NV2.java Sat May 5 20:36:25 2012
@@ -22,6 +22,7 @@ import static com.hp.hpl.jena.sparql.exp
import static com.hp.hpl.jena.sparql.expr.ValueSpaceClassification.VSPACE_NUM ;
import static com.hp.hpl.jena.sparql.expr.ValueSpaceClassification.VSPACE_STRING ;
import static javax.xml.datatype.DatatypeConstants.DAYS ;
+import static javax.xml.datatype.DatatypeConstants.FIELD_UNDEFINED ;
import static javax.xml.datatype.DatatypeConstants.HOURS ;
import static javax.xml.datatype.DatatypeConstants.MINUTES ;
import static javax.xml.datatype.DatatypeConstants.MONTHS ;
@@ -31,12 +32,11 @@ import static javax.xml.datatype.Datatyp
import java.util.GregorianCalendar ;
import javax.xml.datatype.DatatypeConfigurationException ;
-import javax.xml.datatype.DatatypeConstants ;
import javax.xml.datatype.DatatypeFactory ;
import javax.xml.datatype.Duration ;
import javax.xml.datatype.XMLGregorianCalendar ;
-import javax.xml.namespace.QName ;
+import com.hp.hpl.jena.query.ARQ ;
import com.hp.hpl.jena.sparql.ARQInternalErrorException ;
import com.hp.hpl.jena.sparql.expr.ExprEvalTypeException ;
import com.hp.hpl.jena.sparql.expr.NodeValue ;
@@ -53,44 +53,52 @@ public class NV2
// .getYear etc all blow up except if overridden.
//XMLGregorianCalendar.getXYZ return MININT for undef.
+ /* Operations
+ * add, subtract (duration, duration)
+ *
+(xsd:duration, xsd:duration) -> xsd:duration
+ 10.6.1 op:add-yearMonthDurations
+ 10.6.2 op:subtract-yearMonthDurations
+(xsd:duration, xsd:duration) -> xsd:duration
+ 10.6.6 op:add-dayTimeDurations
+ 10.6.7 op:subtract-dayTimeDurations
+** Java has general duration subtract
+
+ * Subtract two date/times
+
+(xsd:dateTime, xsd:dateTime) -> xsd:duration
+ 10.8.1 op:subtract-dateTimes -> xsd:dayTimeDuration
+(xsd:date, xsd:date) -> xsd:duration
+ 10.8.2 op:subtract-dates
+(xsd:time, xsd:time) -> xsd:duration
+ 10.8.3 op:subtract-times
+
+ * Date/time and duration
+** Java has general duration subtract (error needed?)
+
+(xsd:dateTime, xsd:duration) -> xsd:dateTime
+ 10.8.4 op:add-yearMonthDuration-to-dateTime
+ 10.8.5 op:add-dayTimeDuration-to-dateTime
+ 10.8.6 op:subtract-yearMonthDuration-from-dateTime
+ 10.8.7 op:subtract-dayTimeDuration-from-dateTime
+
+(xsd:date, xsd:duration) -> xsd:date
+ 10.8.8 op:add-yearMonthDuration-to-date
+ 10.8.9 op:add-dayTimeDuration-to-date
+ 10.8.10 op:subtract-yearMonthDuration-from-date
+ 10.8.11 op:subtract-dayTimeDuration-from-date
+
+(xsd:time, xsd:duration) -> xsd:time
+ 10.8.12 op:add-dayTimeDuration-to-time
+ 10.8.13 op:subtract-dayTimeDuration-from-time */
+
/*
- * NodeValueDate.java
- * NodeValueDateTime.java
- * NodeValueGDay.java
- * NodeValueGMonth.java
- * NodeValueGMonthDay.java
- * NodeValueGYear.java
- * NodeValueGYearMonth.java
- * NodeValueTime.java
-
fn:dateTime($arg1 as xs:date?, $arg2 as xs:time?) as xs:dateTime?
http://www.w3.org/TR/xmlschema-2/#dateTime-order
Properties of Date/time Seven-property Models
http://www.w3.org/TR/xmlschema11-2/#dt-dt-7PropMod
-
- NodeFunctions.java
- NodeValueBoolean.java
-* NodeValueDate.java
-* NodeValueDateTime.java
- NodeValueDecimal.java
- NodeValueDouble.java
- NodeValueDuration.java
- NodeValueFloat.java
-* NodeValueGDay.java
-* NodeValueGMonth.java
-* NodeValueGMonthDay.java
-* NodeValueGYear.java
-* NodeValueGYearMonth.java
- NodeValueInteger.java
- NodeValueNode.java
- NodeValueString.java
-* NodeValueTime.java
- NodeValueVisitor.java
- NumericType.java
- XSDFuncOp.java
-
*/
private static DatatypeFactory datatypefactory = null ;
@@ -103,139 +111,184 @@ http://www.w3.org/TR/xmlschema11-2/#dt-d
public static void main(String... argv)
{
- NodeValue nv = NodeValue.makeDate("2012-04-29") ;
- //System.out.println(nv.getDateTime().getHours()) ;
-
- //XSDFuncOp.add(nv, nv)
+// execAdd("'2012-05-05T12:45:56.8'^^xsd:dateTime", "'P11DT0.788S'^^xsd:duration") ;
+// execAdd("123", "45") ;
+// execSub("'2012-05-05T12:45:56.8'^^xsd:dateTime", "'P11DT0.788S'^^xsd:duration") ;
+// execAdd("'2012-05-05T12:45:56.8'^^xsd:dateTime", "'P11DT0.788S'^^xsd:duration") ;
+//
+// execSub("'2012-05-05T12:45:56.8'^^xsd:dateTime", "'2011-05-05T12:45:56.6'^^xsd:dateTime") ;
+ execSub("'2012'^^xsd:gYear", "'2012Z'^^xsd:gYear") ;
- Duration dur = datatypefactory.newDuration("P10Y10MT2H") ;
- XMLGregorianCalendar cal = datatypefactory.newXMLGregorianCalendar("2012-04-28T21:06:00Z") ;
-
- XMLGregorianCalendar cal3 = datatypefactory.newXMLGregorianCalendar("2012-04-28") ;
- System.out.println(DatatypeConstants.FIELD_UNDEFINED) ;
- System.out.println("min = "+cal3.getMinute()) ;
-
-
- XMLGregorianCalendar cal2 = datatypefactory.newXMLGregorianCalendar("2012-04-29") ;
+ System.exit(0) ;
- NodeValue nv1 = NodeValue.parse("'2012-04-28T21:06:00Z'^^xsd:dateTime") ;
- NodeValue nv2 = NodeValue.makeDuration("P10Y10MT2H") ;
-
- System.out.println(addNV(nv1, nv2)) ;
- System.out.println(addNV(nv2, nv1)) ;
-
- NodeValue nv3 = NodeValue.makeDuration("P1Y1MT2H") ;
- System.out.println(NodeValue.compare(nv2, nv3)) ;
}
- static NodeValue addNV(NodeValue nv1, NodeValue nv2)
+ static void execAdd(String s1, String s2)
+ {
+ try {
+ NodeValue nv1 = NodeValue.parse(s1) ;
+ NodeValue nv2 = NodeValue.parse(s2) ;
+ System.out.printf("+(%s, %s)\n", nv1, nv2) ;
+ NodeValue nv3 = addNV(nv1, nv2) ;
+ System.out.printf(" %s\n", nv3) ;
+ } catch (Exception ex)
+ {
+ System.out.flush() ;
+ ex.printStackTrace(System.err) ;
+ }
+ }
+
+ static void execSub(String s1, String s2)
+ {
+ try {
+ NodeValue nv1 = NodeValue.parse(s1) ;
+ NodeValue nv2 = NodeValue.parse(s2) ;
+ System.out.printf("- (%s, %s)\n", nv1, nv2) ;
+ NodeValue nv3 = subNV(nv1, nv2) ;
+ System.out.printf(" %s\n", nv3) ;
+ } catch (Exception ex)
+ {
+ System.out.flush() ;
+ ex.printStackTrace(System.err) ;
+ }
+ }
+
+ // NodeFunctions
+ public static NodeValue addNV(NodeValue nv1, NodeValue nv2)
{
ValueSpaceClassification vs1 = nv1.getValueSpace() ;
ValueSpaceClassification vs2 = nv2.getValueSpace() ;
if ( vs1.equals(VSPACE_NUM) && vs2.equals(VSPACE_NUM) )
- return XSDFuncOp.add(nv1, nv2) ;
+ return XSDFuncOp.numAdd(nv1, nv2) ;
+ if ( ARQ.isStrictMode() )
+ throw new ExprEvalTypeException("Operator '+' requires two numbers: got: "+nv1+" and "+nv2) ;
+
if ( vs1.equals(VSPACE_STRING) && vs2.equals(VSPACE_STRING) )
return NodeValue.makeString(nv1.asString()+nv2.asString()) ;
+ if ( vs1.equals(VSPACE_DURATION) && vs2.equals(VSPACE_DURATION) )
+ {
+ Duration d3 = nv1.getDuration().add(nv2.getDuration()) ;
+ return NodeValue.makeDuration(d3) ;
+ }
+ // Loose style. Add any duration to any date or time value.
if ( isDT(vs1) && vs2.equals(VSPACE_DURATION) )
{
- // Temp fakery.
- XMLGregorianCalendar cal = datatypefactory.newXMLGregorianCalendar((GregorianCalendar)nv1.getDateTime().asCalendar()) ;
- XMLGregorianCalendar result = add(cal, nv2.getDuration()) ;
- // Unfakery.
- NodeValue r = NodeValue.makeDateTime(result.toGregorianCalendar()) ;
+ XMLGregorianCalendar cal = nv1.getDateTime() ;
+ XMLGregorianCalendar result = xsd_add(cal, nv2.getDuration()) ;
+ NodeValue r = NodeValue.makeDateTime(result) ;
return r ;
}
if ( isDT(vs2) && vs1.equals(VSPACE_DURATION) )
{
- // Temp fakery.
- XMLGregorianCalendar cal = datatypefactory.newXMLGregorianCalendar((GregorianCalendar)nv2.getDateTime().asCalendar()) ;
- XMLGregorianCalendar result = add(cal, nv1.getDuration()) ;
- // Unfakery.
- NodeValue r = NodeValue.makeDateTime(result.toGregorianCalendar()) ;
+ XMLGregorianCalendar cal = nv2.getDateTime() ;
+ XMLGregorianCalendar result = xsd_add(cal, nv1.getDuration()) ;
+ NodeValue r = NodeValue.makeDateTime(result) ;
return r ;
}
-
throw new ExprEvalTypeException("Operator '+' : Undefined addition: "+nv1+" and "+nv2) ;
}
- private static XMLGregorianCalendar add(XMLGregorianCalendar cal, Duration duration)
+ // NodeFunctions
+ public static NodeValue subNV(NodeValue nv1, NodeValue nv2)
{
+ ValueSpaceClassification vs1 = nv1.getValueSpace() ;
+ ValueSpaceClassification vs2 = nv2.getValueSpace() ;
+
+ if ( vs1.equals(VSPACE_NUM) && vs2.equals(VSPACE_NUM) )
+ return XSDFuncOp.numSubtract(nv1, nv2) ;
+ if ( ARQ.isStrictMode() )
+ throw new ExprEvalTypeException("Operator '-' requires two numbers: got: "+nv1+" and "+nv2) ;
+
+ if ( vs1.equals(VSPACE_DURATION) && vs2.equals(VSPACE_DURATION) )
+ {
+ Duration d3 = nv1.getDuration().subtract(nv2.getDuration()) ;
+ return NodeValue.makeDuration(d3) ;
+ }
+
+ if ( isDT(vs1) && isDT(vs2) )
+ {
+ XMLGregorianCalendar cal1 = nv1.getDateTime() ;
+ XMLGregorianCalendar cal2 = nv2.getDateTime() ;
+ boolean isDef1 = ( cal1.getTimezone() == FIELD_UNDEFINED ) ;
+ boolean isDef2 = ( cal2.getTimezone() == FIELD_UNDEFINED ) ;
+ if ( ( isDef1 && !isDef2 ) || ( !isDef1 && isDef2 ) )
+ throw new ExprEvalTypeException("Operator '-': can't substract timezone/non-timezone values") ;
+ // Inspect duration and force to better type? xsd:dayTimeDuration
+ return NodeValue.makeDuration(xsd_substract(cal1, cal2));
+ }
+
+ // Loose style. Subtract any duration to any date or time value.
+ if ( isDT(vs1) && vs2.equals(VSPACE_DURATION) )
+ {
+ XMLGregorianCalendar cal = nv1.getDateTime() ;
+ // add-negation
+ XMLGregorianCalendar result = xsd_subtract(cal, nv2.getDuration()) ;
+ NodeValue r = NodeValue.makeDateTime(result) ;
+ return r ;
+ }
+
+ throw new ExprEvalTypeException("Operator '-' : Undefined subtraction: "+nv1+" and "+nv2) ;
+ }
+
+ // XSDFuncOps
+ public static XMLGregorianCalendar xsd_add(XMLGregorianCalendar cal, Duration duration)
+ {
+ //if ( ! isYearMonth(duration) && ! isDayTime(duration) )
+
XMLGregorianCalendar result = (XMLGregorianCalendar)cal.clone() ;
result.add(duration) ;
return result ;
}
- static boolean isDT(ValueSpaceClassification vs)
+ // XSDFuncOps
+ public static XMLGregorianCalendar xsd_subtract(XMLGregorianCalendar cal, Duration duration)
+ {
+ return xsd_add(cal, duration.negate()) ;
+ }
+
+ // XSDFuncOps
+ public static Duration xsd_substract(XMLGregorianCalendar cal1, XMLGregorianCalendar cal2)
+ {
+ GregorianCalendar gcal1 = cal1.toGregorianCalendar() ;
+ GregorianCalendar gcal2 = cal2.toGregorianCalendar() ;
+ long x1 = gcal1.getTimeInMillis() ;
+ long x2 = gcal2.getTimeInMillis() ;
+ //return datatypefactory.newDurationDayTime(x1-x2) ;
+ return datatypefactory.newDuration(x1-x2) ;
+ }
+
+ // XSDFuncOps
+ private static boolean isDT(ValueSpaceClassification vs)
{
switch (vs)
{
case VSPACE_DATETIME:
case VSPACE_DATE:
case VSPACE_TIME:
- //case VSPACE_DURATION:
case VSPACE_G_YEAR:
- case VSPACE_G_YEARMONTH: case VSPACE_G_MONTHDAY:
- case VSPACE_G_MONTH: case VSPACE_G_DAY:
+ case VSPACE_G_YEARMONTH:
+ case VSPACE_G_MONTHDAY:
+ case VSPACE_G_MONTH:
+ case VSPACE_G_DAY:
return true ;
default:
return false ;
}
-
- }
-
-
- static XMLGregorianCalendar parsecal(String lex)
- {
- XMLGregorianCalendar cal = datatypefactory.newXMLGregorianCalendar(lex) ;
- QName qname = cal.getXMLSchemaType() ;
- String uri = qname.getNamespaceURI()+"#"+qname.getLocalPart() ;
- return cal ;
- }
-
- static XMLGregorianCalendar add(String lex1, String lex2)
- {
- System.out.println(lex1+" + "+lex2) ;
- XMLGregorianCalendar cal = datatypefactory.newXMLGregorianCalendar(lex1) ;
- Duration dur = datatypefactory.newDuration(lex2) ;
- cal.add(dur) ;
- System.out.println(str(cal)) ;
- return cal ;
- }
-
- private static String str(XMLGregorianCalendar cal)
- {
- QName qname = cal.getXMLSchemaType() ;
- return "'"+cal.toXMLFormat()+"'^^xs:"+qname.getLocalPart() ;
- }
-
-
- static Duration parsedur(String lex)
- {
- Duration dur = datatypefactory.newDuration(lex) ;
- String dt = "duration" ;
- if ( isYearMonth(dur) )
- dt = "yearMonth" ;
- if ( isDayTime(dur) )
- dt = "dayTime" ;
-// System.out.println("'"+dur+"'^^xs:"+dt) ;
- return dur ;
}
-
- // Spec is slightly unclear.
- // It defines it as PnDTnHnMnS
- // but also says "restrict to D/H/M/S i.e. not necessary required"
- // The examples include the shorter forms.
- static boolean isYearMonth(Duration dur)
+ // NodeFunctions
+ public static boolean isYearMonth(Duration dur)
{
+ // Not dur.getXMLSchemaType()
return ( dur.isSet(YEARS) || dur.isSet(MONTHS) ) &&
! dur.isSet(DAYS) && ! dur.isSet(HOURS) && ! dur.isSet(MINUTES) && ! dur.isSet(SECONDS) ;
}
- static boolean isDayTime(Duration dur)
+ // NodeFunctions
+ public static boolean isDayTime(Duration dur)
{
return !dur.isSet(YEARS) && ! dur.isSet(MONTHS) &&
( dur.isSet(DAYS) || dur.isSet(HOURS) || dur.isSet(MINUTES) || dur.isSet(SECONDS) );
Added: incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/projects/nodevalue/TestDateTimeOps.java
URL: http://svn.apache.org/viewvc/incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/projects/nodevalue/TestDateTimeOps.java?rev=1334490&view=auto
==============================================================================
--- incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/projects/nodevalue/TestDateTimeOps.java (added)
+++ incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/projects/nodevalue/TestDateTimeOps.java Sat May 5 20:36:25 2012
@@ -0,0 +1,56 @@
+/**
+ * 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 projects.nodevalue;
+
+import com.hp.hpl.jena.sparql.expr.NodeValue ;
+
+import org.junit.Test ;
+import org.openjena.atlas.junit.BaseTest ;
+
+public class TestDateTimeOps extends BaseTest
+{
+ @Test public void nv_add_1() { testAdd("12", "13", "25" ) ; }
+
+
+
+
+ @Test public void nv_sub_1() { testSub("12", "13", "-1" ) ; }
+
+
+ static void testAdd(String s1, String s2, String s3)
+ {
+ NodeValue nv1 = NodeValue.parse(s1) ;
+ NodeValue nv2 = NodeValue.parse(s2) ;
+ NodeValue nv3 = NodeValue.parse(s3) ;
+ NodeValue nv = NV2.addNV(nv1, nv2) ;
+ assertEquals(nv3, nv) ;
+ }
+
+ static void testSub(String s1, String s2, String s3)
+ {
+ NodeValue nv1 = NodeValue.parse(s1) ;
+ NodeValue nv2 = NodeValue.parse(s2) ;
+ NodeValue nv3 = NodeValue.parse(s3) ;
+ NodeValue nv = NV2.subNV(nv1, nv2) ;
+ assertEquals(nv3, nv) ;
+
+ }
+
+}
+