}
// NodeFunctions
public static NodeValue subtractionNV(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 ( vs1.equals(VSPACE_DURATION) && vs2.equals(VSPACE_DURATION) )
{
// A lot of testing to keep it as derived types.
boolean isDTDur = dtXSDdayTimeDuration.equals(nv1.getDatatypeURI()) &&
dtXSDdayTimeDuration.equals(nv2.getDatatypeURI()) ;
boolean isYMDur = dtXSDyearMonthDuration.equals(nv1.getDatatypeURI()) &&
dtXSDyearMonthDuration.equals(nv2.getDatatypeURI()) ;
Duration d3 = nv1.getDuration().subtract(nv2.getDuration()) ;
String lex = d3.toString() ;
Node n ;
if ( isDTDur )
n = NodeFactoryExtra.createLiteralNode(lex, null, dtXSDdayTimeDuration) ;
else if ( isYMDur )
n = NodeFactoryExtra.createLiteralNode(lex, null, dtXSDyearMonthDuration) ;
else
n = com.hp.hpl.jena.graph.NodeFactory.createLiteral(lex, XSDDatatype.XSDduration) ;
return NodeValue.makeNodeDuration(d3, n) ;
}
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 ( vs1.equals(VSPACE_DATETIME) && vs2.equals(VSPACE_DURATION) )
{
XMLGregorianCalendar cal = nv1.getDateTime() ;
// add-negation
XMLGregorianCalendar result = xsd_subtract(cal, nv2.getDuration()) ;
NodeValue r = NodeValue.makeDateTime(result) ;
return r ;
}
if ( vs1.equals(VSPACE_DATE) && vs2.equals(VSPACE_DURATION) )
{
XMLGregorianCalendar cal = nv1.getDateTime() ;
// add-negation
XMLGregorianCalendar result = xsd_subtract(cal, nv2.getDuration()) ;
NodeValue r = NodeValue.makeDate(result) ;
return r ;
}
if ( vs1.equals(VSPACE_TIME) && vs2.equals(VSPACE_DURATION) )
{
XMLGregorianCalendar cal = nv1.getDateTime() ;
// add-negation
XMLGregorianCalendar result = xsd_subtract(cal, nv2.getDuration()) ;
NodeValue r = NodeValue.makeNode(result.toXMLFormat(), XSDDatatype.XSDtime) ;