Anzo.java Type Conversion
The Anzo.java API supports convenient conversions between native Java types and RDF typed literals. The following tables describe the supported conversions:
Java to RDF
| Java Native Type | RDF Literal Datatype |
| java.lang.Boolean | xsd:boolean |
| java.lang.Byte | xsd:byte |
| java.lang.Double | xsd:double |
| java.lang.Float | xsd:float |
| java.lang.Integer | xsd:int |
| java.lang.Long | xsd:long |
| java.lang.Short | xsd:short |
| java.lang.String | xsd:string |
| byte[] | xsd:base64Binary |
| java.math.BigDecimal | xsd:decimal |
| java.math.BigInteger | xsd:integer |
| java.util.Calendar | xsd:dateTime (with timezone from the Calendar) |
| java.util.Date | xsd:dateTime (time zone is GMT) |
| java.sql.Timestamp | xsd:dateTime (time zone is GMT) |
| java.sql.Time | xsd:date (without time zone) |
| java.sql.Date | xsd:time (without time zone) |
| javax.xml.datatype.XMLGregorianCalendar | Either xsd:dateTime, xsd:date, xsd:time, xsd:gYearMonth, xsd:gYear, xsd:gMonthDay, xsd:gDay, or xsd:gMonth depending on the type returned by calling XMLGregorianCalendar#getXMLSchemaType. If that method throws an exception then no conversion can happen. |
| javax.xml.datatype.Duration | Either xsd:duration, xsd:dayTimeDuration, or xsd:yearMonthDuration depending on the type returned by calling Duration#getXMLSchemaType. If that method throws an exception then no conversion can happen. NOTE: The xsd:dayTimeDuration and xsd:yearMonthDuration types are in the XML Schema namespace but are defined in the XQuery 1.0 and XPath 2.0 Data Model Specification. |
| org.openanzo.rdf.URI | xsd:anyURI |
RDF to Java
| RDF Literal Datatype | Java Native Type |
| xsd:anyURI | org.openanzo.rdf.URI |
| xsd:base64Binary | byte[] |
| xsd:hexBinary | byte[] |
| xsd:boolean | java.lang.Boolean |
| xsd:byte | java.lang.Byte |
| xsd:double | java.lang.Double |
| xsd:float | java.lang.Float |
| xsd:integer | java.math.BigInteger |
| xsd:int | java.lang.Integer |
| xsd:long | java.lang.Long |
| xsd:short | java.lang.Short |
| xsd:string | java.lang.String |
| xsd:unsignedInt | java.lang.Long |
| xsd:unsignedShort | java.lang.Integer |
| xsd:unsignedByte | java.lang.Short |
| xsd:decimal | java.math.BigDecimal |
| xsd:dateTime | javax.xml.datatype.XMLGregorianCalendar |
| xsd:date | javax.xml.datatype.XMLGregorianCalendar |
| xsd:time | javax.xml.datatype.XMLGregorianCalendar |
| xsd:gYearMonth | javax.xml.datatype.XMLGregorianCalendar |
| xsd:gYear | javax.xml.datatype.XMLGregorianCalendar |
| xsd:gMonthDay | javax.xml.datatype.XMLGregorianCalendar |
| xsd:gDay | javax.xml.datatype.XMLGregorianCalendar |
| xsd:gMonth | javax.xml.datatype.XMLGregorianCalendar |
| xsd:duration | javax.xml.datatype.Duration |
| xsd:dayTimeDuration | javax.xml.datatype.Duration |
| xsd:yearMonthDuration | javax.xml.datatype.Duration |
| rdf:XMLLiteral | java.lang.String |
In the previous tables, the prefix xsd refers to http://www.w3.org/2001/XMLSchema# and the prefix rdf refers to http://www.w3.org/1999/02/22-rdf-syntax-ns#.
These tables apply to Jastor as well. When Jastor sees a property with a range defined as being one of the supported dates, it will generate an interface that uses the corresponding Java type. For unsupported range types, the interface will simply use the Literal Java type.
To convert from Java native types to RDF typed literals, use the ValueFactory.createTypedLiteral() method or various forms of the ValueFactory.createLiteral() method like ValueFactory.createLiteral(boolean). For example:
import org.openanzo.rdf.TypedLiteral; import org.openanzo.rdf.Constants; import java.util.Date; //... TypedLiteral l = Constants.valueFactory.createTypedLiteral(new Date()); TypedLiteral l2 = Constants.valueFactory.createLiteral(true);
To retrieve a typed literal as its native Java value, use the TypedLiteral.getNativeValue() method. For example,
// Load a graph from the repository and retrieve a
// birthdate as a Java XMLGregorianCalendar.
AnzoClient client = new AnzoClient(getDefaultClientConfiguration());
client.connect();
ClientGraph graph = client.getReplicaGraph(Constants.valueFactory.createURI("http://example.org/graph1");
Iterator<Statement> stmts = graph.find(Constants.valueFactory.createResource("http://example.org/resource1"),
Constants.valueFactory.createURI("http://example.org/birthdate"),
null);
Statement s = stmts.next();
TypedLiteral l = (TypedLiteral)s.getObject();
XMLGregorianCalendar cal = l.getNativeValue();
Anzo.js Type Conversion
The anzo.js API supports conversion from native ECMAScript (JavaScript) types to RDF typed literals and vice versa.
From ECMAScript to RDF literals
There are multiple ways to convert a native ECMAScript type into an RDF literal. If you want to create an RDF typed literal, you can use the anzo.createTypedLiteral method. For example:
dojo.require("anzo.rdf.Statement");
var lit = anzo.createTypedLiteral(new Date());
When you invoke anzo.createTypedLiteral with just one argument, the datatype used for the RDF literal is based on the input argument. The following table documents the datatype automatically chosen:
| ECMAScript type | Default RDF datatype |
| string or String | xsd:string |
| number or Number | xsd:double |
| boolean or Boolean | xsd:boolean |
| function or Function | xsd:string |
| array or Array | xsd:string |
| Date | xsd:dateTime |
| anzo.rdf.URI | xsd:anyURI |
| object or Object | xsd:string |
All of the basic methods that manipulate graphs in Anzo.js can automatically create typed literals based on the input argument.
dojo.require("anzo.rdf.NamedGraph");
var graph = new anzo.rdf.NamedGraph("http://example.org/graph1");
var date = new Date();
// Adds a typed literal of type xsd:dateTime
graph.add("http://example.org/subject",
"http://example.org/predicate",
date);
graph.find(null, null, date);
graph.contains(null, null, date);
However, when passing the native value directly into graph methods (like add, remove, find, contains, etc.), the values that resolve to xsd:string as the default RDF datatype in the table above, will be converted to plain RDF literals. If you must be sure that a typed literal is created, then use the anzo.createTypedLiteral method. For example:
graph.add("http://example.org/subject",
"http://example.org/predicate",
anzo.createTypedLiteral("hello", "xsd:string");
Sometimes the default RDF datatype isn't exactly what you want. For example, you might want to convert an ECMAScript Number to xsd:int instead of the default xsd:double. For those situations, you can use the second argument of the anzo.createTypedLiteral method.
dojo.require("anzo.rdf.Statement");
var lit = anzo.createTypedLiteral(42, "xsd:int");
When you pass a requested RDF datatype in the second argument to anzo.createTypedLiteral, it tries to convert the value of the first argument into the lexical form required by the requested datatype. There are various conversions supported. The full list is described in the following table:
Allowed Conversions:
| ECMAScript type | Requested RDF datatype | Conversion Notes |
| string or String | any datatype | The string value is used verbatim. |
| number or Number | xsd:double | Converted to format specified by XML Schema spec, including NaN, INF, and -INF. |
| number or Number | xsd:float | Converted to format specified by XML Schema spec, including NaN, INF, and -INF. Note that most ECMAScript implementation store their numbers internally as in double precision IEEE 754 floating point representation. So conversions to this type may yield invalid xsd:float values since xsd:float's value space is that of the numbers representable in single precision IEEE 754 floating point representation. |
| number or Number | xsd:decimal | Converted to format specified by XML Schema spec. Number.NaN, Number.POSITIVE_INFINITY, and Number.NEGATIVE_INFINITY cannot be represented in xsd:decimal, so a conversion error is thrown in that case. |
| number or Number | xsd:integer, xsd:int, xsd:negativeInteger, xsd:long, xsd:short, xsd:byte, xsd:nonNegativeInteger, xsd:unsignedLong, xsd:unsignedInt, xsd:unsignedShort, xsd:unsignedByte, xsd:positiveInteger | Converted to a string by calling Number.toFixed(0). Note that toFixed will round values that aren't already integers. Also note that the value is not checked to ensure that it is within the allowable range for the RDF datatype (such as ensuring that xsd:byte values aren't greater that 127. Number.NaN, Number.POSITIVE_INFINITY, and Number.NEGATIVE_INFINITY cannot be represented in XSD integral types, so a conversion error is thrown in that case. |
| number or Number | xsd:string | Converted using the same format as xsd:double |
| boolean or Boolean | xsd:boolean or xsd:string | Converted to the strings "true" or "false". |
| array or Array | xsd:string | Converted to a string via the toString method. |
| Date | xsd:dateTime or xsd:string | Converted to a string conforming to the xsd:dateTime format using UTC as the time zone. |
| Date | xsd:date, xsd:time, xsd:gYearMonth, xsd:gMonthDay, xsd:gYear, xsd:gMonth, xsd:gDay | Converted to a string in the format of the requested XML Schema datatype. The Date object is interpreted in the local time zone and the final string is output without a timezone indicator. |
| anzo.rdf.URI | xsd:anyURI or xsd:string | The URI is used verbatim. |
| object or Object | xsd:string | Converted to a string via the toString method. |
If a combination of ECMAScript type and RDF datatype isn't mentioned in the Allowed Conversions table above, then that conversion is not supported and an error is thrown.
You can also create plain RDF literals (and RDF literals with language tags) while still taking advantage of the conversion from ECMAScript types to RDF lexical datatypes. The anzo.createLiteral method supplies that functionality. For example,
dojo.require("anzo.rdf.Statement");
var lit = anzo.createLiteral(42.4);
That example creates a plain RDF literal with the value "42.4". The anzo.createLiteral method will convert to the lexical form prescribed by the default RDF datatype from the table above.
RDF to ECMAScript
When retrieving RDF data, Anzo.js provides convenient conversions from RDF typed literals to native ECMAScript types. You can retrieve a literal's corresponding native object using the getNativeValue method. For example:
// Find all statements that use the Dublin Core's 'date' property. var statements = graph.find(null, "dc:date", null); var date = statements[0].object.getNativeValue(); // Work with the ECMAScript Date var year = date.getYear();
Not every literal can be converted to a native ECMAScript type. The supported conversions are given by the following table:
| RDF Literal Datatype | ECMAScript Native Type |
| xsd:string | String |
| xsd:anyURI | String |
| xsd:boolean | Boolean |
| xsd:decimal, xsd:double, xsd:float, xsd:integer, xsd:int, xsd:negativeInteger, xsd:long, xsd:short, xsd:byte, xsd:nonNegativeInteger, xsd:unsignedLong, xsd:unsignedInt, xsd:unsignedShort, xsd:unsignedByte, or xsd:positiveInteger. | Number Note that not all values are representable in ECMAScript. For example, xsd:decimal allows arbitrary precision decimal numbers but ECMAScript implementations typically only support IEEE 754 double precision floating point numbers. |
| xsd:dateTime | Date. Note that the local time zone, as it existed at the particular date, is used if lexical value does not specify a time zone. For example, if my time zone is "America/New York", then a literal without a time zone in January like "2008-01-05T05:04:44" is considered to have an offset from UTC of -05:00. However, in the "America/New York" time zone, a literal in July like "2008-07-29T08:09:32" is considered to have an offset from UTC of -04:00 due to daylight savings time. |
| xsd:date | Date. The time portion is considered to be 00:00:00. Note that the local time zone, as it existed at the particular date, is used if lexical value does not specify a time zone. For example, if my time zone is "America/New York", then a literal without a time zone in January like "2008-01-05" is considered to have an offset from UTC of -05:00. However, in the "America/New York" time zone, a literal in July like "2008-07-29" is considered to have an offset from UTC of -04:00 due to daylight savings time. |
| xsd:time | Date. The date portion is considered to be 1970-01-01. Note that the local time zone, as it existed in January 1, 1970, is used if lexical value does not specify a time zone. For example, if my time zone is "America/New York", then a literal without a time zone "05:04:44" is considered to have an offset from UTC of -05:00 since that is the offset for "America/New York" in January 1, 1970. |
| xsd:gYearMonth, xsd:gMonthDay, xsd:gYear, xsd:gMonth, xsd:gDay | Date. The unspecified portions of a full moment in time are taken from the start of the epoch date (1970-01-01T00:00:00). For example, for an xsd:gYearMonth literal like "2010-07", the ECMAScript Date object created will represent 2010-07-01T00:00:00. Similarly, for a xsd:gDay literal like "---17", the ECMAScript Date object created will represent 1970-01-17T00:00:00. Note that the local time zone, as it existed at the particular full date and time, is used always, regardless of any time zone offset specified in the literal string. For example, if my time zone is "America/New York", then a literal like "---17" is considered to have an offset from UTC of -05:00 Because that is the offset of "America/New York" in January 17th. Similarly, a literal like "--07-29+10:00" also evaluated in the "America/New York" time zone is considered to have an offset of offset from UTC of -04:00. That's because the +10:00 offset is ignored for these types and since July 29th in the "America/New York" time zone has an offset of -04:00 due to daylight savings time. |
| rdf:XMLLiteral | String |


