/**
* 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 org.apache.jena.jdbc.utils;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.Date;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.HashSet;
import java.util.Set;
import org.apache.jena.graph.Node ;
import org.apache.jena.sparql.expr.NodeValue ;
import org.apache.jena.sparql.util.NodeFactoryExtra ;
import org.apache.jena.vocabulary.XSD ;
/**
* Class with helpful utility methods for Jena JDBC
*
*/
public class JdbcNodeUtils {
private static Set<String> numericTypes = new HashSet<String>();
static {
numericTypes.add(XSD.decimal.getURI());
numericTypes.add(XSD.integer.getURI());
numericTypes.add(XSD.negativeInteger.getURI());
numericTypes.add(XSD.nonNegativeInteger.getURI());
numericTypes.add(XSD.nonPositiveInteger.getURI());
numericTypes.add(XSD.unsignedByte.getURI());
numericTypes.add(XSD.unsignedInt.getURI());
numericTypes.add(XSD.unsignedLong.getURI());
numericTypes.add(XSD.unsignedShort.getURI());
numericTypes.add(XSD.xbyte.getURI());
numericTypes.add(XSD.xdouble.getURI());
numericTypes.add(XSD.xfloat.getURI());
numericTypes.add(XSD.xint.getURI());
numericTypes.add(XSD.xlong.getURI());
numericTypes.add(XSD.xshort.getURI());
}
/**
* Private constructor prevents instantiation
*/
private JdbcNodeUtils() {
}
/**
* Tries to convert a node to a boolean
*
* @param n
* Node
* @return Boolean
* @throws SQLException
* Thrown if the node cannot be converted
*/
public static boolean toBoolean(Node n) throws SQLException {
try {
if (n == null)
return false;
if (n.isLiteral()) {
if (n.getLiteralDatatypeURI().equals(XSD.xboolean.getURI())) {
return Boolean.parseBoolean(n.getLiteralLexicalForm());
} else if (hasNumericDatatype(n)) {
return parseAsInteger(n) == 0 ? false : true;
} else {
throw new SQLException("Unable to marshal the given literal to a boolean");
}
} else {
throw new SQLException("Unable to marshal a non-literal to a boolean");
}
} catch (SQLException e) {
// Throw as is
throw e;
} catch (Exception e) {
// Wrap other exceptions
throw new SQLException("Unable to marshal the value to a boolean", e);
}
}
/**
* Tries to convert a node to a byte
*
* @param n
* Node
* @return Byte
* @throws SQLException
* Thrown if the node cannot be converted
*/
public static byte toByte(Node n) throws SQLException {
try {
if (n == null)
return 0;
if (n.isLiteral()) {
return Byte.decode(n.getLiteralLexicalForm());
} else {
throw new SQLException("Unable to marshal a non-literal to a byte");
}
} catch (SQLException e) {
// Throw as is
throw e;
} catch (Exception e) {
// Wrap other exceptions
throw new SQLException("Unable to marshal the value to a byte", e);
}
}
/**
* Tries to convert a node to a short integer
*
* @param n
* Node
* @return Short Integer
* @throws SQLException
* Thrown if the node cannot be converted
*/
public static short toShort(Node n) throws SQLException {
try {
if (n == null)
return 0;
if (n.isLiteral()) {
return Short.parseShort(n.getLiteralLexicalForm());
} else {
throw new SQLException("Unable to marshal a non-literal to an integer");
}
} catch (SQLException e) {
// Throw as is
throw e;
} catch (Exception e) {
// Wrap other exceptions
throw new SQLException("Unable to marshal the value to an integer", e);
}
}
/**
* Tries to convert a node to an integer
*
* @param n
* Node
* @return Integer
* @throws SQLException
* Thrown if the node cannot be converted
*/
public static int toInt(Node n) throws SQLException {
try {
if (n == null)
return 0;
if (n.isLiteral()) {
return NodeFactoryExtra.nodeToInt(n);
} else {
throw new SQLException("Unable to marshal a non-literal to an integer");
}
} catch (SQLException e) {
// Throw as is
throw e;
} catch (Exception e) {
// Wrap other exceptions
throw new SQLException("Unable to marshal the value to an integer", e);
}
}
/**
* Tries to convert a node to a long integer
*
* @param n
* Node
* @return Long Integer
* @throws SQLException
* Thrown if the node cannot be converted
*/
public static long toLong(Node n) throws SQLException {
try {
if (n == null)
return 0;
if (n.isLiteral()) {
return NodeFactoryExtra.nodeToLong(n);
} else {
throw new SQLException("Unable to marshal a non-literal to a long integer");
}
} catch (SQLException e) {
// Throw as is
throw e;
} catch (Exception e) {
// Wrap other exceptions
throw new SQLException("Unable to marshal the value to a long integer", e);
}
}
/**
* Tries to convert a node to a float
*
* @param n
* Node
* @return Float
* @throws SQLException
* Thrown if the node cannot be converted
*/
public static float toFloat(Node n) throws SQLException {
try {
if (n == null)
return 0;
if (n.isLiteral()) {
return NodeFactoryExtra.nodeToFloat(n);
} else {
throw new SQLException("Unable to marshal a non-literal to a float");
}
} catch (SQLException e) {
// Throw as is
throw e;
} catch (Exception e) {
// Wrap other exceptions
throw new SQLException("Unable to marshal the value to a float", e);
}
}
/**
* Tries to convert a node to a double
*
* @param n
* Node
* @return Double
* @throws SQLException
* Thrown if the node cannot be converted
*/
public static double toDouble(Node n) throws SQLException {
try {
if (n == null)
return 0;
if (n.isLiteral()) {
return NodeFactoryExtra.nodeToDouble(n);
} else {
throw new SQLException("Unable to marshal a non-literal to a double");
}
} catch (SQLException e) {
// Throw as is
throw e;
} catch (Exception e) {
// Wrap other exceptions
throw new SQLException("Unable to marshal the value to a double", e);
}
}
/**
* Tries to convert a node to a decimal
*
* @param n
* Node
* @return Decimal
* @throws SQLException
* Thrown if the node cannot be converted
*/
public static BigDecimal toDecimal(Node n) throws SQLException {
try {
if (n == null)
return null;
if (n.isLiteral()) {
return new BigDecimal(n.getLiteralLexicalForm());
} else {
throw new SQLException("Unable to marshal a non-literal to a decimal");
}
} catch (SQLException e) {
// Throw as is
throw e;
} catch (Exception e) {
// Wrap other exceptions
throw new SQLException("Unable to marshal the value to a decimal", e);
}
}
/**
* Tries to convert a node to a date
*
* @param n
* Node
* @return Date
* @throws SQLException
* Thrown if the node cannot be converted
*/
public static Date toDate(Node n) throws SQLException {
try {
if (n == null)
return null;
if (n.isLiteral()) {
return new Date(NodeValue.xmlDatatypeFactory.newXMLGregorianCalendar(n.getLiteralLexicalForm())
.toGregorianCalendar().getTimeInMillis());
} else {
throw new SQLException("Unable to marshal a non-literal to a date");
}
} catch (SQLException e) {
// Throw as is
throw e;
} catch (Exception e) {
// Wrap other exceptions
throw new SQLException("Unable to marshal the value to a date", e);
}
}
/**
* Tries to convert a node to a time
*
* @param n
* Node
* @return Time
* @throws SQLException
* Thrown if the node cannot be converted
*/
public static Time toTime(Node n) throws SQLException {
try {
if (n == null)
return null;
if (n.isLiteral()) {
return new Time(NodeValue.xmlDatatypeFactory.newXMLGregorianCalendar(n.getLiteralLexicalForm())
.toGregorianCalendar().getTimeInMillis());
} else {
throw new SQLException("Unable to marshal a non-literal to a time");
}
} catch (SQLException e) {
// Throw as is
throw e;
} catch (Exception e) {
// Wrap other exceptions
throw new SQLException("Unable to marshal the value to a time", e);
}
}
/**
* Tries to convert a node to a timestamp
*
* @param n
* Node
* @return Timestamp
* @throws SQLException
* Thrown if the node cannot be converted
*/
public static Timestamp toTimestamp(Node n) throws SQLException {
try {
if (n == null)
return null;
if (n.isLiteral()) {
return new Timestamp(NodeValue.xmlDatatypeFactory.newXMLGregorianCalendar(n.getLiteralLexicalForm())
.toGregorianCalendar().getTimeInMillis());
} else {
throw new SQLException("Unable to marshal a non-literal to a timestamp");
}
} catch (SQLException e) {
// Throw as is
throw e;
} catch (Exception e) {
// Wrap other exceptions
throw new SQLException("Unable to marshal the value to a timestamp", e);
}
}
/**
* Tries to convert a noew to a string
*
* @param n
* Node
* @return String
* @throws SQLException
* Thrown if the node cannot be converted
*/
public static String toString(Node n) throws SQLException {
try {
if (n == null)
return null;
if (n.isURI()) {
return n.getURI();
} else if (n.isLiteral()) {
return n.getLiteralLexicalForm();
} else if (n.isBlank()) {
return n.getBlankNodeLabel();
} else if (n.isVariable()) {
return n.getName();
} else {
throw new SQLException("Unable to marshal unknown node types to a string");
}
} catch (SQLException e) {
// Throw as is
throw e;
} catch (Exception e) {
// Wrap other exceptions
throw new SQLException("Unable to marshal the value to a string", e);
}
}
/**
* Tries to convert a node to a URL
*
* @param n
* Node
* @return URL or null
* @throws SQLException
* Thrown if the node cannot be converted
*/
public static URL toURL(Node n) throws SQLException {
try {
if (n == null)
return null;
if (n.isURI()) {
return new URL(n.getURI());
} else {
throw new SQLException("Unable to marshal a non-uri to a URL");
}
} catch (SQLException e) {
// Throw as is
throw e;
} catch (Exception e) {
// Wrap other exceptions
throw new SQLException("Unable to marshal the value to a URL", e);
}
}
private static long parseAsInteger(Node n) throws SQLException {
if (n == null)
throw new SQLException("Unable to marshal a null to an integer");
if (n.isLiteral()) {
try {
String lex = n.getLiteralLexicalForm();
if (lex.contains(".")) {
return Long.parseLong(lex.substring(0, lex.indexOf('.')));
} else {
return Long.parseLong(lex);
}
} catch (Exception e) {
throw new SQLException("Unable to marshal an invalid numeric representation to an integer", e);
}
} else {
throw new SQLException("Unable to marshal a non-literal to an integer");
}
}
/**
* Gets whether a node has a numeric datatype
*
* @param n
* Node
* @return True if a numeric datatype, false otherwise
*/
private static boolean hasNumericDatatype(Node n) {
if (n == null)
return false;
if (!n.isLiteral())
return false;
return numericTypes.contains(n.getLiteralDatatypeURI());
}
}