Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/develop' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
barthanssens committed Oct 27, 2022
2 parents b23c781 + 511339d commit e8c9c62
Show file tree
Hide file tree
Showing 16 changed files with 491 additions and 118 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*******************************************************************************
* Copyright (c) 2022 Eclipse RDF4J contributors.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/
package org.eclipse.rdf4j.query.algebra.evaluation.function.xsd;

import static javax.xml.datatype.DatatypeConstants.FIELD_UNDEFINED;

import static org.eclipse.rdf4j.model.datatypes.XMLDatatypeUtil.isValidDate;
import static org.eclipse.rdf4j.model.datatypes.XMLDatatypeUtil.isValidDateTime;
import static org.eclipse.rdf4j.model.vocabulary.XSD.DATE;
import static org.eclipse.rdf4j.model.vocabulary.XSD.DATETIME;
import static org.eclipse.rdf4j.model.vocabulary.XSD.STRING;

import javax.xml.datatype.XMLGregorianCalendar;

import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.query.algebra.evaluation.ValueExprEvaluationException;

/**
* A {@link org.eclipse.rdf4j.query.algebra.evaluation.function.Function} that tries to cast its argument to an
* <var>xsd:date</var>.
*/
public class DateCast extends CastFunction {

private static final String ZERO = "0";

@Override
protected IRI getXsdDatatype() {
return DATE;
}

@Override
protected boolean isValidForDatatype(String lexicalValue) {
return isValidDate(lexicalValue);
}

@Override
protected Literal convert(ValueFactory vf, Value value) throws ValueExprEvaluationException {
if (value instanceof Literal) {
Literal literal = (Literal) value;
IRI datatype = literal.getDatatype();

if (STRING.equals(datatype) || DATETIME.equals(datatype)) {
try {
XMLGregorianCalendar calValue = literal.calendarValue();
int year = calValue.getYear();
int month = calValue.getMonth();
int day = calValue.getDay();
int timezoneOffset = calValue.getTimezone();

if (FIELD_UNDEFINED != year && FIELD_UNDEFINED != month && FIELD_UNDEFINED != day) {
StringBuilder builder = new StringBuilder();
builder.append(year).append("-");
addZeroIfNeeded(month, builder);
builder.append(month).append("-");
addZeroIfNeeded(day, builder);
builder.append(day);

if (FIELD_UNDEFINED != timezoneOffset) {
int minutes = Math.abs(timezoneOffset);
int hours = minutes / 60;
minutes = minutes - (hours * 60);
builder.append(timezoneOffset > 0 ? "+" : "-");
addZeroIfNeeded(hours, builder);
builder.append(hours);
builder.append(":");
addZeroIfNeeded(minutes, builder);
builder.append(minutes);
}

return vf.createLiteral(builder.toString(), DATE);
} else {
throw typeError(literal, null);
}
} catch (IllegalArgumentException e) {
throw typeError(literal, e);
}
}
}
throw typeError(value, null);
}

private static void addZeroIfNeeded(int value, StringBuilder builder) {
if (value < 10) {
builder.append(ZERO);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ org.eclipse.rdf4j.query.algebra.evaluation.function.string.Substring
org.eclipse.rdf4j.query.algebra.evaluation.function.string.UpperCase
org.eclipse.rdf4j.query.algebra.evaluation.function.xsd.BooleanCast
org.eclipse.rdf4j.query.algebra.evaluation.function.xsd.ByteCast
org.eclipse.rdf4j.query.algebra.evaluation.function.xsd.DateCast
org.eclipse.rdf4j.query.algebra.evaluation.function.xsd.DateTimeCast
org.eclipse.rdf4j.query.algebra.evaluation.function.xsd.DecimalCast
org.eclipse.rdf4j.query.algebra.evaluation.function.xsd.DoubleCast
Expand All @@ -57,4 +58,4 @@ org.eclipse.rdf4j.query.algebra.evaluation.function.triple.IsTripleFunction
org.eclipse.rdf4j.query.algebra.evaluation.function.triple.StatementFunction
org.eclipse.rdf4j.query.algebra.evaluation.function.triple.TripleSubjectFunction
org.eclipse.rdf4j.query.algebra.evaluation.function.triple.TriplePredicateFunction
org.eclipse.rdf4j.query.algebra.evaluation.function.triple.TripleObjectFunction
org.eclipse.rdf4j.query.algebra.evaluation.function.triple.TripleObjectFunction
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*******************************************************************************
* Copyright (c) 2022 Eclipse RDF4J contributors.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/
package org.eclipse.rdf4j.query.algebra.evaluation.function.xsd;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.eclipse.rdf4j.model.datatypes.XMLDatatypeUtil.parseCalendar;
import static org.eclipse.rdf4j.model.vocabulary.XSD.DATE;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;

import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
import org.eclipse.rdf4j.query.algebra.evaluation.ValueExprEvaluationException;
import org.junit.Before;
import org.junit.Test;

public class TestDateCast {

private DateCast dateCast;
private final ValueFactory vf = SimpleValueFactory.getInstance();

@Before
public void setUp() throws Exception {
dateCast = new DateCast();
}

@Test
public void testCastPlainLiteral_date() {
testDateCast(vf.createLiteral("1999-09-09"), "1999-09-09");
}

@Test
public void testCastPlainLiteral_date_withTimeZone_utc() {
testDateCast(vf.createLiteral("1999-09-09Z"), "1999-09-09Z");
}

@Test
public void testCastPlainLiteral_date_withTimeZone_offset() {
testDateCast(vf.createLiteral("1999-09-09-06:00"), "1999-09-09-06:00");
}

@Test
public void testCastPlainLiteral_date_invalid() {
// Arrange
Literal plainLit = vf.createLiteral("1999-09-xx");

// Act & Assert
assertThatExceptionOfType(ValueExprEvaluationException.class).isThrownBy(() -> dateCast.evaluate(vf, plainLit));
}

@Test
public void testCastPlainLiteral_dateTime() {
testDateCast(vf.createLiteral("1999-09-09T14:45:13"), "1999-09-09");
}

@Test
public void testCastPlainLiteral_dateTime_withTimeZone_utc() {
testDateCast(vf.createLiteral("1999-09-09T14:45:13Z"), "1999-09-09-00:00");
}

@Test
public void testCastPlainLiteral_dateTime_withTimeZone_offset() {
testDateCast(vf.createLiteral("1999-09-09T14:45:13-06:00"), "1999-09-09-06:00");
}

@Test
public void testCastPlainLiteral_dateTime_invalid() {
// Arrange
Literal plainLit = vf.createLiteral("1999-09-09T14:45:xx");

// Act & Assert
assertThatExceptionOfType(ValueExprEvaluationException.class).isThrownBy(() -> dateCast.evaluate(vf, plainLit));
}

@Test
public void testCastDateLiteral() {
testDateCast(vf.createLiteral("2022-11-01Z", DATE), "2022-11-01Z");
}

@Test
public void testCastDateTimeLiteral() {
testDateCast(vf.createLiteral(parseCalendar("1999-09-09T14:45:13")), "1999-09-09");
}

@Test
public void testCastDateTimeLiteral_withTimeZone_utc() {
testDateCast(vf.createLiteral(parseCalendar("1999-09-09T14:45:13Z")), "1999-09-09-00:00");
}

@Test
public void testCastDateTimeLiteral_withTimeZone_offset() {
testDateCast(vf.createLiteral(parseCalendar("1999-09-09T14:45:13+03:00")), "1999-09-09+03:00");
}

private void testDateCast(Literal literal, String expected) {
// Arrange
Literal result = null;

// Act
try {
result = dateCast.evaluate(vf, literal);
} catch (ValueExprEvaluationException e) {
fail(e.getMessage());
}

// Assert
assertNotNull(result);
assertThat(result.getLabel()).isEqualTo(expected);
assertThat(result.getDatatype()).isEqualTo(DATE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ public class QueryEvaluationUtilityTest {

private Literal arg2year;

private Literal arg1date;

private Literal arg2date;

private Literal arg1dateTime;

private Literal arg2dateTime;
Expand Down Expand Up @@ -100,6 +104,9 @@ public void setUp() {
arg1year = f.createLiteral("2007", XSD.GYEAR);
arg2year = f.createLiteral("2009", XSD.GYEAR);

arg1date = f.createLiteral("2009-01-01", XSD.DATE);
arg2date = f.createLiteral("2007-01-01", XSD.DATE);

arg1dateTime = f.createLiteral("2009-01-01T20:20:20Z", XSD.DATETIME);
arg2dateTime = f.createLiteral("2007-01-01T20:20:20+02:00", XSD.DATETIME);

Expand Down Expand Up @@ -161,6 +168,7 @@ public void testCompareEQ() {
assertCompareTrue(arg1string, arg1string, EQ);
assertCompareTrue(arg1int, arg1int, EQ);
assertCompareTrue(arg1year, arg1year, EQ);
assertCompareTrue(arg1date, arg1date, EQ);
assertCompareTrue(arg1dateTime, arg1dateTime, EQ);
assertCompareTrue(arg1duration, arg1duration, EQ);
assertCompareTrue(arg1yearMonthDuration, arg1yearMonthDuration, EQ);
Expand Down Expand Up @@ -211,14 +219,24 @@ public void testCompareEQ() {
assertCompareException(arg1year, arg2string, EQ);
assertCompareException(arg1year, arg2int, EQ);
assertCompareFalse(arg1year, arg2year, EQ);
assertCompareFalse(arg1year, arg2date, EQ);
assertCompareFalse(arg1year, arg2dateTime, EQ);
assertCompareException(arg1year, arg2unknown, EQ);

assertCompareException(arg1date, arg2simple, EQ);
assertCompareFalse(arg1date, arg2en, EQ);
assertCompareException(arg1date, arg2string, EQ);
assertCompareException(arg1date, arg2int, EQ);
assertCompareFalse(arg1date, arg2year, EQ);
assertCompareFalse(arg1date, arg2date, EQ);
assertCompareException(arg1date, arg2unknown, EQ);

assertCompareException(arg1dateTime, arg2simple, EQ);
assertCompareFalse(arg1dateTime, arg2en, EQ);
assertCompareException(arg1dateTime, arg2string, EQ);
assertCompareException(arg1dateTime, arg2int, EQ);
assertCompareFalse(arg1dateTime, arg2year, EQ);
assertCompareFalse(arg1dateTime, arg2date, EQ);
assertCompareFalse(arg1dateTime, arg2dateTime, EQ);
assertCompareException(arg1dateTime, arg2unknown, EQ);

Expand All @@ -227,6 +245,7 @@ public void testCompareEQ() {
assertCompareException(arg1duration, arg2string, EQ);
assertCompareException(arg1duration, arg2int, EQ);
assertCompareException(arg1duration, arg2year, EQ);
assertCompareException(arg1duration, arg2date, EQ);
assertCompareException(arg1duration, arg2dateTime, EQ);
assertCompareException(arg1duration, arg2duration, EQ);
assertCompareFalse(arg1duration, arg2duration, EQ, false);
Expand All @@ -243,6 +262,7 @@ public void testCompareNE() {
assertCompareFalse(arg1string, arg1string, NE);
assertCompareFalse(arg1int, arg1int, NE);
assertCompareFalse(arg1year, arg1year, NE);
assertCompareFalse(arg1date, arg1date, NE);
assertCompareFalse(arg1dateTime, arg1dateTime, NE);
assertCompareException(arg1unknown, arg2unknown, NE);

Expand Down Expand Up @@ -291,14 +311,24 @@ public void testCompareNE() {
assertCompareException(arg1year, arg2string, NE);
assertCompareException(arg1year, arg2int, NE);
assertCompareTrue(arg1year, arg2year, NE);
assertCompareTrue(arg1year, arg2date, NE);
assertCompareTrue(arg1year, arg2dateTime, NE);
assertCompareException(arg1year, arg2unknown, NE);

assertCompareException(arg1date, arg2simple, NE);
assertCompareTrue(arg1date, arg2en, NE);
assertCompareException(arg1date, arg2string, NE);
assertCompareException(arg1date, arg2int, NE);
assertCompareTrue(arg1date, arg2year, NE);
assertCompareTrue(arg1date, arg2date, NE);
assertCompareException(arg1date, arg2unknown, NE);

assertCompareException(arg1dateTime, arg2simple, NE);
assertCompareTrue(arg1dateTime, arg2en, NE);
assertCompareException(arg1dateTime, arg2string, NE);
assertCompareException(arg1dateTime, arg2int, NE);
assertCompareTrue(arg1dateTime, arg2year, NE);
assertCompareTrue(arg1dateTime, arg2date, NE);
assertCompareTrue(arg1dateTime, arg2dateTime, NE);
assertCompareException(arg1dateTime, arg2unknown, NE);

Expand All @@ -307,6 +337,7 @@ public void testCompareNE() {
assertCompareException(arg1duration, arg2string, NE);
assertCompareException(arg1duration, arg2int, NE);
assertCompareException(arg1duration, arg2year, NE);
assertCompareException(arg1duration, arg2date, NE);
assertCompareException(arg1duration, arg2dateTime, NE);
assertCompareException(arg1duration, arg2duration, NE);
assertCompareTrue(arg1duration, arg2duration, NE, false);
Expand All @@ -325,6 +356,7 @@ public void testCompareLT() {
assertCompareFalse(arg1string, arg1string, LT);
assertCompareFalse(arg1int, arg1int, LT);
assertCompareFalse(arg1year, arg1year, LT);
assertCompareFalse(arg1date, arg1date, LT);
assertCompareFalse(arg1dateTime, arg1dateTime, LT);
assertCompareException(arg1unknown, arg2unknown, LT);

Expand Down Expand Up @@ -361,21 +393,35 @@ public void testCompareLT() {
assertCompareException(arg1year, arg2int, LT);
assertCompareTrue(arg1year, arg2year, LT);

// comparison between xsd:gYear and xsd:dateTime should raise type error in strict mode
// comparison between xsd:gYear and xsd:dateTime & xsd:date should raise type error in strict mode
assertCompareException(arg1year, arg1date, LT);
assertCompareException(arg1year, arg1dateTime, LT);

// ... but should succeed in extended mode.
assertCompareTrue(arg1year, arg1date, LT, false);
assertCompareTrue(arg1year, arg1dateTime, LT, false);

assertCompareException(arg1year, arg2date, LT);
assertCompareException(arg1year, arg2dateTime, LT);
assertCompareException(arg1year, arg2unknown, LT);

assertCompareException(arg1date, arg2simple, LT);
assertCompareException(arg1date, arg2en, LT);
assertCompareException(arg1date, arg2string, LT);
assertCompareException(arg1date, arg2int, LT);
assertCompareFalse(arg1date, arg1year, LT, false);
assertCompareException(arg1date, arg2year, LT);
assertCompareFalse(arg1date, arg2date, LT);
assertCompareFalse(arg1date, arg2dateTime, LT);
assertCompareException(arg1date, arg2unknown, LT);

assertCompareException(arg1dateTime, arg2simple, LT);
assertCompareException(arg1dateTime, arg2en, LT);
assertCompareException(arg1dateTime, arg2string, LT);
assertCompareException(arg1dateTime, arg2int, LT);
assertCompareFalse(arg1dateTime, arg1year, LT, false);
assertCompareException(arg1dateTime, arg2year, LT);
assertCompareFalse(arg1dateTime, arg2date, LT);
assertCompareFalse(arg1dateTime, arg2dateTime, LT);
assertCompareException(arg1dateTime, arg2unknown, LT);

Expand All @@ -384,6 +430,7 @@ public void testCompareLT() {
assertCompareException(arg1duration, arg2string, LT);
assertCompareException(arg1duration, arg2int, LT);
assertCompareException(arg1duration, arg2year, LT);
assertCompareException(arg1duration, arg2date, LT);
assertCompareException(arg1duration, arg2dateTime, LT);
assertCompareException(arg1duration, arg2duration, LT);
assertCompareTrue(arg1duration, arg2duration, LT, false);
Expand All @@ -396,6 +443,7 @@ public void testCompareLT() {
assertCompareException(arg1yearMonthDuration, arg2string, LT);
assertCompareException(arg1yearMonthDuration, arg2int, LT);
assertCompareException(arg1yearMonthDuration, arg2year, LT);
assertCompareException(arg1yearMonthDuration, arg2date, LT);
assertCompareException(arg1yearMonthDuration, arg2dateTime, LT);
assertCompareException(arg1yearMonthDuration, arg2duration, LT);
assertCompareTrue(arg1yearMonthDuration, arg2duration, LT, false);
Expand Down
Loading

0 comments on commit e8c9c62

Please sign in to comment.