This is an automated email from the ASF dual-hosted git repository. andy pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/jena.git
commit 3807f669eb86b8ed13d3f10ade2ef218b0a848f1 Author: Andy Seaborne <[email protected]> AuthorDate: Thu Nov 6 14:32:01 2025 +0000 GH-3562: NodeValue creation cache --- .../org/apache/jena/sparql/expr/NVCompare.java | 4 +- .../org/apache/jena/sparql/expr/NVDatatypes.java | 102 +++++----- .../org/apache/jena/sparql/expr/NVFactory.java | 27 ++- .../org/apache/jena/sparql/expr/NodeValue.java | 65 +++---- .../org/apache/jena/sparql/expr/TestNVFactory.java | 210 ++++++++++----------- 5 files changed, 212 insertions(+), 196 deletions(-) diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NVCompare.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/NVCompare.java index 5f12156779..16fc63d397 100644 --- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NVCompare.java +++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/NVCompare.java @@ -151,12 +151,12 @@ class NVCompare { case VSPACE_CDT_LIST : { final LiteralLabel lit1 = nv1.asNode().getLiteral() ; final LiteralLabel lit2 = nv2.asNode().getLiteral() ; - return CompositeDatatypeList.type.isEqual(lit1, lit2) ; + return CompositeDatatypeList.datatype().isEqual(lit1, lit2) ; } case VSPACE_CDT_MAP : { final LiteralLabel lit1 = nv1.asNode().getLiteral() ; final LiteralLabel lit2 = nv2.asNode().getLiteral() ; - return CompositeDatatypeMap.type.isEqual(lit1, lit2) ; + return CompositeDatatypeMap.datatype().isEqual(lit1, lit2) ; } } diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NVDatatypes.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/NVDatatypes.java index 6cd527a772..7bdc23101d 100644 --- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NVDatatypes.java +++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/NVDatatypes.java @@ -33,54 +33,53 @@ class NVDatatypes { // Not a derived type of xsd:decimal. //public static final RDFDatatype XSDprecisionDecimal = new XSDPRecisionDecimal("precisionDecimal", BigDecimal.class); - public static final RDFDatatype XSDdecimal = XSDDatatype.XSDdecimal; - public static final RDFDatatype XSDfloat = XSDDatatype.XSDfloat; - public static final RDFDatatype XSDdouble = XSDDatatype.XSDdouble; - - public static final RDFDatatype XSDinteger = XSDDatatype.XSDinteger; - public static final RDFDatatype XSDpositiveInteger = XSDDatatype.XSDpositiveInteger; - public static final RDFDatatype XSDnegativeInteger = XSDDatatype.XSDnegativeInteger; - public static final RDFDatatype XSDnonPositiveInteger = XSDDatatype.XSDnonPositiveInteger; - public static final RDFDatatype XSDnonNegativeInteger = XSDDatatype.XSDnonNegativeInteger; - - public static final RDFDatatype XSDlong = XSDDatatype.XSDlong; - public static final RDFDatatype XSDint = XSDDatatype.XSDint; - public static final RDFDatatype XSDshort = XSDDatatype.XSDshort; - public static final RDFDatatype XSDbyte = XSDDatatype.XSDbyte; - - public static final RDFDatatype XSDunsignedLong = XSDDatatype.XSDunsignedLong; - public static final RDFDatatype XSDunsignedInt = XSDDatatype.XSDunsignedInt; - public static final RDFDatatype XSDunsignedShort = XSDDatatype.XSDunsignedShort; - public static final RDFDatatype XSDunsignedByte = XSDDatatype.XSDunsignedByte; - - public static final RDFDatatype XSDboolean = XSDDatatype.XSDboolean; - - public static final RDFDatatype XSDstring = XSDDatatype.XSDstring; - public static final RDFDatatype langString = RDF.dtLangString; - public static final RDFDatatype dirLangString = RDF.dtDirLangString; - - - public static final RDFDatatype XSDnormalizedString = XSDDatatype.XSDnormalizedString; -// public static final RDFDatatype XSDtoken = XSDDatatype.XSDtoken; -// public static final RDFDatatype XSDlanguage = XSDDatatype.XSDlanguage; - -// public static final RDFDatatype XSDhexBinary = XSDDatatype.XSDhexBinary; -// public static final RDFDatatype XSDbase64Binary = XSDDatatype.XSDbase64Binary; - - public static final RDFDatatype XSDdateTime = XSDDatatype.XSDdateTime; - public static final RDFDatatype XSDdateTimeStamp = XSDDatatype.XSDdateTimeStamp; - public static final RDFDatatype XSDdate = XSDDatatype.XSDdate; - public static final RDFDatatype XSDtime = XSDDatatype.XSDtime; - - public static final RDFDatatype XSDduration = XSDDatatype.XSDduration; - public static final RDFDatatype XSDdayTimeDuration = XSDDatatype.XSDdayTimeDuration; - public static final RDFDatatype XSDyearMonthDuration = XSDDatatype.XSDyearMonthDuration; - - public static final RDFDatatype XSDgYear = XSDDatatype.XSDgYear; - public static final RDFDatatype XSDgMonth = XSDDatatype.XSDgMonth; - public static final RDFDatatype XSDgDay = XSDDatatype.XSDgDay; - public static final RDFDatatype XSDgYearMonth = XSDDatatype.XSDgYearMonth; - public static final RDFDatatype XSDgMonthDay = XSDDatatype.XSDgMonthDay; + public static final RDFDatatype XSDdecimal = datatype(XSDDatatype.XSDdecimal); + public static final RDFDatatype XSDfloat = datatype(XSDDatatype.XSDfloat); + public static final RDFDatatype XSDdouble = datatype(XSDDatatype.XSDdouble); + + public static final RDFDatatype XSDinteger = datatype(XSDDatatype.XSDinteger); + public static final RDFDatatype XSDpositiveInteger = datatype(XSDDatatype.XSDpositiveInteger); + public static final RDFDatatype XSDnegativeInteger = datatype(XSDDatatype.XSDnegativeInteger); + public static final RDFDatatype XSDnonPositiveInteger = datatype(XSDDatatype.XSDnonPositiveInteger); + public static final RDFDatatype XSDnonNegativeInteger = datatype(XSDDatatype.XSDnonNegativeInteger); + + public static final RDFDatatype XSDlong = datatype(XSDDatatype.XSDlong); + public static final RDFDatatype XSDint = datatype(XSDDatatype.XSDint); + public static final RDFDatatype XSDshort = datatype(XSDDatatype.XSDshort); + public static final RDFDatatype XSDbyte = datatype(XSDDatatype.XSDbyte); + + public static final RDFDatatype XSDunsignedLong = datatype(XSDDatatype.XSDunsignedLong); + public static final RDFDatatype XSDunsignedInt = datatype(XSDDatatype.XSDunsignedInt); + public static final RDFDatatype XSDunsignedShort = datatype(XSDDatatype.XSDunsignedShort); + public static final RDFDatatype XSDunsignedByte = datatype(XSDDatatype.XSDunsignedByte); + + public static final RDFDatatype XSDboolean = datatype(XSDDatatype.XSDboolean); + + public static final RDFDatatype XSDstring = datatype(XSDDatatype.XSDstring); + public static final RDFDatatype langString = datatype(RDF.dtLangString); + public static final RDFDatatype dirLangString = datatype(RDF.dtDirLangString); + + public static final RDFDatatype XSDnormalizedString = datatype(XSDDatatype.XSDnormalizedString); +// public static final RDFDatatype XSDtoken = datatype(XSDDatatype.XSDtoken); +// public static final RDFDatatype XSDlanguage = datatype(XSDDatatype.XSDlanguage); + +// public static final RDFDatatype XSDhexBinary = datatype(XSDDatatype.XSDhexBinary); +// public static final RDFDatatype XSDbase64Binary = datatype(XSDDatatype.XSDbase64Binary); + + public static final RDFDatatype XSDdateTime = datatype(XSDDatatype.XSDdateTime); + public static final RDFDatatype XSDdateTimeStamp = datatype(XSDDatatype.XSDdateTimeStamp); + public static final RDFDatatype XSDdate = datatype(XSDDatatype.XSDdate); + public static final RDFDatatype XSDtime = datatype(XSDDatatype.XSDtime); + + public static final RDFDatatype XSDduration = datatype(XSDDatatype.XSDduration); + public static final RDFDatatype XSDdayTimeDuration = datatype(XSDDatatype.XSDdayTimeDuration); + public static final RDFDatatype XSDyearMonthDuration = datatype(XSDDatatype.XSDyearMonthDuration); + + public static final RDFDatatype XSDgYear = datatype(XSDDatatype.XSDgYear); + public static final RDFDatatype XSDgMonth = datatype(XSDDatatype.XSDgMonth); + public static final RDFDatatype XSDgDay = datatype(XSDDatatype.XSDgDay); + public static final RDFDatatype XSDgYearMonth = datatype(XSDDatatype.XSDgYearMonth); + public static final RDFDatatype XSDgMonthDay = datatype(XSDDatatype.XSDgMonthDay); public static final Set<RDFDatatype> numerics = Set.of(XSDdecimal, XSDfloat, XSDdouble, XSDinteger, XSDpositiveInteger, XSDnegativeInteger, XSDnonPositiveInteger, XSDnonNegativeInteger, @@ -92,4 +91,9 @@ class NVDatatypes { public static final Set<RDFDatatype> temporal = Set.of(XSDdateTime, XSDdateTimeStamp,XSDdate, XSDtime, XSDgYear, XSDgMonth, XSDgDay, XSDgYearMonth, XSDgMonthDay); -} + + private static RDFDatatype datatype(RDFDatatype rdfDatatype) { + // Option to register in a set. + return rdfDatatype; + } +} \ No newline at end of file diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NVFactory.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/NVFactory.java index 5da176ba7d..345b5609d5 100644 --- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NVFactory.java +++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/NVFactory.java @@ -28,12 +28,14 @@ import java.util.Map; import javax.xml.datatype.Duration; import javax.xml.datatype.XMLGregorianCalendar; +import org.apache.jena.atlas.lib.InternalErrorException; import org.apache.jena.datatypes.RDFDatatype; import org.apache.jena.graph.Node; import org.apache.jena.graph.impl.LiteralLabel; import org.apache.jena.sparql.ARQInternalErrorException; import org.apache.jena.sparql.SystemARQ; import org.apache.jena.sparql.expr.nodevalue.*; +import org.apache.jena.sparql.util.NodeUtils; import org.apache.jena.sparql.util.RomanNumeral; import org.apache.jena.sparql.util.RomanNumeralDatatype; import org.apache.jena.vocabulary.RDF; @@ -44,8 +46,28 @@ class NVFactory { private static Map<RDFDatatype, ToNodeValue> mapper = dtSetup(); - public static NodeValue create(Node node) { + // Called from NodeValue. + static NodeValue create(Node node) { + if ( ! node.isLiteral() ) + // Not a literal - no value to extract + return new NodeValueNode(node); + + // Special cases: LangString and DirLangString, well-formed. RDFDatatype datatype = node.getLiteralDatatype(); + + boolean hasLangTag = NodeUtils.hasLang(node); // hasLang - covers rdf:langString and rdf:dirLangString + if ( hasLangTag ) { + if ( NodeUtils.hasLangDir(node) ) { + if ( ! RDF.dtDirLangString.equals(datatype) ) + throw new InternalErrorException("Wrong type for literal with a text direction"); + return new NodeValueLangDir(node); + } else { + if ( ! RDF.dtLangString.equals(datatype) ) + throw new InternalErrorException("Wrong type for literal with a langugae tag"); + return new NodeValueLang(node); + } + } + // Includes literal datatype rdf:langString or rdf:dirLangString without the proper special components ToNodeValue function = mapper.get(datatype); if ( function == null ) return new NodeValueNode(node); @@ -86,9 +108,8 @@ class NVFactory { entry(mapper, XSDboolean, NVFactory::booleanMaker); entry(mapper, XSDstring, NVFactory::stringMaker); - //[DT] XXX needs validation entry(mapper, XSDnormalizedString, NVFactory::stringMaker); - //[DT] XXX xsd;token, xsd:language + // XXX May be xsd;token, xsd:language entry(mapper, RDF.dtLangString, NVFactory::langStringMaker); entry(mapper, RDF.dtDirLangString, NVFactory::dirLangStringMaker); diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java index 0e619b453a..42c860b968 100644 --- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java +++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java @@ -31,8 +31,12 @@ import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.Duration; import javax.xml.datatype.XMLGregorianCalendar; +import org.apache.jena.atlas.lib.Cache; +import org.apache.jena.atlas.lib.CacheFactory; import org.apache.jena.atlas.lib.DateTimeUtils; import org.apache.jena.atlas.logging.Log; +import org.apache.jena.cdt.CompositeDatatypeList; +import org.apache.jena.cdt.CompositeDatatypeMap; import org.apache.jena.datatypes.RDFDatatype; import org.apache.jena.datatypes.TypeMapper; import org.apache.jena.ext.xerces.DatatypeFactoryInst; @@ -50,10 +54,8 @@ import org.apache.jena.sparql.serializer.SerializationContext; import org.apache.jena.sparql.sse.SSE; import org.apache.jena.sparql.util.FmtUtils; import org.apache.jena.sparql.util.NodeFactoryExtra; -import org.apache.jena.sparql.util.NodeUtils; import org.apache.jena.sparql.util.XSDNumUtils; import org.apache.jena.sys.JenaSystem; -import org.apache.jena.vocabulary.RDF; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -87,11 +89,17 @@ public abstract class NodeValue extends ExprNode * ref: http://www.w3.org/TR/xquery/#dt-ebv */ - private static Logger log = LoggerFactory.getLogger(NodeValue.class); + static Logger log = LoggerFactory.getLogger(NodeValue.class); public static boolean VerboseWarnings = true; public static boolean VerboseExceptions = false; + // Before constants + public static DatatypeFactory xmlDatatypeFactory = DatatypeFactoryInst.newDatatypeFactory(); + private static int NODEVALUE_CACHE_SIZE = 10_000; + private static Set<RDFDatatype> noCache = Set.of(CompositeDatatypeList.datatype(), CompositeDatatypeMap.datatype()); + private static Cache<Node, NodeValue> nodeValueCache = CacheFactory.createCache(NODEVALUE_CACHE_SIZE); + public static final NodeValue TRUE = NodeValue.makeNode("true", XSDboolean); public static final NodeValue FALSE = NodeValue.makeNode("false", XSDboolean); @@ -111,15 +119,6 @@ public abstract class NodeValue extends ExprNode public static final String xsdNamespace = XSD+"#"; - public static DatatypeFactory xmlDatatypeFactory = null; - - static { - // JDK default regardless. - //xmlDatatypeFactory = DatatypeFactory.newDefaultInstance(); - // Extracted Xerces. - xmlDatatypeFactory = DatatypeFactoryInst.newDatatypeFactory(); - } - private Node node = null; // Null used when a value has not been turned into a Node. protected NodeValue() { super(); } @@ -510,14 +509,32 @@ public abstract class NodeValue extends ExprNode public Duration getDuration() { raise(new ExprEvalTypeException("Not a duration: "+this)); return null; } // ---------------------------------------------------------------- - // ---- Setting : used when a node is used to make a NodeValue private static NodeValue nodeToNodeValue(Node node) { + if ( node.isLiteral() ) { + // XXX Could have a set of all support datatypes in NVDatatypes + RDFDatatype dt = node.getLiteralDatatype(); + if ( noCache.contains(dt) ) { + // Composite datatypes (CDT) are not cached. + return NodeValue.nodeToNodeValueMaker(node); + } + } if ( node.isExt() ) { // Don't judge custom extensions. return new NodeValueNode(node); } + NodeValue nv = nodeValueCache.get(node, NodeValue::nodeToNodeValueMaker); + //NodeValue nv = NodeValue.nodeToNodeValueMaker(node); + return nv; + } + /** + * Always returns a NodeValue of some kind. + * + * If the literal is ill-formed for the datatype, + * then a {@link NodeValueNode} is returned + */ + private static NodeValue nodeToNodeValueMaker(Node node) { if ( ! node.isConcrete() ) { String msg; if ( node.isVariable() ) @@ -528,28 +545,6 @@ public abstract class NodeValue extends ExprNode throw new ExprException("Node is not a constant"); } - if ( ! node.isLiteral() ) - // Not a literal - no value to extract - return new NodeValueNode(node); - - boolean hasLangTag = NodeUtils.isLangString(node); - boolean isPlainLiteral = ( node.getLiteralDatatypeURI() == null && ! hasLangTag ); - - if ( isPlainLiteral ) - return new NodeValueString(node.getLiteralLexicalForm(), node); - - if ( hasLangTag ) { - // Works for RDF 1.0 and RDF 1.1 - if ( node.getLiteralDatatype() != null && ! RDF.dtLangString.equals(node.getLiteralDatatype()) ) { - if ( NodeValue.VerboseWarnings ) - Log.warn(NodeValue.class, "Lang tag and datatype (datatype ignored)"); - } - // RDF 1.2 - if ( NodeUtils.hasLangDir(node) ) - return new NodeValueLangDir(node); - return new NodeValueLang(node); - } - // Includes creating NodeValueNode for ill-formed literals. NodeValue nv = NVFactory.create(node); return nv; diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNVFactory.java b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNVFactory.java index 35c330e357..d35a772660 100644 --- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNVFactory.java +++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNVFactory.java @@ -100,49 +100,6 @@ public class TestNVFactory { assertTrue(nv.isDecimal()); } - @Test - public void testBoolean() { - NodeValue nv1 = test("true", XSDboolean, NodeValueBoolean.class); - NodeValue nv2 = test("false", XSDboolean, NodeValueBoolean.class); - } - - @Test - public void testString() { - NodeValue nv = test("test string", XSDstring, NodeValueString.class); - } - - // Keep original language string tests as they have special handling - @Test - public void testLangString() { - String lex = "hello"; - String lang = "en"; - Node n = NodeFactory.createLiteralLang(lex, lang); - NodeValue nv = NVFactory.create(n); - assertTrue(NodeValueLang.class.isInstance(nv)); - assertEquals(lex, nv.getString()); - assertEquals(lang, nv.getLang()); - } - - @Test - public void testDirLangString() { - String lex = "hello"; - String lang = "en-GB"; - String ltr = "ltr"; - Node n = NodeFactory.createLiteralDirLang(lex, lang, ltr); - NodeValue nv = NVFactory.create(RDF.dtDirLangString, n); - assertTrue(NodeValueLangDir.class.isInstance(nv)); - assertEquals(lex, nv.getString()); - assertEquals(lang, nv.getLang()); - } - - @Test - public void testInvalidIntegerLiteral() { - NodeValue nv = test("not-an-integer", XSDinteger, NodeValueNode.class); - assertNotNull(nv); - assertFalse(nv.isNumber()); - assertFalse(nv.isInteger()); - } - @Test public void testDerivedInt() { NodeValue nv = test("123", XSDint, NodeValueInteger.class); @@ -215,8 +172,110 @@ public class TestNVFactory { assertTrue(nv.isInteger()); } - // Date and time types + @Test + public void testInvalidIntegerLiteral() { + NodeValue nv = test("not-an-integer", XSDinteger, NodeValueNode.class); + assertNotNull(nv); + assertFalse(nv.isNumber()); + assertFalse(nv.isInteger()); + } + + @Test + public void testInvalidDecimalFormat() { + // Multiple decimal points + NodeValue nv = test("12.34.56", XSDdecimal, NodeValueNode.class); + assertFalse(nv.isInteger()); + } + + @Test + public void testInvalidFloatFormat() { + // Incomplete exponent + NodeValue nv = test("12.34e", XSDfloat, NodeValueNode.class); + assertFalse(nv.isInteger()); + } + + @Test + public void testInvalidIntegerFormat() { + // Decimal not allowed for integer + NodeValue nv = test("123.45", XSDinteger, NodeValueNode.class); + assertFalse(nv.isInteger()); + } + + @Test + public void testInvalidPositiveIntegerNegativeValue() { + // Negative value not allowed for positive integer + NodeValue nv = test("-123", XSDpositiveInteger, NodeValueNode.class); + assertFalse(nv.isInteger()); + } + + @Test + public void testInvalidUnsignedIntValue() { + // Negative value not allowed for unsigned + NodeValue nv = test("-1", XSDunsignedInt, NodeValueNode.class); + assertFalse(nv.isInteger()); + } + + @Test + public void testInvalidByteRange() { + // Outside byte range (-128 to 127) + NodeValue nv = test("128", XSDbyte, NodeValueNode.class); + assertFalse(nv.isInteger()); + } + + @Test + public void testInvalidUnsignedByteRange() { + // Outside unsigned byte range (0 to 255) + NodeValue nv = test("256", XSDunsignedByte, NodeValueNode.class); + assertFalse(nv.isInteger()); + } + + @Test + public void testInvalidNonNegativeInteger() { + // Negative value not allowed + NodeValue nv = test("-1", XSDnonNegativeInteger, NodeValueNode.class); + assertFalse(nv.isInteger()); + } + + @Test + public void testInvalidNonPositiveInteger() { + // Positive value not allowed + NodeValue nv = test("1", XSDnonPositiveInteger, NodeValueNode.class); + assertFalse(nv.isInteger()); + } + + @Test + public void testBoolean() { + NodeValue nv1 = test("true", XSDboolean, NodeValueBoolean.class); + NodeValue nv2 = test("false", XSDboolean, NodeValueBoolean.class); + } + + @Test + public void testString() { + NodeValue nv = test("test string", XSDstring, NodeValueString.class); + } + + @Test + public void testLangString() { + String lex = "hello"; + String lang = "en"; + Node n = NodeFactory.createLiteralLang(lex, lang); + NodeValue nv = NVFactory.create(n); + assertTrue(NodeValueLang.class.isInstance(nv)); + assertEquals(lex, nv.getString()); + assertEquals(lang, nv.getLang()); + } + @Test + public void testDirLangString() { + String lex = "hello"; + String lang = "en-GB"; + String ltr = "ltr"; + Node n = NodeFactory.createLiteralDirLang(lex, lang, ltr); + NodeValue nv = NVFactory.create(RDF.dtDirLangString, n); + assertTrue(NodeValueLangDir.class.isInstance(nv)); + assertEquals(lex, nv.getString()); + assertEquals(lang, nv.getLang()); + } @Test public void testDateTimeType() { @@ -374,27 +433,6 @@ public class TestNVFactory { NodeValue nv = test("2025-12-25", XSDdateTime, NodeValueNode.class); } - @Test - public void testInvalidDecimalFormat() { - // Multiple decimal points - NodeValue nv = test("12.34.56", XSDdecimal, NodeValueNode.class); - assertFalse(nv.isInteger()); - } - - @Test - public void testInvalidFloatFormat() { - // Incomplete exponent - NodeValue nv = test("12.34e", XSDfloat, NodeValueNode.class); - assertFalse(nv.isInteger()); - } - - @Test - public void testInvalidIntegerFormat() { - // Decimal not allowed for integer - NodeValue nv = test("123.45", XSDinteger, NodeValueNode.class); - assertFalse(nv.isInteger()); - } - @Test public void testInvalidDurationFormat() { // Invalid duration designator @@ -412,46 +450,4 @@ public class TestNVFactory { // Invalid day value test("---32", XSDgDay, NodeValueNode.class); } - - @Test - public void testInvalidPositiveIntegerNegativeValue() { - // Negative value not allowed for positive integer - NodeValue nv = test("-123", XSDpositiveInteger, NodeValueNode.class); - assertFalse(nv.isInteger()); - } - - @Test - public void testInvalidUnsignedIntValue() { - // Negative value not allowed for unsigned - NodeValue nv = test("-1", XSDunsignedInt, NodeValueNode.class); - assertFalse(nv.isInteger()); - } - - @Test - public void testInvalidByteRange() { - // Outside byte range (-128 to 127) - NodeValue nv = test("128", XSDbyte, NodeValueNode.class); - assertFalse(nv.isInteger()); - } - - @Test - public void testInvalidUnsignedByteRange() { - // Outside unsigned byte range (0 to 255) - NodeValue nv = test("256", XSDunsignedByte, NodeValueNode.class); - assertFalse(nv.isInteger()); - } - - @Test - public void testInvalidNonNegativeInteger() { - // Negative value not allowed - NodeValue nv = test("-1", XSDnonNegativeInteger, NodeValueNode.class); - assertFalse(nv.isInteger()); - } - - @Test - public void testInvalidNonPositiveInteger() { - // Positive value not allowed - NodeValue nv = test("1", XSDnonPositiveInteger, NodeValueNode.class); - assertFalse(nv.isInteger()); - } } \ No newline at end of file
