Skip to content

Commit

Permalink
GH-3587 CoreDatatype enum for literals (#3596)
Browse files Browse the repository at this point in the history
  • Loading branch information
hmottestad authored Jan 19, 2022
1 parent 8faacbc commit 55f932e
Show file tree
Hide file tree
Showing 37 changed files with 2,305 additions and 676 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.Statement;
import org.eclipse.rdf4j.model.base.CoreDatatype;
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
import org.eclipse.rdf4j.model.vocabulary.XSD;
import org.eclipse.rdf4j.repository.sail.SailRepository;
Expand Down Expand Up @@ -390,6 +391,19 @@ public void testRejectedDatatypes() {
assertEquals("Is the fourth literal accepted?", false, index.accept(literal4));
}

@Test
public void testRejectedCoreDatatypes() {
Literal literal1 = fac.createLiteral("hi there");
Literal literal2 = fac.createLiteral("hi there, too", CoreDatatype.XSD.STRING);
Literal literal3 = fac.createLiteral("1.0");
Literal literal4 = fac.createLiteral("1.0", CoreDatatype.XSD.FLOAT);

assertEquals("Is the first literal accepted?", true, index.accept(literal1));
assertEquals("Is the second literal accepted?", true, index.accept(literal2));
assertEquals("Is the third literal accepted?", true, index.accept(literal3));
assertEquals("Is the fourth literal accepted?", false, index.accept(literal4));
}

private void assertStatement(Statement statement) throws Exception {
SearchDocument document = index.getDocument(statement.getSubject(), statement.getContext());
if (document == null) {
Expand Down
38 changes: 28 additions & 10 deletions core/model-api/src/main/java/org/eclipse/rdf4j/model/Literal.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

import javax.xml.datatype.XMLGregorianCalendar;

import org.eclipse.rdf4j.model.base.CoreDatatype;

/**
* An RDF-1.1 literal consisting of a label (the lexical value), a datatype, and optionally a language tag.
*
Expand Down Expand Up @@ -144,12 +146,12 @@ default boolean isLiteral() {

/**
* Retrieves the {@link TemporalAccessor temporal accessor} value of this literal.
*
*
* <p>
* A temporal accessor representation can be given for literals whose label conforms to the syntax of the following
* <a href="https://www.w3.org/TR/xmlschema11-2">XML Schema 1.1</a> date/time datatypes:
* </p>
*
*
* <ul>
*
* <li><a href="https://www.w3.org/TR/xmlschema11-2/#dateTime">xsd:dateTime</a>,</li>
Expand All @@ -161,24 +163,24 @@ default boolean isLiteral() {
* <li><a href="https://www.w3.org/TR/xmlschema11-2/#gMonthDay">xsd:gMonthDay</a>,</li>
* <li><a href="https://www.w3.org/TR/xmlschema11-2/#gDay">xsd:gDay</a>,</li>
* <li><a href="https://www.w3.org/TR/xmlschema11-2/#gMonth">xsd:gMonth</a>.</li>
*
*
* </ul>
*
*
* <p>
* Temporal accessor representations may be converted to specific {@link java.time} values like
* {@link OffsetDateTime} using target static factory methods, for instance
* {@code OffsetDateTime.from(literal.temporalAccessorValue())}.
* </p>
*
*
* <p>
* Note however that {@link java.time} doesn't include dedicated classes for some legal XML Schema date/time values,
* like offset dates (for instance, {@code 2020-11-16+01:00}) and {@code xsd:gDay} (for instance, {@code ---16}).
* </p>
*
*
* @return the temporal accessor value of this literal
*
* @throws DateTimeException if this literal cannot be represented by a {@link TemporalAccessor} value
*
*
* @since 3.5.0
* @author Alessandro Bollini
*
Expand All @@ -192,7 +194,7 @@ default boolean isLiteral() {
* Datatypes Second Edition</a>: it is not included among temporal datatypes automatically assigned by
* {@link ValueFactory#createLiteral(TemporalAmount)} in order to provide better interoperability with the
* latter version of the standard.
*
*
* @implSpec The default method implementation throws an {@link UnsupportedOperationException} and is only supplied
* as a stop-gap measure for backward compatibility: concrete classes implementing this interface are
* expected to override it.
Expand All @@ -209,7 +211,7 @@ default TemporalAccessor temporalAccessorValue() throws DateTimeException {
* <a href="https://www.w3.org/TR/xmlschema-2/">XML Schema 2</a>
* <a href="https://www.w3.org/TR/xmlschema-2/#duration">xsd:duration</a> datatype.
* </p>
*
*
* <p>
* The adoption of the <a href="https://www.w3.org/TR/xmlschema-2/">XML Schema 2</a> definition is a known deviation
* from the <a href="http://www.w3.org/TR/rdf11-concepts/#section-Graph-Literal">RDF 1.1</a> standard;
Expand All @@ -225,7 +227,7 @@ default TemporalAccessor temporalAccessorValue() throws DateTimeException {
* Note however that {@link java.time} doesn't include dedicated classes for legal XML Schema duration values
* including both date and time components (for instance, {@code P1YT23H}).
* </p>
*
*
* @return the temporal amount value of this literal
*
* @throws DateTimeException if this literal cannot be represented by a {@link TemporalAmount} value
Expand Down Expand Up @@ -267,6 +269,22 @@ default TemporalAmount temporalAmountValue() throws DateTimeException {
*/
XMLGregorianCalendar calendarValue();

/**
* CoreDatatype is an interface for natively supported datatypes in RDF4J. This includes, among others, the XML
* Schema datatypes and rdf:langString. CoreDatatypes are implemented as enums and more performant and convenient to
* work with than IRI-based datatypes. The constant {@link CoreDatatype#NONE)} is used to represent a datatype that
* is not one of the supported core datatypes.
*
* @return The CoreDatatype or {@link CoreDatatype#NONE)} if the datatype matches none of the core datatypes. This
* method will not return null.
*
* @implNote This method may not return null. Returning {@link CoreDatatype#NONE)} is only permitted if the datatype
* does not match any of the core datatypes. A literal with a language tag must return
* {@link CoreDatatype.RDF#LANGSTRING)}. A literal without a specified datatype must return
* {@link CoreDatatype.XSD#STRING)}.
*/
CoreDatatype getCoreDatatype();

/**
* Compares this literal to another object.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

import javax.xml.datatype.XMLGregorianCalendar;

import org.eclipse.rdf4j.model.base.CoreDatatype;

/**
* A factory for creating {@link IRI IRIs}, {@link BNode blank nodes}, {@link Literal literals} and {@link Statement
* statements} based on the RDF-1.1 Concepts and Abstract Syntax, a W3C Recommendation.
Expand Down Expand Up @@ -90,6 +92,14 @@ public interface ValueFactory {
*/
Literal createLiteral(String label, IRI datatype);

/**
* Creates a new literal with the supplied label and datatype.
*
* @param label The literal's label, must not be <var>null</var>.
* @param datatype The literal's datatype. It may not be null.
*/
Literal createLiteral(String label, CoreDatatype datatype);

/**
* Creates a new <var>xsd:boolean</var>-typed literal representing the specified value.
*
Expand Down
Loading

0 comments on commit 55f932e

Please sign in to comment.