net.sf.saxon.s9api.XdmAtomicValue Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of saxon-he Show documentation
Show all versions of saxon-he Show documentation
An OSGi bundle for Saxon-HE
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2013 Saxonica Limited.
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
package net.sf.saxon.s9api;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.type.*;
import net.sf.saxon.value.*;
import java.math.BigDecimal;
import java.net.URI;
/**
* The class XdmAtomicValue represents an item in an XPath 2.0 sequence that is an atomic value.
* The value may belong to any of the 19 primitive types defined in XML Schema, or to a type
* derived from these primitive types, or the XPath 2.0 type xs:untypedAtomic. The type may
* be either a built-in type or a user-defined type.
*
* An XdmAtomicValue
is immutable.
*/
public class XdmAtomicValue extends XdmItem {
protected XdmAtomicValue(AtomicValue value) {
super(value);
}
/**
* Create an xs:boolean atomic value
* @param value the boolean value, true or false
*/
public XdmAtomicValue(boolean value) {
super(BooleanValue.get(value));
}
/**
* Create an xs:integer atomic value
* @param value the xs:integer value, as a long
*/
public XdmAtomicValue(long value) {
super(Int64Value.makeIntegerValue(value));
}
/**
* Create an xs:decimal atomic value
* @param value the xs:decimal value, as a BigDecimal
*/
public XdmAtomicValue(BigDecimal value) {
super(new DecimalValue(value));
}
/**
* Create an xs:double atomic value
* @param value the xs:double value, as a double
*/
public XdmAtomicValue(double value) {
super(new DoubleValue(value));
}
/**
* Create an xs:float atomic value
* @param value the xs:float value, as a float
*/
public XdmAtomicValue(float value) {
super(new FloatValue(value));
}
/**
* Create an xs:string atomic value
* @param value the xs:string value, as a string
*/
public XdmAtomicValue(String value) {
super(new StringValue(value));
}
/**
* Create an xs:anyURI atomic value
* @param value the xs:anyURI value, as a URI
*/
public XdmAtomicValue(URI value) {
super(new AnyURIValue(value.toString()));
}
/**
* Create an xs:QName atomic value
* @param value the xs:QName value, as a QName
*/
public XdmAtomicValue(QName value) {
super(new QNameValue(value.getStructuredQName(), BuiltInAtomicType.QNAME));
}
/**
* Construct an atomic value given its lexical representation and the name of the required
* built-in atomic type.
* This method cannot be used to construct values that are namespace-sensitive (QNames and Notations)
* @param lexicalForm the value in the lexical space of the target data type. More strictly, the input
* value before the actions of the whitespace facet for the target data type are applied.
* @param type the required atomic type. This must either be one of the built-in
* atomic types defined in XML Schema, or a user-defined type whose definition appears
* in a schema that is known to the Processor. It must not be an abstract type.
* @throws SaxonApiException if the type is unknown, or is not atomic, or is namespace-sensitive;
* or if the value supplied in lexicalForm is not in the lexical space of the specified atomic
* type.
*/
public XdmAtomicValue(String lexicalForm, ItemType type) throws SaxonApiException {
net.sf.saxon.type.ItemType it = type.getUnderlyingItemType();
if (!it.isPlainType()) {
throw new SaxonApiException("Requested type is not atomic");
}
if (((AtomicType)it).isAbstract()) {
throw new SaxonApiException("Requested type is an abstract type");
}
if (((AtomicType)it).isNamespaceSensitive()) {
throw new SaxonApiException("Requested type is namespace-sensitive");
}
try {
StringConverter converter = type.getConversionRules().getStringConverter((AtomicType)it);
setValue(converter.convertString(lexicalForm).asAtomic());
} catch (ValidationException e) {
throw new SaxonApiException(e);
}
}
/**
* Get the result of converting the atomic value to a string. This has the same
* effect as the XPath string() function.
*/
public String toString() {
return getStringValue();
}
/**
* Get the primitive type of this atomic value, as a QName. The primitive types for this purpose are
* the 19 primitive types of XML Schema, plus xs:integer, xs:dayTimeDuration and xs:yearMonthDuration,
* and xs:untypedAtomic. For external objects, the result is xs:anyAtomicType.
* @return a QName naming the primitive type of this atomic value. This will always be an atomic type.
*/
/*@NotNull*/ public QName getPrimitiveTypeName() {
AtomicValue value = (AtomicValue)getUnderlyingValue();
BuiltInAtomicType type = value.getPrimitiveType();
return new QName(type.getQualifiedName());
}
/**
* Get the value as a Java object of the nearest equivalent type.
*
* The result type is as follows:
*
*
* XPath type Java class
* xs:string String
* xs:integer java.math.BigInteger
* xs:decimal java.math.BigDecimal
* xs:double Double
* xs:float Float
* xs:boolean Boolean
* xs:QName QName
* xs:anyURI String
* xs:untypedAtomic String
* Other types currently String, but this may change in the future
*
* @return the value, converted to a Java object of a suitable type
*/
@SuppressWarnings({"AutoBoxing"})
public Object getValue() {
AtomicValue av = (AtomicValue)getUnderlyingValue();
if (av instanceof StringValue) {
return av.getStringValue();
} else if (av instanceof IntegerValue) {
return ((IntegerValue)av).asBigInteger();
} else if (av instanceof DoubleValue) {
return ((DoubleValue)av).getDoubleValue();
} else if (av instanceof FloatValue) {
return ((FloatValue)av).getFloatValue();
} else if (av instanceof BooleanValue) {
return ((BooleanValue)av).getBooleanValue();
} else if (av instanceof DecimalValue) {
return ((DecimalValue)av).getDecimalValue();
} else if (av instanceof QNameValue) {
QNameValue q = (QNameValue)av;
return new QName(q.getPrefix(), q.getNamespaceURI(), q.getLocalName());
} else {
return av.getStringValue();
}
}
/**
* Get the value converted to a boolean using the XPath casting rules
* @return the result of converting to a boolean (Note: this is not the same as the
* effective boolean value).
* @throws SaxonApiException if the value cannot be cast to a boolean
*/
public boolean getBooleanValue() throws SaxonApiException {
AtomicValue av = (AtomicValue)getUnderlyingValue();
if (av instanceof BooleanValue) {
return ((BooleanValue)av).getBooleanValue();
} else if (av instanceof NumericValue) {
return !av.isNaN() && ((NumericValue)av).signum() != 0;
} else if (av instanceof StringValue) {
String s = av.getStringValue().trim();
return "1".equals(s) || "true".equals(s);
} else {
throw new SaxonApiException("Cannot cast item to a boolean");
}
}
/**
* Get the value converted to an integer using the XPath casting rules
* @return the result of converting to an integer
* @throws SaxonApiException if the value cannot be cast to an integer
*/
public long getLongValue() throws SaxonApiException {
AtomicValue av = (AtomicValue)getUnderlyingValue();
if (av instanceof BooleanValue) {
return ((BooleanValue)av).getBooleanValue() ? 0L : 1L;
} else if (av instanceof NumericValue) {
try {
return ((NumericValue)av).longValue();
} catch (XPathException e) {
throw new SaxonApiException("Cannot cast item to an integer");
}
} else if (av instanceof StringValue) {
StringToDouble converter = StringToDouble.getInstance();
return (long)converter.stringToNumber(av.getStringValueCS());
} else {
throw new SaxonApiException("Cannot cast item to an integer");
}
}
/**
* Get the value converted to a double using the XPath casting rules.
* If the value is a string, the XSD 1.1 rules are used, which means that the string
* "+INF" is recognised.
* @return the result of converting to a double
* @throws SaxonApiException if the value cannot be cast to a double
*/
public double getDoubleValue() throws SaxonApiException {
AtomicValue av = (AtomicValue)getUnderlyingValue();
if (av instanceof BooleanValue) {
return ((BooleanValue)av).getBooleanValue() ? 0.0 : 1.0;
} else if (av instanceof NumericValue) {
return ((NumericValue)av).getDoubleValue();
} else if (av instanceof StringValue) {
try {
StringToDouble converter = StringToDouble11.getInstance();
return converter.stringToNumber(av.getStringValueCS());
} catch (NumberFormatException e) {
throw new SaxonApiException(e.getMessage());
}
} else {
throw new SaxonApiException("Cannot cast item to a double");
}
}
/**
* Get the value converted to a decimal using the XPath casting rules
* @return the result of converting to a decimal
* @throws SaxonApiException if the value cannot be cast to a double
*/
public BigDecimal getDecimalValue() throws SaxonApiException {
AtomicValue av = (AtomicValue)getUnderlyingValue();
if (av instanceof BooleanValue) {
return ((BooleanValue)av).getBooleanValue() ? BigDecimal.ZERO : BigDecimal.ONE;
} else if (av instanceof NumericValue) {
try {
return ((NumericValue)av).getDecimalValue();
} catch (XPathException e) {
throw new SaxonApiException("Cannot cast item to a decimal");
}
} else if (av instanceof StringValue) {
return new BigDecimal(av.getStringValueCS().toString());
} else {
throw new SaxonApiException("Cannot cast item to a decimal");
}
}
}