You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2023/12/27 17:02:37 UTC

(jena) branch main updated (7bf97bfbfc -> 2d8785f25d)

This is an automated email from the ASF dual-hosted git repository.

andy pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/jena.git


    from 7bf97bfbfc Format
     new 74a134d7dd GH-2039: Case insensitive langtags (initial)
     new 4965c75522 GH-2126: Rename in NodeFactory: createLiteral(,lang) -> createLiteralLang(,lang)
     new 0505f571dc GH-2051: Initial text direction
     new 8ef5849068 GH-2126: NodeFactory.createLiteralString
     new d8eab6b73e Remove unused GetTriple
     new b13a79f8be GH-2039: Case insensitive langtags
     new 793334d528 Remove unused NodeValueCompare
     new be56ea9e96 Add tests (RDFString, ModelUtil, Lib)
     new 4817c276a2 Update contract tests to Jena5
     new 2d8785f25d Convert to Lib functions lowercase/uppercase

The 10 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../java/org/apache/jena/http/auth/AuthHeader.java |   4 +-
 .../java/org/apache/jena/riot/RDFLanguages.java    |   8 +-
 .../org/apache/jena/riot/RDFParserBuilder.java     |  10 +-
 .../apache/jena/riot/adapters/RDFReaderRIOT.java   |  77 +--
 .../apache/jena/riot/adapters/RDFWriterRIOT.java   |   5 +-
 .../jena/riot/lang/rdfxml/ReaderRDFXML_ARP0.java   |   2 +-
 .../process/normalize/CanonicalizeLiteral.java     |   6 +-
 .../riot/process/normalize/NormalizeValue.java     |   6 +-
 .../process/normalize/StreamCanonicalLangTag.java  |   9 +-
 .../apache/jena/riot/protobuf/ProtobufConvert.java |   4 +-
 .../jena/riot/rowset/rw/RowSetReaderCSV.java       |   2 +-
 .../org/apache/jena/riot/system/FactoryRDFStd.java |   4 +-
 .../apache/jena/riot/system/stream/LocatorURL.java |  35 +-
 .../java/org/apache/jena/riot/tokens/Token.java    |   4 +-
 .../java/org/apache/jena/riot/web/HttpMethod.java  |   4 +-
 .../org/apache/jena/sparql/algebra/op/OpBGP.java   |  20 +-
 .../jena/sparql/engine/optimizer/StatsMatcher.java |   2 +-
 .../java/org/apache/jena/sparql/expr/E_MD5.java    |   8 +-
 .../java/org/apache/jena/sparql/expr/E_SHA1.java   |  20 +-
 .../java/org/apache/jena/sparql/expr/E_SHA224.java |  20 +-
 .../java/org/apache/jena/sparql/expr/E_SHA256.java |  20 +-
 .../java/org/apache/jena/sparql/expr/E_SHA384.java |  20 +-
 .../java/org/apache/jena/sparql/expr/E_SHA512.java |  20 +-
 .../org/apache/jena/sparql/expr/NodeValue.java     |   4 +-
 .../apache/jena/sparql/expr/NodeValueCompare.java  | 406 ---------------
 .../jena/sparql/expr/aggregate/AggCustom.java      |   5 +-
 .../jena/sparql/expr/aggregate/AggregatorBase.java |  59 +--
 .../jena/sparql/expr/nodevalue/NodeValueLang.java  |   2 +-
 .../sparql/expr/nodevalue/NodeValueSortKey.java    |   2 +-
 .../sparql/expr/nodevalue/NodeValueString.java     |   2 +-
 .../sparql/function/library/FN_CollationKey.java   |  13 +-
 .../sparql/function/scripting/ScriptFunction.java  |   4 +-
 .../org/apache/jena/sparql/graph/NodeConst.java    |   2 +-
 .../apache/jena/sparql/lang/QueryParserBase.java   |   4 +-
 .../jena/sparql/pfunction/library/blankNode.java   |   2 +-
 .../jena/sparql/pfunction/library/concat.java      |   2 +-
 .../jena/sparql/pfunction/library/splitIRI.java    |   2 +-
 .../apache/jena/sparql/pfunction/library/str.java  |   2 +-
 .../jena/sparql/pfunction/library/strSplit.java    |   2 +-
 .../main/java/org/apache/jena/sparql/sse/Item.java |   2 +-
 .../jena/sparql/sse/lang/ParseHandlerPlain.java    |   2 +-
 .../java/org/apache/jena/sparql/util/FmtUtils.java | 545 +++++++++------------
 .../org/apache/jena/sparql/util/RomanNumeral.java  |   4 +-
 .../org/apache/jena/sparql/util/StringUtils.java   |  14 +-
 .../jena/arq/junit/sparql/tests/QueryEvalTest.java |   2 +-
 .../jena/atlas/data/TestDistinctDataBag.java       |  10 +-
 .../jena/atlas/data/TestDistinctDataNet.java       |   4 +-
 .../apache/jena/atlas/data/TestSortedDataBag.java  |   4 +-
 .../jena/query/TestParameterizedSparqlString.java  |  18 +-
 .../java/org/apache/jena/riot/TestRDFParser.java   |  23 +-
 .../java/org/apache/jena/riot/TestSysRIOT.java     |   7 +-
 .../jena/riot/process/TestNormalization.java       |  21 +-
 .../apache/jena/riot/thrift/TestThriftTerm.java    |   2 +-
 .../org/apache/jena/riot/writer/TestRDFJSON.java   |   6 +-
 .../algebra/optimize/TestSemanticEquivalence.java  |   2 +-
 .../iterator/AbstractTestDistinctReduced.java      |   2 +-
 .../sparql/engine/iterator/TestQueryIterSort.java  |   4 +-
 .../iterator/TestSortedDataBagCancellation.java    |   8 +-
 .../apache/jena/sparql/expr/TestExpressions.java   |  28 +-
 .../org/apache/jena/sparql/expr/TestFunctions.java |   2 +-
 .../apache/jena/sparql/expr/TestNodeFunctions.java | 315 ++++++------
 .../org/apache/jena/sparql/expr/TestNodeValue.java |  24 +-
 .../org/apache/jena/sparql/expr/TestOrdering.java  |  47 +-
 .../apache/jena/sparql/expr/TestSortOrdering.java  |  13 +-
 .../org/apache/jena/sparql/expr/TestXSDFuncOp.java |   2 +-
 .../jena/sparql/graph/TestGraphUnionRead.java      |   4 +-
 .../sparql/pfunction/library/TestStrSplit.java     |   2 +-
 .../jena/sparql/resultset/TestResultSet.java       |   3 +
 .../org/apache/jena/sparql/sse/TestSSE_Basic.java  |   4 +-
 .../org/apache/jena/sparql/util/TestFmtUtils.java  |   6 +-
 jena-arq/testing/ARQ/Sort/sort-result-2.ttl        | 252 +++++-----
 jena-arq/testing/ARQ/Sort/sort-result-3.ttl        | 252 +++++-----
 jena-arq/testing/DAWG/examples/ex11.2.3.7_0.rq     |   2 +-
 .../main/java/org/apache/jena/atlas/lib/Lib.java   |  78 +--
 .../org/apache/jena/atlas/junit/AssertExtra.java   |  13 +-
 .../java/org/apache/jena/atlas/lib/TS_Lib.java     |   8 +-
 .../org/apache/jena/atlas/lib/TestBaseLib.java     |  46 ++
 jena-cmds/src/main/java/arq/qparse.java            |  60 +--
 .../java/org/apache/jena/datatypes/TypeMapper.java |  10 +-
 .../{RDFLangString.java => RDFDirLangString.java}  |  21 +-
 .../java/org/apache/jena/graph/FrontsNode.java     |  18 +-
 .../java/org/apache/jena/graph/FrontsTriple.java   |  13 +-
 .../main/java/org/apache/jena/graph/GetTriple.java |  37 --
 .../src/main/java/org/apache/jena/graph/Node.java  |  23 +-
 .../java/org/apache/jena/graph/NodeFactory.java    | 165 ++++++-
 .../java/org/apache/jena/graph/Node_Literal.java   |  17 +-
 .../graph/{Node_Marker.java => TextDirection.java} |  43 +-
 .../apache/jena/graph/impl/CollectionGraph.java    |  17 -
 .../org/apache/jena/graph/impl/LiteralLabel.java   | 197 +++++---
 .../jena/graph/impl/LiteralLabelFactory.java       |  63 ++-
 .../org/apache/jena/graph/langtag/LangTags.java    | 165 +++++++
 .../java/org/apache/jena/rdf/model/Literal.java    |  14 +-
 .../org/apache/jena/rdf/model/ResourceFactory.java |   4 +-
 .../org/apache/jena/rdf/model/impl/AltImpl.java    |   2 +-
 .../apache/jena/rdf/model/impl/ContainerImpl.java  |   2 +-
 .../apache/jena/rdf/model/impl/LiteralImpl.java    |  10 +
 .../org/apache/jena/rdf/model/impl/ModelCom.java   |   8 +-
 .../org/apache/jena/rdf/model/impl/SeqImpl.java    |   2 +-
 .../apache/jena/rdf/model/impl/StatementBase.java  |   2 +-
 .../java/org/apache/jena/rdf/model/impl/Util.java  | 128 +++--
 .../jena/rdfxml/xmlinput0/RDFXMLReader0.java       |   2 +-
 .../apache/jena/rdfxml/xmlinput1/RDFXMLReader.java |   2 +-
 .../org/apache/jena/reasoner/rulesys/Rule.java     |   4 +-
 .../jena/reasoner/rulesys/builtins/Regex.java      |   2 +-
 .../jena/reasoner/rulesys/builtins/StrConcat.java  |   2 +-
 .../main/java/org/apache/jena/vocabulary/RDF.java  | 163 +++---
 .../org/apache/jena/graph/GraphContractTest.java   |  34 +-
 .../apache/jena/graph/test/AbstractTestGraph.java  |  20 +-
 .../apache/jena/graph/test/NodeCreateUtils.java    |  13 +-
 .../graph/test/TestLiteralLabelSameValueAs.java    |   2 +
 .../apache/jena/graph/test/TestLiteralLabels.java  |   1 +
 .../java/org/apache/jena/graph/test/TestNode.java  |   9 +-
 .../org/apache/jena/graph/test/TestNodeExtras.java |   2 +-
 .../apache/jena/graph/test/TestPackage_graph.java  |   2 +
 .../jena/graph/test/TestRDFStringLiterals.java     | 145 ++++++
 .../apache/jena/graph/test/TestTypedLiterals.java  |   4 +-
 .../java/org/apache/jena/irix/TestIRIxSyntax.java  |   6 +-
 .../java/org/apache/jena/irix/TestRFC3986.java     |   7 +-
 .../jena/rdf/model/test/AbstractTestPackage.java   |   4 +-
 .../jena/reasoner/rulesys/test/TestFBRules.java    |  78 +--
 .../java/org/apache/jena/test/JenaTestBase.java    | 265 +++++-----
 .../java/org/apache/jena/test/TestModelUtil.java   |  96 ++++
 .../org/apache/jena/test/TestPackage_core.java     |   2 +
 .../jena/testing_framework/NodeCreateUtils.java    |  20 +-
 .../jena/testing_framework/TestFileData.java       |   4 +-
 .../arq/examples/propertyfunction/localname.java   |   4 +-
 .../arq/examples/propertyfunction/uppercase.java   |   2 +-
 .../apache/jena/commonsrdf/impl/JCR_Factory.java   |   4 +-
 .../jena/arq/querybuilder/AskBuilderTest.java      |   2 +-
 .../arq/querybuilder/ConstructBuilderTest.java     |   2 +-
 .../jena/arq/querybuilder/ConvertersTest.java      |   4 +-
 .../jena/arq/querybuilder/SelectBuilderTest.java   |   2 +-
 .../jena/arq/querybuilder/UpdateBuilderTest.java   |   2 +-
 .../arq/querybuilder/clauses/ValuesClauseTest.java |  98 ++--
 .../arq/querybuilder/clauses/WhereClauseTest.java  |  22 +-
 .../querybuilder/handlers/ValuesHandlerTest.java   |  70 +--
 .../querybuilder/handlers/WhereHandlerTest.java    |  30 +-
 .../rewriters/NodeValueRewriterTest.java           |   6 +-
 .../service/enhancer/init/ServiceEnhancerInit.java |   2 +-
 .../sparql/service/enhancer/pfunction/cacheLs.java |   4 +-
 .../TestServiceEnhancerBatchQueryRewriter.java     |   4 +-
 .../apache/jena/fuseki/access/SecurityContext.java |   4 +-
 .../org/apache/jena/fuseki/server/Operation.java   |   5 +-
 .../apache/jena/fuseki/servlets/ActionREST.java    |   5 +-
 .../apache/jena/fuseki/servlets/ResponseOps.java   |   8 +-
 .../jena/fuseki/servlets/SPARQLQueryProcessor.java |   3 +-
 .../org/apache/jena/fuseki/mgt/ActionDatasets.java |   5 +-
 .../permissions/model/impl/SecuredLiteralImpl.java |  14 +-
 .../permissions/model/impl/SecuredModelImpl.java   |   6 +-
 .../model/impl/SecuredResourceImpl.java            |   2 +-
 .../model/impl/SecuredStatementImpl.java           |   4 +-
 .../java/org/apache/jena/rdfpatch/PatchHeader.java |   5 +-
 .../apache/jena/rdfpatch/filelog/FilePolicy.java   |   5 +-
 .../java/org/apache/jena/rdfpatch/system/Id.java   |   2 +-
 .../org/apache/jena/shacl/ValidationReport.java    |   2 +-
 .../shacl/engine/constraint/SparqlValidation.java  |   2 +-
 .../apache/jena/shacl/validation/ReportEntry.java  |   2 +-
 .../org/apache/jena/shex/expressions/NodeKind.java |   5 +-
 .../org/apache/jena/shex/parser/ParserShExC.java   |   2 +-
 .../org/apache/jena/shex/writer/WriterShExC.java   |  11 +-
 .../apache/jena/tdb1/store/DatasetPrefixesTDB.java |   6 +-
 .../store/nodetable/AbstractTestNodeTable.java     |   2 +-
 .../jena/tdb1/store/nodetable/TestNodec.java       |   2 +-
 .../jena/tdb2/loader/main/PrefixHandlerBulk.java   |   2 +-
 .../apache/jena/tdb2/store/StoragePrefixesTDB.java |   6 +-
 .../apache/jena/query/text/TextIndexLucene.java    |   6 +-
 .../text/TestDatasetWithLuceneStoredLiterals.java  |  14 +-
 .../query/text/TestLuceneWithMultipleThreads.java  |   2 +-
 .../jena/query/text/TestTextHighlighting.java      |   8 +-
 169 files changed, 2614 insertions(+), 2298 deletions(-)
 delete mode 100644 jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValueCompare.java
 create mode 100644 jena-base/src/test/java/org/apache/jena/atlas/lib/TestBaseLib.java
 copy jena-core/src/main/java/org/apache/jena/datatypes/xsd/impl/{RDFLangString.java => RDFDirLangString.java} (69%)
 delete mode 100644 jena-core/src/main/java/org/apache/jena/graph/GetTriple.java
 copy jena-core/src/main/java/org/apache/jena/graph/{Node_Marker.java => TextDirection.java} (54%)
 create mode 100644 jena-core/src/main/java/org/apache/jena/graph/langtag/LangTags.java
 create mode 100644 jena-core/src/test/java/org/apache/jena/graph/test/TestRDFStringLiterals.java
 create mode 100644 jena-core/src/test/java/org/apache/jena/test/TestModelUtil.java


(jena) 07/10: Remove unused NodeValueCompare

Posted by an...@apache.org.
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 793334d52853d49b0b013646ae65dd35b4a0ded5
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Sun Dec 24 21:44:57 2023 +0000

    Remove unused NodeValueCompare
---
 .../apache/jena/sparql/expr/NodeValueCompare.java  | 406 ---------------------
 1 file changed, 406 deletions(-)

diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValueCompare.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValueCompare.java
deleted file mode 100644
index 7d98029bf4..0000000000
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValueCompare.java
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * 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.sparql.expr;
-
-/*package*/ class NodeValueCompare {}
-//// Old (upto 4.6.1 comprare code.)
-
-// XXX Delete!
-
-///*package*/ class NodeValueCompare {
-//    private NodeValueCompare() {}
-//
-//    // ----------------------------------------------------------------
-//    // ---- sameValueAs
-//
-//    // Disjoint value spaces : dateTime and dates are not comparable
-//    // Every langtag implies another value space as well.
-//
-//    /**
-//     * Return true if the two NodeValues are known to be the same value return false
-//     * if known to be different values, throw ExprEvalException otherwise
-//     */
-//    /*public*/private static boolean sameValueAs(NodeValue nv1, NodeValue nv2) {
-//        if ( nv1 == null || nv2 == null )
-//            throw new ARQInternalErrorException("Attempt to sameValueAs on a null");
-//
-//        ValueSpaceClassification compType = NodeValue.classifyValueOp(nv1, nv2);
-//
-//        // Special case - date/dateTime comparison is affected by timezones and may
-//        // be
-//        // indeterminate based on the value of the dateTime/date.
-//
-//        switch (compType) {
-//            case VSPACE_NUM :
-//                return XSDFuncOp.compareNumeric(nv1, nv2) == CMP_EQUAL;
-//            case VSPACE_DATETIME :
-//            case VSPACE_DATE :
-//            case VSPACE_TIME :
-//            case VSPACE_G_YEAR :
-//            case VSPACE_G_YEARMONTH :
-//            case VSPACE_G_MONTH :
-//            case VSPACE_G_MONTHDAY :
-//            case VSPACE_G_DAY : {
-//                int x = XSDFuncOp.compareDateTime(nv1, nv2);
-//                if ( x == Expr.CMP_INDETERMINATE )
-//                    throw new ExprNotComparableException("Indeterminate dateTime comparison");
-//                return x == CMP_EQUAL;
-//            }
-//            case VSPACE_DURATION : {
-//                int x = XSDFuncOp.compareDuration(nv1, nv2);
-//                if ( x == Expr.CMP_INDETERMINATE )
-//                    throw new ExprNotComparableException("Indeterminate duration comparison");
-//                return x == CMP_EQUAL;
-//            }
-//
-//            case VSPACE_STRING :
-//                return XSDFuncOp.compareString(nv1, nv2) == CMP_EQUAL;
-//            case VSPACE_BOOLEAN :
-//                return XSDFuncOp.compareBoolean(nv1, nv2) == CMP_EQUAL;
-//
-//            case VSPACE_TRIPLE_TERM : {
-//                Triple t1 = nv1.getNode().getTriple();
-//                Triple t2 = nv2.getNode().getTriple();
-//                return nSameValueAs(t1.getSubject(),   t2.getSubject()) &&
-//                       nSameValueAs(t1.getPredicate(), t2.getPredicate()) &&
-//                       nSameValueAs(t1.getObject(),    t2.getObject());
-//            }
-//
-//            case VSPACE_LANG :
-//            case VSPACE_NODE :
-//                // Two non-literals
-//                return NodeFunctions.sameTerm(nv1.getNode(), nv2.getNode());
-//
-//            case VSPACE_UNKNOWN : {
-//                // One or two unknown value spaces, or one has a lang tag (but not
-//                // both).
-//                Node node1 = nv1.asNode();
-//                Node node2 = nv2.asNode();
-//
-//                if ( !SystemARQ.ValueExtensions )
-//                    // No value extensions => raw rdfTermEquals
-//                    return NodeFunctions.rdfTermEquals(node1, node2);
-//
-//                // Some "value spaces" are know to be not equal (no overlap).
-//                // Like one literal with a language tag, and one without can't be
-//                // sameAs.
-//
-//                if ( !node1.isLiteral() || !node2.isLiteral() )
-//                    // Can't both be non-literals - that's VSPACE_NODE
-//                    // One or other not a literal => not sameAs
-//                    return false;
-//
-//                // Two literals at this point.
-//
-//                if ( NodeFunctions.sameTerm(node1, node2) )
-//                    return true;
-//
-//                if ( !node1.getLiteralLanguage().equals("") || !node2.getLiteralLanguage().equals("") )
-//                    // One had lang tag but weren't sameNode => not equals
-//                    return false;
-//
-//                raise(new ExprEvalException("Unknown equality test: " + nv1 + " and " + nv2));
-//                throw new ARQInternalErrorException("raise returned (sameValueAs)");
-//            }
-//            case VSPACE_SORTKEY :
-//                return nv1.getSortKey().compareTo(nv2.getSortKey()) == 0;
-//
-//            case VSPACE_DIFFERENT :
-//                // Known to be incompatible.
-//                if ( !SystemARQ.ValueExtensions && (nv1.isLiteral() && nv2.isLiteral()) )
-//                    raise(new ExprEvalException("Incompatible: " + nv1 + " and " + nv2));
-//                return false;
-//        }
-//
-//        throw new ARQInternalErrorException("sameValueAs failure " + nv1 + " and " + nv2);
-//    }
-//
-//    /** Worker for sameAs. */
-//    private static boolean nSameValueAs(Node n1, Node n2) {
-//        NodeValue nv1 = NodeValue.makeNode(n1);
-//        NodeValue nv2 = NodeValue.makeNode(n2);
-//        return sameValueAs(nv1, nv2);
-//    }
-//
-//    /**
-//     * Return true if the two Nodes are known to be different, return false if the
-//     * two Nodes are known to be the same, else throw ExprEvalException
-//     */
-//    /*package*/private static boolean notSameAs(Node n1, Node n2) {
-//        return notSameValueAs(NodeValue.makeNode(n1), NodeValue.makeNode(n2));
-//    }
-//
-//    /**
-//     * Return true if the two NodeValues are known to be different, return false if
-//     * the two NodeValues are known to be the same, else throw ExprEvalException
-//     */
-//    /*package*/private static boolean notSameValueAs(NodeValue nv1, NodeValue nv2) {
-//        return !sameValueAs(nv1, nv2);
-//    }
-//
-//    // ----------------------------------------------------------------
-//    // compare
-//
-//    // Compare by value code is here
-//    // NodeUtils.compareRDFTerms for syntactic comparison
-//
-//    /**
-//     * Compare by value if possible else compare by kind/type/lexical form Only use
-//     * when you want an ordering regardless of form of NodeValue, for example in
-//     * ORDER BY
-//     *
-//     * @param nv1
-//     * @param nv2
-//     * @return negative, 0, or positive for less than, equal, greater than.
-//     */
-//
-//    /*package*/private static int $_compareAlways(NodeValue nv1, NodeValue nv2) {
-//        try {
-//            int x = compare(nv1, nv2, true);
-//            // Same?
-//            if ( x != CMP_EQUAL )
-//                return x;
-//        } catch (ExprNotComparableException ex) { /* Drop through */ }
-//        return NodeCmp.compareRDFTerms(nv1.asNode(), nv2.asNode());
-//    }
-//
-//    /**
-//     * Compare by value (and only value) if possible. Supports &lt;, &lt;=, &gt;,
-//     * &gt;= but not = nor != (which are sameValueAs and notSameValueAs)
-//     *
-//     * @param nv1
-//     * @param nv2
-//     * @return Expr.CMP_LESS(-1), Expr.CMP_EQUAL(0) or Expr.CMP_GREATER(+1)
-//     * @throws ExprNotComparableException for Expr.CMP_INDETERMINATE(+2)
-//     */
-//    /*package*/private static int $_compare(NodeValue nv1, NodeValue nv2) {
-//        if ( nv1 == null || nv2 == null )
-//            // raise(new ExprEvalException("Attempt to notSameValueAs on null") ;
-//            throw new ARQInternalErrorException("Attempt to compare on null");
-//        int x = compare(nv1, nv2, false);
-//        if ( x == Expr.CMP_INDETERMINATE )
-//            throw new ExprNotComparableException("Indeterminate comparison");
-//        return x;
-//    }
-//
-//    // E_GreaterThan/E_LessThan/E_GreaterThanOrEqual/E_LessThanOrEqual
-//    // ==> compare(nv1, nv2) => compare (nv1, nv2, false)
-//
-//    // BindingComparator => compareAlways(nv1, nv2) => compare (nv1, nv2, true)
-//
-//    // E_Equals calls NodeValue.sameAs() ==>
-//
-//    // sortOrderingCompare means that the comparison should do something with
-//    // normally unlike things,
-//    // and split plain strings from xsd:strings.
-//
-//    private static int compare(NodeValue nv1, NodeValue nv2, boolean sortOrderingCompare) {
-//        if ( nv1 == null && nv2 == null )
-//            return CMP_EQUAL;
-//
-//        if ( nv1 == null )
-//            return Expr.CMP_LESS;
-//        if ( nv2 == null )
-//            return Expr.CMP_GREATER;
-//
-//        ValueSpaceClassification compType = NodeValue.classifyValueOp(nv1, nv2);
-//
-//        // Special case - date/dateTime comparison is affected by timezones and may
-//        // be
-//        // indeterminate based on the value of the dateTime/date.
-//        // Do this first, so that indeterminate can drop through to a general
-//        // ordering.
-//
-//        switch (compType) {
-//            case VSPACE_DATETIME :
-//            case VSPACE_DATE :
-//            case VSPACE_TIME :
-//            case VSPACE_G_DAY :
-//            case VSPACE_G_MONTH :
-//            case VSPACE_G_MONTHDAY :
-//            case VSPACE_G_YEAR :
-//            case VSPACE_G_YEARMONTH : {
-//                int x = XSDFuncOp.compareDateTime(nv1, nv2);
-//                if ( x != Expr.CMP_INDETERMINATE )
-//                    return x;
-//                // Indeterminate => can't compare as strict values.
-//                compType = ValueSpaceClassification.VSPACE_DIFFERENT;
-//                break;
-//            }
-//            case VSPACE_DURATION : {
-//                int x = XSDFuncOp.compareDuration(nv1, nv2);
-//                // Fix up - Java (Oracle java7 at least) returns "equals" for
-//                // "P1Y"/"P365D" and "P1M"/"P28D", and others split over
-//                // YearMonth/DayTime.
-//
-//                // OR return Expr.CMP_INDETERMINATE ??
-//                if ( x == CMP_EQUAL ) {
-//                    Duration d1 = nv1.getDuration();
-//                    Duration d2 = nv2.getDuration();
-//                    if ( (XSDFuncOp.isDayTime(d1) && XSDFuncOp.isYearMonth(d2)) || (XSDFuncOp.isDayTime(d2) && XSDFuncOp.isYearMonth(d1)) )
-//                        x = Expr.CMP_INDETERMINATE;
-//                }
-//                if ( x != Expr.CMP_INDETERMINATE )
-//                    return x;
-//                compType = ValueSpaceClassification.VSPACE_DIFFERENT;
-//                break;
-//            }
-//
-//            // No special cases.
-//            case VSPACE_BOOLEAN :
-//            case VSPACE_DIFFERENT :
-//            case VSPACE_LANG :
-//            case VSPACE_TRIPLE_TERM :
-//            case VSPACE_NODE :
-//            case VSPACE_NUM :
-//            case VSPACE_STRING :
-//            case VSPACE_SORTKEY :
-//            case VSPACE_UNKNOWN :
-//                // Drop through.
-//        }
-//
-//        switch (compType) {
-//            case VSPACE_DATETIME :
-//            case VSPACE_DATE :
-//            case VSPACE_TIME :
-//            case VSPACE_G_DAY :
-//            case VSPACE_G_MONTH :
-//            case VSPACE_G_MONTHDAY :
-//            case VSPACE_G_YEAR :
-//            case VSPACE_G_YEARMONTH :
-//            case VSPACE_DURATION :
-//                throw new ARQInternalErrorException("Still seeing date/dateTime/time/duration compare type");
-//
-//            case VSPACE_NUM :
-//                return XSDFuncOp.compareNumeric(nv1, nv2);
-//            case VSPACE_STRING : {
-//                int cmp = XSDFuncOp.compareString(nv1, nv2);
-//
-//                if ( !sortOrderingCompare )
-//                    return cmp;
-//                if ( cmp != CMP_EQUAL )
-//                    return cmp;
-//
-//                // Equality.
-//                if ( JenaRuntime.isRDF11 )
-//                    // RDF 1.1 : No literals without datatype.
-//                    return cmp;
-//
-//                // RDF 1.0
-//                // Split plain literals and xsd:strings for sorting purposes.
-//                // Same by string value.
-//                String dt1 = nv1.asNode().getLiteralDatatypeURI();
-//                String dt2 = nv2.asNode().getLiteralDatatypeURI();
-//                if ( dt1 == null && dt2 != null )
-//                    return Expr.CMP_LESS;
-//                if ( dt2 == null && dt1 != null )
-//                    return Expr.CMP_GREATER;
-//                return CMP_EQUAL;  // Both plain or both xsd:string.
-//            }
-//            case VSPACE_SORTKEY :
-//                return nv1.getSortKey().compareTo(nv2.getSortKey());
-//
-//            case VSPACE_BOOLEAN :
-//                return XSDFuncOp.compareBoolean(nv1, nv2);
-//
-//            case VSPACE_LANG : {
-//                // Two literals, both with language tags.
-//                Node node1 = nv1.asNode();
-//                Node node2 = nv2.asNode();
-//
-//                int x = StrUtils.strCompareIgnoreCase(node1.getLiteralLanguage(), node2.getLiteralLanguage());
-//                if ( x != CMP_EQUAL ) {
-//                    // Different lang tags
-//                    if ( !sortOrderingCompare )
-//                        raise(new ExprNotComparableException("Can't compare (different languages) " + nv1 + " and " + nv2));
-//                    // Different lang tags - sorting
-//                    return x;
-//                }
-//
-//                // same lang tag (case insensitive)
-//                x = StrUtils.strCompare(node1.getLiteralLexicalForm(), node2.getLiteralLexicalForm());
-//                if ( x != CMP_EQUAL )
-//                    return x;
-//                // Same lexical forms, same lang tag by value
-//                // Try to split by syntactic lang tags.
-//                x = StrUtils.strCompare(node1.getLiteralLanguage(), node2.getLiteralLanguage());
-//                // Maybe they are the same after all!
-//                // Should be node.equals by now.
-//                if ( x == CMP_EQUAL && !NodeFunctions.sameTerm(node1, node2) )
-//                    throw new ARQInternalErrorException("Looks like the same (lang tags) but not node equals");
-//                return x;
-//            }
-//
-//            case VSPACE_TRIPLE_TERM : {
-//                Triple t1 = nv1.asNode().getTriple();
-//                Triple t2 = nv2.asNode().getTriple();
-//                int x = nCompare(t1.getSubject(), t2.getSubject(), sortOrderingCompare);
-//                if ( x != CMP_EQUAL )
-//                    return x;
-//                x = nCompare(t1.getPredicate(), t2.getPredicate(), sortOrderingCompare);
-//                if ( x != CMP_EQUAL )
-//                    return x;
-//                return nCompare(t1.getObject(), t2.getObject(), sortOrderingCompare);
-//            }
-//
-//            case VSPACE_NODE :
-//                // Two non-literals don't compare except for sorting.
-//                if ( sortOrderingCompare )
-//                    return NodeCmp.compareRDFTerms(nv1.asNode(), nv2.asNode());
-//                else {
-//                    raise(new ExprNotComparableException("Can't compare (nodes) " + nv1 + " and " + nv2));
-//                    throw new ARQInternalErrorException("NodeValue.raise returned");
-//                }
-//
-//            case VSPACE_UNKNOWN : {
-//                // One or two unknown value spaces.
-//                Node node1 = nv1.asNode();
-//                Node node2 = nv2.asNode();
-//                // Two unknown literals can be equal.
-//                if ( NodeFunctions.sameTerm(node1, node2) )
-//                    return CMP_EQUAL;
-//
-//                if ( sortOrderingCompare )
-//                    return NodeCmp.compareRDFTerms(node1, node2);
-//
-//                raise(new ExprNotComparableException("Can't compare " + nv1 + " and " + nv2));
-//                throw new ARQInternalErrorException("NodeValue.raise returned");
-//            }
-//
-//            case VSPACE_DIFFERENT :
-//                // Two literals, from different known value spaces
-//                if ( sortOrderingCompare )
-//                    return NodeCmp.compareRDFTerms(nv1.asNode(), nv2.asNode());
-//                return Expr.CMP_INDETERMINATE;
-//// // ***
-//// raise(new ExprNotComparableException("Can't compare (incompatible value
-//// spaces)"+nv1+" and "+nv2)) ;
-//// throw new ARQInternalErrorException("NodeValue.raise returned") ;
-//        }
-//        throw new ARQInternalErrorException("Compare failure " + nv1 + " and " + nv2);
-//    }
-//
-//    private static int nCompare(Node n1, Node n2, boolean sortOrderingCompare) {
-//        if ( n1.equals(n2) )
-//            return CMP_EQUAL;
-//        NodeValue nv1 = NodeValue.makeNode(n1);
-//        NodeValue nv2 = NodeValue.makeNode(n2);
-//        return compare(nv1, nv2, sortOrderingCompare);
-//    }
-//}


(jena) 09/10: Update contract tests to Jena5

Posted by an...@apache.org.
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 4817c276a237828a0c2a9efba17d763cf44e5a09
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Sun Dec 24 22:34:17 2023 +0000

    Update contract tests to Jena5
---
 .../org/apache/jena/graph/GraphContractTest.java   | 34 ++++------------------
 .../jena/testing_framework/NodeCreateUtils.java    | 20 +++++--------
 2 files changed, 14 insertions(+), 40 deletions(-)

diff --git a/jena-core/src/test/java/org/apache/jena/graph/GraphContractTest.java b/jena-core/src/test/java/org/apache/jena/graph/GraphContractTest.java
index 142bf2eb3a..7433e1fd31 100644
--- a/jena-core/src/test/java/org/apache/jena/graph/GraphContractTest.java
+++ b/jena-core/src/test/java/org/apache/jena/graph/GraphContractTest.java
@@ -18,30 +18,8 @@
 
 package org.apache.jena.graph;
 
-import static org.apache.jena.testing_framework.GraphHelper.assertContainsAll;
-import static org.apache.jena.testing_framework.GraphHelper.assertIsomorphic;
-import static org.apache.jena.testing_framework.GraphHelper.assertOmitsAll;
-import static org.apache.jena.testing_framework.GraphHelper.graphAddTxn;
-import static org.apache.jena.testing_framework.GraphHelper.graphWith;
-import static org.apache.jena.testing_framework.GraphHelper.iteratorToSet;
-import static org.apache.jena.testing_framework.GraphHelper.memGraph;
-import static org.apache.jena.testing_framework.GraphHelper.node;
-import static org.apache.jena.testing_framework.GraphHelper.nodeSet;
-import static org.apache.jena.testing_framework.GraphHelper.triple;
-import static org.apache.jena.testing_framework.GraphHelper.tripleArray;
-import static org.apache.jena.testing_framework.GraphHelper.tripleSet;
-import static org.apache.jena.testing_framework.GraphHelper.txnBegin;
-import static org.apache.jena.testing_framework.GraphHelper.txnRun;
-import static org.apache.jena.testing_framework.GraphHelper.txnCommit;
-import static org.apache.jena.testing_framework.GraphHelper.txnRollback;
-import static org.apache.jena.testing_framework.TestUtils.assertDiffer;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.apache.jena.testing_framework.GraphHelper.*;
+import static org.junit.Assert.*;
 
 import java.io.InputStream;
 import java.net.MalformedURLException;
@@ -858,7 +836,7 @@ public class GraphContractTest<T extends Graph>
 		if (g.getCapabilities().handlesLiteralTyping())
 		{
 			Node chaten = node("'chat'en"), chatEN = node("'chat'EN");
-			assertDiffer(chaten, chatEN);
+			assertEquals(chaten, chatEN);
 			assertTrue(chaten.sameValueAs(chatEN));
 			assertEquals(chaten.getIndexingValue(), chatEN.getIndexingValue());
 			txnBegin(g);
@@ -875,7 +853,7 @@ public class GraphContractTest<T extends Graph>
 		if (g.getCapabilities().handlesLiteralTyping())
 		{
 			Node chaten = node("'chat'en"), chatEN = node("'chat'EN");
-			assertDiffer(chaten, chatEN);
+			assertEquals(chaten, chatEN);
 			assertTrue(chaten.sameValueAs(chatEN));
 			assertEquals(chaten.getIndexingValue(), chatEN.getIndexingValue());
 			txnBegin(g);
@@ -995,7 +973,7 @@ public class GraphContractTest<T extends Graph>
 		if (g.getCapabilities().handlesLiteralTyping())
 		{
 			Node chaten = node("'chat'en"), chatEN = node("'chat'EN");
-			assertDiffer(chaten, chatEN);
+			assertEquals(chaten, chatEN);
 			assertTrue(chaten.sameValueAs(chatEN));
 			assertEquals(chaten.getIndexingValue(), chatEN.getIndexingValue());
 			txnBegin(g);
@@ -1014,7 +992,7 @@ public class GraphContractTest<T extends Graph>
 		if (g.getCapabilities().handlesLiteralTyping())
 		{
 			Node chaten = node("'chat'en"), chatEN = node("'chat'EN");
-			assertDiffer(chaten, chatEN);
+			assertEquals(chaten, chatEN);
 			assertTrue(chaten.sameValueAs(chatEN));
 			assertEquals(chaten.getIndexingValue(), chatEN.getIndexingValue());
 			txnBegin(g);
diff --git a/jena-core/src/test/java/org/apache/jena/testing_framework/NodeCreateUtils.java b/jena-core/src/test/java/org/apache/jena/testing_framework/NodeCreateUtils.java
index 7feab5f958..7763d6d80a 100644
--- a/jena-core/src/test/java/org/apache/jena/testing_framework/NodeCreateUtils.java
+++ b/jena-core/src/test/java/org/apache/jena/testing_framework/NodeCreateUtils.java
@@ -25,8 +25,6 @@ import org.apache.jena.datatypes.xsd.XSDDatatype ;
 import org.apache.jena.graph.Node ;
 import org.apache.jena.graph.NodeFactory ;
 import org.apache.jena.graph.Triple ;
-import org.apache.jena.graph.impl.LiteralLabel ;
-import org.apache.jena.graph.impl.LiteralLabelFactory ;
 import org.apache.jena.shared.JenaException ;
 import org.apache.jena.shared.PrefixMapping ;
 
@@ -80,14 +78,13 @@ public class NodeCreateUtils {
 	 *            the string encoding the node to create
 	 * @return a node with the appropriate type and label
 	 */
-    @SuppressWarnings("deprecation")
 	public static Node create(PrefixMapping pm, String x) {
 		if (x.equals(""))
 			throw new JenaException(
 					"Node.create does not accept an empty string as argument");
 		char first = x.charAt(0);
 		if (first == '\'' || first == '\"')
-			return NodeFactory.createLiteral(newString(pm, first, x));
+			return newLiteral(pm, first, x);
 		if (Character.isDigit(first))
 			return NodeFactory.createLiteral(x, "", XSDDatatype.XSDinteger);
 		if (first == '_')
@@ -138,21 +135,20 @@ public class NodeCreateUtils {
 		}
 	}
 
-	public static LiteralLabel literal(PrefixMapping pm, String spelling,
-			String langOrType) {
+	public static Node literal(PrefixMapping pm, String spelling, String langOrType) {
 		String content = unEscape(spelling);
 		int colon = langOrType.indexOf(':');
-		if ( colon < 0 )
-		    return LiteralLabelFactory.createLang(content, langOrType);
-		else {
+		if ( colon < 0 ) {
+		    // It's a language
+		    return NodeFactory.createLiteralLang(content, langOrType);
+		} else {
 		    String dtURI = pm.expandPrefix(langOrType);
 		    RDFDatatype dt = NodeFactory.getType(dtURI);
-		    return LiteralLabelFactory.create(content, dt);
+		    return NodeFactory.createLiteral(content, dt);
 		}
 	}
 
-	public static LiteralLabel newString(PrefixMapping pm, char quote,
-			String nodeString) {
+	public static Node newLiteral(PrefixMapping pm, char quote, String nodeString) {
 		int close = nodeString.lastIndexOf(quote);
 		return literal(pm, nodeString.substring(1, close),
 				nodeString.substring(close + 1));


(jena) 04/10: GH-2126: NodeFactory.createLiteralString

Posted by an...@apache.org.
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 8ef58490684db6174901a62fc0ddaed404231db1
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Sat Dec 9 16:47:00 2023 +0000

    GH-2126: NodeFactory.createLiteralString
---
 .../riot/process/normalize/NormalizeValue.java     |  4 +-
 .../apache/jena/riot/protobuf/ProtobufConvert.java |  2 +-
 .../jena/riot/rowset/rw/RowSetReaderCSV.java       |  2 +-
 .../org/apache/jena/riot/system/FactoryRDFStd.java |  2 +-
 .../java/org/apache/jena/riot/tokens/Token.java    |  2 +-
 .../org/apache/jena/sparql/expr/NodeValue.java     |  2 +-
 .../sparql/expr/nodevalue/NodeValueSortKey.java    |  2 +-
 .../sparql/expr/nodevalue/NodeValueString.java     |  2 +-
 .../org/apache/jena/sparql/graph/NodeConst.java    |  2 +-
 .../apache/jena/sparql/lang/QueryParserBase.java   |  2 +-
 .../jena/sparql/pfunction/library/blankNode.java   |  2 +-
 .../jena/sparql/pfunction/library/concat.java      |  2 +-
 .../jena/sparql/pfunction/library/splitIRI.java    |  2 +-
 .../apache/jena/sparql/pfunction/library/str.java  |  2 +-
 .../jena/sparql/pfunction/library/strSplit.java    |  2 +-
 .../main/java/org/apache/jena/sparql/sse/Item.java |  2 +-
 .../jena/arq/junit/sparql/tests/QueryEvalTest.java |  2 +-
 .../jena/atlas/data/TestDistinctDataBag.java       | 10 +--
 .../jena/atlas/data/TestDistinctDataNet.java       |  4 +-
 .../apache/jena/atlas/data/TestSortedDataBag.java  |  4 +-
 .../jena/query/TestParameterizedSparqlString.java  | 18 ++--
 .../apache/jena/riot/thrift/TestThriftTerm.java    |  2 +-
 .../org/apache/jena/riot/writer/TestRDFJSON.java   |  6 +-
 .../algebra/optimize/TestSemanticEquivalence.java  |  2 +-
 .../iterator/AbstractTestDistinctReduced.java      |  2 +-
 .../sparql/engine/iterator/TestQueryIterSort.java  |  4 +-
 .../iterator/TestSortedDataBagCancellation.java    |  8 +-
 .../apache/jena/sparql/expr/TestExpressions.java   |  2 +-
 .../apache/jena/sparql/expr/TestNodeFunctions.java | 26 +++---
 .../org/apache/jena/sparql/expr/TestNodeValue.java |  2 +-
 .../org/apache/jena/sparql/expr/TestOrdering.java  | 18 ++--
 .../org/apache/jena/sparql/expr/TestXSDFuncOp.java |  2 +-
 .../jena/sparql/graph/TestGraphUnionRead.java      |  4 +-
 .../sparql/pfunction/library/TestStrSplit.java     |  2 +-
 .../org/apache/jena/sparql/sse/TestSSE_Basic.java  |  2 +-
 .../org/apache/jena/sparql/util/TestFmtUtils.java  |  6 +-
 .../java/org/apache/jena/graph/NodeFactory.java    | 23 +++--
 .../org/apache/jena/rdf/model/impl/ModelCom.java   |  4 +-
 .../org/apache/jena/reasoner/rulesys/Rule.java     |  2 +-
 .../jena/reasoner/rulesys/builtins/Regex.java      |  2 +-
 .../jena/reasoner/rulesys/builtins/StrConcat.java  |  2 +-
 .../org/apache/jena/graph/test/TestNodeExtras.java |  2 +-
 .../jena/reasoner/rulesys/test/TestFBRules.java    | 76 ++++++++---------
 .../jena/testing_framework/TestFileData.java       |  4 +-
 .../arq/examples/propertyfunction/localname.java   |  4 +-
 .../arq/examples/propertyfunction/uppercase.java   |  2 +-
 .../apache/jena/commonsrdf/impl/JCR_Factory.java   |  2 +-
 .../jena/arq/querybuilder/AskBuilderTest.java      |  2 +-
 .../arq/querybuilder/ConstructBuilderTest.java     |  2 +-
 .../jena/arq/querybuilder/ConvertersTest.java      |  4 +-
 .../jena/arq/querybuilder/SelectBuilderTest.java   |  2 +-
 .../jena/arq/querybuilder/UpdateBuilderTest.java   |  2 +-
 .../arq/querybuilder/clauses/ValuesClauseTest.java | 98 +++++++++++-----------
 .../arq/querybuilder/clauses/WhereClauseTest.java  | 22 ++---
 .../querybuilder/handlers/ValuesHandlerTest.java   | 70 ++++++++--------
 .../querybuilder/handlers/WhereHandlerTest.java    | 30 +++----
 .../rewriters/NodeValueRewriterTest.java           |  4 +-
 .../service/enhancer/init/ServiceEnhancerInit.java |  2 +-
 .../sparql/service/enhancer/pfunction/cacheLs.java |  4 +-
 .../TestServiceEnhancerBatchQueryRewriter.java     |  4 +-
 .../apache/jena/fuseki/access/SecurityContext.java |  4 +-
 .../org/apache/jena/fuseki/mgt/ActionDatasets.java |  2 +-
 .../permissions/model/impl/SecuredLiteralImpl.java |  2 +-
 .../java/org/apache/jena/rdfpatch/system/Id.java   |  2 +-
 .../org/apache/jena/shacl/ValidationReport.java    |  2 +-
 .../shacl/engine/constraint/SparqlValidation.java  |  2 +-
 .../apache/jena/shacl/validation/ReportEntry.java  |  2 +-
 .../apache/jena/tdb1/store/DatasetPrefixesTDB.java |  6 +-
 .../jena/tdb2/loader/main/PrefixHandlerBulk.java   |  2 +-
 .../apache/jena/tdb2/store/StoragePrefixesTDB.java |  6 +-
 .../apache/jena/query/text/TextIndexLucene.java    |  2 +-
 .../text/TestDatasetWithLuceneStoredLiterals.java  | 12 +--
 .../query/text/TestLuceneWithMultipleThreads.java  |  2 +-
 .../jena/query/text/TestTextHighlighting.java      |  6 +-
 74 files changed, 290 insertions(+), 291 deletions(-)

diff --git a/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/NormalizeValue.java b/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/NormalizeValue.java
index b29d10d06c..56ec85801a 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/NormalizeValue.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/NormalizeValue.java
@@ -184,7 +184,7 @@ class NormalizeValue
     } ;
 
     /** Convert xsd:string to simple literal */
-    static DatatypeHandler dtXSDString = (Node node, String lexicalForm, RDFDatatype datatype) -> NodeFactory.createLiteral(lexicalForm) ;
+    static DatatypeHandler dtXSDString = (Node node, String lexicalForm, RDFDatatype datatype) -> NodeFactory.createLiteralString(lexicalForm) ;
 
     /** Convert simple literal to xsd:string */
     static DatatypeHandler dtSimpleLiteral = (Node node, String lexicalForm, RDFDatatype datatype) -> NodeFactory.createLiteral(lexicalForm, datatype) ;
@@ -200,7 +200,7 @@ class NormalizeValue
 
         String lex = lexicalForm.substring(0, idx) ;
         if ( idx == lexicalForm.length()-1 )
-            return NodeFactory.createLiteral(lex) ;
+            return NodeFactory.createLiteralString(lex) ;
         String lang = lexicalForm.substring(idx+1) ;
         return NodeFactory.createLiteralLang(lex, lang) ;
     } ;
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/protobuf/ProtobufConvert.java b/jena-arq/src/main/java/org/apache/jena/riot/protobuf/ProtobufConvert.java
index 7dd31d1cf4..be45a6e669 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/protobuf/ProtobufConvert.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/protobuf/ProtobufConvert.java
@@ -173,7 +173,7 @@ public class ProtobufConvert
                     String lex = lit.getLex() ;
                     switch ( lit.getLiteralKindCase() ) {
                         case SIMPLE :
-                            return NodeFactory.createLiteral(lex) ;
+                            return NodeFactory.createLiteralString(lex) ;
                         case LANGTAG : {
                             String lang = lit.getLangtag();
                             return NodeFactory.createLiteralLang(lex, lang) ;
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/rowset/rw/RowSetReaderCSV.java b/jena-arq/src/main/java/org/apache/jena/riot/rowset/rw/RowSetReaderCSV.java
index e5b63d069c..054a04c87f 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/rowset/rw/RowSetReaderCSV.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/rowset/rw/RowSetReaderCSV.java
@@ -100,7 +100,7 @@ public class RowSetReaderCSV implements RowSetReader {
                 for ( int i = 0 ; i < vars.size() ; i++ ) {
                     Var v = vars.get(i);
                     String field = (i < row.size()) ? row.get(i) : "";
-                    Node n = NodeFactory.createLiteral(field);
+                    Node n = NodeFactory.createLiteralString(field);
                     builder.add(v, n);
                 }
                 count++;
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/system/FactoryRDFStd.java b/jena-arq/src/main/java/org/apache/jena/riot/system/FactoryRDFStd.java
index 7cc7d87ad2..f0a5335823 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/system/FactoryRDFStd.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/system/FactoryRDFStd.java
@@ -67,7 +67,7 @@ public class FactoryRDFStd implements FactoryRDF {
 
     @Override
     public Node createStringLiteral(String lexical) {
-        return NodeFactory.createLiteral(lexical) ;
+        return NodeFactory.createLiteralString(lexical) ;
     }
 
     @Override
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/tokens/Token.java b/jena-arq/src/main/java/org/apache/jena/riot/tokens/Token.java
index 6218d85a0e..f5c2b5cd63 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/tokens/Token.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/tokens/Token.java
@@ -404,7 +404,7 @@ public final class Token
             case LITERAL_LANG :
                 return NodeFactory.createLiteralLang(tokenImage, tokenImage2);
             case STRING :
-                return NodeFactory.createLiteral(tokenImage);
+                return NodeFactory.createLiteralString(tokenImage);
             case VAR :
                 return Var.alloc(tokenImage);
             case KEYWORD :
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 06f315e9ec..af69337971 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
@@ -282,7 +282,7 @@ public abstract class NodeValue extends ExprNode
             RDFDatatype dType = TypeMapper.getInstance().getSafeTypeByName(datatype) ;
             n = NodeFactory.createLiteral(lexicalForm, dType) ;
         } else
-            n = NodeFactory.createLiteral(lexicalForm) ;
+            n = NodeFactory.createLiteralString(lexicalForm) ;
 
         return NodeValue.makeNode(n) ;
     }
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueSortKey.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueSortKey.java
index 44051a3a39..5e797e2d5f 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueSortKey.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueSortKey.java
@@ -86,7 +86,7 @@ public final class NodeValueSortKey extends NodeValue implements Comparable<Node
      */
     @Override
     protected Node makeNode() {
-        return NodeFactory.createLiteral(string);
+        return NodeFactory.createLiteralString(string);
     }
 
     @Override
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueString.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueString.java
index a921c433ad..2d64c6243d 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueString.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueString.java
@@ -55,7 +55,7 @@ public class NodeValueString extends NodeValue
     
     @Override
     protected Node makeNode()
-    { return NodeFactory.createLiteral(string) ; }
+    { return NodeFactory.createLiteralString(string) ; }
     
     @Override
     public void visit(NodeValueVisitor visitor) { visitor.visit(this) ; }
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/graph/NodeConst.java b/jena-arq/src/main/java/org/apache/jena/sparql/graph/NodeConst.java
index b86c9a16bf..51ea1d48eb 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/graph/NodeConst.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/graph/NodeConst.java
@@ -45,7 +45,7 @@ public class NodeConst {
     public static final Node nodeTwo       = literal("2", XSDDatatype.XSDinteger);
     public static final Node nodeTen       = literal("10", XSDDatatype.XSDinteger);
     public static final Node nodeMinusOne  = literal("-1", XSDDatatype.XSDinteger);
-    public static final Node emptyString   = NodeFactory.createLiteral("");
+    public static final Node emptyString   = NodeFactory.createLiteralString("");
     public static final Node TRUE = NodeConst.nodeTrue;
     public static final Node FALSE = NodeConst.nodeFalse;
 
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/lang/QueryParserBase.java b/jena-arq/src/main/java/org/apache/jena/sparql/lang/QueryParserBase.java
index ec4e3144ea..a8a84ec428 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/lang/QueryParserBase.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/lang/QueryParserBase.java
@@ -217,7 +217,7 @@ public class QueryParserBase
         } else if ( langTag != null && !langTag.isEmpty() )
             n = NodeFactory.createLiteralLang(lexicalForm, langTag);
         else
-            n = NodeFactory.createLiteral(lexicalForm);
+            n = NodeFactory.createLiteralString(lexicalForm);
         return n;
     }
 
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/library/blankNode.java b/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/library/blankNode.java
index bde4cdc4b9..af79c3e98a 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/library/blankNode.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/library/blankNode.java
@@ -40,7 +40,7 @@ public class blankNode extends PFuncSimple
         if ( ! subject.isBlank() )
             return IterLib.noResults(execCxt) ;
         String str = subject.getBlankNodeLabel() ;
-        Node obj = NodeFactory.createLiteral(str) ;
+        Node obj = NodeFactory.createLiteralString(str) ;
         if ( Var.isVar(object) )
             return IterLib.oneResult(binding, Var.alloc(object), obj, execCxt) ;
         
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/library/concat.java b/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/library/concat.java
index 1944736916..daa6ee7c71 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/library/concat.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/library/concat.java
@@ -48,7 +48,7 @@ public class concat extends PFuncSimpleAndList
             x = x+str ;
         }
          
-        return IterLib.oneResult(binding, Var.alloc(subject), NodeFactory.createLiteral(x), execCxt) ;
+        return IterLib.oneResult(binding, Var.alloc(subject), NodeFactory.createLiteralString(x), execCxt) ;
     }
 
 }
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/library/splitIRI.java b/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/library/splitIRI.java
index 867ee5629a..4ca5663ac7 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/library/splitIRI.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/library/splitIRI.java
@@ -122,7 +122,7 @@ public class splitIRI extends PropertyFunctionEval
         }
 
         if ( Var.isVar(localnameNode) )
-            builder.add(Var.alloc(localnameNode), NodeFactory.createLiteral(localname)) ;
+            builder.add(Var.alloc(localnameNode), NodeFactory.createLiteralString(localname)) ;
         else
         {
             // Only string literals (plain strings or datatype xsd:string)
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/library/str.java b/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/library/str.java
index f15fcd2874..3b19996c52 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/library/str.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/library/str.java
@@ -62,7 +62,7 @@ public class str extends PFuncSimple
         if ( object.isBlank() )
             throw new QueryExecException("str: object is a blank node") ;
         
-        Node strValue =  NodeFactory.createLiteral(NodeFunctions.str(object)) ;
+        Node strValue =  NodeFactory.createLiteralString(NodeFunctions.str(object)) ;
         
         if ( Var.isVar(subject) )
             return IterLib.oneResult(binding, Var.alloc(subject), strValue, execCxt) ;
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/library/strSplit.java b/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/library/strSplit.java
index 5effc04610..97f81c3b88 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/library/strSplit.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/library/strSplit.java
@@ -80,7 +80,7 @@ public class strSplit extends PFuncSimpleAndList
 
             Iterator<Binding> it = Iter.map(
                     tokens.iterator(),
-                    item -> BindingFactory.binding(binding, subjectVar, NodeFactory.createLiteral(item)));
+                    item -> BindingFactory.binding(binding, subjectVar, NodeFactory.createLiteralString(item)));
             return QueryIterPlainWrapper.create(it, execCxt);
 
         } else if ( Util.isSimpleString(subject) ) {
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/sse/Item.java b/jena-arq/src/main/java/org/apache/jena/sparql/sse/Item.java
index e195581bc0..5ec2e5f0f0 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/sse/Item.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/sse/Item.java
@@ -97,7 +97,7 @@ public class Item extends ItemLocation {
     }
 
     public static void addPair(ItemList list, String key, String value) {
-        addPair(list, Item.createSymbol(key), Item.createNode(NodeFactory.createLiteral(value)));
+        addPair(list, Item.createSymbol(key), Item.createNode(NodeFactory.createLiteralString(value)));
     }
 
     public static void addPair(ItemList list, String key, Node node) {
diff --git a/jena-arq/src/test/java/org/apache/jena/arq/junit/sparql/tests/QueryEvalTest.java b/jena-arq/src/test/java/org/apache/jena/arq/junit/sparql/tests/QueryEvalTest.java
index 9d8aa060e9..ce1b51a95f 100644
--- a/jena-arq/src/test/java/org/apache/jena/arq/junit/sparql/tests/QueryEvalTest.java
+++ b/jena-arq/src/test/java/org/apache/jena/arq/junit/sparql/tests/QueryEvalTest.java
@@ -273,7 +273,7 @@ public class QueryEvalTest implements Runnable {
                     s = "_:" + n.getBlankNodeLabel();
                 else
                     s = NodeFunctions.str(n);
-                builder.add(v, NodeFactory.createLiteral(s));
+                builder.add(v, NodeFactory.createLiteralString(s));
             }
             bindings.add(builder.build());
         }
diff --git a/jena-arq/src/test/java/org/apache/jena/atlas/data/TestDistinctDataBag.java b/jena-arq/src/test/java/org/apache/jena/atlas/data/TestDistinctDataBag.java
index 1de25bbc1e..463b81df3f 100644
--- a/jena-arq/src/test/java/org/apache/jena/atlas/data/TestDistinctDataBag.java
+++ b/jena-arq/src/test/java/org/apache/jena/atlas/data/TestDistinctDataBag.java
@@ -161,11 +161,11 @@ public class TestDistinctDataBag
         builder.add(vars[0], NodeFactory.createBlankNode());
         builder.add(vars[1], NodeFactory.createURI(randomURI()));
         builder.add(vars[2], NodeFactory.createURI(randomURI()));
-        builder.add(vars[3], NodeFactory.createLiteral(randomString(20)));
+        builder.add(vars[3], NodeFactory.createLiteralString(randomString(20)));
         builder.add(vars[4], NodeFactory.createBlankNode());
         builder.add(vars[5], NodeFactory.createURI(randomURI()));
         builder.add(vars[6], NodeFactory.createURI(randomURI()));
-        builder.add(vars[7], NodeFactory.createLiteral(randomString(5)));
+        builder.add(vars[7], NodeFactory.createLiteralString(randomString(5)));
         builder.add(vars[8], NodeFactory.createLiteral("" + random.nextInt(), XSDDatatype.XSDinteger));
         builder.add(vars[9], NodeFactory.createBlankNode());
         return builder.build();
@@ -190,10 +190,10 @@ public class TestDistinctDataBag
         // JENA-1770
         // Setup a situation where the second binding in a spill file binds more
         // variables than the first binding.
-        Binding binding1 = BindingFactory.binding(Var.alloc("1"), NodeFactory.createLiteral("A"));
+        Binding binding1 = BindingFactory.binding(Var.alloc("1"), NodeFactory.createLiteralString("A"));
 
-        Binding binding2 = BindingFactory.binding(Var.alloc("1"), NodeFactory.createLiteral("A"),
-                                                  Var.alloc("2"), NodeFactory.createLiteral("B"));
+        Binding binding2 = BindingFactory.binding(Var.alloc("1"), NodeFactory.createLiteralString("A"),
+                                                  Var.alloc("2"), NodeFactory.createLiteralString("B"));
 
         List<Binding> undistinct = Arrays.asList(binding1, binding2, binding1);
         List<Binding> control = Iter.toList(Iter.distinct(undistinct.iterator()));
diff --git a/jena-arq/src/test/java/org/apache/jena/atlas/data/TestDistinctDataNet.java b/jena-arq/src/test/java/org/apache/jena/atlas/data/TestDistinctDataNet.java
index 40b7a4e80c..df7dce0c0c 100644
--- a/jena-arq/src/test/java/org/apache/jena/atlas/data/TestDistinctDataNet.java
+++ b/jena-arq/src/test/java/org/apache/jena/atlas/data/TestDistinctDataNet.java
@@ -266,11 +266,11 @@ public class TestDistinctDataNet
         builder.add(vars[0], NodeFactory.createBlankNode());
         builder.add(vars[1], NodeFactory.createURI(randomURI()));
         builder.add(vars[2], NodeFactory.createURI(randomURI()));
-        builder.add(vars[3], NodeFactory.createLiteral(randomString(20)));
+        builder.add(vars[3], NodeFactory.createLiteralString(randomString(20)));
         builder.add(vars[4], NodeFactory.createBlankNode());
         builder.add(vars[5], NodeFactory.createURI(randomURI()));
         builder.add(vars[6], NodeFactory.createURI(randomURI()));
-        builder.add(vars[7], NodeFactory.createLiteral(randomString(5)));
+        builder.add(vars[7], NodeFactory.createLiteralString(randomString(5)));
         builder.add(vars[8], NodeFactory.createLiteral("" + random.nextInt(), XSDDatatype.XSDinteger));
         builder.add(vars[9], NodeFactory.createBlankNode());
         return builder.build();
diff --git a/jena-arq/src/test/java/org/apache/jena/atlas/data/TestSortedDataBag.java b/jena-arq/src/test/java/org/apache/jena/atlas/data/TestSortedDataBag.java
index 683a74f895..fb5720090f 100644
--- a/jena-arq/src/test/java/org/apache/jena/atlas/data/TestSortedDataBag.java
+++ b/jena-arq/src/test/java/org/apache/jena/atlas/data/TestSortedDataBag.java
@@ -181,11 +181,11 @@ public class TestSortedDataBag
         builder.add(vars[0], NodeFactory.createBlankNode());
         builder.add(vars[1], NodeFactory.createURI(randomURI()));
         builder.add(vars[2], NodeFactory.createURI(randomURI()));
-        builder.add(vars[3], NodeFactory.createLiteral(randomString(20)));
+        builder.add(vars[3], NodeFactory.createLiteralString(randomString(20)));
         builder.add(vars[4], NodeFactory.createBlankNode());
         builder.add(vars[5], NodeFactory.createURI(randomURI()));
         builder.add(vars[6], NodeFactory.createURI(randomURI()));
-        builder.add(vars[7], NodeFactory.createLiteral(randomString(5)));
+        builder.add(vars[7], NodeFactory.createLiteralString(randomString(5)));
         builder.add(vars[8], NodeFactory.createLiteral("" + random.nextInt(), XSDDatatype.XSDinteger));
         builder.add(vars[9], NodeFactory.createBlankNode());
         return builder.build();
diff --git a/jena-arq/src/test/java/org/apache/jena/query/TestParameterizedSparqlString.java b/jena-arq/src/test/java/org/apache/jena/query/TestParameterizedSparqlString.java
index 0e954dee8d..9309bd529e 100644
--- a/jena-arq/src/test/java/org/apache/jena/query/TestParameterizedSparqlString.java
+++ b/jena-arq/src/test/java/org/apache/jena/query/TestParameterizedSparqlString.java
@@ -1263,7 +1263,7 @@ public class TestParameterizedSparqlString {
         ParameterizedSparqlString query = new ParameterizedSparqlString(cmdText);
         query.setParam(0, NodeFactory.createURI("http://example.org"));
         query.setParam(1, NodeFactory.createURI("http://predicate"));
-        query.setParam(2, NodeFactory.createLiteral("test"));
+        query.setParam(2, NodeFactory.createLiteralString("test"));
 
         Assert.assertEquals("SELECT * WHERE { <http://example.org> <http://predicate> \"test\" . }", query.toString());
     }
@@ -1273,9 +1273,9 @@ public class TestParameterizedSparqlString {
         // Test regular string injection
         String cmdText = "SELECT * WHERE { ? ? ? . }";
         ParameterizedSparqlString query = new ParameterizedSparqlString(cmdText);
-        query.setParam(0, NodeFactory.createLiteral("with ? mark"));
+        query.setParam(0, NodeFactory.createLiteralString("with ? mark"));
         query.setParam(1, NodeFactory.createURI("http://predicate"));
-        query.setParam(2, NodeFactory.createLiteral("test"));
+        query.setParam(2, NodeFactory.createLiteralString("test"));
 
         Assert.assertEquals("SELECT * WHERE { \"with ? mark\" <http://predicate> \"test\" . }", query.toString());
     }
@@ -1285,9 +1285,9 @@ public class TestParameterizedSparqlString {
         // Test regular string injection
         String cmdText = "SELECT * WHERE { ? ? ? . }";
         ParameterizedSparqlString query = new ParameterizedSparqlString(cmdText);
-        query.setParam(0, NodeFactory.createLiteral("with ? mark"));
-        query.setParam(1, NodeFactory.createLiteral("with ? mark"));
-        query.setParam(2, NodeFactory.createLiteral("test"));
+        query.setParam(0, NodeFactory.createLiteralString("with ? mark"));
+        query.setParam(1, NodeFactory.createLiteralString("with ? mark"));
+        query.setParam(2, NodeFactory.createLiteralString("test"));
 
         Assert.assertEquals("SELECT * WHERE { \"with ? mark\" \"with ? mark\" \"test\" . }", query.toString());
     }
@@ -1299,7 +1299,7 @@ public class TestParameterizedSparqlString {
         ParameterizedSparqlString query = new ParameterizedSparqlString(cmdText);
         query.setParam(0, NodeFactory.createURI("http://example.org"));
         query.setParam(1, NodeFactory.createURI("http://predicate"));
-        query.setParam(2, NodeFactory.createLiteral("test"));
+        query.setParam(2, NodeFactory.createLiteralString("test"));
 
         Assert.assertEquals("SELECT * WHERE { <http://example.org> <http://predicate> \"test\". }", query.toString());
     }
@@ -1311,7 +1311,7 @@ public class TestParameterizedSparqlString {
         ParameterizedSparqlString query = new ParameterizedSparqlString(cmdText);
         query.setParam(0, NodeFactory.createURI("http://example.org"));
         query.setParam(1, NodeFactory.createURI("http://predicate"));
-        query.setParam(2, NodeFactory.createLiteral("test"));
+        query.setParam(2, NodeFactory.createLiteralString("test"));
 
         Assert.assertEquals("SELECT * WHERE { <http://example.org> <http://predicate> \"test\"; ?p ?o . }", query.toString());
     }
@@ -1323,7 +1323,7 @@ public class TestParameterizedSparqlString {
         ParameterizedSparqlString query = new ParameterizedSparqlString(cmdText);
         query.setParam(0, NodeFactory.createURI("http://example.org"));
         query.setParam(1, NodeFactory.createURI("http://predicate"));
-        query.setParam(2, NodeFactory.createLiteral("test"));
+        query.setParam(2, NodeFactory.createLiteralString("test"));
 
         Assert.assertEquals("SELECT * WHERE { <http://example.org> <http://predicate> \"test\", ?o . }", query.toString());
     }
diff --git a/jena-arq/src/test/java/org/apache/jena/riot/thrift/TestThriftTerm.java b/jena-arq/src/test/java/org/apache/jena/riot/thrift/TestThriftTerm.java
index abf6273b2b..d23b8146eb 100644
--- a/jena-arq/src/test/java/org/apache/jena/riot/thrift/TestThriftTerm.java
+++ b/jena-arq/src/test/java/org/apache/jena/riot/thrift/TestThriftTerm.java
@@ -314,7 +314,7 @@ public class TestThriftTerm {
     }
 
     @Test public void round_trip_bytes_02() {
-        testTermBytes(NodeFactory.createLiteral("value"));
+        testTermBytes(NodeFactory.createLiteralString("value"));
     }
 
     @Test public void round_trip_bytes_03() {
diff --git a/jena-arq/src/test/java/org/apache/jena/riot/writer/TestRDFJSON.java b/jena-arq/src/test/java/org/apache/jena/riot/writer/TestRDFJSON.java
index 634c15d6a6..0d0a43dcc6 100644
--- a/jena-arq/src/test/java/org/apache/jena/riot/writer/TestRDFJSON.java
+++ b/jena-arq/src/test/java/org/apache/jena/riot/writer/TestRDFJSON.java
@@ -146,9 +146,9 @@ public class TestRDFJSON {
         Graph g = GraphFactory.createGraphMem();
         Node s = NodeFactory.createBlankNode();
         Node p = NodeFactory.createURI("http://host");
-        g.add(Triple.create(s, p, NodeFactory.createLiteral("quote \" character")));
-        g.add(Triple.create(s, p, NodeFactory.createLiteral("new \n\r lines")));
-        g.add(Triple.create(s, p, NodeFactory.createLiteral("tab \t character")));
+        g.add(Triple.create(s, p, NodeFactory.createLiteralString("quote \" character")));
+        g.add(Triple.create(s, p, NodeFactory.createLiteralString("new \n\r lines")));
+        g.add(Triple.create(s, p, NodeFactory.createLiteralString("tab \t character")));
         test(g);
     }
 
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/algebra/optimize/TestSemanticEquivalence.java b/jena-arq/src/test/java/org/apache/jena/sparql/algebra/optimize/TestSemanticEquivalence.java
index 7820a7e026..159aff2697 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/algebra/optimize/TestSemanticEquivalence.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/algebra/optimize/TestSemanticEquivalence.java
@@ -62,7 +62,7 @@ public class TestSemanticEquivalence {
         Node p1 = NodeFactory.createURI("http://p1");
         Node p2 = NodeFactory.createURI("http://p2");
         Node pSelf = NodeFactory.createURI("http://self");
-        Node o = NodeFactory.createLiteral("object");
+        Node o = NodeFactory.createLiteralString("object");
 
         DatasetGraph dsg = implJoin.asDatasetGraph();
         dsg.add(Quad.defaultGraphNodeGenerated, a, p1, o);
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/engine/iterator/AbstractTestDistinctReduced.java b/jena-arq/src/test/java/org/apache/jena/sparql/engine/iterator/AbstractTestDistinctReduced.java
index 99e981e75d..1b1f33a7d0 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/engine/iterator/AbstractTestDistinctReduced.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/engine/iterator/AbstractTestDistinctReduced.java
@@ -43,7 +43,7 @@ public abstract class AbstractTestDistinctReduced {
 
     private static List<Binding> build(List<String> items) {
         return items.stream().sequential()
-                .map((s)-> BindingFactory.binding(var_a, NodeFactory.createLiteral(s)))
+                .map((s)-> BindingFactory.binding(var_a, NodeFactory.createLiteralString(s)))
                 .collect(Collectors.toList());
     }
 
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/engine/iterator/TestQueryIterSort.java b/jena-arq/src/test/java/org/apache/jena/sparql/engine/iterator/TestQueryIterSort.java
index c21d4b69e1..34ceb2827e 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/engine/iterator/TestQueryIterSort.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/engine/iterator/TestQueryIterSort.java
@@ -308,11 +308,11 @@ public class TestQueryIterSort {
         builder.add(vars[0], NodeFactory.createBlankNode());
         builder.add(vars[1], NodeFactory.createURI(randomURI()));
         builder.add(vars[2], NodeFactory.createURI(randomURI()));
-        builder.add(vars[3], NodeFactory.createLiteral(randomString(20)));
+        builder.add(vars[3], NodeFactory.createLiteralString(randomString(20)));
         builder.add(vars[4], NodeFactory.createBlankNode());
         builder.add(vars[5], NodeFactory.createURI(randomURI()));
         builder.add(vars[6], NodeFactory.createURI(randomURI()));
-        builder.add(vars[7], NodeFactory.createLiteral(randomString(5)));
+        builder.add(vars[7], NodeFactory.createLiteralString(randomString(5)));
         builder.add(vars[8], NodeFactory.createLiteral("" + random.nextInt(), XSDDatatype.XSDinteger));
         builder.add(vars[9], NodeFactory.createBlankNode());
         return builder.build();
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/engine/iterator/TestSortedDataBagCancellation.java b/jena-arq/src/test/java/org/apache/jena/sparql/engine/iterator/TestSortedDataBagCancellation.java
index f240a53b9c..5161a9bb14 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/engine/iterator/TestSortedDataBagCancellation.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/engine/iterator/TestSortedDataBagCancellation.java
@@ -56,10 +56,10 @@ import org.junit.Test;
 */
 public class TestSortedDataBagCancellation {
 
-    static final Binding b1 = BindingFactory.binding(Var.alloc("v1"), NodeFactory.createLiteral("alpha"));
-    static final Binding b2 = BindingFactory.binding(Var.alloc("v2"), NodeFactory.createLiteral("beta"));
-    static final Binding b3 = BindingFactory.binding(Var.alloc("v3"), NodeFactory.createLiteral("gamma"));
-    static final Binding b4 = BindingFactory.binding(Var.alloc("v4"), NodeFactory.createLiteral("delta"));
+    static final Binding b1 = BindingFactory.binding(Var.alloc("v1"), NodeFactory.createLiteralString("alpha"));
+    static final Binding b2 = BindingFactory.binding(Var.alloc("v2"), NodeFactory.createLiteralString("beta"));
+    static final Binding b3 = BindingFactory.binding(Var.alloc("v3"), NodeFactory.createLiteralString("gamma"));
+    static final Binding b4 = BindingFactory.binding(Var.alloc("v4"), NodeFactory.createLiteralString("delta"));
 
     final Context params = new Context();
 
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions.java b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions.java
index 6286107c91..e3282f8964 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions.java
@@ -419,7 +419,7 @@ public class TestExpressions
         query.setPrefix("select",  selNS) ;
     }
     static String xsd = XSDDatatype.XSD+"#" ;
-    static Binding env = BindingFactory.binding(Var.alloc("a"), NodeFactory.createLiteral("A"),
+    static Binding env = BindingFactory.binding(Var.alloc("a"), NodeFactory.createLiteralString("A"),
                                                 Var.alloc("b"), NodeFactory.createBlankNode(),
                                                 Var.alloc("x"), NodeFactory.createURI("urn:ex:abcd")) ;
 
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeFunctions.java b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeFunctions.java
index 65140ac773..e3f0bf5fd7 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeFunctions.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeFunctions.java
@@ -38,32 +38,32 @@ public class TestNodeFunctions {
     private static final double accuracyClose = 0.000001d ;
 
     @Test public void testSameTerm1() {
-        Node n1 = NodeFactory.createLiteral("xyz") ;
-        Node n2 = NodeFactory.createLiteral("xyz") ;
+        Node n1 = NodeFactory.createLiteralString("xyz") ;
+        Node n2 = NodeFactory.createLiteralString("xyz") ;
         assertTrue(NodeFunctions.sameTerm(n1, n2)) ;
     }
 
     @Test public void testSameTerm2() {
-        Node n1 = NodeFactory.createLiteral("xyz") ;
-        Node n2 = NodeFactory.createLiteral("abc") ;
+        Node n1 = NodeFactory.createLiteralString("xyz") ;
+        Node n2 = NodeFactory.createLiteralString("abc") ;
         assertFalse(NodeFunctions.sameTerm(n1, n2)) ;
     }
 
     @Test public void testSameTerm3() {
-        Node n1 = NodeFactory.createLiteral("xyz") ;
+        Node n1 = NodeFactory.createLiteralString("xyz") ;
         Node n2 = NodeFactory.createURI("xyz") ;
         assertFalse(NodeFunctions.sameTerm(n1, n2)) ;
     }
 
     @Test public void testSameTerm4() {
-        Node n1 = NodeFactory.createLiteral("xyz") ;
+        Node n1 = NodeFactory.createLiteralString("xyz") ;
         Node n2 = NodeFactory.createLiteral("xyz", XSDDatatype.XSDstring) ;
         assertTrue(NodeFunctions.sameTerm(n1, n2)) ;
     }
 
     @Test public void testSameTerm5() {
         Node n1 = NodeFactory.createLiteralLang("xyz", "en") ;
-        Node n2 = NodeFactory.createLiteral("xyz") ;
+        Node n2 = NodeFactory.createLiteralString("xyz") ;
         assertFalse(NodeFunctions.sameTerm(n1, n2)) ;
     }
 
@@ -75,7 +75,7 @@ public class TestNodeFunctions {
 
     @Test public void testRDFtermEquals1() {
         Node n1 = NodeFactory.createURI("xyz") ;
-        Node n2 = NodeFactory.createLiteral("xyz") ;
+        Node n2 = NodeFactory.createLiteralString("xyz") ;
         assertFalse(NodeFunctions.rdfTermEquals(n1, n2)) ;
     }
 
@@ -88,7 +88,7 @@ public class TestNodeFunctions {
     @Test(expected=ExprEvalException.class)
     public void testRDFtermEquals3() {
         // Unextended - not known to be same (no language tag support).
-        Node n1 = NodeFactory.createLiteral("xyz") ;
+        Node n1 = NodeFactory.createLiteralString("xyz") ;
         Node n2 = NodeFactory.createLiteralLang("xyz", "en") ;
         NodeFunctions.rdfTermEquals(n1, n2);
     }
@@ -248,7 +248,7 @@ public class TestNodeFunctions {
     }
 
     @Test public void testLang4() {
-        NodeValue nv = NodeValue.makeNode(NodeFactory.createLiteral("simple")) ;
+        NodeValue nv = NodeValue.makeNode(NodeFactory.createLiteralString("simple")) ;
         NodeValue r = NodeFunctions.lang(nv) ;
         NodeValue e = NodeValue.makeString("") ;
         assertEquals(e, r) ;
@@ -345,7 +345,7 @@ public class TestNodeFunctions {
     }
 
     @Test public void testIsIRI_2() {
-        NodeValue nv = NodeValue.makeNode(NodeFactory.createLiteral("http://example/")) ;
+        NodeValue nv = NodeValue.makeNode(NodeFactory.createLiteralString("http://example/")) ;
         NodeValue r = NodeFunctions.isIRI(nv) ;
         assertEquals(NodeValue.FALSE, r) ;
     }
@@ -357,7 +357,7 @@ public class TestNodeFunctions {
     }
 
     @Test public void testIsBlank2() {
-        NodeValue nv = NodeValue.makeNode(NodeFactory.createLiteral("xyz")) ;
+        NodeValue nv = NodeValue.makeNode(NodeFactory.createLiteralString("xyz")) ;
         NodeValue r = NodeFunctions.isBlank(nv) ;
         assertEquals(NodeValue.FALSE, r) ;
     }
@@ -370,7 +370,7 @@ public class TestNodeFunctions {
     }
 
     @Test public void testIsLiteral1() {
-        NodeValue nv = NodeValue.makeNode(NodeFactory.createLiteral("xyz")) ;
+        NodeValue nv = NodeValue.makeNode(NodeFactory.createLiteralString("xyz")) ;
         NodeValue r = NodeFunctions.isLiteral(nv) ;
         assertEquals(NodeValue.TRUE, r) ;
     }
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeValue.java b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeValue.java
index 67757c355b..ffd01acb8d 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeValue.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeValue.java
@@ -1217,7 +1217,7 @@ public class TestNodeValue
     @Test
     public void testNotEquals3() { // Literals and URIs are different.
         NodeValue nv1 = NodeValue.makeNode(org.apache.jena.graph.NodeFactory.createURI("http://example"));
-        NodeValue nv2 = NodeValue.makeNode(org.apache.jena.graph.NodeFactory.createLiteral("http://example"));
+        NodeValue nv2 = NodeValue.makeNode(org.apache.jena.graph.NodeFactory.createLiteralString("http://example"));
         assertFalse("NodeValue.equals()", nv1.equals(nv2));
     }
 
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestOrdering.java b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestOrdering.java
index ee152373d7..20f30731b9 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestOrdering.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestOrdering.java
@@ -123,7 +123,7 @@ public class TestOrdering {
 
     @Test
     public void test_xsd_string1() {
-        NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteral("abc"));
+        NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteralString("abc"));
         NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteral("abc", XSDDatatype.XSDstring));
         int x = NodeValue.compare(nv1, nv2);
         assertTrue(Expr.CMP_EQUAL == x);
@@ -131,7 +131,7 @@ public class TestOrdering {
 
     @Test
     public void test_xsd_string2() {
-        NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteral("xyz"));
+        NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteralString("xyz"));
         NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteral("abc", XSDDatatype.XSDstring));
         int x = NodeValue.compare(nv1, nv2);
         assertTrue(Expr.CMP_GREATER == x);
@@ -140,14 +140,14 @@ public class TestOrdering {
     @Test
     public void test_xsd_string3() {
         NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteral("xyz", XSDDatatype.XSDstring));
-        NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteral("abc"));
+        NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteralString("abc"));
         int x = NodeValue.compare(nv1, nv2);
         assertTrue(Expr.CMP_GREATER == x);
     }
 
     @Test
     public void test_xsd_string4() {
-        NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteral("abc"));
+        NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteralString("abc"));
         NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteral("xyz", XSDDatatype.XSDstring));
         int x = NodeValue.compare(nv1, nv2);
         assertTrue(Expr.CMP_LESS == x);
@@ -156,7 +156,7 @@ public class TestOrdering {
     @Test
     public void test_xsd_string5() {
         NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteral("abc", XSDDatatype.XSDstring));
-        NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteral("xyz"));
+        NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteralString("xyz"));
         int x = NodeValue.compare(nv1, nv2);
         assertTrue(Expr.CMP_LESS == x);
     }
@@ -164,7 +164,7 @@ public class TestOrdering {
     @Test
     public void test_lang1() {
         NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteralLang("abc", "en"));
-        NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteral("abc"));
+        NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteralString("abc"));
 
         int x = NodeCmp.compareRDFTerms(nv1.asNode(), nv2.asNode());
         assertTrue("Lang tags should sort after plain literal", Expr.CMP_GREATER == x);
@@ -203,7 +203,7 @@ public class TestOrdering {
 
     @Test
     public void test_lang5() {
-        NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteral("abc"));
+        NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteralString("abc"));
         NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteralLang("xyz", "en"));
 
         int x = NodeValue.compareAlways(nv1, nv2);
@@ -214,7 +214,7 @@ public class TestOrdering {
 
     @Test
     public void test_lang6() {
-        NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteral("xyz"));
+        NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteralString("xyz"));
         NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteralLang("abc", "en"));
 
         int x = NodeValue.compareAlways(nv1, nv2);
@@ -301,7 +301,7 @@ public class TestOrdering {
     @Test
     public void test_variable5() {
         Node x = NodeFactory.createVariable("x");
-        Node y = NodeFactory.createLiteral("test");
+        Node y = NodeFactory.createLiteralString("test");
 
         int res = NodeCmp.compareRDFTerms(x, y);
         assertTrue("Variable nodes should be less than literal nodes", Expr.CMP_LESS == res);
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestXSDFuncOp.java b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestXSDFuncOp.java
index 1c55e9358f..659de02163 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestXSDFuncOp.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestXSDFuncOp.java
@@ -659,7 +659,7 @@ public class TestXSDFuncOp {
     }
 
     @Test public void testCompareGeneral3() {
-        NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteral("test:abc"));
+        NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteralString("test:abc"));
         NodeValue nv2 = NodeValue.makeNode(NodeFactory.createURI("test:abc"));
 
         // URIs before literals
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/graph/TestGraphUnionRead.java b/jena-arq/src/test/java/org/apache/jena/sparql/graph/TestGraphUnionRead.java
index 6797a31822..fca53928cb 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/graph/TestGraphUnionRead.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/graph/TestGraphUnionRead.java
@@ -85,7 +85,7 @@ public class TestGraphUnionRead
     public void gr_union_03() {
         List<Node> gnodes = list(gn1, gn2, gn9);
         Graph g = new GraphUnionRead(dsg, gnodes);
-        Node o = NodeFactory.createLiteral("g2");
+        Node o = NodeFactory.createLiteralString("g2");
         long x = Iter.count(g.find(null, null, o));
         assertEquals(1, x);
     }
@@ -120,7 +120,7 @@ public class TestGraphUnionRead
         Graph g = new GraphUnionRead(dsg, gnodes);
         long x1 = Iter.count(g.find(null, null, null));
         assertEquals(2, x1);
-        Node o = NodeFactory.createLiteral("g2");
+        Node o = NodeFactory.createLiteralString("g2");
         long x2 = Iter.count(g.find(null, null, o));
         assertEquals(1, x2);
     }
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/pfunction/library/TestStrSplit.java b/jena-arq/src/test/java/org/apache/jena/sparql/pfunction/library/TestStrSplit.java
index e8d2cd0cf4..51414cd8d5 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/pfunction/library/TestStrSplit.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/pfunction/library/TestStrSplit.java
@@ -136,7 +136,7 @@ public class TestStrSplit {
 	private void assertAllX(String... literalValues) {
 		List<Node> expectedNodes = new ArrayList<>();
 		for (String value: literalValues) {
-			expectedNodes.add(NodeFactory.createLiteral(value));
+			expectedNodes.add(NodeFactory.createLiteralString(value));
 		}
 		ResultSet rs = qe.execSelect();
 		List<Node> actualNodes = new ArrayList<>();
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/sse/TestSSE_Basic.java b/jena-arq/src/test/java/org/apache/jena/sparql/sse/TestSSE_Basic.java
index 361f4346d4..c79bf2c799 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/sse/TestSSE_Basic.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/sse/TestSSE_Basic.java
@@ -87,7 +87,7 @@ public class TestSSE_Basic
 
     @Test public void testLit_12()
     {
-        Node n = org.apache.jena.graph.NodeFactory.createLiteral("A\tB") ;
+        Node n = org.apache.jena.graph.NodeFactory.createLiteralString("A\tB") ;
         testNode("'''A\\tB'''", n) ;
     }
 
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/util/TestFmtUtils.java b/jena-arq/src/test/java/org/apache/jena/sparql/util/TestFmtUtils.java
index 3c3ef7a377..b35140ec4c 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/util/TestFmtUtils.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/util/TestFmtUtils.java
@@ -202,7 +202,7 @@ public class TestFmtUtils
     private Triple getTriple() {
         Node n1 = aNode() ;
         Node n2 = NodeFactory.createURI("n2") ;
-        Node l3 = NodeFactory.createLiteral("l3") ;
+        Node l3 = NodeFactory.createLiteralString("l3") ;
         return Triple.create(n1, n2, l3) ;
     }
 
@@ -213,14 +213,14 @@ public class TestFmtUtils
     private Triple getTriple2() {
         Node n1 = NodeFactory.createURI("nb1") ;
         Node n2 = NodeFactory.createURI("nb2") ;
-        Node l3 = NodeFactory.createLiteral("lb3") ;
+        Node l3 = NodeFactory.createLiteralString("lb3") ;
         return Triple.create(n1, n2, l3) ;
     }
 
     private Triple getPrefixedTriple() {
         Node n1 = aUriRemappableNode() ;
         Node n2 = NodeFactory.createURI("n2") ;
-        Node l3 = NodeFactory.createLiteral("l3") ;
+        Node l3 = NodeFactory.createLiteralString("l3") ;
 
         return Triple.create(n1, n2, l3) ;
     }
diff --git a/jena-core/src/main/java/org/apache/jena/graph/NodeFactory.java b/jena-core/src/main/java/org/apache/jena/graph/NodeFactory.java
index 19a5e8d2b1..8695860047 100644
--- a/jena-core/src/main/java/org/apache/jena/graph/NodeFactory.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/NodeFactory.java
@@ -20,7 +20,6 @@ package org.apache.jena.graph;
 
 
 import static org.apache.jena.atlas.lib.Lib.isEmpty;
-import static org.apache.jena.graph.NodeFactory.noLangTag;
 
 import java.util.Locale;
 import java.util.Objects;
@@ -88,20 +87,20 @@ public class NodeFactory {
         return new Node_Literal( lit );
     }
 
+    /** @deprecated Use {@link #createLiteral} */
+    @Deprecated
+    public static Node createLiteral(String string) {
+        return createLiteralString(string);
+    }
+
     /*
      * Make literal which is a string (xsd:string)
      */
-    public static Node createLiteral(String string) {
+    public static Node createLiteralString(String string) {
         Objects.requireNonNull(string, "Argument to NodeFactory.createLiteralString is null");
         return new Node_Literal(string);
     }
 
-//    /** @deprecated Use {@link #createLiteral} */
-//    @Deprecated
-//    public static Node createLiteral(String string) {
-//        return createLiteralString(string);
-//    }
-
     /**
      * Make a literal with specified language. The lexical form must not be null.
      *
@@ -169,7 +168,7 @@ public class NodeFactory {
      * This is a convenience operation for passing in language and datatype without
      * needing the caller to differentiate between the xsd:string, rdf:langString and other
      * datatype cases.
-     * It calls {@link #createLiteral(String)},
+     * It calls {@link #createLiteralString(String)},
      * {@link #createLiteralDirLang(String, String, String)} or
      * {@link #createLiteral(String, RDFDatatype)}
      * as appropriate.
@@ -188,7 +187,7 @@ public class NodeFactory {
      * This is a convenience operation for passing in language and datatype without
      * needing the caller to differentiate between the xsd:string, rdf:langString, and other
      * datatype cases.
-     * It calls {@link #createLiteral(String)},
+     * It calls {@link #createLiteralString(String)},
      * {@link #createLiteralDirLang(String, String, String)} or
      * {@link #createLiteral(String, RDFDatatype)}
      * as appropriate.
@@ -209,7 +208,7 @@ public class NodeFactory {
      * This is a convenience operation for passing in language and datatype without
      * needing the caller to differentiate between the xsd:string, rdf:langString, and other
      * datatype cases.
-     * It calls {@link #createLiteral(String)},
+     * It calls {@link #createLiteralString(String)},
      * {@link #createLiteralDirLang(String, String, String)} or
      * {@link #createLiteral(String, RDFDatatype)}
      * as appropriate.
@@ -235,7 +234,7 @@ public class NodeFactory {
         }
         if ( dtype == null )
             // No datatype, no lang (it is null or "") => xsd:string.
-            return createLiteral(lex);
+            return createLiteralString(lex);
 
         // No lang, with a datatype
         if ( dtype.equals(RDFLangString.rdfLangString) )
diff --git a/jena-core/src/main/java/org/apache/jena/rdf/model/impl/ModelCom.java b/jena-core/src/main/java/org/apache/jena/rdf/model/impl/ModelCom.java
index d95b42a287..9de0851a11 100644
--- a/jena-core/src/main/java/org/apache/jena/rdf/model/impl/ModelCom.java
+++ b/jena-core/src/main/java/org/apache/jena/rdf/model/impl/ModelCom.java
@@ -369,7 +369,7 @@ public class ModelCom extends EnhGraph implements Model, PrefixMapping, Lock
     @Override
     public StmtIterator listStatements( Resource S, Property P, String O ) {
         return O == null ? listStatements(S, P, Node.ANY)
-                         :  listStatements( S, P, NodeFactory.createLiteral( O ) );
+                         :  listStatements( S, P, NodeFactory.createLiteralString( O ) );
     }
 
     @Override
@@ -564,7 +564,7 @@ public class ModelCom extends EnhGraph implements Model, PrefixMapping, Lock
      */
     @Override
     public Literal createTypedLiteral(String v)  {
-        return new LiteralImpl(NodeFactory.createLiteral(v), this);
+        return new LiteralImpl(NodeFactory.createLiteralString(v), this);
     }
 
     /**
diff --git a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/Rule.java b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/Rule.java
index 5a8dca72be..6cbf7be400 100755
--- a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/Rule.java
+++ b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/Rule.java
@@ -946,7 +946,7 @@ public class Rule implements ClauseEntry {
                     RDFDatatype dt = TypeMapper.getInstance().getSafeTypeByName(dtURI);
                     return NodeFactory.createLiteral(lit, dt);
                 } else {
-                    return NodeFactory.createLiteral(lit);
+                    return NodeFactory.createLiteralString(lit);
                 }
             } else  if ( Character.isDigit(token.charAt(0)) ||
                          (token.charAt(0) == '-' && token.length() > 1 && Character.isDigit(token.charAt(1))) ) {
diff --git a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Regex.java b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Regex.java
index 2974b68e46..832a420c0d 100644
--- a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Regex.java
+++ b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Regex.java
@@ -69,7 +69,7 @@ public class Regex extends BaseBuiltin {
             BindingEnvironment env = context.getEnv();
             for (int i = 0; i < Math.min(length-2, m.groupCount()); i++) {
                 String gm = m.group(i+1);
-                Node match =  (gm != null) ? NodeFactory.createLiteral( gm ) : NodeFactory.createLiteral("");
+                Node match =  (gm != null) ? NodeFactory.createLiteralString( gm ) : NodeFactory.createLiteralString("");
                 if ( !env.bind(args[i+2], match) ) return false;
             }
         }
diff --git a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/StrConcat.java b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/StrConcat.java
index 4e748c695a..7f8e98d092 100644
--- a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/StrConcat.java
+++ b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/StrConcat.java
@@ -66,7 +66,7 @@ public class StrConcat extends BaseBuiltin {
         for (int i = 0; i < length-1; i++) {
             buff.append( lex(getArg(i, args, context), context) );
         }
-        Node result = NodeFactory.createLiteral(buff.toString());
+        Node result = NodeFactory.createLiteralString(buff.toString());
         return context.getEnv().bind(args[length-1], result);
     }
     
diff --git a/jena-core/src/test/java/org/apache/jena/graph/test/TestNodeExtras.java b/jena-core/src/test/java/org/apache/jena/graph/test/TestNodeExtras.java
index 43eadbc060..71b343dcfb 100644
--- a/jena-core/src/test/java/org/apache/jena/graph/test/TestNodeExtras.java
+++ b/jena-core/src/test/java/org/apache/jena/graph/test/TestNodeExtras.java
@@ -84,7 +84,7 @@ public class TestNodeExtras {
 
     @Test(expected=UnsupportedOperationException.class)
     public void term_triple_bad_1() {
-        Node n = NodeFactory.createLiteral("abc");
+        Node n = NodeFactory.createLiteralString("abc");
         n.getTriple();
     }
 
diff --git a/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/test/TestFBRules.java b/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/test/TestFBRules.java
index 55895fcc94..7983f8d559 100644
--- a/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/test/TestFBRules.java
+++ b/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/test/TestFBRules.java
@@ -792,18 +792,18 @@ public class TestFBRules extends TestCase {
 
         TestUtil.assertIteratorValues(this, infgraph.find(n1, s, null),
             new Triple[] {
-                Triple.create(n1, s, NodeFactory.createLiteral("literal")),
-                Triple.create(n1, s, NodeFactory.createLiteral("notBNode")),
+                Triple.create(n1, s, NodeFactory.createLiteralString("literal")),
+                Triple.create(n1, s, NodeFactory.createLiteralString("notBNode")),
             });
         TestUtil.assertIteratorValues(this, infgraph.find(n2, s, null),
             new Triple[] {
-                Triple.create(n2, s, NodeFactory.createLiteral("notLiteral")),
-                Triple.create(n2, s, NodeFactory.createLiteral("notBNode")),
+                Triple.create(n2, s, NodeFactory.createLiteralString("notLiteral")),
+                Triple.create(n2, s, NodeFactory.createLiteralString("notBNode")),
             });
         TestUtil.assertIteratorValues(this, infgraph.find(n3, s, null),
             new Triple[] {
-                Triple.create(n3, s, NodeFactory.createLiteral("notLiteral")),
-                Triple.create(n3, s, NodeFactory.createLiteral("bNode")),
+                Triple.create(n3, s, NodeFactory.createLiteralString("notLiteral")),
+                Triple.create(n3, s, NodeFactory.createLiteralString("bNode")),
             });
 
         // Data type checking
@@ -817,7 +817,7 @@ public class TestFBRules extends TestCase {
                        "";
         data = GraphMemFactory.createGraphMem();
         data.add(Triple.create(n1, p, Util.makeIntNode(3)) );
-        data.add(Triple.create(n2, p, NodeFactory.createLiteral("foo")) );
+        data.add(Triple.create(n2, p, NodeFactory.createLiteralString("foo")) );
         data.add(Triple.create(n3, p, NodeFactory.createLiteral("foo", XSDDatatype.XSDstring)) );
         data.add(Triple.create(n4, p, n4));
         data.add(Triple.create(n5, p, NodeFactory.createLiteral("-1", XSDDatatype.XSDnonNegativeInteger)) );
@@ -825,25 +825,25 @@ public class TestFBRules extends TestCase {
 
         TestUtil.assertIteratorValues(this, infgraph.find(null, s, null),
             new Triple[] {
-                Triple.create(n1, s, NodeFactory.createLiteral("isLiteral")),
-                Triple.create(n1, s, NodeFactory.createLiteral("isXSDInt")),
-                Triple.create(n1, s, NodeFactory.createLiteral("notXSDString")),
+                Triple.create(n1, s, NodeFactory.createLiteralString("isLiteral")),
+                Triple.create(n1, s, NodeFactory.createLiteralString("isXSDInt")),
+                Triple.create(n1, s, NodeFactory.createLiteralString("notXSDString")),
 
-                Triple.create(n2, s, NodeFactory.createLiteral("isLiteral")),
-                Triple.create(n2, s, NodeFactory.createLiteral("notXSDInt")),
-                Triple.create(n2, s, NodeFactory.createLiteral("isXSDString")),
+                Triple.create(n2, s, NodeFactory.createLiteralString("isLiteral")),
+                Triple.create(n2, s, NodeFactory.createLiteralString("notXSDInt")),
+                Triple.create(n2, s, NodeFactory.createLiteralString("isXSDString")),
 
-                Triple.create(n3, s, NodeFactory.createLiteral("isLiteral")),
-                Triple.create(n3, s, NodeFactory.createLiteral("notXSDInt")),
-                Triple.create(n3, s, NodeFactory.createLiteral("isXSDString")),
+                Triple.create(n3, s, NodeFactory.createLiteralString("isLiteral")),
+                Triple.create(n3, s, NodeFactory.createLiteralString("notXSDInt")),
+                Triple.create(n3, s, NodeFactory.createLiteralString("isXSDString")),
 
-                Triple.create(n4, s, NodeFactory.createLiteral("notLiteral")),
-                Triple.create(n4, s, NodeFactory.createLiteral("notXSDInt")),
-                Triple.create(n4, s, NodeFactory.createLiteral("notXSDString")),
+                Triple.create(n4, s, NodeFactory.createLiteralString("notLiteral")),
+                Triple.create(n4, s, NodeFactory.createLiteralString("notXSDInt")),
+                Triple.create(n4, s, NodeFactory.createLiteralString("notXSDString")),
 
-                Triple.create(n5, s, NodeFactory.createLiteral("notLiteral")),
-                Triple.create(n5, s, NodeFactory.createLiteral("notXSDInt")),
-                Triple.create(n5, s, NodeFactory.createLiteral("notXSDString")),
+                Triple.create(n5, s, NodeFactory.createLiteralString("notLiteral")),
+                Triple.create(n5, s, NodeFactory.createLiteralString("notXSDInt")),
+                Triple.create(n5, s, NodeFactory.createLiteralString("notXSDString")),
             });
 
         // Literal counting
@@ -885,13 +885,13 @@ public class TestFBRules extends TestCase {
             "[r1: (?x p ?y) strConcat(?z) -> (?x q ?z) ] \n" +
             "[r2: (?x p ?y) uriConcat('http://jena.hpl.hp.com/test#', ?y, ?z) -> (?x q ?z) ]";
         Graph data = GraphMemFactory.createGraphMem();
-        data.add(Triple.create(n1, p, NodeFactory.createLiteral("test")) );
+        data.add(Triple.create(n1, p, NodeFactory.createLiteralString("test")) );
         InfGraph infgraph = createInfGraph(rules, data);
 
         TestUtil.assertIteratorValues(this, infgraph.find(null, q, null),
             new Triple[] {
-            Triple.create(n1, q, NodeFactory.createLiteral("testhttp://www.w3.org/1999/02/22-rdf-syntax-ns#typefoo")),
-            Triple.create(n1, q, NodeFactory.createLiteral("")),
+            Triple.create(n1, q, NodeFactory.createLiteralString("testhttp://www.w3.org/1999/02/22-rdf-syntax-ns#typefoo")),
+            Triple.create(n1, q, NodeFactory.createLiteralString("")),
             Triple.create(n1, q, NodeFactory.createURI("http://jena.hpl.hp.com/test#test")),
             });
 
@@ -900,16 +900,16 @@ public class TestFBRules extends TestCase {
             "[r2: (?x p ?y) regex(?y, '(.*)\\\\s(.*) (f.*)', ?m1, ?m2, ?m3) -> (?x r ?m2) ] \n" +
             "";
         data = GraphMemFactory.createGraphMem();
-        data.add(Triple.create(n1, p, NodeFactory.createLiteral("foo bar foo")) );
-        data.add(Triple.create(n2, p, NodeFactory.createLiteral("foo bar baz")) );
+        data.add(Triple.create(n1, p, NodeFactory.createLiteralString("foo bar foo")) );
+        data.add(Triple.create(n2, p, NodeFactory.createLiteralString("foo bar baz")) );
         infgraph = createInfGraph(rules, data);
         TestUtil.assertIteratorValues(this, infgraph.find(null, q, null),
                 new Triple[] {
-                Triple.create(n1, q, NodeFactory.createLiteral("ok")),
+                Triple.create(n1, q, NodeFactory.createLiteralString("ok")),
                 });
         TestUtil.assertIteratorValues(this, infgraph.find(null, r, null),
                 new Triple[] {
-                Triple.create(n1, r, NodeFactory.createLiteral("bar")),
+                Triple.create(n1, r, NodeFactory.createLiteralString("bar")),
                 });
     }
 
@@ -921,14 +921,14 @@ public class TestFBRules extends TestCase {
             "[r2: (?x p ?y) regex(?y, '((Boys)|(Girls))(.*)', ?m1, ?m2, ?m3, ?m4) ->  (?x q ?m2) (?x r ?m3) (?x s ?m4) ] \n" +
             "";
         Graph data = GraphMemFactory.createGraphMem();
-        data.add(Triple.create(n1, p, NodeFactory.createLiteral("Girls44")) );
+        data.add(Triple.create(n1, p, NodeFactory.createLiteralString("Girls44")) );
         InfGraph infgraph = createInfGraph(rules, data);
         infgraph.prepare();
         TestUtil.assertIteratorValues(this, infgraph.getDeductionsGraph().find(null, null, null),
                 new Triple[] {
-            Triple.create(n1, q, NodeFactory.createLiteral("")),
-            Triple.create(n1, r, NodeFactory.createLiteral("Girls")),
-            Triple.create(n1, s, NodeFactory.createLiteral("44")),
+            Triple.create(n1, q, NodeFactory.createLiteralString("")),
+            Triple.create(n1, r, NodeFactory.createLiteralString("Girls")),
+            Triple.create(n1, s, NodeFactory.createLiteralString("44")),
                 });
     }
 
@@ -1026,14 +1026,14 @@ public class TestFBRules extends TestCase {
         assertNotSame( getSkolem(a, Util.makeIntNode(42)),
                        getSkolem(a, Util.makeIntNode(43)) );
 
-        assertNotSame( getSkolem(a, NodeFactory.createLiteral("foo")),
+        assertNotSame( getSkolem(a, NodeFactory.createLiteralString("foo")),
                        getSkolem(a, NodeFactory.createLiteralLang("foo", "en")) );
 
-        assertEquals( getSkolem(NodeFactory.createLiteral("foo")),
-                getSkolem(NodeFactory.createLiteral("foo")));
+        assertEquals( getSkolem(NodeFactory.createLiteralString("foo")),
+                getSkolem(NodeFactory.createLiteralString("foo")));
 
-        assertNotSame( getSkolem(NodeFactory.createLiteral("foo")),
-                       getSkolem(NodeFactory.createLiteral("bar")));
+        assertNotSame( getSkolem(NodeFactory.createLiteralString("foo")),
+                       getSkolem(NodeFactory.createLiteralString("bar")));
     }
 
     private Node getSkolem(Node x, Node y) {
diff --git a/jena-core/src/test/java/org/apache/jena/testing_framework/TestFileData.java b/jena-core/src/test/java/org/apache/jena/testing_framework/TestFileData.java
index 5f180d01e7..b74f8928b3 100644
--- a/jena-core/src/test/java/org/apache/jena/testing_framework/TestFileData.java
+++ b/jena-core/src/test/java/org/apache/jena/testing_framework/TestFileData.java
@@ -222,11 +222,11 @@ public class TestFileData {
 
 		g.add(Triple.create(NodeFactory.createBlankNode("b"),
 				NodeFactory.createURI("http://example.com/p2"), NodeFactory
-						.createLiteral("foo")));
+						.createLiteralString("foo")));
 
 		g.add(Triple.create(NodeFactory.createURI("http://example.com/ns/e"),
 				NodeFactory.createURI("http://example.com/ns/p5"), NodeFactory
-						.createLiteral("verify base works")));
+						.createLiteralString("verify base works")));
 
 		return g;
 	}
diff --git a/jena-examples/src/main/java/arq/examples/propertyfunction/localname.java b/jena-examples/src/main/java/arq/examples/propertyfunction/localname.java
index 158b1bf3ec..a787a01831 100644
--- a/jena-examples/src/main/java/arq/examples/propertyfunction/localname.java
+++ b/jena-examples/src/main/java/arq/examples/propertyfunction/localname.java
@@ -81,7 +81,7 @@ public class localname extends PFuncSimple
             return QueryIterNullIterator.create(execCxt) ;
 
         // Subject is bound and a URI - get the localname as a Node
-        Node localname = NodeFactory.createLiteral(nodeURI.getLocalName()) ;
+        Node localname = NodeFactory.createLiteralString(nodeURI.getLocalName()) ;
 
         // Object - unbound variable or a value?
         if ( ! nodeLocalname.isVariable() )
@@ -132,7 +132,7 @@ public class localname extends PFuncSimple
     private void slot(Collection<Binding> bindings, Binding input, Node node, Var subjVar, Node nodeLocalname)
     {
         if ( ! node.isURI() ) return ;
-        Node localname = NodeFactory.createLiteral(node.getLocalName()) ;
+        Node localname = NodeFactory.createLiteralString(node.getLocalName()) ;
         if ( nodeLocalname.isVariable() )
         {
             // Object is an unbound variable.
diff --git a/jena-examples/src/main/java/arq/examples/propertyfunction/uppercase.java b/jena-examples/src/main/java/arq/examples/propertyfunction/uppercase.java
index e333a758b1..ce38f5a94f 100644
--- a/jena-examples/src/main/java/arq/examples/propertyfunction/uppercase.java
+++ b/jena-examples/src/main/java/arq/examples/propertyfunction/uppercase.java
@@ -45,6 +45,6 @@ public class uppercase extends PFuncAssignToObject
         if ( ! node.isLiteral() )
             return null ;
         String str = node.getLiteralLexicalForm().toUpperCase() ;
-        return NodeFactory.createLiteral(str) ;
+        return NodeFactory.createLiteralString(str) ;
     }
 }
diff --git a/jena-extras/jena-commonsrdf/src/main/java/org/apache/jena/commonsrdf/impl/JCR_Factory.java b/jena-extras/jena-commonsrdf/src/main/java/org/apache/jena/commonsrdf/impl/JCR_Factory.java
index 63577d4710..af6c52cb36 100644
--- a/jena-extras/jena-commonsrdf/src/main/java/org/apache/jena/commonsrdf/impl/JCR_Factory.java
+++ b/jena-extras/jena-commonsrdf/src/main/java/org/apache/jena/commonsrdf/impl/JCR_Factory.java
@@ -36,7 +36,7 @@ public class JCR_Factory {
     }
 
     public static Literal createLiteral(String lexStr) {
-        return new JCR_Literal(NodeFactory.createLiteral(lexStr));
+        return new JCR_Literal(NodeFactory.createLiteralString(lexStr));
     }
 
     public static Literal createLiteralDT(String lexStr, String datatypeIRI) {
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AskBuilderTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AskBuilderTest.java
index 1bcaa7811e..de5bf8840e 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AskBuilderTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AskBuilderTest.java
@@ -107,7 +107,7 @@ public class AskBuilderTest extends AbstractRegexpBasedTest {
 
         Node one = NodeFactory.createURI("one");
         Node two = Var.alloc("two");
-        Node three = NodeFactory.createLiteral("three");
+        Node three = NodeFactory.createLiteralString("three");
         Node foo = NodeFactory.createURI("foo");
         Node bar = NodeFactory.createURI("bar");
 
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/ConstructBuilderTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/ConstructBuilderTest.java
index 87bba2a9e4..cd90b0ac56 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/ConstructBuilderTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/ConstructBuilderTest.java
@@ -110,7 +110,7 @@ public class ConstructBuilderTest extends AbstractRegexpBasedTest {
 
         Node one = NodeFactory.createURI("one");
         Node two = Var.alloc("two");
-        Node three = NodeFactory.createLiteral("three");
+        Node three = NodeFactory.createLiteralString("three");
         Node foo = NodeFactory.createURI("foo");
         Node bar = NodeFactory.createURI("bar");
 
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/ConvertersTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/ConvertersTest.java
index bde7c0398e..abeb3e5f69 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/ConvertersTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/ConvertersTest.java
@@ -330,11 +330,11 @@ public class ConvertersTest {
         assertTriplePath(Triple.create(Node.ANY, RDF.first.asNode(), getSubject(lst.get(2))), lst.get(4));
         assertTriplePath(Triple.create(getSubject(lst.get(4)), RDF.rest.asNode(), getSubject(lst.get(12))), lst.get(5));
         // sublist 2
-        assertTriplePath(Triple.create(Node.ANY, RDF.first.asNode(), NodeFactory.createLiteral("an")), lst.get(6));
+        assertTriplePath(Triple.create(Node.ANY, RDF.first.asNode(), NodeFactory.createLiteralString("an")), lst.get(6));
         assertTriplePath(Triple.create(getSubject(lst.get(6)), RDF.rest.asNode(), getSubject(lst.get(8))), lst.get(7));
         assertTriplePath(Triple.create(Node.ANY, RDF.first.asNode(), NodeFactory.createURI("embedded")), lst.get(8));
         assertTriplePath(Triple.create(getSubject(lst.get(8)), RDF.rest.asNode(), getSubject(lst.get(10))), lst.get(9));
-        assertTriplePath(Triple.create(Node.ANY, RDF.first.asNode(), NodeFactory.createLiteral("array")), lst.get(10));
+        assertTriplePath(Triple.create(Node.ANY, RDF.first.asNode(), NodeFactory.createLiteralString("array")), lst.get(10));
         assertTriplePath(Triple.create(getSubject(lst.get(10)), RDF.rest.asNode(), RDF.nil.asNode()), lst.get(11));
         // end of sublist 2
         assertTriplePath(Triple.create(Node.ANY, RDF.first.asNode(), getSubject(lst.get(6))), lst.get(12));
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/SelectBuilderTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/SelectBuilderTest.java
index de96b2ea53..2110f9537c 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/SelectBuilderTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/SelectBuilderTest.java
@@ -137,7 +137,7 @@ public class SelectBuilderTest extends AbstractRegexpBasedTest {
 
         Node one = NodeFactory.createURI("one");
         Node two = Var.alloc("two");
-        Node three = NodeFactory.createLiteral("three");
+        Node three = NodeFactory.createLiteralString("three");
         Node foo = NodeFactory.createURI("foo");
         Node bar = NodeFactory.createURI("bar");
 
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/UpdateBuilderTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/UpdateBuilderTest.java
index 7672b9fbed..6856651b2a 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/UpdateBuilderTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/UpdateBuilderTest.java
@@ -528,7 +528,7 @@ public class UpdateBuilderTest {
     public void example1() {
         Node n = NodeFactory.createURI("http://example/book1");
         Node priceN = NodeFactory.createURI("http://example.org/ns#price");
-        Node priceV = NodeFactory.createLiteral("42");
+        Node priceV = NodeFactory.createLiteralString("42");
         UpdateBuilder builder = new UpdateBuilder().addPrefix("dc", DC_11.NS).addInsert(n, DC_11.title, "A new book")
                 .addInsert(n, DC_11.creator, "A.N.Other");
 
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/ValuesClauseTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/ValuesClauseTest.java
index de08db64ce..1cc70935c1 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/ValuesClauseTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/ValuesClauseTest.java
@@ -84,7 +84,7 @@ public class ValuesClauseTest<T extends ValuesClause<?>> extends AbstractClauseT
         List<Binding> bindings = query.getValuesData();
         assertEquals( 1, bindings.size() );
         Binding binding = bindings.get(0);
-        assertEquals( NodeFactory.createLiteral( "foo"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "foo"), binding.get("x"));
     }
 
     @ContractTest
@@ -100,9 +100,9 @@ public class ValuesClauseTest<T extends ValuesClause<?>> extends AbstractClauseT
         List<Binding> bindings = query.getValuesData();
         assertEquals( 2, bindings.size() );
         Binding binding = bindings.get(0);
-        assertEquals( NodeFactory.createLiteral( "foo"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "foo"), binding.get("x"));
          binding = bindings.get(1);
-        assertEquals( NodeFactory.createLiteral( "bar"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "bar"), binding.get("x"));
     }
 
     @ContractTest
@@ -120,11 +120,11 @@ public class ValuesClauseTest<T extends ValuesClause<?>> extends AbstractClauseT
         List<Binding> bindings = query.getValuesData();
         assertEquals( 2, bindings.size() );
         Binding binding = bindings.get(0);
-        assertEquals( NodeFactory.createLiteral( "foo"), binding.get("x"));
-        assertEquals( NodeFactory.createLiteral( "bar"), binding.get("y"));
+        assertEquals( NodeFactory.createLiteralString( "foo"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "bar"), binding.get("y"));
         binding = bindings.get(1);
-        assertEquals( NodeFactory.createLiteral( "fu"), binding.get("x"));
-        assertEquals( NodeFactory.createLiteral( "bear"), binding.get("y"));
+        assertEquals( NodeFactory.createLiteralString( "fu"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "bear"), binding.get("y"));
     }
 
     @ContractTest
@@ -142,10 +142,10 @@ public class ValuesClauseTest<T extends ValuesClause<?>> extends AbstractClauseT
         List<Binding> bindings = query.getValuesData();
         assertEquals( 2, bindings.size() );
         Binding binding = bindings.get(0);
-        assertEquals( NodeFactory.createLiteral( "foo"), binding.get("x"));
-        assertEquals( NodeFactory.createLiteral( "bar" ), binding.get("y"));
+        assertEquals( NodeFactory.createLiteralString( "foo"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "bar" ), binding.get("y"));
         binding = bindings.get(1);
-        assertEquals( NodeFactory.createLiteral( "fu" ), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "fu" ), binding.get("x"));
         assertNull( binding.get("y"));
     }
 
@@ -165,14 +165,14 @@ public class ValuesClauseTest<T extends ValuesClause<?>> extends AbstractClauseT
         List<Binding> bindings = query.getValuesData();
         assertEquals( 3, bindings.size() );
         Binding binding = bindings.get(0);
-        assertEquals( NodeFactory.createLiteral( "foo"), binding.get("x"));
-        assertEquals( NodeFactory.createLiteral( "bar"), binding.get("y"));
+        assertEquals( NodeFactory.createLiteralString( "foo"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "bar"), binding.get("y"));
         binding = bindings.get(1);
-        assertEquals( NodeFactory.createLiteral( "fu"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "fu"), binding.get("x"));
         assertNull( binding.get("y"));
         binding = bindings.get(2);
         assertNull( binding.get("x"));
-        assertEquals( NodeFactory.createLiteral( "pub"), binding.get("y"));
+        assertEquals( NodeFactory.createLiteralString( "pub"), binding.get("y"));
     }
 
     @ContractTest
@@ -199,11 +199,11 @@ public class ValuesClauseTest<T extends ValuesClause<?>> extends AbstractClauseT
         List<Binding> bindings = query.getValuesData();
         assertEquals( 2, bindings.size() );
         Binding binding = bindings.get(0);
-        assertEquals( NodeFactory.createLiteral( "foo"), binding.get("x"));
-        assertEquals( NodeFactory.createLiteral( "bar"), binding.get("y"));
+        assertEquals( NodeFactory.createLiteralString( "foo"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "bar"), binding.get("y"));
         binding = bindings.get(1);
-        assertEquals( NodeFactory.createLiteral( "fu"), binding.get("x"));
-        assertEquals( NodeFactory.createLiteral( "bear"), binding.get("y"));
+        assertEquals( NodeFactory.createLiteralString( "fu"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "bear"), binding.get("y"));
     }
 
     @ContractTest
@@ -221,10 +221,10 @@ public class ValuesClauseTest<T extends ValuesClause<?>> extends AbstractClauseT
         List<Binding> bindings = query.getValuesData();
         assertEquals( 2, bindings.size() );
         Binding binding = bindings.get(0);
-        assertEquals( NodeFactory.createLiteral( "foo"), binding.get("x"));
-        assertEquals( NodeFactory.createLiteral( "bar"), binding.get("y"));
+        assertEquals( NodeFactory.createLiteralString( "foo"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "bar"), binding.get("y"));
         binding = bindings.get(1);
-        assertEquals( NodeFactory.createLiteral( "fu"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "fu"), binding.get("x"));
         assertNull( binding.get("y"));
     }
 
@@ -242,10 +242,10 @@ public class ValuesClauseTest<T extends ValuesClause<?>> extends AbstractClauseT
         List<Binding> bindings = query.getValuesData();
         assertEquals( 2, bindings.size() );
         Binding binding = bindings.get(0);
-        assertEquals( NodeFactory.createLiteral( "foo"), binding.get("x"));
-        assertEquals( NodeFactory.createLiteral( "bar"), binding.get("y"));
+        assertEquals( NodeFactory.createLiteralString( "foo"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "bar"), binding.get("y"));
         binding = bindings.get(1);
-        assertEquals( NodeFactory.createLiteral( "fu"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "fu"), binding.get("x"));
         assertNull( binding.get("y"));
     }
 
@@ -270,10 +270,10 @@ public class ValuesClauseTest<T extends ValuesClause<?>> extends AbstractClauseT
         List<Binding> bindings = query.getValuesData();
         assertEquals( 3, bindings.size() );
         Binding binding = bindings.get(0);
-        assertEquals( NodeFactory.createLiteral( "foo"), binding.get("x"));
-        assertEquals( NodeFactory.createLiteral( "bar"), binding.get("y"));
+        assertEquals( NodeFactory.createLiteralString( "foo"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "bar"), binding.get("y"));
         binding = bindings.get(1);
-        assertEquals( NodeFactory.createLiteral( "fu"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "fu"), binding.get("x"));
         assertNull( binding.get("y"));
         binding = bindings.get(2);
         assertEquals( tripleNode, binding.get("x"));
@@ -284,7 +284,7 @@ public class ValuesClauseTest<T extends ValuesClause<?>> extends AbstractClauseT
     public void testAddingMatrix() {
         Map<Object, Collection<Object>> map = new LinkedHashMap<Object, Collection<Object>>();
 
-        map.put("?x", Arrays.asList("foo", NodeFactory.createLiteral("fu")));
+        map.put("?x", Arrays.asList("foo", NodeFactory.createLiteralString("fu")));
         map.put(Var.alloc("y"), Arrays.asList("bar", null));
         AbstractQueryBuilder<?> builder = valuesClause.addValueVars(map);
 
@@ -298,10 +298,10 @@ public class ValuesClauseTest<T extends ValuesClause<?>> extends AbstractClauseT
         List<Binding> bindings = query.getValuesData();
         assertEquals( 2, bindings.size() );
         Binding binding = bindings.get(0);
-        assertEquals( NodeFactory.createLiteral( "foo"), binding.get("x"));
-        assertEquals( NodeFactory.createLiteral( "bar"), binding.get("y"));
+        assertEquals( NodeFactory.createLiteralString( "foo"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "bar"), binding.get("y"));
         binding = bindings.get(1);
-        assertEquals( NodeFactory.createLiteral( "fu"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "fu"), binding.get("x"));
         assertNull( binding.get("y"));
     }
 
@@ -309,13 +309,13 @@ public class ValuesClauseTest<T extends ValuesClause<?>> extends AbstractClauseT
     public void testAppendingMatrix() {
         Map<Object, Collection<Object>> map = new LinkedHashMap<Object, Collection<Object>>();
 
-        map.put("?x", Arrays.asList("foo", NodeFactory.createLiteral("fu")));
+        map.put("?x", Arrays.asList("foo", NodeFactory.createLiteralString("fu")));
         map.put(Var.alloc("y"), Arrays.asList("bar", null));
         AbstractQueryBuilder<?> builder = valuesClause.addValueVars(map);
 
         Map<Var, Collection<Node>> map2 = new LinkedHashMap<Var, Collection<Node>>();
-        map2.put(Var.alloc("y"), Arrays.asList(NodeFactory.createLiteral("baz"), Var.alloc("z")));
-        map2.put(Var.alloc("z"), Arrays.asList(NodeFactory.createLiteral("dog"), NodeFactory.createLiteral("cat")));
+        map2.put(Var.alloc("y"), Arrays.asList(NodeFactory.createLiteralString("baz"), Var.alloc("z")));
+        map2.put(Var.alloc("z"), Arrays.asList(NodeFactory.createLiteralString("dog"), NodeFactory.createLiteralString("cat")));
 
         builder.addValueVars(map2);
 
@@ -329,23 +329,23 @@ public class ValuesClauseTest<T extends ValuesClause<?>> extends AbstractClauseT
         List<Binding> bindings = query.getValuesData();
         assertEquals( 4, bindings.size() );
         Binding binding = bindings.get(0);
-        assertEquals( NodeFactory.createLiteral( "foo"), binding.get("x"));
-        assertEquals( NodeFactory.createLiteral( "bar"), binding.get("y"));
+        assertEquals( NodeFactory.createLiteralString( "foo"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "bar"), binding.get("y"));
         assertNull( binding.get("z"));
         binding = bindings.get(1);
-        assertEquals( NodeFactory.createLiteral( "fu"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "fu"), binding.get("x"));
         assertNull( binding.get("y"));
         assertNull( binding.get("z"));
 
         binding = bindings.get(2);
         assertNull( binding.get("x"));
-        assertEquals( NodeFactory.createLiteral( "baz"), binding.get("y"));
-        assertEquals( NodeFactory.createLiteral( "dog"), binding.get("z"));
+        assertEquals( NodeFactory.createLiteralString( "baz"), binding.get("y"));
+        assertEquals( NodeFactory.createLiteralString( "dog"), binding.get("z"));
 
         binding = bindings.get(3);
         assertNull( binding.get("x"));
         assertEquals( Var.alloc( "z"), binding.get("y"));
-        assertEquals( NodeFactory.createLiteral( "cat"), binding.get("z"));
+        assertEquals( NodeFactory.createLiteralString( "cat"), binding.get("z"));
     }
 
     @ContractTest
@@ -365,10 +365,10 @@ public class ValuesClauseTest<T extends ValuesClause<?>> extends AbstractClauseT
         List<Binding> bindings = query.getValuesData();
         assertEquals( 2, bindings.size() );
         Binding binding = bindings.get(0);
-        assertEquals( NodeFactory.createLiteral( "foo"), binding.get("x"));
-        assertEquals( NodeFactory.createLiteral( "bar"), binding.get("y"));
+        assertEquals( NodeFactory.createLiteralString( "foo"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "bar"), binding.get("y"));
         binding = bindings.get(1);
-        assertEquals( NodeFactory.createLiteral( "fu"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "fu"), binding.get("x"));
         assertNull( binding.get("y"));
     }
 
@@ -389,10 +389,10 @@ public class ValuesClauseTest<T extends ValuesClause<?>> extends AbstractClauseT
         List<Binding> bindings = query.getValuesData();
         assertEquals( 2, bindings.size() );
         Binding binding = bindings.get(0);
-        assertEquals( NodeFactory.createLiteral( "foo"), binding.get("x"));
-        assertEquals( NodeFactory.createLiteral( "bar"), binding.get("y"));
+        assertEquals( NodeFactory.createLiteralString( "foo"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "bar"), binding.get("y"));
         binding = bindings.get(1);
-        assertEquals( NodeFactory.createLiteral( "fu"), binding.get("x"));
+        assertEquals( NodeFactory.createLiteralString( "fu"), binding.get("x"));
         assertNull( binding.get("y"));
     }
 
@@ -413,12 +413,12 @@ public class ValuesClauseTest<T extends ValuesClause<?>> extends AbstractClauseT
         assertEquals(2, map.keySet().size());
         List<Node> nodes = map.get(Var.alloc("x"));
         assertEquals(2, nodes.size());
-        assertEquals(NodeFactory.createLiteral("foo"), nodes.get(0));
-        assertEquals(NodeFactory.createLiteral("fu"), nodes.get(1));
+        assertEquals(NodeFactory.createLiteralString("foo"), nodes.get(0));
+        assertEquals(NodeFactory.createLiteralString("fu"), nodes.get(1));
 
         nodes = map.get(Var.alloc("y"));
         assertEquals(2, nodes.size());
-        assertEquals(NodeFactory.createLiteral("bar"), nodes.get(0));
+        assertEquals(NodeFactory.createLiteralString("bar"), nodes.get(0));
         assertNull(nodes.get(1));
 
         builder.clearValues();
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/WhereClauseTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/WhereClauseTest.java
index c2cd83338f..3aaa5e25aa 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/WhereClauseTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/WhereClauseTest.java
@@ -84,7 +84,7 @@ public class WhereClauseTest<T extends WhereClause<?>> extends AbstractClauseTes
 
         ElementPathBlock epb = new ElementPathBlock();
         Triple t = Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"),
-                NodeFactory.createLiteral("three"));
+                NodeFactory.createLiteralString("three"));
         epb.addTriple(t);
 
         WhereValidator visitor = new WhereValidator(epb);
@@ -214,7 +214,7 @@ public class WhereClauseTest<T extends WhereClause<?>> extends AbstractClauseTes
         ElementPathBlock epb = new ElementPathBlock();
         ElementOptional optional = new ElementOptional(epb);
         Triple t = Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"),
-                NodeFactory.createLiteral("three"));
+                NodeFactory.createLiteralString("three"));
         epb.addTriple(t);
 
         WhereValidator visitor = new WhereValidator(optional);
@@ -231,7 +231,7 @@ public class WhereClauseTest<T extends WhereClause<?>> extends AbstractClauseTes
         Path path = new P_Seq(new P_Link(NodeFactory.createURI("two")), new P_Link(NodeFactory.createURI("dos")));
         ElementPathBlock epb = new ElementPathBlock();
         ElementOptional optional = new ElementOptional(epb);
-        TriplePath tp = new TriplePath(NodeFactory.createURI("one"), path, NodeFactory.createLiteral("three"));
+        TriplePath tp = new TriplePath(NodeFactory.createURI("one"), path, NodeFactory.createLiteralString("three"));
         epb.addTriplePath(tp);
 
         WhereValidator visitor = new WhereValidator(optional);
@@ -450,7 +450,7 @@ public class WhereClauseTest<T extends WhereClause<?>> extends AbstractClauseTes
         subQuery.addProjectVars(Arrays.asList("x"));
         subQuery.setQueryPattern(epb);
         Triple t = Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"),
-                NodeFactory.createLiteral("three"));
+                NodeFactory.createLiteralString("three"));
         epb.addTriple(t);
 
         WhereValidator visitor = new WhereValidator(union);
@@ -909,7 +909,7 @@ public class WhereClauseTest<T extends WhereClause<?>> extends AbstractClauseTes
 
         Node one = NodeFactory.createURI("one");
         Var two = Var.alloc("two");
-        Node three = NodeFactory.createLiteral("three");
+        Node three = NodeFactory.createLiteralString("three");
         Node foo = NodeFactory.createURI("foo");
         Node bar = NodeFactory.createURI("bar");
 
@@ -944,7 +944,7 @@ public class WhereClauseTest<T extends WhereClause<?>> extends AbstractClauseTes
         ElementPathBlock epb = new ElementPathBlock();
         ElementMinus minus = new ElementMinus(epb);
         epb.addTriplePath(new TriplePath(Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"),
-                NodeFactory.createLiteral("three"))));
+                NodeFactory.createLiteralString("three"))));
         WhereValidator visitor = new WhereValidator(minus);
         query.getQueryPattern().visit(visitor);
         assertTrue(visitor.matching);
@@ -1135,10 +1135,10 @@ public class WhereClauseTest<T extends WhereClause<?>> extends AbstractClauseTes
 
     private static void setupBindings(ElementData edat, Var x, Var v) {
         Binding binding1 = BindingFactory.binding(v, NodeFactory.createURI("one"), x,
-                NodeFactory.createLiteral("three"));
+                NodeFactory.createLiteralString("three"));
         edat.add(binding1);
         Binding binding2 = BindingFactory.binding(v, NodeFactory.createURI("two"), x,
-                NodeFactory.createLiteral("four"));
+                NodeFactory.createLiteralString("four"));
         edat.add(binding2);
     }
 
@@ -1363,12 +1363,12 @@ public class WhereClauseTest<T extends WhereClause<?>> extends AbstractClauseTes
         assertEquals(2, map.keySet().size());
         List<Node> nodes = map.get(Var.alloc("x"));
         assertEquals(2, nodes.size());
-        assertEquals(NodeFactory.createLiteral("foo"), nodes.get(0));
-        assertEquals(NodeFactory.createLiteral("fu"), nodes.get(1));
+        assertEquals(NodeFactory.createLiteralString("foo"), nodes.get(0));
+        assertEquals(NodeFactory.createLiteralString("fu"), nodes.get(1));
 
         nodes = map.get(Var.alloc("y"));
         assertEquals(2, nodes.size());
-        assertEquals(NodeFactory.createLiteral("bar"), nodes.get(0));
+        assertEquals(NodeFactory.createLiteralString("bar"), nodes.get(0));
         assertNull(nodes.get(1));
 
         whereClause.clearWhereValues();
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/ValuesHandlerTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/ValuesHandlerTest.java
index 75d52b2eb0..b588629202 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/ValuesHandlerTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/ValuesHandlerTest.java
@@ -79,7 +79,7 @@ public class ValuesHandlerTest extends AbstractHandlerTest {
 
     @Test
     public void oneVarOneData() {
-        Node n = NodeFactory.createLiteral("hello");
+        Node n = NodeFactory.createLiteralString("hello");
         Var v = Var.alloc("x");
         handler.addValueVar(v, Arrays.asList(n));
         handler.build();
@@ -99,8 +99,8 @@ public class ValuesHandlerTest extends AbstractHandlerTest {
 
     @Test
     public void oneVarTwoData() {
-        Node n = NodeFactory.createLiteral("hello");
-        Node n2 = NodeFactory.createLiteral("there");
+        Node n = NodeFactory.createLiteralString("hello");
+        Node n2 = NodeFactory.createLiteralString("there");
 
         Var v = Var.alloc("x");
         handler.addValueVar(v, Arrays.asList(n, n2));
@@ -127,7 +127,7 @@ public class ValuesHandlerTest extends AbstractHandlerTest {
 
     @Test
     public void twoVarOneData() {
-        Node n = NodeFactory.createLiteral("hello");
+        Node n = NodeFactory.createLiteralString("hello");
         Var v = Var.alloc("x");
         Var v2 = Var.alloc("y");
         handler.addValueVar(v, Arrays.asList(n));
@@ -142,10 +142,10 @@ public class ValuesHandlerTest extends AbstractHandlerTest {
 
     @Test
     public void twoVarTwoBlocks() {
-        Node n = NodeFactory.createLiteral("hello");
-        Node nn = NodeFactory.createLiteral("hola");
-        Node n2 = NodeFactory.createLiteral("there");
-        Node nn2 = NodeFactory.createLiteral("aqui");
+        Node n = NodeFactory.createLiteralString("hello");
+        Node nn = NodeFactory.createLiteralString("hola");
+        Node n2 = NodeFactory.createLiteralString("there");
+        Node nn2 = NodeFactory.createLiteralString("aqui");
 
         Var v = Var.alloc("x");
         Var v2 = Var.alloc("y");
@@ -186,10 +186,10 @@ public class ValuesHandlerTest extends AbstractHandlerTest {
 
     @Test
     public void twoVarTwoBlocksWithVarReplacement() {
-        Node n = NodeFactory.createLiteral("hello");
-        Node nn = NodeFactory.createLiteral("hola");
-        Node n2 = NodeFactory.createLiteral("there");
-        Node nn2 = NodeFactory.createLiteral("aqui");
+        Node n = NodeFactory.createLiteralString("hello");
+        Node nn = NodeFactory.createLiteralString("hola");
+        Node n2 = NodeFactory.createLiteralString("there");
+        Node nn2 = NodeFactory.createLiteralString("aqui");
 
         Var v = Var.alloc("x");
         Var v2 = Var.alloc("y");
@@ -226,9 +226,9 @@ public class ValuesHandlerTest extends AbstractHandlerTest {
 
     @Test
     public void twoVarTwoBlocksReplaceDataVar() {
-        Node n = NodeFactory.createLiteral("hello");
-        Node nn = NodeFactory.createLiteral("hola");
-        Node n2 = NodeFactory.createLiteral("there");
+        Node n = NodeFactory.createLiteralString("hello");
+        Node nn = NodeFactory.createLiteralString("hola");
+        Node n2 = NodeFactory.createLiteralString("there");
         Var nn2 = Var.alloc("z");
 
         Var v = Var.alloc("x");
@@ -239,7 +239,7 @@ public class ValuesHandlerTest extends AbstractHandlerTest {
         handler.addValueRow(Arrays.asList(n, n2));
         handler.addValueRow(Arrays.asList(nn, nn2));
 
-        Node rep = NodeFactory.createLiteral("aqui");
+        Node rep = NodeFactory.createLiteralString("aqui");
         Map<Var, Node> replaceVars = new HashMap<Var, Node>();
         replaceVars.put(nn2, rep);
 
@@ -275,8 +275,8 @@ public class ValuesHandlerTest extends AbstractHandlerTest {
 
     @Test
     public void oneVarTwoBlocksWithReplacement() {
-        Node n = NodeFactory.createLiteral("hello");
-        Node n2 = NodeFactory.createLiteral("there");
+        Node n = NodeFactory.createLiteralString("hello");
+        Node n2 = NodeFactory.createLiteralString("there");
 
         Var v = Var.alloc("x");
         handler.addValueVar(v, Arrays.asList(n, n2));
@@ -294,10 +294,10 @@ public class ValuesHandlerTest extends AbstractHandlerTest {
     @Test
     public void testAddSquare() {
 
-        Node n = NodeFactory.createLiteral("hello");
-        Node nn = NodeFactory.createLiteral("hola");
-        Node n2 = NodeFactory.createLiteral("there");
-        Node nn2 = NodeFactory.createLiteral("aqui");
+        Node n = NodeFactory.createLiteralString("hello");
+        Node nn = NodeFactory.createLiteralString("hola");
+        Node n2 = NodeFactory.createLiteralString("there");
+        Node nn2 = NodeFactory.createLiteralString("aqui");
 
         Var v = Var.alloc("x");
         Var v2 = Var.alloc("y");
@@ -306,8 +306,8 @@ public class ValuesHandlerTest extends AbstractHandlerTest {
         handler.addValueVar(v2, Arrays.asList(nn, nn2));
 
         ValuesHandler handler2 = new ValuesHandler(new Query());
-        Node n3 = NodeFactory.createLiteral("why");
-        Node nn3 = NodeFactory.createLiteral("quando");
+        Node n3 = NodeFactory.createLiteralString("why");
+        Node nn3 = NodeFactory.createLiteralString("quando");
         handler2.addValueVar(v, Arrays.asList(n3));
         handler2.addValueVar(v2, Arrays.asList(nn3));
 
@@ -346,10 +346,10 @@ public class ValuesHandlerTest extends AbstractHandlerTest {
     @Test
     public void testAddNotSquare() {
 
-        Node n = NodeFactory.createLiteral("hello");
-        Node nn = NodeFactory.createLiteral("hola");
-        Node n2 = NodeFactory.createLiteral("there");
-        Node nn2 = NodeFactory.createLiteral("aqui");
+        Node n = NodeFactory.createLiteralString("hello");
+        Node nn = NodeFactory.createLiteralString("hola");
+        Node n2 = NodeFactory.createLiteralString("there");
+        Node nn2 = NodeFactory.createLiteralString("aqui");
 
         Var v = Var.alloc("x");
         Var v2 = Var.alloc("y");
@@ -359,8 +359,8 @@ public class ValuesHandlerTest extends AbstractHandlerTest {
         handler.addValueVar(v2, Arrays.asList(nn, nn2));
 
         ValuesHandler handler2 = new ValuesHandler(new Query());
-        Node n3 = NodeFactory.createLiteral("why");
-        Node nn3 = NodeFactory.createLiteral("quando");
+        Node n3 = NodeFactory.createLiteralString("why");
+        Node nn3 = NodeFactory.createLiteralString("quando");
         handler2.addValueVar(v2, Arrays.asList(n3));
         handler2.addValueVar(v3, Arrays.asList(nn3));
 
@@ -401,8 +401,8 @@ public class ValuesHandlerTest extends AbstractHandlerTest {
         final Var x = Var.alloc("x");
         final Node one = NodeFactory.createURI("one");
         final Node two = NodeFactory.createURI("two");
-        final Node three = NodeFactory.createLiteral("three");
-        final Node four = NodeFactory.createLiteral("four");
+        final Node three = NodeFactory.createLiteralString("three");
+        final Node four = NodeFactory.createLiteralString("four");
 
         handler.addValueVar(v, Arrays.asList(one, two));
         handler.addValueVar(x, Arrays.asList(three, four));
@@ -412,10 +412,10 @@ public class ValuesHandlerTest extends AbstractHandlerTest {
         edat.add(x);
 
         Binding binding1 = BindingFactory.binding(v, NodeFactory.createURI("one"), x,
-                NodeFactory.createLiteral("three"));
+                NodeFactory.createLiteralString("three"));
         edat.add(binding1);
         Binding binding2 = BindingFactory.binding(v, NodeFactory.createURI("two"), x,
-                NodeFactory.createLiteral("four"));
+                NodeFactory.createLiteralString("four"));
         edat.add(binding2);
 
         WhereValidator visitor = new WhereValidator(edat);
@@ -446,7 +446,7 @@ public class ValuesHandlerTest extends AbstractHandlerTest {
         Var x = Var.alloc("x");
         Var y = Var.alloc("y");
         Node foo = NodeFactory.createURI("foo");
-        Node bar = NodeFactory.createLiteral("bar");
+        Node bar = NodeFactory.createLiteralString("bar");
 
         assertTrue(handler.getValuesVars().isEmpty());
 
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/WhereHandlerTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/WhereHandlerTest.java
index ffbb84f3f2..d962eb67a4 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/WhereHandlerTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/WhereHandlerTest.java
@@ -66,12 +66,12 @@ public class WhereHandlerTest extends AbstractHandlerTest {
         Query query2 = new Query();
         WhereHandler handler2 = new WhereHandler(query2);
         handler2.addWhere(new TriplePath(Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"),
-                NodeFactory.createLiteral("three"))));
+                NodeFactory.createLiteralString("three"))));
         handler.addAll(handler2);
         handler.build();
 
         Triple t1 = Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"),
-                NodeFactory.createLiteral("three"));
+                NodeFactory.createLiteralString("three"));
         TriplePath tp = new TriplePath(t1);
         ElementPathBlock epb = new ElementPathBlock();
         epb.addTriple(tp);
@@ -88,7 +88,7 @@ public class WhereHandlerTest extends AbstractHandlerTest {
         Query query2 = new Query();
         WhereHandler handler2 = new WhereHandler(query2);
         handler2.addWhere(new TriplePath(Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"),
-                NodeFactory.createLiteral("three"))));
+                NodeFactory.createLiteralString("three"))));
         handler.addAll(handler2);
         handler.build();
 
@@ -98,7 +98,7 @@ public class WhereHandlerTest extends AbstractHandlerTest {
         eg.addElement(epb);
         epb = new ElementPathBlock();
         Triple t1 = Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"),
-                NodeFactory.createLiteral("three"));
+                NodeFactory.createLiteralString("three"));
         epb.addTriple(t1);
         eg.addElement(epb);
 
@@ -354,7 +354,7 @@ public class WhereHandlerTest extends AbstractHandlerTest {
         handler.build();
 
         Triple t1 = Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"),
-                NodeFactory.createLiteral("three"));
+                NodeFactory.createLiteralString("three"));
         TriplePath tp = new TriplePath(t1);
         ElementPathBlock epb = new ElementPathBlock();
         epb.addTriple(tp);
@@ -377,7 +377,7 @@ public class WhereHandlerTest extends AbstractHandlerTest {
         handler.build();
 
         Triple t1 = Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"),
-                NodeFactory.createLiteral("three"));
+                NodeFactory.createLiteralString("three"));
         TriplePath tp = new TriplePath(t1);
         ElementPathBlock epb = new ElementPathBlock();
         epb.addTriple(tp);
@@ -400,7 +400,7 @@ public class WhereHandlerTest extends AbstractHandlerTest {
         handler.build();
 
         Triple t1 = Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"),
-                NodeFactory.createLiteral("three"));
+                NodeFactory.createLiteralString("three"));
         TriplePath tp = new TriplePath(t1);
         ElementPathBlock epb = new ElementPathBlock();
         epb.addTriple(tp);
@@ -786,7 +786,7 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 
         Node one = NodeFactory.createURI("one");
         Node two = Var.alloc("var");
-        Node three = NodeFactory.createLiteral("three");
+        Node three = NodeFactory.createLiteralString("three");
 
         ElementPathBlock epb = new ElementPathBlock();
         Node firstObject = NodeFactory.createBlankNode();
@@ -830,7 +830,7 @@ public class WhereHandlerTest extends AbstractHandlerTest {
         o = NodeFactory.createBlankNode();
         epb.addTriple(new TriplePath(s, rest, o));
         s = o;
-        epb.addTriple(new TriplePath(s, first, NodeFactory.createLiteral("three")));
+        epb.addTriple(new TriplePath(s, first, NodeFactory.createLiteralString("three")));
         epb.addTriple(new TriplePath(s, rest, RDF.nil.asNode()));
         epb.addTriple(new TriplePath(list, foo, NodeFactory.createURI("bar")));
 
@@ -849,7 +849,7 @@ public class WhereHandlerTest extends AbstractHandlerTest {
         ElementPathBlock epb = new ElementPathBlock();
         ElementMinus minus = new ElementMinus(epb);
         epb.addTriplePath(new TriplePath(Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"),
-                NodeFactory.createLiteral("three"))));
+                NodeFactory.createLiteralString("three"))));
         WhereValidator visitor = new WhereValidator(minus);
         query.getQueryPattern().visit(visitor);
         assertTrue(visitor.matching);
@@ -956,10 +956,10 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 
     private static void setupBindings(ElementData edat, Var x, Var v) {
         Binding binding1 = BindingFactory.binding(v, NodeFactory.createURI("one"), x,
-                NodeFactory.createLiteral("three"));
+                NodeFactory.createLiteralString("three"));
         edat.add(binding1);
         Binding binding2 = BindingFactory.binding(v, NodeFactory.createURI("two"), x,
-                NodeFactory.createLiteral("four"));
+                NodeFactory.createLiteralString("four"));
         edat.add(binding2);
     }
 
@@ -996,8 +996,8 @@ public class WhereHandlerTest extends AbstractHandlerTest {
         assertTrue(lst.contains(NodeFactory.createURI("two")));
         lst = map.get(x);
         assertEquals(2, lst.size());
-        assertTrue(lst.contains(NodeFactory.createLiteral("three")));
-        assertTrue(lst.contains(NodeFactory.createLiteral("four")));
+        assertTrue(lst.contains(NodeFactory.createLiteralString("three")));
+        assertTrue(lst.contains(NodeFactory.createLiteralString("four")));
     }
 
     @Test
@@ -1044,7 +1044,7 @@ public class WhereHandlerTest extends AbstractHandlerTest {
         Var x = Var.alloc("x");
         Var y = Var.alloc("y");
         Node foo = NodeFactory.createURI("foo");
-        Node bar = NodeFactory.createLiteral("bar");
+        Node bar = NodeFactory.createLiteralString("bar");
 
         assertTrue(handler.getValuesVars().isEmpty());
 
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/rewriters/NodeValueRewriterTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/rewriters/NodeValueRewriterTest.java
index dcc8522849..18981c12fb 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/rewriters/NodeValueRewriterTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/rewriters/NodeValueRewriterTest.java
@@ -167,7 +167,7 @@ public class NodeValueRewriterTest {
 
     @Test
     public void visitNodeValueStringNodeTest() {
-        Node n = NodeFactory.createLiteral("Hello");
+        Node n = NodeFactory.createLiteralString("Hello");
         NodeValue nv = new NodeValueString("Hello", n);
         nv.visit(rewriter);
         NodeValue result = rewriter.getResult();
@@ -186,7 +186,7 @@ public class NodeValueRewriterTest {
 
     @Test
     public void visitNodeValueSortKeyNodeTest() {
-        Node n = NodeFactory.createLiteral("Hello");
+        Node n = NodeFactory.createLiteralString("Hello");
         NodeValue nv = new NodeValueSortKey("Hello", "fi", n);
         nv.visit(rewriter);
         NodeValue result = rewriter.getResult();
diff --git a/jena-extras/jena-serviceenhancer/src/main/java/org/apache/jena/sparql/service/enhancer/init/ServiceEnhancerInit.java b/jena-extras/jena-serviceenhancer/src/main/java/org/apache/jena/sparql/service/enhancer/init/ServiceEnhancerInit.java
index 840922e472..1ed451cc15 100644
--- a/jena-extras/jena-serviceenhancer/src/main/java/org/apache/jena/sparql/service/enhancer/init/ServiceEnhancerInit.java
+++ b/jena-extras/jena-serviceenhancer/src/main/java/org/apache/jena/sparql/service/enhancer/init/ServiceEnhancerInit.java
@@ -276,7 +276,7 @@ public class ServiceEnhancerInit
         if (id == null) {
             DatasetGraph dg = execCxt.getDataset();
             int hashCode = System.identityHashCode(dg);
-            id = NodeFactory.createLiteral(ServiceEnhancerConstants.SELF.getURI() + "@dataset" + hashCode);
+            id = NodeFactory.createLiteralString(ServiceEnhancerConstants.SELF.getURI() + "@dataset" + hashCode);
         }
 
         return id;
diff --git a/jena-extras/jena-serviceenhancer/src/main/java/org/apache/jena/sparql/service/enhancer/pfunction/cacheLs.java b/jena-extras/jena-serviceenhancer/src/main/java/org/apache/jena/sparql/service/enhancer/pfunction/cacheLs.java
index 948949263f..75f026f677 100644
--- a/jena-extras/jena-serviceenhancer/src/main/java/org/apache/jena/sparql/service/enhancer/pfunction/cacheLs.java
+++ b/jena-extras/jena-serviceenhancer/src/main/java/org/apache/jena/sparql/service/enhancer/pfunction/cacheLs.java
@@ -142,10 +142,10 @@ public class cacheLs
                     Op normOp = key.getOp();
                     Op op = Rename.reverseVarRename(normOp, true);
                     Query query = OpAsQuery.asQuery(op);
-                    return NodeFactory.createLiteral(query.toString());
+                    return NodeFactory.createLiteralString(query.toString());
                 });
 
-                parentBuilder = processArg(parentBuilder, objectArgs, 2, () -> NodeFactory.createLiteral(key.getBinding().toString()));
+                parentBuilder = processArg(parentBuilder, objectArgs, 2, () -> NodeFactory.createLiteralString(key.getBinding().toString()));
 
                 Optional<Binding> parentBindingOpt = parentBuilder.map(BindingBuilder::build);
 
diff --git a/jena-extras/jena-serviceenhancer/src/test/java/org/apache/jena/sparql/service/enhancer/impl/TestServiceEnhancerBatchQueryRewriter.java b/jena-extras/jena-serviceenhancer/src/test/java/org/apache/jena/sparql/service/enhancer/impl/TestServiceEnhancerBatchQueryRewriter.java
index 11512e904d..7cfc6dafb8 100644
--- a/jena-extras/jena-serviceenhancer/src/test/java/org/apache/jena/sparql/service/enhancer/impl/TestServiceEnhancerBatchQueryRewriter.java
+++ b/jena-extras/jena-serviceenhancer/src/test/java/org/apache/jena/sparql/service/enhancer/impl/TestServiceEnhancerBatchQueryRewriter.java
@@ -48,8 +48,8 @@ public class TestServiceEnhancerBatchQueryRewriter {
 
         Batch<Integer, PartitionRequest<Binding>> batch = BatchImpl.forInteger();
         Var o = Var.alloc("o");
-        batch.put(0, new PartitionRequest<>(0, BindingFactory.binding(o, NodeFactory.createLiteral("x1")), 1, 5));
-        batch.put(1, new PartitionRequest<>(1, BindingFactory.binding(o, NodeFactory.createLiteral("x2")), 2, 6));
+        batch.put(0, new PartitionRequest<>(0, BindingFactory.binding(o, NodeFactory.createLiteralString("x1")), 1, 5));
+        batch.put(1, new PartitionRequest<>(1, BindingFactory.binding(o, NodeFactory.createLiteralString("x2")), 2, 6));
 
         BatchQueryRewriter rewriter = new BatchQueryRewriter(new OpServiceInfo(op), Var.alloc("idx"), false, false, false);
         BatchQueryRewriteResult rewrite = rewriter.rewrite(batch);
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContext.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContext.java
index fa4defc09a..b9ce9bdefb 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContext.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContext.java
@@ -48,8 +48,8 @@ public interface SecurityContext {
 
     public static final Node allGraphs = NodeFactory.createURI("urn:jena:accessAllGraphs");
     public static final Node allNamedGraphs = NodeFactory.createURI("urn:jena:accessAllNamedGraphs");
-    public static final Node allNamedGraphsStr = NodeFactory.createLiteral("*");
-    public static final Node allGraphsStr = NodeFactory.createLiteral("**");
+    public static final Node allNamedGraphsStr = NodeFactory.createLiteralString("*");
+    public static final Node allGraphsStr = NodeFactory.createLiteralString("**");
 
     /**
      * Collection of visible graph names.
diff --git a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java
index 9c88002341..52852205fe 100644
--- a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java
+++ b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java
@@ -431,7 +431,7 @@ public class ActionDatasets extends ActionContainerItem {
             // -- System database
             // Find graph associated with this dataset name.
             // (Statically configured databases aren't in the system database.)
-            Node n = NodeFactory.createLiteral(DataAccessPoint.canonical(name));
+            Node n = NodeFactory.createLiteralString(DataAccessPoint.canonical(name));
             Quad q = getOne(systemDSG, null, null, pServiceName.asNode(), n);
 //            if ( q == null )
 //                ServletOps.errorBadRequest("Failed to find dataset for '"+name+"'");
diff --git a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredLiteralImpl.java b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredLiteralImpl.java
index 6ce2dd6a88..8e6421124b 100644
--- a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredLiteralImpl.java
+++ b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredLiteralImpl.java
@@ -97,7 +97,7 @@ public class SecuredLiteralImpl extends SecuredRDFNodeImpl implements SecuredLit
         if (canRead()) {
             throw new ResourceRequiredException(asNode());
         }
-        throw new ResourceRequiredException(NodeFactory.createLiteral("Can not read"));
+        throw new ResourceRequiredException(NodeFactory.createLiteralString("Can not read"));
     }
 
     /**
diff --git a/jena-rdfpatch/src/main/java/org/apache/jena/rdfpatch/system/Id.java b/jena-rdfpatch/src/main/java/org/apache/jena/rdfpatch/system/Id.java
index fb5442acac..b89de74ca7 100644
--- a/jena-rdfpatch/src/main/java/org/apache/jena/rdfpatch/system/Id.java
+++ b/jena-rdfpatch/src/main/java/org/apache/jena/rdfpatch/system/Id.java
@@ -224,7 +224,7 @@ public final class Id {
     public Node asNode() {
         if ( uuid != null )
             return NodeFactory.createURI(SchemeUuid+uuid.toString());
-        return NodeFactory.createLiteral(string);
+        return NodeFactory.createLiteralString(string);
     }
 
     @Override
diff --git a/jena-shacl/src/main/java/org/apache/jena/shacl/ValidationReport.java b/jena-shacl/src/main/java/org/apache/jena/shacl/ValidationReport.java
index 3963f124ef..dc4e03905e 100644
--- a/jena-shacl/src/main/java/org/apache/jena/shacl/ValidationReport.java
+++ b/jena-shacl/src/main/java/org/apache/jena/shacl/ValidationReport.java
@@ -185,7 +185,7 @@ public class ValidationReport {
             if ( shape.getMessages() != null && ! shape.getMessages().isEmpty() )
                 messages = shape.getMessages();
             else
-                messages = Collections.singleton(NodeFactory.createLiteral(message));
+                messages = Collections.singleton(NodeFactory.createLiteralString(message));
 
             ReportEntry e = ReportEntry.create()
                 .focusNode(focusNode)
diff --git a/jena-shacl/src/main/java/org/apache/jena/shacl/engine/constraint/SparqlValidation.java b/jena-shacl/src/main/java/org/apache/jena/shacl/engine/constraint/SparqlValidation.java
index 7f5b7529a0..d40d0f092b 100644
--- a/jena-shacl/src/main/java/org/apache/jena/shacl/engine/constraint/SparqlValidation.java
+++ b/jena-shacl/src/main/java/org/apache/jena/shacl/engine/constraint/SparqlValidation.java
@@ -263,7 +263,7 @@ import org.apache.jena.sparql.util.ModelUtils;
         Pattern pattern = Pattern.compile("{[$?][^{}]+}");
         if ( path != null )
             // PATH is special.
-            substitions.put(Var.alloc("PATH"), NodeFactory.createLiteral(ShaclPaths.pathToString(path)));
+            substitions.put(Var.alloc("PATH"), NodeFactory.createLiteralString(ShaclPaths.pathToString(path)));
         return subsitute(message, substitions);
     }
 
diff --git a/jena-shacl/src/main/java/org/apache/jena/shacl/validation/ReportEntry.java b/jena-shacl/src/main/java/org/apache/jena/shacl/validation/ReportEntry.java
index 80ad54fd67..6358225faf 100644
--- a/jena-shacl/src/main/java/org/apache/jena/shacl/validation/ReportEntry.java
+++ b/jena-shacl/src/main/java/org/apache/jena/shacl/validation/ReportEntry.java
@@ -172,7 +172,7 @@ public class ReportEntry {
 
     public ReportEntry message(String msg) {
         if ( msg != null )
-            messages.add(NodeFactory.createLiteral(msg));
+            messages.add(NodeFactory.createLiteralString(msg));
         return this;
     }
 
diff --git a/jena-tdb1/src/main/java/org/apache/jena/tdb1/store/DatasetPrefixesTDB.java b/jena-tdb1/src/main/java/org/apache/jena/tdb1/store/DatasetPrefixesTDB.java
index 61d26e9f5f..8b9264e113 100644
--- a/jena-tdb1/src/main/java/org/apache/jena/tdb1/store/DatasetPrefixesTDB.java
+++ b/jena-tdb1/src/main/java/org/apache/jena/tdb1/store/DatasetPrefixesTDB.java
@@ -45,7 +45,7 @@ public class DatasetPrefixesTDB implements DatasetPrefixStorage
     @Override
     public synchronized void insertPrefix(String graphName, String prefix, String uri) {
         Node g = NodeFactory.createURI(graphName) ;
-        Node p = NodeFactory.createLiteral(prefix) ;
+        Node p = NodeFactory.createLiteralString(prefix) ;
         Node u = NodeFactory.createURI(uri) ;
         // Remove any previous mapping.
         remove_prefix(g,p,Node.ANY);
@@ -78,7 +78,7 @@ public class DatasetPrefixesTDB implements DatasetPrefixStorage
     @Override
     public synchronized String readPrefix(String graphName, String prefix) {
         Node g = NodeFactory.createURI(graphName) ;
-        Node p = NodeFactory.createLiteral(prefix) ;
+        Node p = NodeFactory.createLiteralString(prefix) ;
 
         Iterator<Tuple<Node>> iter = nodeTupleTable.find(g, p, null) ;
         try {
@@ -131,7 +131,7 @@ public class DatasetPrefixesTDB implements DatasetPrefixStorage
     @Override
     public void removeFromPrefixMap(String graphName, String prefix) {
         Node g = NodeFactory.createURI(graphName) ;
-        Node p = NodeFactory.createLiteral(prefix) ;
+        Node p = NodeFactory.createLiteralString(prefix) ;
         removeAll(g, p, null) ;
     }
 
diff --git a/jena-tdb2/src/main/java/org/apache/jena/tdb2/loader/main/PrefixHandlerBulk.java b/jena-tdb2/src/main/java/org/apache/jena/tdb2/loader/main/PrefixHandlerBulk.java
index 31dd4f3283..f6bf24c528 100644
--- a/jena-tdb2/src/main/java/org/apache/jena/tdb2/loader/main/PrefixHandlerBulk.java
+++ b/jena-tdb2/src/main/java/org/apache/jena/tdb2/loader/main/PrefixHandlerBulk.java
@@ -67,7 +67,7 @@ public class PrefixHandlerBulk implements BulkStartFinish {
 
     public PrefixHandler handler() {
         return (prefix, uriStr) -> {
-            Node p = NodeFactory.createLiteral(prefix);
+            Node p = NodeFactory.createLiteralString(prefix);
             Node u = NodeFactory.createURI(uriStr);
             prefixes.add_ext(Prefixes.nodeDataset, prefix, uriStr);
         };
diff --git a/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/StoragePrefixesTDB.java b/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/StoragePrefixesTDB.java
index 007afc7508..19991f9a4a 100644
--- a/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/StoragePrefixesTDB.java
+++ b/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/StoragePrefixesTDB.java
@@ -54,7 +54,7 @@ public class StoragePrefixesTDB implements StoragePrefixes {
     public String get(Node graphNode, String prefix) {
         requireTxn();
         graphNode = canonicalGraphName(graphNode);
-        Node p = NodeFactory.createLiteral(prefix);
+        Node p = NodeFactory.createLiteralString(prefix);
         Iterator<Tuple<Node>> iter = prefixTable.find(graphNode, p, null);
         if ( ! iter.hasNext() )
             return null;
@@ -90,7 +90,7 @@ public class StoragePrefixesTDB implements StoragePrefixes {
         // added prefixes. Going to the NodeTupleTable prefixTable would skip those and
         // require node creation in the caller as well.
         graphNode = canonicalGraphName(graphNode);
-        Node p = NodeFactory.createLiteral(prefix);
+        Node p = NodeFactory.createLiteralString(prefix);
         Node u = NodeFactory.createURI(iriStr);
         // Delete any existing old mapping of prefix.
         remove_ext(graphNode, p, Node.ANY);
@@ -99,7 +99,7 @@ public class StoragePrefixesTDB implements StoragePrefixes {
 
     @Override
     public void delete(Node graphNode, String prefix) {
-        Node p = NodeFactory.createLiteral(prefix);
+        Node p = NodeFactory.createLiteralString(prefix);
         remove(graphNode, p, null);
     }
 
diff --git a/jena-text/src/main/java/org/apache/jena/query/text/TextIndexLucene.java b/jena-text/src/main/java/org/apache/jena/query/text/TextIndexLucene.java
index 7f69af11ae..aacb56713b 100644
--- a/jena-text/src/main/java/org/apache/jena/query/text/TextIndexLucene.java
+++ b/jena-text/src/main/java/org/apache/jena/query/text/TextIndexLucene.java
@@ -562,7 +562,7 @@ public class TextIndexLucene implements TextIndex {
                         literal = NodeFactory.createLiteralLang(lexical, doclang);
                     }
                 } else {
-                    literal = NodeFactory.createLiteral(lexical);
+                    literal = NodeFactory.createLiteralString(lexical);
                 }
             }
 
diff --git a/jena-text/src/test/java/org/apache/jena/query/text/TestDatasetWithLuceneStoredLiterals.java b/jena-text/src/test/java/org/apache/jena/query/text/TestDatasetWithLuceneStoredLiterals.java
index f2983ccb6d..9bb199b54e 100644
--- a/jena-text/src/test/java/org/apache/jena/query/text/TestDatasetWithLuceneStoredLiterals.java
+++ b/jena-text/src/test/java/org/apache/jena/query/text/TestDatasetWithLuceneStoredLiterals.java
@@ -195,7 +195,7 @@ public class TestDatasetWithLuceneStoredLiterals extends AbstractTestDatasetWith
         Map<String,Literal> literals = doTestSearchWithLiterals(turtle, queryString, expectedURIs);
         Literal value = literals.get(R_S1);
         assertNotNull(value);
-        assertEquals(NodeFactory.createLiteral("text"), value.asNode());
+        assertEquals(NodeFactory.createLiteralString("text"), value.asNode());
     }
 
     @Test
@@ -221,7 +221,7 @@ public class TestDatasetWithLuceneStoredLiterals extends AbstractTestDatasetWith
         Map<String,Literal> literals = doTestSearchWithLiterals(turtle, queryString, expectedURIs);
         Literal value = literals.get(RESOURCE_BASE + testName);
         assertNotNull(value);
-        assertEquals(NodeFactory.createLiteral("a text comment"), value.asNode());
+        assertEquals(NodeFactory.createLiteralString("a text comment"), value.asNode());
     }
 
     @Test
@@ -298,8 +298,8 @@ public class TestDatasetWithLuceneStoredLiterals extends AbstractTestDatasetWith
         List<Node> literals = doTestSearchWithLiteralsMultiple(turtle, queryString, expectedURI);
 
         assertEquals(2, literals.size());
-        assertTrue(literals.contains(NodeFactory.createLiteral("a nontext comment")));
-        assertTrue(literals.contains(NodeFactory.createLiteral("another nontext comment")));
+        assertTrue(literals.contains(NodeFactory.createLiteralString("a nontext comment")));
+        assertTrue(literals.contains(NodeFactory.createLiteralString("another nontext comment")));
     }
 
     @Test
@@ -328,8 +328,8 @@ public class TestDatasetWithLuceneStoredLiterals extends AbstractTestDatasetWith
         List<Node> literals = doTestSearchWithLiteralsMultiple(turtle, queryString, expectedURI);
 
         assertEquals(2, literals.size());
-        assertTrue(literals.contains(NodeFactory.createLiteral("a nontext comment")));
-        assertTrue(literals.contains(NodeFactory.createLiteral("another nontext comment")));
+        assertTrue(literals.contains(NodeFactory.createLiteralString("a nontext comment")));
+        assertTrue(literals.contains(NodeFactory.createLiteralString("another nontext comment")));
     }
 
 }
diff --git a/jena-text/src/test/java/org/apache/jena/query/text/TestLuceneWithMultipleThreads.java b/jena-text/src/test/java/org/apache/jena/query/text/TestLuceneWithMultipleThreads.java
index ac1b6e2c9d..6e62755949 100644
--- a/jena-text/src/test/java/org/apache/jena/query/text/TestLuceneWithMultipleThreads.java
+++ b/jena-text/src/test/java/org/apache/jena/query/text/TestLuceneWithMultipleThreads.java
@@ -245,7 +245,7 @@ public class TestLuceneWithMultipleThreads
 
             dsg.begin(ReadWrite.WRITE);
 
-            dsg.add(NodeFactory.createURI("http://example.org/graph"), NodeFactory.createURI("http://example.org/test"), RDFS.label.asNode(), NodeFactory.createLiteral("test"));
+            dsg.add(NodeFactory.createURI("http://example.org/graph"), NodeFactory.createURI("http://example.org/test"), RDFS.label.asNode(), NodeFactory.createLiteralString("test"));
 
             // TODO use a Semaphore!
             Thread.sleep(500);
diff --git a/jena-text/src/test/java/org/apache/jena/query/text/TestTextHighlighting.java b/jena-text/src/test/java/org/apache/jena/query/text/TestTextHighlighting.java
index e6ceab14eb..1583e41036 100644
--- a/jena-text/src/test/java/org/apache/jena/query/text/TestTextHighlighting.java
+++ b/jena-text/src/test/java/org/apache/jena/query/text/TestTextHighlighting.java
@@ -192,7 +192,7 @@ public class TestTextHighlighting extends AbstractTestDatasetWithTextIndexBase {
         
         Literal value = literals.get(RESOURCE_BASE + "testResultThreeInModelA");
         assertNotNull(value);
-        assertEquals(NodeFactory.createLiteral("bar ↦testResultThree↤ barfoo foo"), value.asNode());
+        assertEquals(NodeFactory.createLiteralString("bar ↦testResultThree↤ barfoo foo"), value.asNode());
     }
 
     @Test
@@ -232,11 +232,11 @@ public class TestTextHighlighting extends AbstractTestDatasetWithTextIndexBase {
         
         Literal value = literals.get(RESOURCE_BASE + "testResultOneInModelA");
         assertNotNull(value);
-        assertEquals(NodeFactory.createLiteral("bar <em class='hilite'>testResultOne</em> barfoo foo"), value.asNode());
+        assertEquals(NodeFactory.createLiteralString("bar <em class='hilite'>testResultOne</em> barfoo foo"), value.asNode());
         
         value = literals.get(RESOURCE_BASE + "testResultOneInModelB");
         assertNotNull(value);
-        assertEquals(NodeFactory.createLiteral("bar <em class='hilite'>testResultOne</em> barfoo foo"), value.asNode());
+        assertEquals(NodeFactory.createLiteralString("bar <em class='hilite'>testResultOne</em> barfoo foo"), value.asNode());
     }
 
     @Test


(jena) 10/10: Convert to Lib functions lowercase/uppercase

Posted by an...@apache.org.
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 2d8785f25d9332973f206888d252b6504a3fe9fa
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Tue Dec 26 12:37:38 2023 +0000

    Convert to Lib functions lowercase/uppercase
---
 .../java/org/apache/jena/http/auth/AuthHeader.java |   4 +-
 .../java/org/apache/jena/riot/RDFLanguages.java    |   8 +-
 .../apache/jena/riot/adapters/RDFReaderRIOT.java   |  77 +--
 .../apache/jena/riot/adapters/RDFWriterRIOT.java   |   5 +-
 .../process/normalize/StreamCanonicalLangTag.java  |   4 +-
 .../apache/jena/riot/system/stream/LocatorURL.java |  35 +-
 .../java/org/apache/jena/riot/web/HttpMethod.java  |   4 +-
 .../org/apache/jena/sparql/algebra/op/OpBGP.java   |  20 +-
 .../java/org/apache/jena/sparql/expr/E_MD5.java    |   8 +-
 .../java/org/apache/jena/sparql/expr/E_SHA1.java   |  20 +-
 .../java/org/apache/jena/sparql/expr/E_SHA224.java |  20 +-
 .../java/org/apache/jena/sparql/expr/E_SHA256.java |  20 +-
 .../java/org/apache/jena/sparql/expr/E_SHA384.java |  20 +-
 .../java/org/apache/jena/sparql/expr/E_SHA512.java |  20 +-
 .../jena/sparql/expr/aggregate/AggCustom.java      |   5 +-
 .../jena/sparql/expr/aggregate/AggregatorBase.java |  59 +--
 .../sparql/function/library/FN_CollationKey.java   |  13 +-
 .../sparql/function/scripting/ScriptFunction.java  |   4 +-
 .../java/org/apache/jena/sparql/util/FmtUtils.java | 545 +++++++++------------
 .../org/apache/jena/sparql/util/RomanNumeral.java  |   4 +-
 .../java/org/apache/jena/riot/TestSysRIOT.java     |   7 +-
 .../main/java/org/apache/jena/atlas/lib/Lib.java   |   4 +-
 .../org/apache/jena/atlas/junit/AssertExtra.java   |  13 +-
 jena-cmds/src/main/java/arq/qparse.java            |  60 +--
 .../apache/jena/graph/impl/CollectionGraph.java    |  17 -
 .../java/org/apache/jena/irix/TestIRIxSyntax.java  |   6 +-
 .../java/org/apache/jena/irix/TestRFC3986.java     |   7 +-
 .../org/apache/jena/fuseki/server/Operation.java   |   5 +-
 .../apache/jena/fuseki/servlets/ActionREST.java    |   5 +-
 .../apache/jena/fuseki/servlets/ResponseOps.java   |   8 +-
 .../jena/fuseki/servlets/SPARQLQueryProcessor.java |   3 +-
 .../org/apache/jena/fuseki/mgt/ActionDatasets.java |   3 +-
 .../java/org/apache/jena/rdfpatch/PatchHeader.java |   5 +-
 .../apache/jena/rdfpatch/filelog/FilePolicy.java   |   5 +-
 .../org/apache/jena/shex/expressions/NodeKind.java |   5 +-
 .../org/apache/jena/shex/writer/WriterShExC.java   |  11 +-
 36 files changed, 498 insertions(+), 561 deletions(-)

diff --git a/jena-arq/src/main/java/org/apache/jena/http/auth/AuthHeader.java b/jena-arq/src/main/java/org/apache/jena/http/auth/AuthHeader.java
index 37a036a59c..2f4e7020a9 100644
--- a/jena-arq/src/main/java/org/apache/jena/http/auth/AuthHeader.java
+++ b/jena-arq/src/main/java/org/apache/jena/http/auth/AuthHeader.java
@@ -19,9 +19,9 @@
 package org.apache.jena.http.auth;
 
 import static org.apache.jena.atlas.lib.Chars.CH_RSLASH;
+import static org.apache.jena.atlas.lib.Lib.lowercase;
 
 import java.util.LinkedHashMap;
-import java.util.Locale;
 import java.util.Map;
 import java.util.function.IntPredicate;
 
@@ -414,7 +414,7 @@ public class AuthHeader {
                 String value = tokenOrQuotedString();
                 if ( value == null )
                     return null;
-                String lcKey = key.toLowerCase(Locale.ROOT);
+                String lcKey = lowercase(key);
                 map.put(lcKey, value);
                 skipWhitespaceComma();
             }
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/RDFLanguages.java b/jena-arq/src/main/java/org/apache/jena/riot/RDFLanguages.java
index 84a99d9def..27eb0fe931 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/RDFLanguages.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/RDFLanguages.java
@@ -18,9 +18,13 @@
 
 package org.apache.jena.riot;
 
+import static org.apache.jena.atlas.lib.Lib.lowercase;
 import static org.apache.jena.riot.WebContent.*;
 
-import java.util.*;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
 
 import org.apache.jena.atlas.io.IO;
 import org.apache.jena.atlas.web.ContentType;
@@ -462,7 +466,7 @@ public class RDFLanguages
         return lang;
     }
 
-    private static String canonicalKey(String x) { return x.toLowerCase(Locale.ROOT); }
+    private static String canonicalKey(String x) { return lowercase(x); }
 
     public static ContentType guessContentType(String resourceName) {
         if ( resourceName == null )
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/adapters/RDFReaderRIOT.java b/jena-arq/src/main/java/org/apache/jena/riot/adapters/RDFReaderRIOT.java
index e092c519bb..3d0179015e 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/adapters/RDFReaderRIOT.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/adapters/RDFReaderRIOT.java
@@ -16,52 +16,53 @@
  * limitations under the License.
  */
 
-package org.apache.jena.riot.adapters ;
+package org.apache.jena.riot.adapters;
 
-import java.io.InputStream ;
-import java.io.Reader ;
-import java.util.Locale ;
+import static org.apache.jena.atlas.lib.Lib.lowercase;
 
-import org.apache.jena.graph.GraphEvents ;
-import org.apache.jena.rdf.model.Model ;
-import org.apache.jena.rdf.model.RDFErrorHandler ;
-import org.apache.jena.rdf.model.RDFReaderI ;
-import org.apache.jena.rdf.model.impl.RDFDefaultErrorHandler ;
-import org.apache.jena.riot.Lang ;
-import org.apache.jena.riot.RDFDataMgr ;
-import org.apache.jena.riot.RDFLanguages ;
+import java.io.InputStream;
+import java.io.Reader;
+
+import org.apache.jena.graph.GraphEvents;
+import org.apache.jena.rdf.model.Model;
+import org.apache.jena.rdf.model.RDFErrorHandler;
+import org.apache.jena.rdf.model.RDFReaderI;
+import org.apache.jena.rdf.model.impl.RDFDefaultErrorHandler;
+import org.apache.jena.riot.Lang;
+import org.apache.jena.riot.RDFDataMgr;
+import org.apache.jena.riot.RDFLanguages;
 import org.apache.jena.riot.RDFParser;
 import org.apache.jena.riot.system.StreamRDF;
 import org.apache.jena.riot.system.StreamRDFLib;
-import org.apache.jena.sparql.util.Context ;
-import org.apache.jena.sparql.util.Symbol ;
+import org.apache.jena.sparql.util.Context;
+import org.apache.jena.sparql.util.Symbol;
 
 /** Adapter from Jena2 original style to RIOT reader. */
 public class RDFReaderRIOT implements RDFReaderI {
-    private final String      basename ;
-    protected final Lang      hintlang ;
-    protected Context         context      = new Context() ;
-    protected RDFErrorHandler errorHandler = new RDFDefaultErrorHandler() ;
+    private final String      basename;
+    protected final Lang      hintlang;
+    protected Context         context      = new Context();
+    protected RDFErrorHandler errorHandler = new RDFDefaultErrorHandler();
 
     public RDFReaderRIOT() {
-        this((Lang)null) ;
+        this((Lang)null);
     }
 
     public RDFReaderRIOT(String lang) {
-        this(lang != null ? RDFLanguages.nameToLang(lang) : null) ;
+        this(lang != null ? RDFLanguages.nameToLang(lang) : null);
     }
 
     public RDFReaderRIOT(Lang hintlang) {
-        this.hintlang = hintlang ;
+        this.hintlang = hintlang;
         this.basename = (hintlang==null)
             ? "org.apache.jena.riot.reader.generic"
-            : "org.apache.jena.riot.reader." + hintlang.getLabel().toLowerCase(Locale.ROOT) ;
+            : "org.apache.jena.riot.reader." + lowercase(hintlang.getLabel());
     }
 
     @SuppressWarnings("deprecation")
     @Override
     public void read(Model model, Reader r, String base) {
-        startRead(model) ;
+        startRead(model);
         StreamRDF dest = StreamRDFLib.graph(model.getGraph());
         RDFParser.create()
             .source(r)
@@ -69,42 +70,42 @@ public class RDFReaderRIOT implements RDFReaderI {
             .lang(hintlang)
             //.context(context)
             .parse(dest);
-        finishRead(model) ;
+        finishRead(model);
     }
 
     @Override
     public void read(Model model, InputStream r, String base) {
-        startRead(model) ;
-        RDFDataMgr.read(model, r, base, hintlang) ;
-        finishRead(model) ;
+        startRead(model);
+        RDFDataMgr.read(model, r, base, hintlang);
+        finishRead(model);
     }
 
     @Override
     public void read(Model model, String url) {
-        startRead(model) ;
-        RDFDataMgr.read(model, url, hintlang) ;
-        finishRead(model) ;
+        startRead(model);
+        RDFDataMgr.read(model, url, hintlang);
+        finishRead(model);
     }
 
     @Override
     public Object setProperty(String propName, Object propValue) {
-        Symbol sym = Symbol.create(basename + propName) ;
-        Object oldObj = context.get(sym) ;
-        return oldObj ;
+        Symbol sym = Symbol.create(basename + propName);
+        Object oldObj = context.get(sym);
+        return oldObj;
     }
 
     protected void startRead(Model model) {
-        model.notifyEvent(GraphEvents.startRead) ;
+        model.notifyEvent(GraphEvents.startRead);
     }
 
     protected void finishRead(Model model) {
-        model.notifyEvent(GraphEvents.finishRead) ;
+        model.notifyEvent(GraphEvents.finishRead);
     }
 
     @Override
     public RDFErrorHandler setErrorHandler(RDFErrorHandler errHandler) {
-        RDFErrorHandler old = errorHandler ;
-        errorHandler = errHandler ;
-        return old ;
+        RDFErrorHandler old = errorHandler;
+        errorHandler = errHandler;
+        return old;
     }
 }
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/adapters/RDFWriterRIOT.java b/jena-arq/src/main/java/org/apache/jena/riot/adapters/RDFWriterRIOT.java
index afc1446369..07bc9c196c 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/adapters/RDFWriterRIOT.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/adapters/RDFWriterRIOT.java
@@ -18,10 +18,11 @@
 
 package org.apache.jena.riot.adapters;
 
+import static org.apache.jena.atlas.lib.Lib.lowercase;
+
 import java.io.OutputStream ;
 import java.io.Writer ;
 import java.util.HashMap ;
-import java.util.Locale ;
 import java.util.Map ;
 
 import org.apache.jena.rdf.model.Model ;
@@ -54,7 +55,7 @@ public class RDFWriterRIOT implements RDFWriterI
     public RDFWriterRIOT(String jenaName) {
         this.basename = (jenaName==null)
                 ? "org.apache.jena.riot.writer.generic"
-                : "org.apache.jena.riot.writer." + jenaName.toLowerCase(Locale.ROOT) ;
+                : "org.apache.jena.riot.writer." + lowercase(jenaName);
 
         this.jenaName = jenaName;
 
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/StreamCanonicalLangTag.java b/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/StreamCanonicalLangTag.java
index da6bbea784..700ad5ce5b 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/StreamCanonicalLangTag.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/StreamCanonicalLangTag.java
@@ -18,6 +18,8 @@
 
 package org.apache.jena.riot.process.normalize;
 
+import static org.apache.jena.atlas.lib.Lib.lowercase;
+
 import java.util.IllformedLocaleException;
 import java.util.Locale;
 import java.util.function.BiFunction;
@@ -72,6 +74,6 @@ public class StreamCanonicalLangTag extends StreamRDFApplyObject {
     }
 
     public static String langTagLC(Locale.Builder locBuild, String str) {
-        return str.toLowerCase(Locale.ROOT);
+        return lowercase(str);
     }
 }
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/system/stream/LocatorURL.java b/jena-arq/src/main/java/org/apache/jena/riot/system/stream/LocatorURL.java
index 2ac6fb88e8..e5eb75d6c7 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/system/stream/LocatorURL.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/system/stream/LocatorURL.java
@@ -18,39 +18,38 @@
 
 package org.apache.jena.riot.system.stream;
 
-import java.util.Locale ;
-
-import org.apache.jena.atlas.web.TypedInputStream ;
+import org.apache.jena.atlas.lib.Lib;
+import org.apache.jena.atlas.web.TypedInputStream;
 import org.apache.jena.irix.IRIs;
-import org.slf4j.Logger ;
+import org.slf4j.Logger;
 
 public abstract class LocatorURL implements Locator
 {
-    private final String[] schemeNames ;
+    private final String[] schemeNames;
 
     protected LocatorURL(String[] sNames) {
-        schemeNames = sNames ;
+        schemeNames = sNames;
     }
 
-    protected abstract Logger log() ;
+    protected abstract Logger log();
 
     @Override
     public TypedInputStream open(String uri) {
         if ( ! acceptByScheme(uri) ) {
             if ( StreamManager.logAllLookups && log().isTraceEnabled() )
-                log().trace("Not found : "+uri) ;
+                log().trace("Not found : "+uri);
             return null;
         }
-        return performOpen(uri) ;
+        return performOpen(uri);
     }
 
-    protected abstract TypedInputStream performOpen(String uri) ;
+    protected abstract TypedInputStream performOpen(String uri);
 
     protected boolean acceptByScheme(String filenameOrURI) {
-        String uriSchemeName = IRIs.scheme(filenameOrURI) ;
+        String uriSchemeName = IRIs.scheme(filenameOrURI);
         if ( uriSchemeName == null )
-            return false ;
-        uriSchemeName = uriSchemeName.toLowerCase(Locale.ROOT) ;
+            return false;
+        uriSchemeName = Lib.lowercase(uriSchemeName);
         for ( String schemeName : schemeNames )
         {
             if ( uriSchemeName.equals( schemeName ) )
@@ -58,17 +57,17 @@ public abstract class LocatorURL implements Locator
                 return true;
             }
         }
-        return false ;
+        return false;
     }
 
     @Override
-    public abstract int hashCode() ;
+    public abstract int hashCode();
 
     @Override
     public boolean equals(Object obj) {
-        if (this == obj) return true ;
-        if (obj == null) return false ;
-        return getClass() == obj.getClass() ;
+        if (this == obj) return true;
+        if (obj == null) return false;
+        return getClass() == obj.getClass();
     }
 }
 
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/web/HttpMethod.java b/jena-arq/src/main/java/org/apache/jena/riot/web/HttpMethod.java
index a0e57d5992..f6cc46935b 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/web/HttpMethod.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/web/HttpMethod.java
@@ -18,7 +18,7 @@
 
 package org.apache.jena.riot.web;
 
-import java.util.Locale;
+import static org.apache.jena.atlas.lib.Lib.uppercase;
 
 public enum HttpMethod {
     // METHOD_ only for transition/rename.
@@ -43,7 +43,7 @@ public enum HttpMethod {
 
     public static HttpMethod fromString(String name) {
         try {
-            return HttpMethod.valueOf(name.toUpperCase(Locale.ROOT));
+            return HttpMethod.valueOf(uppercase(name));
         } catch (IllegalArgumentException ex) {
             return null;
         }
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/op/OpBGP.java b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/op/OpBGP.java
index 904ff532f9..cae395998c 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/op/OpBGP.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/op/OpBGP.java
@@ -35,26 +35,26 @@ public class OpBGP extends Op0
     }
 
     public OpBGP() { this(new BasicPattern()); }
-    
+
     public OpBGP(BasicPattern pattern)
     { this.pattern = pattern; }
-    
-    public BasicPattern getPattern()        { return pattern; } 
-    
+
+    public BasicPattern getPattern()        { return pattern; }
+
     @Override
-    public String getName()                 { return Tags.tagBGP /*.toUpperCase(Locale.ROOT)*/; }
+    public String getName()                 { return Tags.tagBGP; }
     @Override
-    public Op apply(Transform transform)    { return transform.transform(this); } 
+    public Op apply(Transform transform)    { return transform.transform(this); }
     @Override
     public void visit(OpVisitor opVisitor)  { opVisitor.visit(this); }
     @Override
     public Op0 copy()                       { return new OpBGP(pattern); }
-    
+
     @Override
     public int hashCode()
-    { 
+    {
         int calcHashCode = OpBase.HashBasicGraphPattern;
-        calcHashCode ^=  pattern.hashCode(); 
+        calcHashCode ^=  pattern.hashCode();
         return calcHashCode;
     }
 
@@ -63,7 +63,7 @@ public class OpBGP extends Op0
     {
         if ( ! ( op2 instanceof OpBGP) )
             return false;
-        
+
         OpBGP bgp2 = (OpBGP)op2;
         return pattern.equiv(bgp2.pattern, labelMap);
     }
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_MD5.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_MD5.java
index 72c3a9fbf9..2beb1ce2d3 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_MD5.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_MD5.java
@@ -18,19 +18,19 @@
 
 package org.apache.jena.sparql.expr;
 
-import java.util.Locale ;
+import static org.apache.jena.atlas.lib.Lib.uppercase;
 
 import org.apache.jena.sparql.sse.Tags ;
 
 public class E_MD5 extends ExprDigest
 {
-    private static final String symbol = Tags.tagMD5.toUpperCase(Locale.ROOT) ;
+    private static final String symbol = uppercase(Tags.tagMD5) ;
 
     public E_MD5(Expr expr)
     {
         super(expr, symbol, "MD5") ;
     }
-    
+
     @Override
-    public Expr copy(Expr expr) { return new E_MD5(expr) ; } 
+    public Expr copy(Expr expr) { return new E_MD5(expr) ; }
 }
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SHA1.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SHA1.java
index 303d92700f..bd45a8d117 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SHA1.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SHA1.java
@@ -18,19 +18,19 @@
 
 package org.apache.jena.sparql.expr;
 
-import java.util.Locale ;
+import static org.apache.jena.atlas.lib.Lib.uppercase;
 
-import org.apache.jena.sparql.sse.Tags ;
+import org.apache.jena.sparql.sse.Tags;
 
-public class E_SHA1 extends ExprDigest
-{
-    private static final String symbol = Tags.tagSHA1.toUpperCase(Locale.ROOT) ;
+public class E_SHA1 extends ExprDigest {
+    private static final String symbol = uppercase(Tags.tagSHA1);
 
-    public E_SHA1(Expr expr)
-    {
-        super(expr, symbol, "SHA-1") ;
+    public E_SHA1(Expr expr) {
+        super(expr, symbol, "SHA-1");
     }
-    
+
     @Override
-    public Expr copy(Expr expr) { return new E_SHA1(expr) ; } 
+    public Expr copy(Expr expr) {
+        return new E_SHA1(expr);
+    }
 }
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SHA224.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SHA224.java
index d4517c4937..b83c9d5f08 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SHA224.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SHA224.java
@@ -18,19 +18,19 @@
 
 package org.apache.jena.sparql.expr;
 
-import java.util.Locale ;
+import static org.apache.jena.atlas.lib.Lib.uppercase;
 
-import org.apache.jena.sparql.sse.Tags ;
+import org.apache.jena.sparql.sse.Tags;
 
-public class E_SHA224 extends ExprDigest
-{
-    private static final String symbol = Tags.tagSHA224.toUpperCase(Locale.ROOT) ;
+public class E_SHA224 extends ExprDigest {
+    private static final String symbol = uppercase(Tags.tagSHA224);
 
-    public E_SHA224(Expr expr)
-    {
-        super(expr, symbol, "SHA-224") ;
+    public E_SHA224(Expr expr) {
+        super(expr, symbol, "SHA-224");
     }
-    
+
     @Override
-    public Expr copy(Expr expr) { return new E_SHA224(expr) ; } 
+    public Expr copy(Expr expr) {
+        return new E_SHA224(expr);
+    }
 }
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SHA256.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SHA256.java
index 7b99b66cb9..7b602eb470 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SHA256.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SHA256.java
@@ -18,19 +18,19 @@
 
 package org.apache.jena.sparql.expr;
 
-import java.util.Locale ;
+import static org.apache.jena.atlas.lib.Lib.uppercase;
 
-import org.apache.jena.sparql.sse.Tags ;
+import org.apache.jena.sparql.sse.Tags;
 
-public class E_SHA256 extends ExprDigest
-{
-    private static final String symbol = Tags.tagSHA256.toUpperCase(Locale.ROOT) ;
+public class E_SHA256 extends ExprDigest {
+    private static final String symbol = uppercase(Tags.tagSHA256);
 
-    public E_SHA256(Expr expr)
-    {
-        super(expr, symbol, "SHA-256") ;
+    public E_SHA256(Expr expr) {
+        super(expr, symbol, "SHA-256");
     }
-    
+
     @Override
-    public Expr copy(Expr expr) { return new E_SHA256(expr) ; } 
+    public Expr copy(Expr expr) {
+        return new E_SHA256(expr);
+    }
 }
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SHA384.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SHA384.java
index cadade06a7..fa9aaf729b 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SHA384.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SHA384.java
@@ -18,19 +18,19 @@
 
 package org.apache.jena.sparql.expr;
 
-import java.util.Locale ;
+import static org.apache.jena.atlas.lib.Lib.uppercase;
 
-import org.apache.jena.sparql.sse.Tags ;
+import org.apache.jena.sparql.sse.Tags;
 
-public class E_SHA384 extends ExprDigest
-{
-    private static final String symbol = Tags.tagSHA384.toUpperCase(Locale.ROOT) ;
+public class E_SHA384 extends ExprDigest {
+    private static final String symbol = uppercase(Tags.tagSHA384);
 
-    public E_SHA384(Expr expr)
-    {
-        super(expr, symbol, "SHA-384") ;
+    public E_SHA384(Expr expr) {
+        super(expr, symbol, "SHA-384");
     }
-    
+
     @Override
-    public Expr copy(Expr expr) { return new E_SHA384(expr) ; } 
+    public Expr copy(Expr expr) {
+        return new E_SHA384(expr);
+    }
 }
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SHA512.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SHA512.java
index 12ba915c4e..604917932e 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SHA512.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SHA512.java
@@ -18,19 +18,19 @@
 
 package org.apache.jena.sparql.expr;
 
-import java.util.Locale ;
+import static org.apache.jena.atlas.lib.Lib.uppercase;
 
-import org.apache.jena.sparql.sse.Tags ;
+import org.apache.jena.sparql.sse.Tags;
 
-public class E_SHA512 extends ExprDigest
-{
-    private static final String symbol = Tags.tagSHA512.toUpperCase(Locale.ROOT) ;
+public class E_SHA512 extends ExprDigest {
+    private static final String symbol = uppercase(Tags.tagSHA512);
 
-    public E_SHA512(Expr expr)
-    {
-        super(expr, symbol, "SHA-512") ;
+    public E_SHA512(Expr expr) {
+        super(expr, symbol, "SHA-512");
     }
-    
+
     @Override
-    public Expr copy(Expr expr) { return new E_SHA512(expr) ; } 
+    public Expr copy(Expr expr) {
+        return new E_SHA512(expr);
+    }
 }
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/aggregate/AggCustom.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/aggregate/AggCustom.java
index d3a4aa8e00..8485d289f0 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/aggregate/AggCustom.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/aggregate/AggCustom.java
@@ -18,7 +18,8 @@
 
 package org.apache.jena.sparql.expr.aggregate;
 
-import java.util.Locale;
+import static org.apache.jena.atlas.lib.Lib.lowercase;
+
 import java.util.Objects;
 
 import org.apache.jena.atlas.io.IndentedLineBuffer;
@@ -81,7 +82,7 @@ public class AggCustom extends AggregatorBase {
     public String toPrefixString() {
         IndentedLineBuffer x = new IndentedLineBuffer();
         x.append("(");
-        x.append(getName().toLowerCase(Locale.ROOT));
+        x.append(lowercase(getName()));
         x.append(" <");
         x.append(iri);
         x.append("> ");
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/aggregate/AggregatorBase.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/aggregate/AggregatorBase.java
index 247948dd4f..d60edb1116 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/aggregate/AggregatorBase.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/aggregate/AggregatorBase.java
@@ -18,8 +18,9 @@
 
 package org.apache.jena.sparql.expr.aggregate;
 
+import static org.apache.jena.atlas.lib.Lib.lowercase;
+
 import java.util.HashMap ;
-import java.util.Locale ;
 import java.util.Map ;
 
 import org.apache.jena.atlas.io.IndentedLineBuffer ;
@@ -34,40 +35,40 @@ import org.apache.jena.sparql.serializer.SerializationContext ;
 import org.apache.jena.sparql.sse.writers.WriterExpr ;
 import org.apache.jena.sparql.util.ExprUtils ;
 
-/** Aggregate that does everything except the per-group aggregation that is needed for each operation */  
-public abstract class AggregatorBase implements Aggregator 
+/** Aggregate that does everything except the per-group aggregation that is needed for each operation */
+public abstract class AggregatorBase implements Aggregator
 {
     // Aggregator -- handles one aggregation over one group, and is the syntax unit.
-    
+
     // AggregateFactory -- delays the creating of Aggregator so multiple mentions over the same group gives the same Aggregator
-    
+
     // Accumulator -- the per-group, per-key accumulator for the aggregate
     // queries track their aggregators so if one is used twice, the calculataion is only done once.
-    // For distinct, that means only uniquefier. 
-    
+    // For distinct, that means only uniquefier.
+
     // Built-ins: COUNT, SUM, MIN, MAX, AVG, GROUP_CONCAT, and SAMPLE
     // but COUNT(*) and COUNT(Expr) are different beasts
-    // each in DISTINCT and non-DISTINCT versions 
-    
-    protected final String name ; 
+    // each in DISTINCT and non-DISTINCT versions
+
+    protected final String name ;
     protected final boolean isDistinct ;
     protected final ExprList exprList ;
-    
+
     protected AggregatorBase(String name, boolean isDistinct, Expr expr) {
         this(name, isDistinct, new ExprList(expr)) ;
     }
-    
+
     protected AggregatorBase(String name, boolean isDistinct, ExprList exprList) {
         this.name = name ;
-        this.isDistinct = isDistinct ;  
+        this.isDistinct = isDistinct ;
         this.exprList = exprList ;
     }
-    
+
     private Map<Binding, Accumulator> buckets = new HashMap<>() ;   // Bindingkey => Accumulator
 
     @Override
     public abstract Accumulator createAccumulator() ;
-    
+
     @Override
     public abstract Node getValueEmpty() ;
 
@@ -77,14 +78,14 @@ public abstract class AggregatorBase implements Aggregator
         if ( acc == null )
             throw new ARQInternalErrorException("Null for accumulator") ;
         NodeValue nv = acc.getValue();
-        if ( nv == null ) 
+        if ( nv == null )
             return null ;
         return nv.asNode() ;
     }
-    
+
     @Override
     public String key() {  return toPrefixString() ; }
-    
+
     @Override
     public final Aggregator copyTransform(NodeTransform transform)
     {
@@ -93,7 +94,7 @@ public abstract class AggregatorBase implements Aggregator
             e = e.applyNodeTransform(transform) ;
         return copy(e) ;
     }
-    
+
     /** Many aggregate use a single expression.
      *  This convenience operation gets the expression if there is exactly one.
      */
@@ -102,12 +103,12 @@ public abstract class AggregatorBase implements Aggregator
             return getExprList().get(0) ;
         return null ;
     }
-    
+
     @Override
     public ExprList getExprList()           { return exprList ; }
 
     @Override
-    public String getName()                 { return name ; } 
+    public String getName()                 { return name ; }
 
     @Override
     public String toString()                { return asSparqlExpr(null) ; }
@@ -129,8 +130,8 @@ public abstract class AggregatorBase implements Aggregator
     public String toPrefixString() {
         IndentedLineBuffer x = new IndentedLineBuffer() ;
         x.append("(") ;
-        x.append(getName().toLowerCase(Locale.ROOT)) ;
-        x.incIndent(); 
+        x.append(lowercase(getName())) ;
+        x.incIndent();
         if ( isDistinct )
             x.append(" distinct") ;
         for ( Expr e : getExprList() ) {
@@ -141,7 +142,7 @@ public abstract class AggregatorBase implements Aggregator
         x.append(")") ;
         return x.asString() ;
     }
-    
+
     @Override
     public abstract int hashCode() ;
 
@@ -152,7 +153,7 @@ public abstract class AggregatorBase implements Aggregator
         if ( ! ( other instanceof Aggregator ) ) return false ;
         return equals((Aggregator)other, false) ;
     }
-    
+
     protected static final int HC_AggAvg                    =  0x170 ;
     protected static final int HC_AggAvgDistinct            =  0x171 ;
 
@@ -164,19 +165,19 @@ public abstract class AggregatorBase implements Aggregator
 
     protected static final int HC_AggMin                    =  0x176 ;
     protected static final int HC_AggMinDistinct            =  0x177 ;
-    
+
     protected static final int HC_AggMax                    =  0x178 ;
     protected static final int HC_AggMaxDistinct            =  0x179 ;
 
     protected static final int HC_AggSample                 =  0x17A ;
     protected static final int HC_AggSampleDistinct         =  0x17B ;
-    
+
     protected static final int HC_AggSum                    =  0x17C ;
     protected static final int HC_AggSumDistinct            =  0x17D ;
-    
+
     protected static final int HC_AggGroupConcat            =  0x17E ;
     protected static final int HC_AggGroupConcatDistinct    =  0x17F ;
-    
+
     protected static final int HC_AggNull                   =  0x180 ;
     protected static final int HC_AggCustom                 =  0x181 ;
 
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/function/library/FN_CollationKey.java b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/FN_CollationKey.java
index 6f98f256df..3f5d6e8eba 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/function/library/FN_CollationKey.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/function/library/FN_CollationKey.java
@@ -18,30 +18,31 @@
 
 package org.apache.jena.sparql.function.library;
 
+import static org.apache.jena.atlas.lib.Lib.lowercase;
+
 import java.nio.charset.StandardCharsets ;
 import java.util.Base64 ;
-import java.util.Locale ;
 
 import org.apache.jena.datatypes.xsd.XSDDatatype ;
 import org.apache.jena.sparql.expr.NodeValue ;
 import org.apache.jena.sparql.function.FunctionBase2 ;
 
 /** XPath and XQuery Functions and Operators 3.1
- * <p> 
+ * <p>
  * {@code fn:collation-key($key as xs:string, $collation as xs:string) as xs:base64Binary}
  */
 public class FN_CollationKey extends FunctionBase2 {
 
     // The function2 variant
-    // Function1 is default collation -> codepoint. 
-    
+    // Function1 is default collation -> codepoint.
+
     @Override
     public NodeValue exec(NodeValue v1, NodeValue v2) {
         //fn:collation-key($key as xs:string, $collation as xs:string) as xs:base64Binary
         if ( ! v1.isString() ) {}
         if ( ! v2.isString() ) {}
-        String collation = v2 == null ? "" : v2.getString().toLowerCase(Locale.ROOT); 
-        
+        String collation = v2 == null ? "" : lowercase(v2.getString());
+
         // The irony of using the lexical form of old rdf:plainLiteral (RDF 1.1 does not
         // need rdf:plainLiteral and rdf:plainLiteral should never appear in RDF)
         String x = v1.getString()+"@"+v2.getString();
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/function/scripting/ScriptFunction.java b/jena-arq/src/main/java/org/apache/jena/sparql/function/scripting/ScriptFunction.java
index f27cc98967..2807ab632f 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/function/scripting/ScriptFunction.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/function/scripting/ScriptFunction.java
@@ -18,6 +18,8 @@
 
 package org.apache.jena.sparql.function.scripting;
 
+import static org.apache.jena.atlas.lib.Lib.lowercase;
+
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.Reader;
@@ -112,7 +114,7 @@ public class ScriptFunction extends FunctionBase {
         this.name = localPart.substring(separatorPos + 1);
         this.allowList = allowList(cxt, ARQ.symCustomFunctionScriptAllowList);
 
-        String cname = lang.toLowerCase(Locale.ROOT);
+        String cname = lowercase(lang);
         switch(cname) {
             case "js":
                 // never allow these.
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/FmtUtils.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/FmtUtils.java
index ff65b10a4e..6c171820ab 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/util/FmtUtils.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/FmtUtils.java
@@ -18,7 +18,8 @@
 
 package org.apache.jena.sparql.util;
 
-import java.util.Locale ;
+import static org.apache.jena.atlas.lib.Lib.uppercase;
+
 import java.util.regex.Pattern ;
 
 import org.apache.jena.atlas.io.IndentedWriter ;
@@ -46,222 +47,195 @@ import org.apache.jena.vocabulary.XSD ;
  *  @see NodeFmtLib
  */
 
-public class FmtUtils
-{
+public class FmtUtils {
     // See also riot.NodeFmtLib
 
     // Consider withdrawing non-serialization context forms of this.
     // Or a temporary SerialzationContext does not abbreviate bNodes.
-    static final String indentPrefix = "  " ;
-    public static boolean multiLineExpr = false ;
-    public static boolean printOpName = true ;
+    static final String indentPrefix = "  ";
+    public static boolean multiLineExpr = false;
+    public static boolean printOpName = true;
 
-    static NodeToLabelMap bNodeMap = new NodeToLabelMapBNode("b", false) ;
+    static NodeToLabelMap bNodeMap = new NodeToLabelMapBNode("b", false);
 
-    public static SerializationContext sCxt()
-    {
-        return sCxt(ARQConstants.getGlobalPrefixMap()) ;
+    public static SerializationContext sCxt() {
+        return sCxt(ARQConstants.getGlobalPrefixMap());
     }
 
-    public static SerializationContext sCxt(PrefixMapping pmap)
-    {
-        return new SerializationContext(pmap) ;
+    public static SerializationContext sCxt(PrefixMapping pmap) {
+        return new SerializationContext(pmap);
     }
 
     // Formatting various items
-    public static String stringForTriple( Triple triple )
-    {
+    public static String stringForTriple(Triple triple) {
         StringBuilder result = new StringBuilder();
-        stringForNode( result, triple.getSubject() );
-        result.append( " " );
-        stringForNode( result, triple.getPredicate() );
-        result.append( " " );
-        stringForNode( result, triple.getObject() );
+        stringForNode(result, triple.getSubject());
+        result.append(" ");
+        stringForNode(result, triple.getPredicate());
+        result.append(" ");
+        stringForNode(result, triple.getObject());
         return result.toString();
     }
 
-    public static String stringForTriple(Triple triple, PrefixMapping prefixMap)
-    {
-        return stringForTriple(triple, sCxt(prefixMap)) ;
+    public static String stringForTriple(Triple triple, PrefixMapping prefixMap) {
+        return stringForTriple(triple, sCxt(prefixMap));
     }
 
-    public static String stringForTriple(Triple triple, SerializationContext sCxt)
-    {
+    public static String stringForTriple(Triple triple, SerializationContext sCxt) {
         StringBuilder result = new StringBuilder();
-        stringForTriple(result, triple, sCxt) ;
+        stringForTriple(result, triple, sCxt);
         return result.toString();
     }
 
-    public static void stringForTriple(StringBuilder result, Triple triple, SerializationContext sCxt)
-    {
-        stringForNode(result, triple.getSubject(), sCxt );
-        result.append( " " );
-        stringForNode(result, triple.getPredicate(), sCxt );
-        result.append( " " );
-        stringForNode(result, triple.getObject(), sCxt );
+    public static void stringForTriple(StringBuilder result, Triple triple, SerializationContext sCxt) {
+        stringForNode(result, triple.getSubject(), sCxt);
+        result.append(" ");
+        stringForNode(result, triple.getPredicate(), sCxt);
+        result.append(" ");
+        stringForNode(result, triple.getObject(), sCxt);
     }
 
     public static String stringForQuad(Quad quad, PrefixMapping prefixMap) {
-        return stringForQuad(quad, sCxt(prefixMap)) ;
+        return stringForQuad(quad, sCxt(prefixMap));
     }
 
-    public static String stringForQuad(Quad quad)
-    {
-        StringBuilder sb = new StringBuilder() ;
+    public static String stringForQuad(Quad quad) {
+        StringBuilder sb = new StringBuilder();
 
-        if ( quad.getGraph() != null )
-        {
-            sb.append(stringForNode(quad.getGraph())) ;
-            sb.append(" ") ;
+        if ( quad.getGraph() != null ) {
+            sb.append(stringForNode(quad.getGraph()));
+            sb.append(" ");
         }
 
-        stringForNode(sb, quad.getSubject() );
-        sb.append(" ") ;
+        stringForNode(sb, quad.getSubject());
+        sb.append(" ");
         stringForNode(sb, quad.getPredicate());
-        sb.append(" ") ;
+        sb.append(" ");
         stringForNode(sb, quad.getObject());
-        return sb.toString() ;
+        return sb.toString();
     }
 
     public static String stringForQuad(Quad quad, SerializationContext sCxt) {
-        StringBuilder sb = new StringBuilder() ;
-        stringForQuad(sb, quad, sCxt) ;
-        return sb.toString() ;
+        StringBuilder sb = new StringBuilder();
+        stringForQuad(sb, quad, sCxt);
+        return sb.toString();
     }
 
-    public static void stringForQuad(StringBuilder sb, Quad quad, SerializationContext sCxt)
-    {
-        if ( quad.getGraph() != null )
-        {
-            sb.append(stringForNode(quad.getGraph(), sCxt)) ;
-            sb.append(" ") ;
+    public static void stringForQuad(StringBuilder sb, Quad quad, SerializationContext sCxt) {
+        if ( quad.getGraph() != null ) {
+            sb.append(stringForNode(quad.getGraph(), sCxt));
+            sb.append(" ");
         }
 
         stringForNode(sb, quad.getSubject(), sCxt);
-        sb.append(" ") ;
-        stringForNode( sb, quad.getPredicate(), sCxt );
-        sb.append(" ") ;
+        sb.append(" ");
+        stringForNode(sb, quad.getPredicate(), sCxt);
+        sb.append(" ");
         stringForNode(sb, quad.getObject(), sCxt);
     }
 
-    public static void formatPattern(IndentedWriter out, BasicPattern pattern, SerializationContext sCxt)
-    {
-        StringBuilder buffer = new StringBuilder() ;
-        boolean first = true ;
-        for (Triple triple : pattern )
-        {
-            if ( ! first )
-                buffer.append("\n") ;
-            stringForTriple(buffer, triple, sCxt) ;
-            buffer.append(" ." ) ;
-            out.print(buffer.toString()) ;
-            buffer.setLength(0) ;
-            first = false ;
+    public static void formatPattern(IndentedWriter out, BasicPattern pattern, SerializationContext sCxt) {
+        StringBuilder buffer = new StringBuilder();
+        boolean first = true;
+        for ( Triple triple : pattern ) {
+            if ( !first )
+                buffer.append("\n");
+            stringForTriple(buffer, triple, sCxt);
+            buffer.append(" .");
+            out.print(buffer.toString());
+            buffer.setLength(0);
+            first = false;
         }
     }
 
-    public static String stringForObject(Object obj)
-    {
+    public static String stringForObject(Object obj) {
         if ( obj == null )
-            return "<<null>>" ;
+            return "<<null>>";
 
         if ( obj instanceof RDFNode )
-            return stringForRDFNode((RDFNode)obj) ;
+            return stringForRDFNode((RDFNode)obj);
         if ( obj instanceof Node )
-            return stringForNode((Node)obj) ;
-        return obj.toString() ;
+            return stringForNode((Node)obj);
+        return obj.toString();
     }
 
-
-    public static String stringForRDFNode(RDFNode obj)
-    {
-        Model m = null ;
+    public static String stringForRDFNode(RDFNode obj) {
+        Model m = null;
         if ( obj instanceof Resource )
-            m = obj.getModel() ;
-        return stringForRDFNode(obj, newSerializationContext(m)) ;
+            m = obj.getModel();
+        return stringForRDFNode(obj, newSerializationContext(m));
     }
 
-    public static String stringForRDFNode(RDFNode obj, SerializationContext context)
-    {
-        return stringForNode(obj.asNode(), context) ;
+    public static String stringForRDFNode(RDFNode obj, SerializationContext context) {
+        return stringForNode(obj.asNode(), context);
     }
 
-    public static String stringForLiteral(Node_Literal literal, SerializationContext context)
-    {
-        StringBuilder result = new StringBuilder(  );
-        stringForLiteral( result, literal, context );
+    public static String stringForLiteral(Node_Literal literal, SerializationContext context) {
+        StringBuilder result = new StringBuilder();
+        stringForLiteral(result, literal, context);
         return result.toString();
     }
 
-    public static void stringForLiteral(StringBuilder result, Node_Literal literal, SerializationContext context)
-    {
-        String datatype = literal.getLiteralDatatypeURI() ;
-        String lang = literal.getLiteralLanguage() ;
-        String s = literal.getLiteralLexicalForm() ;
+    public static void stringForLiteral(StringBuilder result, Node_Literal literal, SerializationContext context) {
+        String datatype = literal.getLiteralDatatypeURI();
+        String lang = literal.getLiteralLanguage();
+        String s = literal.getLiteralLexicalForm();
 
-        //For some literals we can use plain literal form unless the Serialization Context
-        //explicitly says not to
-        //For backwards compatibility if using a null context then we use plain literal
-        //forms where possible as this was the existing behaviour prior to this addition to the API
-        if ( datatype != null && (context == null || context.getUsePlainLiterals()))
-        {
+        // For some literals we can use plain literal form unless the Serialization
+        // Context explicitly says not to. For backwards compatibility if using a
+        // null context then we use plain literal forms where possible as this was
+        // the existing behaviour prior to this addition to the API
+        if ( datatype != null && (context == null || context.getUsePlainLiterals()) ) {
             // Special form we know how to handle?
             // Assume valid text
-            if ( datatype.equals(XSD.integer.getURI()) )
-            {
+            if ( datatype.equals(XSD.integer.getURI()) ) {
                 try {
-                    String s1 = s ;
+                    String s1 = s;
                     // BigInteger does not allow leading +
                     // so chop it off before the format test
                     // BigDecimal does allow a leading +
                     if ( s.startsWith("+") )
-                        s1 = s.substring(1) ;
-                    new java.math.BigInteger(s1) ;
+                        s1 = s.substring(1);
+                    new java.math.BigInteger(s1);
                     result.append(s);
                     return;
                 } catch (NumberFormatException nfe) {}
-                // No luck.  Continue.
+                // No luck. Continue.
                 // Continuing is always safe.
             }
 
-            if ( datatype.equals(XSD.decimal.getURI()) )
-            {
-                if ( s.indexOf('.') > 0 )
-                {
+            if ( datatype.equals(XSD.decimal.getURI()) ) {
+                if ( s.indexOf('.') > 0 ) {
                     try {
                         // BigDecimal does allow a leading +
-                        new java.math.BigDecimal(s) ;
+                        new java.math.BigDecimal(s);
                         result.append(s);
                         return;
                     } catch (NumberFormatException nfe) {}
-                    // No luck.  Continue.
+                    // No luck. Continue.
                 }
             }
 
-            if ( datatype.equals(XSD.xdouble.getURI()) )
-            {
+            if ( datatype.equals(XSD.xdouble.getURI()) ) {
                 // Assumes SPARQL has decimals and doubles.
                 // Must have 'e' or 'E' to be a double short form.
 
-                if ( s.indexOf('e') >= 0 || s.indexOf('E') >= 0 )
-                {
+                if ( s.indexOf('e') >= 0 || s.indexOf('E') >= 0 ) {
                     try {
-                        Double.parseDouble(s) ;
+                        Double.parseDouble(s);
                         result.append(s);
                         return;  // returm the original lexical form.
                     } catch (NumberFormatException nfe) {}
-                    // No luck.  Continue.
+                    // No luck. Continue.
                 }
             }
 
-            if ( datatype.equals(XSD.xboolean.getURI()) )
-            {
+            if ( datatype.equals(XSD.xboolean.getURI()) ) {
                 // Pragmatics: if the data wrote "1"^^xsd:boolean, keep that form.
                 // The lexical form must be lower case.
-//                if ( s.equals("true") || s.equals("1") ) return s ;
-//                if ( s.equals("false") || s.equals("0")  ) return s ;
-                if ( s.equals("true") || s.equals("false"))
-                {
+                // if ( s.equals("true") || s.equals("1") ) return s ;
+                // if ( s.equals("false") || s.equals("0") ) return s ;
+                if ( s.equals("true") || s.equals("false") ) {
                     result.append(s);
                     return;
                 }
@@ -270,112 +244,101 @@ public class FmtUtils
             // Not a recognized form.
         }
 
-        result.append("\"") ;
-        stringEsc(result, s, true) ;
-        result.append("\"") ;
+        result.append("\"");
+        stringEsc(result, s, true);
+        result.append("\"");
 
         if ( NodeUtils.isSimpleString(literal) ) {
             // No op.
-            return ;
+            return;
         }
 
         if ( NodeUtils.isLangString(literal) ) {
-            result.append("@") ;
-            result.append(lang) ;
-            return ;
+            result.append("@");
+            result.append(lang);
+            return;
         }
 
-        if ( datatype != null )
-        {
-            result.append("^^") ;
-            stringForURI( result, datatype, context );
+        if ( datatype != null ) {
+            result.append("^^");
+            stringForURI(result, datatype, context);
         }
     }
 
-    public static String stringForString(String str)
-    {
-        StringBuilder sbuff = new StringBuilder() ;
-        sbuff.append("\"") ;
-        stringEsc(sbuff, str, true) ;
-        sbuff.append("\"") ;
-        return sbuff.toString() ;
+    public static String stringForString(String str) {
+        StringBuilder sbuff = new StringBuilder();
+        sbuff.append("\"");
+        stringEsc(sbuff, str, true);
+        sbuff.append("\"");
+        return sbuff.toString();
     }
 
-    public static String stringForResource(Resource r)
-    {
-        return stringForResource(r, newSerializationContext(r.getModel())) ;
+    public static String stringForResource(Resource r) {
+        return stringForResource(r, newSerializationContext(r.getModel()));
     }
 
-    public static String stringForResource(Resource r, SerializationContext context)
-    {
-        return stringForNode(r.asNode(), context) ;
+    public static String stringForResource(Resource r, SerializationContext context) {
+        return stringForNode(r.asNode(), context);
     }
 
-    public static String stringForNode(Node n)
-    {
+    public static String stringForNode(Node n) {
         StringBuilder sb = new StringBuilder();
-        stringForNode(sb, n, ARQConstants.getGlobalPrefixMap()) ;
+        stringForNode(sb, n, ARQConstants.getGlobalPrefixMap());
         return sb.toString();
     }
 
-    public static void stringForNode(StringBuilder result, Node n)
-    {
-        stringForNode( result, n, ARQConstants.getGlobalPrefixMap()) ;
+    public static void stringForNode(StringBuilder result, Node n) {
+        stringForNode(result, n, ARQConstants.getGlobalPrefixMap());
     }
 
-    public static String stringForNode(Node n, PrefixMapping prefixMap)
-    {
+    public static String stringForNode(Node n, PrefixMapping prefixMap) {
         StringBuilder sb = new StringBuilder();
-        stringForNode(sb, n, newSerializationContext(prefixMap)) ;
+        stringForNode(sb, n, newSerializationContext(prefixMap));
         return sb.toString();
     }
 
-    public static void stringForNode(StringBuilder result, Node n, PrefixMapping prefixMap)
-    {
-        stringForNode( result, n, newSerializationContext(prefixMap)) ;
+    public static void stringForNode(StringBuilder result, Node n, PrefixMapping prefixMap) {
+        stringForNode(result, n, newSerializationContext(prefixMap));
     }
 
-    public static String stringForNode(Node n, Prologue prologue)
-    {
+    public static String stringForNode(Node n, Prologue prologue) {
         StringBuilder sb = new StringBuilder();
-        stringForNode(sb, n, newSerializationContext(prologue)) ;
+        stringForNode(sb, n, newSerializationContext(prologue));
         return sb.toString();
     }
 
-    public static String stringForNode(Node n, SerializationContext context)
-    {
-        StringBuilder sb = new StringBuilder(  );
-        stringForNode( sb, n, context );
+    public static String stringForNode(Node n, SerializationContext context) {
+        StringBuilder sb = new StringBuilder();
+        stringForNode(sb, n, context);
         return sb.toString();
     }
 
-    public static void stringForNode(StringBuilder result, Node n, SerializationContext context)
-    {
+    public static void stringForNode(StringBuilder result, Node n, SerializationContext context) {
         if ( n == null ) {
-            result.append("<<null>>") ;
-            return ;
+            result.append("<<null>>");
+            return;
         }
 
         // mappable?
         if ( context != null && context.getBNodeMap() != null ) {
-            String str = context.getBNodeMap().asString(n) ;
+            String str = context.getBNodeMap().asString(n);
             if ( str != null ) {
-                result.append(str) ;
-                return ;
+                result.append(str);
+                return;
             }
         }
 
         if ( n.isBlank() ) {
-            result.append("_:").append(n.getBlankNodeLabel()) ;
+            result.append("_:").append(n.getBlankNodeLabel());
         } else if ( n.isLiteral() ) {
-            stringForLiteral(result, (Node_Literal)n, context) ;
+            stringForLiteral(result, (Node_Literal)n, context);
         } else if ( n.isURI() ) {
-            String uri = n.getURI() ;
-            stringForURI(result, uri, context) ;
+            String uri = n.getURI();
+            stringForURI(result, uri, context);
         } else if ( n.isVariable() ) {
-            result.append("?").append(n.getName()) ;
+            result.append("?").append(n.getName());
         } else if ( n.equals(Node.ANY) ) {
-            result.append("ANY") ;
+            result.append("ANY");
         } else if ( n.isNodeTriple() ) {
             Triple t = n.getTriple();
             result.append("<< ");
@@ -386,79 +349,67 @@ public class FmtUtils
             stringForNode(result, t.getObject(), context);
             result.append(" >>");
         } else if ( n.isNodeGraph() ) {
-            Log.warn(FmtUtils.class, "Can not turn a graph term node into a string") ;
+            Log.warn(FmtUtils.class, "Can not turn a graph term node into a string");
             result.append(" { graph }");
         } else {
-            Log.warn(FmtUtils.class, "Failed to turn a node into a string: " + n) ;
-            result.append(n.toString()) ;
+            Log.warn(FmtUtils.class, "Failed to turn a node into a string: " + n);
+            result.append(n.toString());
         }
     }
 
-    static public String stringForURI(String uri)
-    {
+    public static String stringForURI(String uri) {
         StringBuilder sb = new StringBuilder();
         stringForURI(sb, uri);
         return sb.toString();
     }
 
-	static public void stringForURI(StringBuilder target, String uri)
-	{
-		target.append("<");
-		stringEsc(target, uri);
-		target.append(">");
-	}
-
+    public static void stringForURI(StringBuilder target, String uri) {
+        target.append("<");
+        stringEsc(target, uri);
+        target.append(">");
+    }
 
-	static public String stringForURI(String uri, Prologue prologue)
-    {
-        return stringForURI(uri, prologue.getBaseURI(), prologue.getPrefixMapping()) ;
+    public static String stringForURI(String uri, Prologue prologue) {
+        return stringForURI(uri, prologue.getBaseURI(), prologue.getPrefixMapping());
     }
 
-    static public String stringForURI(String uri, String baseIRI)
-    {
-        return stringForURI(uri, baseIRI, null) ;
+    public static String stringForURI(String uri, String baseIRI) {
+        return stringForURI(uri, baseIRI, null);
     }
 
-    static public String stringForURI(String uri, SerializationContext context)
-    {
+    public static String stringForURI(String uri, SerializationContext context) {
         if ( context == null )
-            return stringForURI(uri, null, null) ;
-        return stringForURI(uri, context.getBaseIRI(), context.getPrefixMapping()) ;
+            return stringForURI(uri, null, null);
+        return stringForURI(uri, context.getBaseIRI(), context.getPrefixMapping());
     }
 
-    static public void stringForURI(StringBuilder result, String uri, SerializationContext context)
-    {
+    public static void stringForURI(StringBuilder result, String uri, SerializationContext context) {
         if ( context == null )
-            stringForURI(result, uri, null, null) ;
+            stringForURI(result, uri, null, null);
         else
-            stringForURI(result, uri, context.getBaseIRI(), context.getPrefixMapping()) ;
+            stringForURI(result, uri, context.getBaseIRI(), context.getPrefixMapping());
     }
 
-    static public String stringForURI(String uri, PrefixMapping mapping)
+    public static String stringForURI(String uri, PrefixMapping mapping)
     { return stringForURI(uri, null, mapping) ; }
 
-    static public String stringForURI(String uri, String base, PrefixMapping mapping)
-    {
-        StringBuilder result = new StringBuilder(  );
-        stringForURI( result, uri, base, mapping );
+    public static String stringForURI(String uri, String base, PrefixMapping mapping) {
+        StringBuilder result = new StringBuilder();
+        stringForURI(result, uri, base, mapping);
         return result.toString();
     }
 
-    static public void stringForURI(StringBuilder result, String uri, String base, PrefixMapping mapping)
-    {
-        if ( mapping != null )
-        {
-            String pname = prefixFor(uri, mapping) ;
-            if ( pname != null )
-            {
-                result.append( pname);
+    public static void stringForURI(StringBuilder result, String uri, String base, PrefixMapping mapping) {
+        if ( mapping != null ) {
+            String pname = prefixFor(uri, mapping);
+            if ( pname != null ) {
+                result.append(pname);
                 return;
             }
 
         }
-        if ( base != null )
-        {
-            String x = abbrevByBase(uri, base) ;
+        if ( base != null ) {
+            String x = abbrevByBase(uri, base);
             if ( x != null ) {
                 result.append("<");
                 result.append(x);
@@ -466,7 +417,7 @@ public class FmtUtils
                 return;
             }
         }
-        stringForURI( result, uri ) ;
+        stringForURI(result, uri);
     }
 
     public static String abbrevByBase(String uriStr, String base) {
@@ -487,65 +438,60 @@ public class FmtUtils
         return schemePattern.matcher(uriStr).matches() ;
     }
 
-    private static String prefixFor(String uri, PrefixMapping mapping)
-    {
-        if ( mapping == null ) return null ;
+    private static String prefixFor(String uri, PrefixMapping mapping) {
+        if ( mapping == null )
+            return null;
 
-        String pname = mapping.shortForm(uri) ;
+        String pname = mapping.shortForm(uri);
         if ( pname != uri && checkValidPrefixName(pname) )
-            return pname ;
-        pname = mapping.qnameFor(uri) ;
+            return pname;
+        pname = mapping.qnameFor(uri);
         if ( pname != null && checkValidPrefixName(pname) )
-            return pname ;
-        return null ;
+            return pname;
+        return null;
     }
 
-    private static boolean checkValidPrefixName(String prefixedName)
-    {
+    private static boolean checkValidPrefixName(String prefixedName) {
         // Split it to get the parts.
-        int i = prefixedName.indexOf(':') ;
+        int i = prefixedName.indexOf(':');
         if ( i < 0 )
-            throw new ARQInternalErrorException("Broken short form -- "+prefixedName) ;
-        String p = prefixedName.substring(0,i) ;
-        String x = prefixedName.substring(i+1) ;
+            throw new ARQInternalErrorException("Broken short form -- " + prefixedName);
+        String p = prefixedName.substring(0, i);
+        String x = prefixedName.substring(i + 1);
         // Check legality
         if ( checkValidPrefix(p) && checkValidLocalname(x) )
-            return true ;
-        return false ;
+            return true;
+        return false;
     }
 
-    private static boolean checkValidPrefix(String prefixStr)
-    {
-        if ( prefixStr.startsWith("_"))
+    private static boolean checkValidPrefix(String prefixStr) {
+        if ( prefixStr.startsWith("_") )
             // Should .equals??
-            return false ;
-        return checkValidLocalname(prefixStr) ;
+            return false;
+        return checkValidLocalname(prefixStr);
     }
 
-    private static boolean checkValidLocalname(String localname)
-    {
+    private static boolean checkValidLocalname(String localname) {
         if ( localname.length() == 0 )
-            return true ;
+            return true;
 
-        for ( int idx = 0 ; idx < localname.length() ; idx++ )
-        {
-            char ch = localname.charAt(idx) ;
-            if ( ! validPNameChar(ch) )
-                return false ;
+        for ( int idx = 0 ; idx < localname.length() ; idx++ ) {
+            char ch = localname.charAt(idx);
+            if ( !validPNameChar(ch) )
+                return false;
         }
 
         // Test start and end - at least one character in the name.
 
         if ( localname.endsWith(".") )
-            return false ;
+            return false;
         if ( localname.startsWith(".") )
-            return false ;
+            return false;
 
-        return true ;
+        return true;
     }
 
-    private static boolean validPNameChar(char ch)
-    {
+    private static boolean validPNameChar(char ch) {
         if ( Character.isLetterOrDigit(ch) ) return true ;
         if ( ch == '.' )    return true ;
         if ( ch == ':' )    return true ;
@@ -562,66 +508,61 @@ public class FmtUtils
     public static String stringEsc(String s)
     { return stringEsc( s, true ) ; }
 
-    public static String stringEsc(String s, boolean singleLineString)
-    {
-        StringBuilder sb = new StringBuilder() ;
-        stringEsc(sb, s, singleLineString) ;
-        return sb.toString() ;
+    public static String stringEsc(String s, boolean singleLineString) {
+        StringBuilder sb = new StringBuilder();
+        stringEsc(sb, s, singleLineString);
+        return sb.toString();
     }
 
     public static void stringEsc(StringBuilder sbuff, String s)
     { stringEsc( sbuff,  s, true ) ; }
 
-    public static void stringEsc(StringBuilder sbuff, String s, boolean singleLineString)
-    {
-        int len = s.length() ;
-        for (int i = 0; i < len; i++) {
+    public static void stringEsc(StringBuilder sbuff, String s, boolean singleLineString) {
+        int len = s.length();
+        for ( int i = 0 ; i < len ; i++ ) {
             char c = s.charAt(i);
 
             // Escape escapes and quotes
-            if (c == '\\' || c == '"' )
-            {
-                sbuff.append('\\') ;
-                sbuff.append(c) ;
-                continue ;
+            if ( c == '\\' || c == '"' ) {
+                sbuff.append('\\');
+                sbuff.append(c);
+                continue;
             }
 
-            // Characters to literally output.
-            // This would generate 7-bit safe files
-//            if (c >= 32 && c < 127)
-//            {
-//                sbuff.append(c) ;
+//            // Characters to literally output.
+//            // This would generate 7-bit safe files
+//            if ( c >= 32 && c < 127 ) {
+//                sbuff.append(c);
 //                continue;
 //            }
 
             // Whitespace
-            if ( singleLineString && ( c == '\n' || c == '\r' || c == '\f' || c == '\t' ) )
-            {
-                if (c == '\n') sbuff.append("\\n");
-                if (c == '\t') sbuff.append("\\t");
-                if (c == '\r') sbuff.append("\\r");
-                if (c == '\f') sbuff.append("\\f");
-                continue ;
+            if ( singleLineString && (c == '\n' || c == '\r' || c == '\f' || c == '\t') ) {
+                if ( c == '\n' )
+                    sbuff.append("\\n");
+                if ( c == '\t' )
+                    sbuff.append("\\t");
+                if ( c == '\r' )
+                    sbuff.append("\\r");
+                if ( c == '\f' )
+                    sbuff.append("\\f");
+                continue;
             }
 
             // Output as is (subject to UTF-8 encoding on output that is)
 
-            if ( ! applyUnicodeEscapes )
-                sbuff.append(c) ;
-            else
-            {
+            if ( !applyUnicodeEscapes )
+                sbuff.append(c);
+            else {
                 // Unicode escapes
                 // c < 32, c >= 127, not whitespace or other specials
-                if ( c >= 32 && c < 127 )
-                {
-                    sbuff.append(c) ;
-                }
-                else
-                {
-                    String hexstr = Integer.toHexString(c).toUpperCase(Locale.ROOT);
+                if ( c >= 32 && c < 127 ) {
+                    sbuff.append(c);
+                } else {
+                    String hexstr = uppercase(Integer.toHexString(c));
                     int pad = 4 - hexstr.length();
                     sbuff.append("\\u");
-                    for (; pad > 0; pad--)
+                    for ( ; pad > 0 ; pad-- )
                         sbuff.append("0");
                     sbuff.append(hexstr);
                 }
@@ -629,16 +570,16 @@ public class FmtUtils
         }
     }
 
-    static public void resetBNodeLabels() { bNodeMap = new NodeToLabelMapBNode("b", false) ; }
+    public static void resetBNodeLabels() {
+        bNodeMap = new NodeToLabelMapBNode("b", false);
+    }
 
-    private static SerializationContext newSerializationContext(PrefixMapping prefixMapping)
-    {
-        return new SerializationContext(prefixMapping, bNodeMap) ;
+    private static SerializationContext newSerializationContext(PrefixMapping prefixMapping) {
+        return new SerializationContext(prefixMapping, bNodeMap);
     }
 
-    private static SerializationContext newSerializationContext(Prologue prologue)
-    {
-        return new SerializationContext(prologue, bNodeMap) ;
+    private static SerializationContext newSerializationContext(Prologue prologue) {
+        return new SerializationContext(prologue, bNodeMap);
     }
 
 }
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/RomanNumeral.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/RomanNumeral.java
index 63b2d170dd..87adb212ae 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/util/RomanNumeral.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/RomanNumeral.java
@@ -22,6 +22,8 @@ import java.util.Locale ;
 import java.util.regex.Matcher ;
 import java.util.regex.Pattern ;
 
+import org.apache.jena.atlas.lib.Lib;
+
 /**
  * References:
  * <ul>
@@ -72,7 +74,7 @@ public class RomanNumeral
 
     // It is easier working right to left!
     public static int r2i(String lex) {
-        lex = lex.toUpperCase(Locale.ROOT) ;
+        lex = Lib.uppercase(lex) ;
 
         // This is overly permissive.
         // 1 - allows multiple reducing values
diff --git a/jena-arq/src/test/java/org/apache/jena/riot/TestSysRIOT.java b/jena-arq/src/test/java/org/apache/jena/riot/TestSysRIOT.java
index 3c7329ca20..95118dc12b 100644
--- a/jena-arq/src/test/java/org/apache/jena/riot/TestSysRIOT.java
+++ b/jena-arq/src/test/java/org/apache/jena/riot/TestSysRIOT.java
@@ -18,7 +18,8 @@
 
 package org.apache.jena.riot;
 
-import java.util.Locale;
+import static org.apache.jena.atlas.lib.Lib.lowercase;
+
 import java.util.function.Predicate;
 
 import org.apache.jena.atlas.io.IO;
@@ -42,7 +43,7 @@ public class TestSysRIOT {
     public void chooseBaseIRI_3() {
         if ( Sys.isWindows ) {
             if ( IO.exists("c:/") )
-                testChooseBaseIRI("c:", s->s.toLowerCase(Locale.ROOT).startsWith("file:///c:/"));
+                testChooseBaseIRI("c:", s->lowercase(s).startsWith("file:///c:/"));
         } else
             testChooseBaseIRI("x:", "x:");
     }
@@ -51,7 +52,7 @@ public class TestSysRIOT {
     public void chooseBaseIRI_4() {
         if ( Sys.isWindows ) {
             if ( IO.exists("c:/") )
-                testChooseBaseIRI("c:", s->s.toLowerCase(Locale.ROOT).startsWith("file:///c:/"));
+                testChooseBaseIRI("c:", s->lowercase(s).startsWith("file:///c:/"));
         } else
             testChooseBaseIRI("x:/", "x:/");
     }
diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java
index 0356e6c80f..e77ab46c92 100644
--- a/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java
+++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java
@@ -134,13 +134,13 @@ public class Lib
         return StringUtils.isEmpty(cs);
     }
 
-    /** Non-locale lowercase */
+    /** Non-locale lowercase {@link Locale#ROOT} */
     public static String lowercase(String string) {
         // Hide implementation
         return string.toLowerCase(Locale.ROOT);
     }
 
-    /** Non-locale uppercase */
+    /** Non-locale uppercase {@link Locale#ROOT} */
     public static String uppercase(String string) {
         // Hide implementation
         return string.toUpperCase(Locale.ROOT);
diff --git a/jena-base/src/test/java/org/apache/jena/atlas/junit/AssertExtra.java b/jena-base/src/test/java/org/apache/jena/atlas/junit/AssertExtra.java
index 86b685f2f2..019bc85bfa 100644
--- a/jena-base/src/test/java/org/apache/jena/atlas/junit/AssertExtra.java
+++ b/jena-base/src/test/java/org/apache/jena/atlas/junit/AssertExtra.java
@@ -19,33 +19,28 @@
 package org.apache.jena.atlas.junit ;
 
 import java.util.List ;
-import java.util.Locale ;
 
 import org.apache.jena.atlas.lib.ListUtils ;
 import org.junit.Assert ;
 
 public class AssertExtra {
     public static void assertEqualsIgnoreCase(String a, String b) {
-        a = a.toLowerCase(Locale.ROOT) ;
-        b = b.toLowerCase(Locale.ROOT) ;
-        Assert.assertEquals(a, b) ;
+        Assert.assertTrue(a.equalsIgnoreCase(b)) ;
     }
 
     public static void assertEqualsIgnoreCase(String msg, String a, String b) {
-        a = a.toLowerCase(Locale.ROOT) ;
-        b = b.toLowerCase(Locale.ROOT) ;
-        Assert.assertEquals(msg, a, b) ;
+        Assert.assertTrue(msg, a.equalsIgnoreCase(b));
     }
 
     public static <T> void assertEqualsUnordered(List<T> list1, List<T> list2) {
         assertEqualsUnordered(null, list1, list2) ;
     }
-    
+
     public static <T> void assertEqualsUnordered(String msg, List<T> list1, List<T> list2) {
         if ( ! ListUtils.equalsUnordered(list1, list2) )
             Assert.fail(msg(msg, list1, list2)) ;
     }
-    
+
     private static <T> String msg(String msg, List<T> list1, List<T> list2) {
         String x = ( msg == null ) ? "" : msg+": " ;
         x = x +"Expected: " + list1 + " : Actual: " + list2 ;
diff --git a/jena-cmds/src/main/java/arq/qparse.java b/jena-cmds/src/main/java/arq/qparse.java
index 39d7df3b1f..986ce4cf6b 100644
--- a/jena-cmds/src/main/java/arq/qparse.java
+++ b/jena-cmds/src/main/java/arq/qparse.java
@@ -18,9 +18,10 @@
 
 package arq;
 
+import static org.apache.jena.atlas.lib.Lib.lowercase;
+
 import java.io.PrintStream ;
 import java.util.Iterator ;
-import java.util.Locale;
 
 import arq.cmdline.CmdARQ ;
 import arq.cmdline.ModEngine ;
@@ -45,13 +46,13 @@ import org.apache.jena.sparql.util.QueryUtils ;
 public class qparse extends CmdARQ
 {
     protected ModQueryIn    modQuery        = new ModQueryIn(Syntax.syntaxARQ) ;
-    protected ModQueryOut   modOutput       = new ModQueryOut() ; 
+    protected ModQueryOut   modOutput       = new ModQueryOut() ;
     protected ModEngine     modEngine       = new ModEngine() ;
     protected final ArgDecl argDeclPrint    = new ArgDecl(ArgDecl.HasValue, "print") ;
     protected final ArgDecl argDeclOpt      = new ArgDecl(ArgDecl.NoValue, "opt", "optimize") ;
     protected final ArgDecl argDeclExplain  = new ArgDecl(ArgDecl.NoValue, "explain") ;
     protected final ArgDecl argDeclFixup    = new ArgDecl(ArgDecl.NoValue, "fixup") ;
-    
+
     protected boolean printNone             = false ;
     protected boolean printQuery            = false ;
     protected boolean printOp               = false ;
@@ -59,12 +60,12 @@ public class qparse extends CmdARQ
     protected boolean printQuad             = false ;
     protected boolean printQuadOpt          = false ;
     protected boolean printPlan             = false ;
-    
+
     public static void main(String... argv)
     {
         new qparse(argv).mainRun() ;
     }
-    
+
     public qparse(String[] argv)
     {
         super(argv) ;
@@ -76,16 +77,16 @@ public class qparse extends CmdARQ
         super.add(argDeclExplain, "--explain", "Print with algebra-level optimization") ;
         super.add(argDeclOpt, "--opt", "[deprecated]") ;
         super.add(argDeclFixup, "--fixup", "Convert undeclared prefix names to URIs") ;
-        
-        // Switch off function build warnings.  
+
+        // Switch off function build warnings.
         E_Function.WarnOnUnknownFunction = false ;
     }
-    
+
     @Override
     protected void processModulesAndArgs()
     {
         super.processModulesAndArgs() ;
-        
+
         if ( contains(argDeclOpt) )
             printOpt = true ;
         if ( contains(argDeclExplain) )
@@ -98,9 +99,8 @@ public class qparse extends CmdARQ
             ARQ.set(ARQ.fixupUndefinedPrefixes, true);
         }
 
-        for ( String arg : getValues( argDeclPrint ) )
-        {
-            switch(arg.toLowerCase(Locale.ROOT)) {
+        for ( String arg : getValues( argDeclPrint ) ) {
+            switch(lowercase(arg)) {
                 case "query":
                     printQuery = true;
                     break;
@@ -113,32 +113,32 @@ public class qparse extends CmdARQ
                 case "plan":
                     printPlan = true;
                     break;
-                case "opt": 
+                case "opt":
                     printOpt = true;
                     break;
                 case "optquad": case "quadopt":
                     printQuadOpt = true;
                     break;
-                case "none": 
+                case "none":
                     printNone = true;
                     break;
                 default:
                     throw new CmdException("Not a recognized print form: " + arg + " : Choices are: query, op, quad, opt, optquad, plan" );
             }
         }
-        
+
         if ( ! printQuery && ! printOp && ! printQuad && ! printPlan && ! printOpt && ! printQuadOpt && ! printNone )
             printQuery = true ;
     }
 
     static String usage = qparse.class.getName()+" [--in syntax] [--out syntax] [--print=FORM] [\"query\"] | --query <file>" ;
-    
+
     @Override
     protected String getSummary()
     {
         return usage ;
     }
-    
+
     static final String divider = "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -" ;
     //static final String divider = "" ;
     boolean needDivider = false ;
@@ -147,7 +147,7 @@ public class qparse extends CmdARQ
         if ( needDivider ) System.out.println(divider) ;
         needDivider = true ;
     }
-    
+
     @Override
     protected void exec()
     {
@@ -165,7 +165,7 @@ public class qparse extends CmdARQ
             }
             finally { LogCtl.setLevel(QueryParserBase.ParserLoggerName, "INFO") ; }
 
-            
+
             // Print the query out in some syntax
             if ( printQuery )
             { divider() ; modOutput.output(query) ; }
@@ -173,22 +173,22 @@ public class qparse extends CmdARQ
             // Print internal forms.
             if ( printOp )
             { divider() ; modOutput.outputOp(query, false) ; }
-            
+
             if ( printQuad )
             { divider() ; modOutput.outputQuad(query, false) ; }
-            
+
             if ( printOpt )
             { divider() ; modOutput.outputOp(query, true) ; }
-            
+
             if ( printQuadOpt )
             { divider() ; modOutput.outputQuad(query, true) ; }
-            
+
             if ( printPlan )
-            { 
+            {
                 divider() ;
                 // This forces internal query initialization - must be after QueryUtils.checkQuery
                 QueryExecution qExec = QueryExecutionFactory.create(query, DatasetFactory.createGeneral()) ;
-                QueryOutputUtils.printPlan(query, qExec) ; 
+                QueryOutputUtils.printPlan(query, qExec) ;
             }
         }
         catch (ARQInternalErrorException intEx)
@@ -212,10 +212,10 @@ public class qparse extends CmdARQ
             //System.err.println(qEx.getMessage()) ;
             throw new CmdException("Query Exeception", qEx) ;
         }
-        catch (JenaException ex) { 
+        catch (JenaException ex) {
             ex.printStackTrace() ;
-            throw ex ; } 
-        catch (CmdException ex) { throw ex ; } 
+            throw ex ; }
+        catch (CmdException ex) { throw ex ; }
         catch (Exception ex)
         {
             throw new CmdException("Exception", ex) ;
@@ -236,7 +236,7 @@ public class qparse extends CmdARQ
 //            "  --parse        Parse only - don't print\n"+
 //            "  ---planning    Turn planning on/off\n"+
 //            "  --show X       Show internal structure (X = query or plan)\n" ;
-    
+
     static void writeSyntaxes(String msg, PrintStream out)
     {
         if ( msg != null )
@@ -255,6 +255,6 @@ public class qparse extends CmdARQ
         StringBuilder r = new StringBuilder(x) ;
         for ( int i = x.length() ; i <= len ; i++ )
             r.append(" ") ;
-        return r.toString() ; 
+        return r.toString() ;
     }
 }
diff --git a/jena-core/src/main/java/org/apache/jena/graph/impl/CollectionGraph.java b/jena-core/src/main/java/org/apache/jena/graph/impl/CollectionGraph.java
index cf14b8c17e..38826305c0 100644
--- a/jena-core/src/main/java/org/apache/jena/graph/impl/CollectionGraph.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/impl/CollectionGraph.java
@@ -19,12 +19,10 @@ package org.apache.jena.graph.impl;
 
 import java.util.Collection ;
 import java.util.HashSet ;
-import java.util.Locale ;
 import java.util.Set ;
 
 import org.apache.jena.graph.Capabilities ;
 import org.apache.jena.graph.Node ;
-import org.apache.jena.graph.NodeFactory ;
 import org.apache.jena.graph.Triple ;
 import org.apache.jena.util.iterator.ExtendedIterator ;
 
@@ -53,24 +51,9 @@ public class CollectionGraph extends GraphBase
     }
 
     private static boolean equalNode(Node m, Node n) {
-        n = fixupNode(n);
-        m = fixupNode(m);
         return (m == null) || (m == Node.ANY) || m.equals(n);
     }
 
-    private static Node fixupNode(Node node) {
-        if ( node == null || node == Node.ANY )
-            return node;
-
-        // RDF says ... language tags should be canonicalized to lower case.
-        if ( node.isLiteral() ) {
-            String lang = node.getLiteralLanguage();
-            if ( lang != null && !lang.equals("") )
-                node = NodeFactory.createLiteralLang(node.getLiteralLexicalForm(), lang.toLowerCase(Locale.ROOT));
-        }
-        return node;
-    }
-
     // the collection
     private final Collection<Triple> triples;
     private final boolean uniqueOnly;
diff --git a/jena-core/src/test/java/org/apache/jena/irix/TestIRIxSyntax.java b/jena-core/src/test/java/org/apache/jena/irix/TestIRIxSyntax.java
index ff161aa482..ae51671fe9 100644
--- a/jena-core/src/test/java/org/apache/jena/irix/TestIRIxSyntax.java
+++ b/jena-core/src/test/java/org/apache/jena/irix/TestIRIxSyntax.java
@@ -18,7 +18,7 @@
 
 package org.apache.jena.irix;
 
-import java.util.Locale;
+import static org.apache.jena.atlas.lib.Lib.uppercase;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -99,13 +99,13 @@ public class TestIRIxSyntax extends AbstractTestIRIx {
 
     @Test public void parse_uuid_01() { parse("uuid:"+testUUID); }
 
-    @Test public void parse_uuid_02() { parse("uuid:"+(testUUID.toUpperCase(Locale.ROOT))); }
+    @Test public void parse_uuid_02() { parse("uuid:"+uppercase(testUUID)); }
 
     @Test public void parse_uuid_03() { parse("UUID:"+testUUID); }
 
     @Test public void parse_uuid_04() { parse("urn:uuid:"+testUUID); }
 
-    @Test public void parse_uuid_05() { parse("urn:uuid:"+(testUUID.toUpperCase(Locale.ROOT))); }
+    @Test public void parse_uuid_05() { parse("urn:uuid:"+uppercase(testUUID)); }
 
     @Test public void parse_uuid_06() { parse("URN:UUID:"+testUUID); }
 
diff --git a/jena-core/src/test/java/org/apache/jena/irix/TestRFC3986.java b/jena-core/src/test/java/org/apache/jena/irix/TestRFC3986.java
index b2f39acf2a..474ac7a82d 100644
--- a/jena-core/src/test/java/org/apache/jena/irix/TestRFC3986.java
+++ b/jena-core/src/test/java/org/apache/jena/irix/TestRFC3986.java
@@ -18,12 +18,11 @@
 
 package org.apache.jena.irix;
 
+import static org.apache.jena.atlas.lib.Lib.uppercase;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
 
-import java.util.Locale;
-
 import org.apache.jena.iri.IRI;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
@@ -261,7 +260,7 @@ public class TestRFC3986 extends AbstractTestIRIx {
 
     @Test public void parse_uuid_01() { good("uuid:"+testUUID); }
 
-    @Test public void parse_uuid_02() { good("uuid:"+(testUUID.toUpperCase(Locale.ROOT))); }
+    @Test public void parse_uuid_02() { good("uuid:"+(uppercase(testUUID))); }
 
     @Test public void parse_uuid_bad_01() { badSpecific("uuid:06e775ac-2c38-11b2-801c-8086f2cc00c9?query=foo"); }
 
@@ -291,7 +290,7 @@ public class TestRFC3986 extends AbstractTestIRIx {
 
     @Test public void parse_urn_uuid_01() { good("urn:uuid:"+testUUID); }
 
-    @Test public void parse_urn_uuid_02() { good("urn:uuid:"+(testUUID.toUpperCase(Locale.ROOT))); }
+    @Test public void parse_urn_uuid_02() { good("urn:uuid:"+uppercase(testUUID)); }
 
     @Test public void parse_urn_uuid_03() { parse_uuid_8141("urn:uuid:"+testUUID+"#frag"); }
 
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Operation.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Operation.java
index db34a3dd17..5b1ef7536f 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Operation.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Operation.java
@@ -18,8 +18,9 @@
 
 package org.apache.jena.fuseki.server;
 
+import static org.apache.jena.atlas.lib.Lib.lowercase;
+
 import java.util.HashMap;
-import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
 
@@ -73,7 +74,7 @@ public class Operation {
         // Currently, (3.13.0) the JS name is the short display name in lower
         // case. Just in case it diverges in the future, leave provision for
         // a different setting.
-        return new Operation(id, shortName, shortName.toLowerCase(Locale.ROOT), description);
+        return new Operation(id, shortName, lowercase(shortName), description);
     }
 
     public static final Operation Query    = alloc(FusekiVocab.opQuery.asNode(),   "query",   "SPARQL Query");
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionREST.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionREST.java
index b1bdacebf6..44dc655d70 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionREST.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionREST.java
@@ -18,11 +18,10 @@
 
 package org.apache.jena.fuseki.servlets;
 
+import static org.apache.jena.atlas.lib.Lib.uppercase;
 import static org.apache.jena.fuseki.servlets.ActionExecLib.incCounter;
 import static org.apache.jena.riot.web.HttpNames.*;
 
-import java.util.Locale;
-
 import org.apache.jena.fuseki.server.CounterName;
 import org.apache.jena.sparql.core.DatasetGraph;
 
@@ -36,7 +35,7 @@ public abstract class ActionREST extends ActionService
     @Override
     public void execute(HttpAction action) {
         // Intercept to put counters around calls.
-        String method = action.getRequestMethod().toUpperCase(Locale.ROOT);
+        String method = uppercase(action.getRequestMethod());
 
         if (method.equals(METHOD_GET))
             doGet$(action);
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseOps.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseOps.java
index 0785133781..d98afc439a 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseOps.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseOps.java
@@ -18,19 +18,19 @@
 
 package org.apache.jena.fuseki.servlets;
 
+import static org.apache.jena.atlas.lib.Lib.lowercase;
+
 import java.io.IOException;
-import java.util.Locale;
 import java.util.Map;
 
 import jakarta.servlet.http.HttpServletRequest;
-
 import org.apache.jena.riot.WebContent;
 import org.apache.jena.riot.web.HttpNames;
 
 class ResponseOps {
     // Helpers
     public static void put(Map<String, String> map, String key, String value) {
-        map.put(key.toLowerCase(Locale.ROOT), value);
+        map.put(lowercase(key), value);
     }
 
     public static boolean isEOFexception(IOException ioEx) {
@@ -64,7 +64,7 @@ class ResponseOps {
         if ( str == null )
             return null;
         // Force keys to lower case. See put() above.
-        String key = str.toLowerCase(Locale.ROOT);
+        String key = lowercase(str);
         String str2 = map.get(key);
         if ( str2 == null )
             return str;
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQLQueryProcessor.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQLQueryProcessor.java
index fb1f3f1fb8..ab91c0fbe0 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQLQueryProcessor.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQLQueryProcessor.java
@@ -19,6 +19,7 @@
 package org.apache.jena.fuseki.servlets;
 
 import static java.lang.String.format;
+import static org.apache.jena.atlas.lib.Lib.uppercase;
 import static org.apache.jena.fuseki.server.CounterName.QueryTimeouts;
 import static org.apache.jena.fuseki.servlets.ActionExecLib.incCounter;
 import static org.apache.jena.riot.WebContent.ctHTMLForm;
@@ -111,7 +112,7 @@ public abstract class SPARQLQueryProcessor extends ActionService
      */
     @Override
     public void validate(HttpAction action) {
-        String method = action.getRequestMethod().toUpperCase(Locale.ROOT);
+        String method = uppercase(action.getRequestMethod());
 
         if ( HttpNames.METHOD_OPTIONS.equals(method) )
             return;
diff --git a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java
index 52852205fe..e62215c495 100644
--- a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java
+++ b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java
@@ -19,6 +19,7 @@
 package org.apache.jena.fuseki.mgt;
 
 import static java.lang.String.format;
+import static org.apache.jena.atlas.lib.Lib.lowercase;
 import static org.apache.jena.fuseki.build.FusekiPrefixes.PREFIXES;
 
 import java.io.IOException;
@@ -477,7 +478,7 @@ public class ActionDatasets extends ActionContainerItem {
 
         //action.log.info(format("[%d] Create database : name = %s, type = %s", action.id, dbName, dbType ));
 
-        String template = dbTypeToTemplate.get(dbType.toLowerCase(Locale.ROOT));
+        String template = dbTypeToTemplate.get(lowercase(dbType));
         if ( template == null )
             ServletOps.errorBadRequest(format("dbType can be only '%s', '%s' or '%s'", tDatabaseTDB, tDatabaseTDB2, tDatabaseMem));
 
diff --git a/jena-rdfpatch/src/main/java/org/apache/jena/rdfpatch/PatchHeader.java b/jena-rdfpatch/src/main/java/org/apache/jena/rdfpatch/PatchHeader.java
index 0bd2e063cc..26f1a7e857 100644
--- a/jena-rdfpatch/src/main/java/org/apache/jena/rdfpatch/PatchHeader.java
+++ b/jena-rdfpatch/src/main/java/org/apache/jena/rdfpatch/PatchHeader.java
@@ -18,7 +18,8 @@
 
 package org.apache.jena.rdfpatch;
 
-import java.util.Locale;
+import static org.apache.jena.atlas.lib.Lib.lowercase;
+
 import java.util.Map;
 import java.util.function.BiConsumer;
 import java.util.stream.Collectors;
@@ -82,7 +83,7 @@ public class PatchHeader {
     }
 
     private static String lc(String str) {
-        return str.toLowerCase(Locale.ROOT);
+        return lowercase(str);
     }
 
     @Override
diff --git a/jena-rdfpatch/src/main/java/org/apache/jena/rdfpatch/filelog/FilePolicy.java b/jena-rdfpatch/src/main/java/org/apache/jena/rdfpatch/filelog/FilePolicy.java
index a487ba0374..4657803375 100644
--- a/jena-rdfpatch/src/main/java/org/apache/jena/rdfpatch/filelog/FilePolicy.java
+++ b/jena-rdfpatch/src/main/java/org/apache/jena/rdfpatch/filelog/FilePolicy.java
@@ -18,7 +18,8 @@
 
 package org.apache.jena.rdfpatch.filelog;
 
-import java.util.Locale;
+import static org.apache.jena.atlas.lib.Lib.lowercase;
+
 import java.util.Objects;
 
 import org.apache.jena.rdfpatch.filelog.rotate.FileRotateException;
@@ -52,7 +53,7 @@ public enum FilePolicy {
 
     public static FilePolicy policy(String name) {
         Objects.requireNonNull(name);
-        String nameLC = name.toLowerCase(Locale.ROOT);
+        String nameLC = lowercase(name);
         switch(nameLC) {
             case "date" :       return DATE;
             case "timestamp" :  return TIMESTAMP;
diff --git a/jena-shex/src/main/java/org/apache/jena/shex/expressions/NodeKind.java b/jena-shex/src/main/java/org/apache/jena/shex/expressions/NodeKind.java
index 9ddc5809ab..85938b6291 100644
--- a/jena-shex/src/main/java/org/apache/jena/shex/expressions/NodeKind.java
+++ b/jena-shex/src/main/java/org/apache/jena/shex/expressions/NodeKind.java
@@ -18,8 +18,7 @@
 
 package org.apache.jena.shex.expressions;
 
-import java.util.Locale;
-
+import org.apache.jena.atlas.lib.Lib;
 import org.apache.jena.shex.ShexException;
 
 public enum NodeKind {
@@ -30,7 +29,7 @@ public enum NodeKind {
 
     NodeKind(String string) {
         this.label = string;
-        this.ucLabel = string.toUpperCase(Locale.ROOT);
+        this.ucLabel = Lib.uppercase(string);
     }
 
     public static NodeKind create(String nodeKind) {
diff --git a/jena-shex/src/main/java/org/apache/jena/shex/writer/WriterShExC.java b/jena-shex/src/main/java/org/apache/jena/shex/writer/WriterShExC.java
index 19b07d730f..9f3ecf942d 100644
--- a/jena-shex/src/main/java/org/apache/jena/shex/writer/WriterShExC.java
+++ b/jena-shex/src/main/java/org/apache/jena/shex/writer/WriterShExC.java
@@ -18,9 +18,10 @@
 
 package org.apache.jena.shex.writer;
 
+import static org.apache.jena.atlas.lib.Lib.uppercase;
+
 import java.io.OutputStream;
 import java.util.List;
-import java.util.Locale;
 import java.util.function.Consumer;
 
 import org.apache.jena.atlas.io.AWriter;
@@ -356,7 +357,7 @@ public class WriterShExC {
         @Override
         public void visit(StrLengthConstraint constraint) {
             //stringLength       ::=      "LENGTH" | "MINLENGTH" | "MAXLENGTH"
-            out.print(constraint.getLengthType().label().toUpperCase(Locale.ROOT));
+            out.print(uppercase(constraint.getLengthType().label()));
             out.print(" ");
             out.print(Integer.toString(constraint.getLength()));
         }
@@ -368,7 +369,7 @@ public class WriterShExC {
 
         @Override
         public void visit(NodeKindConstraint constraint) {
-            out.print(constraint.getNodeKind().label().toUpperCase(Locale.ROOT));
+            out.print(uppercase(constraint.getNodeKind().label()));
         }
 
         // [30]        numericFacet       ::=      numericRange numericLiteral | numericLength INTEGER
@@ -376,7 +377,7 @@ public class WriterShExC {
         @Override
         public void visit(NumLengthConstraint constraint) {
             // [32]        numericLength      ::=      "TOTALDIGITS" | "FRACTIONDIGITS"
-            out.print(constraint.getLengthType().label().toUpperCase(Locale.ROOT));
+            out.print(uppercase(constraint.getLengthType().label()));
             out.print(" ");
             out.print(Integer.toString(constraint.getLength()));
         }
@@ -384,7 +385,7 @@ public class WriterShExC {
         @Override
         public void visit(NumRangeConstraint constraint) {
             // [31]        numericRange       ::=      "MININCLUSIVE" | "MINEXCLUSIVE" | "MAXINCLUSIVE" | "MAXEXCLUSIVE"
-            out.print(constraint.getRangeKind().label().toUpperCase(Locale.ROOT));
+            out.print(uppercase(constraint.getRangeKind().label()));
             out.print(" ");
             printNode(constraint.getValue());
         }


(jena) 05/10: Remove unused GetTriple

Posted by an...@apache.org.
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 d8eab6b73e472dea88121cc5ce1400e1e473b7bf
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Tue Dec 12 22:47:13 2023 +0000

    Remove unused GetTriple
---
 .../java/org/apache/jena/graph/FrontsNode.java     | 18 +++++------
 .../java/org/apache/jena/graph/FrontsTriple.java   | 13 ++++----
 .../main/java/org/apache/jena/graph/GetTriple.java | 37 ----------------------
 3 files changed, 14 insertions(+), 54 deletions(-)

diff --git a/jena-core/src/main/java/org/apache/jena/graph/FrontsNode.java b/jena-core/src/main/java/org/apache/jena/graph/FrontsNode.java
index 98e80654f9..63f58e3782 100644
--- a/jena-core/src/main/java/org/apache/jena/graph/FrontsNode.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/FrontsNode.java
@@ -19,15 +19,13 @@
 package org.apache.jena.graph;
 
 /**
-	HasNode - interface for objects that front a Node in some context. The critical
-    semantics for HasNode is that classes implementing HasNode promise that
-    their .equals() is based *only* on the underlying Node. 
-
-*/
-public interface FrontsNode 
-    {
+ * HasNode - interface for objects that front a Node in some context. The critical
+ * semantics for HasNode is that classes implementing HasNode promise that their
+ * .equals() is based *only* on the underlying Node.
+ */
+public interface FrontsNode {
     /**
-        Answer the Node associated with this object.
-    */
+     * Answer the Node associated with this object.
+     */
     Node asNode();
-    }
+}
diff --git a/jena-core/src/main/java/org/apache/jena/graph/FrontsTriple.java b/jena-core/src/main/java/org/apache/jena/graph/FrontsTriple.java
index 98b907d544..d8b77b4deb 100644
--- a/jena-core/src/main/java/org/apache/jena/graph/FrontsTriple.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/FrontsTriple.java
@@ -19,10 +19,9 @@
 package org.apache.jena.graph;
 
 /**
- 	FrontsTriple (see also FrontsNode) is an interface for things that can
- 	be seen as wrappers round triples.
-*/
-public interface FrontsTriple
-	{
-	Triple asTriple();
-	}
+ * FrontsTriple (see also FrontsNode) is an interface for things that can be seen as
+ * wrappers round triples.
+ */
+public interface FrontsTriple {
+    Triple asTriple();
+}
diff --git a/jena-core/src/main/java/org/apache/jena/graph/GetTriple.java b/jena-core/src/main/java/org/apache/jena/graph/GetTriple.java
deleted file mode 100644
index b0bd8236da..0000000000
--- a/jena-core/src/main/java/org/apache/jena/graph/GetTriple.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.graph;
-
-/**
-    this interface describes types that can have a triple extracted using
-    a <code>getTriple</code> method. It was constructed so that Node's 
-    can have possibly embedded triples but defer to a GetTriple object if 
-    they have no triple of their own; the particular GetTriple used initially is
-    in Reifier, but that seemed excessively special.
-*/
-
-public interface GetTriple
-    {
-    /**
-        Answer the triple associated with the node <code>n</code>.
-        @param n the node to use as the key
-        @return the associated triple, or <code>null</code> if none
-    */
-    public Triple getTriple( Node n );
-    }


(jena) 01/10: GH-2039: Case insensitive langtags (initial)

Posted by an...@apache.org.
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 74a134d7dd1e5052b59b710777dd7af58edc3bd6
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Fri Dec 8 15:33:22 2023 +0000

    GH-2039: Case insensitive langtags (initial)
---
 .../apache/jena/sparql/lang/QueryParserBase.java   |  2 +-
 .../org/apache/jena/graph/impl/LiteralLabel.java   | 23 ++++++++++++++++++++--
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/lang/QueryParserBase.java b/jena-arq/src/main/java/org/apache/jena/sparql/lang/QueryParserBase.java
index 75920d7f05..ec4e3144ea 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/lang/QueryParserBase.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/lang/QueryParserBase.java
@@ -215,7 +215,7 @@ public class QueryParserBase
             RDFDatatype dType = TypeMapper.getInstance().getSafeTypeByName(datatypeURI);
             n = NodeFactory.createLiteral(lexicalForm, dType);
         } else if ( langTag != null && !langTag.isEmpty() )
-            n = NodeFactory.createLiteral(lexicalForm, langTag);
+            n = NodeFactory.createLiteralLang(lexicalForm, langTag);
         else
             n = NodeFactory.createLiteral(lexicalForm);
         return n;
diff --git a/jena-core/src/main/java/org/apache/jena/graph/impl/LiteralLabel.java b/jena-core/src/main/java/org/apache/jena/graph/impl/LiteralLabel.java
index 2e62963c90..f4dffe0011 100644
--- a/jena-core/src/main/java/org/apache/jena/graph/impl/LiteralLabel.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/impl/LiteralLabel.java
@@ -106,7 +106,7 @@ final public class LiteralLabel {
     /*package*/ LiteralLabel(String lex, String lang, RDFDatatype dtype) {
         this.lexicalForm = lex;
         this.dtype = Objects.requireNonNull(dtype);
-        this.lang = (lang == null ? "" : lang);
+        this.lang = formLangTag(lang);
         hash = calcHashCode();
         if ( valueMode == ValueMode.EAGER ) {
             this.wellformed = setValue(lex, dtype);
@@ -116,6 +116,24 @@ final public class LiteralLabel {
             value = null;
     }
 
+    private static final boolean legacyLangTag = true;
+
+    /** Prepare the language tag - apply formatting normalization */
+    private static String formLangTag(String input) {
+        if ( legacyLangTag )
+            return (input == null ? "" : input);
+        // Format.
+        return (input == null ? "" : input.toLowerCase(Locale.ROOT));
+    }
+
+    /** Calculate the indexing form for a language tag */
+    private static String indexingLang(String lang) {
+        if ( legacyLangTag )
+            return lang.toLowerCase(Locale.ROOT);
+        return lang;
+    }
+
+
     /**
      * Build a typed literal label from its value form using
      * whatever datatype is currently registered as the default
@@ -304,7 +322,8 @@ final public class LiteralLabel {
         if ( indexingValueIsSelf() )
             return this;
         if ( !lang.equals("") )
-            return getLexicalForm() + "@" + lang.toLowerCase(Locale.ROOT);
+            // Assumed formatted/case-insensitive language tags.
+            return getLexicalForm() + "@" + indexingLang(lang);
         if ( wellformed ) {
             Object value = getValue();
             // JENA-1936


(jena) 03/10: GH-2051: Initial text direction

Posted by an...@apache.org.
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 0505f571dcf680ab8541caf03ab6f45a4c2cbfc3
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Fri Dec 8 21:06:25 2023 +0000

    GH-2051: Initial text direction
---
 .../java/org/apache/jena/riot/TestRDFParser.java   |  23 +--
 .../main/java/org/apache/jena/atlas/lib/Lib.java   |  80 +++++----
 .../java/org/apache/jena/datatypes/TypeMapper.java |  10 +-
 .../jena/datatypes/xsd/impl/RDFDirLangString.java  |  59 ++++++
 .../src/main/java/org/apache/jena/graph/Node.java  |   8 +
 .../java/org/apache/jena/graph/NodeFactory.java    | 122 ++++++++++---
 .../java/org/apache/jena/graph/Node_Literal.java   |  17 +-
 .../java/org/apache/jena/graph/TextDirection.java  |  55 ++++++
 .../org/apache/jena/graph/impl/LiteralLabel.java   | 198 +++++++++++++--------
 .../jena/graph/impl/LiteralLabelFactory.java       |  64 ++++---
 .../java/org/apache/jena/rdf/model/Literal.java    |  14 +-
 .../apache/jena/rdf/model/impl/LiteralImpl.java    |  10 ++
 .../java/org/apache/jena/rdf/model/impl/Util.java  | 128 ++++++++-----
 .../main/java/org/apache/jena/vocabulary/RDF.java  | 163 +++++++++--------
 .../apache/jena/graph/test/NodeCreateUtils.java    |  13 +-
 .../rewriters/NodeValueRewriterTest.java           |   2 +-
 .../permissions/model/impl/SecuredLiteralImpl.java |  12 ++
 17 files changed, 681 insertions(+), 297 deletions(-)

diff --git a/jena-arq/src/test/java/org/apache/jena/riot/TestRDFParser.java b/jena-arq/src/test/java/org/apache/jena/riot/TestRDFParser.java
index d4a27b9410..129c55eaac 100644
--- a/jena-arq/src/test/java/org/apache/jena/riot/TestRDFParser.java
+++ b/jena-arq/src/test/java/org/apache/jena/riot/TestRDFParser.java
@@ -231,17 +231,18 @@ public class TestRDFParser {
         testNormalization("+123.00e0", "1.23E2", builder().canonicalValues(true));
     }
 
-    @Test public void canonical_langTag_1() {
-        testNormalization("'abc'@En-gB", "'abc'@En-gB", builder().langTagAsGiven());
-    }
-
-    @Test public void canonical_langTag_2() {
-        testNormalization("'abc'@En-gB", "'abc'@en-gb", builder().langTagLowerCase());
-    }
-
-    @Test public void canonical_langTag_3() {
-        testNormalization("'abc'@En-gB", "'abc'@en-GB", builder().langTagCanonical());
-    }
+    // Old tests that applied to Java4. Delete in the future.
+//    @Test public void canonical_langTag_1() {
+//        testNormalization("'abc'@En-gB", "'abc'@En-gB", builder().langTagAsGiven());
+//    }
+//
+//    @Test public void canonical_langTag_2() {
+//        testNormalization("'abc'@En-gB", "'abc'@en-gb", builder().langTagLowerCase());
+//    }
+//
+//    @Test public void canonical_langTag_3() {
+//        testNormalization("'abc'@En-gB", "'abc'@en-GB", builder().langTagCanonical());
+//    }
 
     @Test
     public void parser_fragment() {
diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java
index dbe2d6981c..5ae21d676d 100644
--- a/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java
+++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java
@@ -21,12 +21,13 @@ package org.apache.jena.atlas.lib;
 import java.nio.charset.StandardCharsets;
 import java.util.*;
 import java.util.stream.Stream;
-import java.util.zip.Adler32 ;
-import java.util.zip.CRC32 ;
-import java.util.zip.Checksum ;
+import java.util.zip.Adler32;
+import java.util.zip.CRC32;
+import java.util.zip.Checksum;
 
 import org.apache.commons.codec.digest.MurmurHash3;
-import org.apache.jena.atlas.logging.Log ;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.jena.atlas.logging.Log;
 
 public class Lib
 {
@@ -61,12 +62,12 @@ public class Lib
 
     /** "ConcurrentHashSet" */
     public static final <X> Set<X> concurrentHashSet() {
-        return SetUtils.concurrentHashSet() ;
+        return SetUtils.concurrentHashSet();
     }
 
     public static final void sync(Object object) {
         if ( object instanceof Sync syncobj )
-            syncobj.sync() ;
+            syncobj.sync();
     }
 
     /**
@@ -75,33 +76,33 @@ public class Lib
      */
     public static final <T> boolean equals(T obj1, T obj2) {
         // Include because other equals* operations are here.
-        return Objects.equals(obj1, obj2) ;
+        return Objects.equals(obj1, obj2);
     }
 
     /** Return true if obj1 and obj are both null or are .equals, else return false */
     public static final boolean equalsIgnoreCase(String str1, String str2) {
         if ( str1 == null )
-            return str2 == null ;
-        return str1.equalsIgnoreCase(str2) ;
+            return str2 == null;
+        return str1.equalsIgnoreCase(str2);
     }
 
     /** Return true if obj1 and obj are not equal */
     public static final <T> boolean notEqual(T obj1, T obj2) {
-        return !Objects.equals(obj1, obj2) ;
+        return !Objects.equals(obj1, obj2);
     }
 
     /** Safely return the class short name for an object -- obj.getClass().getSimpleName() */
     static public final String className(Object obj) {
         if ( obj == null )
-            return "null" ;
-        return classShortName(obj.getClass()) ;
+            return "null";
+        return classShortName(obj.getClass());
     }
 
     /** Safely return the class short name for a class */
     static public final String classShortName(Class<? > cls) {
         if ( cls == null )
-            return "null" ;
-        return cls.getSimpleName() ;
+            return "null";
+        return cls.getSimpleName();
     }
 
     /** Create {@link UnsupportedOperationException} with formatted message. */
@@ -112,25 +113,44 @@ public class Lib
     /** Do two lists have the same elements without considering the order of the lists nor duplicates? */
     public static <T> boolean equalsListAsSet(List<T> list1, List<T> list2) {
         if ( list1 == null && list2 == null )
-            return true ;
-        if ( list1 == null ) return false ;
-        if ( list2 == null ) return false ;
-        return list1.containsAll(list2) && list2.containsAll(list1) ;
+            return true;
+        if ( list1 == null ) return false;
+        if ( list2 == null ) return false;
+        return list1.containsAll(list2) && list2.containsAll(list1);
     }
 
     /** HashCode - allow nulls */
-    public static final int hashCodeObject(Object obj) { return hashCodeObject(obj, -4) ; }
+    public static final int hashCodeObject(Object obj) { return hashCodeObject(obj, -4); }
 
     /** HashCode - allow nulls */
     public static final int hashCodeObject(Object obj, int nullHashCode) {
         if ( obj == null )
-            return nullHashCode ;
-        return obj.hashCode() ;
+            return nullHashCode;
+        return obj.hashCode();
     }
 
+    public static boolean isEmpty(CharSequence cs) {
+        // Hide implementation
+        return StringUtils.isEmpty(cs);
+    }
+
+    /** Non-locale lowercase */
+    public static String lowercase(String string) {
+        // Hide implementation
+        return string.toLowerCase(Locale.ROOT);
+    }
+
+    /** Non-locale uppercase */
+    public static String uppercase(String string) {
+        // Hide implementation
+        return string.toUpperCase(Locale.ROOT);
+    }
+
+
+
     public static final void sleep(int milliSeconds) {
-        try  { Thread.sleep(milliSeconds) ; }
-        catch (InterruptedException ex) { Log.warn(Lib.class, "interrupted", ex) ; }
+        try  { Thread.sleep(milliSeconds); }
+        catch (InterruptedException ex) { Log.warn(Lib.class, "interrupted", ex); }
     }
 
     /** Get an environment variable value; if not found try in the system properties. */
@@ -173,7 +193,7 @@ public class Lib
         X x = threadLocal.get();
         if ( x == null )
             threadLocal.remove();
-        return x ;
+        return x;
     }
 
     /**
@@ -181,20 +201,20 @@ public class Lib
      */
     public static long crc32(byte[] bytes)
     {
-        return crc(new CRC32(), bytes) ;
+        return crc(new CRC32(), bytes);
     }
 
     /** Faster than CRC32, nearly as good.
      * @see Adler32
      */
     public static long adler32(byte[] bytes) {
-        return crc(new Adler32(), bytes) ;
+        return crc(new Adler32(), bytes);
     }
 
     private static long crc(Checksum alg, byte[] bytes) {
-        alg.reset() ;
-        alg.update(bytes, 0, bytes.length) ;
-        return alg.getValue() ;
+        alg.reset();
+        alg.update(bytes, 0, bytes.length);
+        return alg.getValue();
     }
 
     /** Calculate the Murmur3 hash of a string, and return it as a hex-encoded string. */
@@ -215,7 +235,7 @@ public class Lib
         // Avoiding generating intermediate strings from e.g. Bytes.asHexLC
         // Byte loop.
         // Bytes get encoded "high bits first". "AF" is value A*16+F
-        for ( int idx = 0 ; idx < 8 ; idx++ ) {
+        for ( int idx = 0; idx < 8; idx++ ) {
             int i = idx * 8;
             int bValue = (int)((value >> i) & 0xFF);
             // Keep order of the byte - high nibble, low nibble.
diff --git a/jena-core/src/main/java/org/apache/jena/datatypes/TypeMapper.java b/jena-core/src/main/java/org/apache/jena/datatypes/TypeMapper.java
index 872f0bb033..7a944fa9ad 100644
--- a/jena-core/src/main/java/org/apache/jena/datatypes/TypeMapper.java
+++ b/jena-core/src/main/java/org/apache/jena/datatypes/TypeMapper.java
@@ -24,8 +24,7 @@ import java.util.Iterator;
 import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.jena.datatypes.xsd.XSDDatatype ;
-import org.apache.jena.datatypes.xsd.impl.RDFLangString ;
-import org.apache.jena.datatypes.xsd.impl.XMLLiteralType ;
+import org.apache.jena.datatypes.xsd.impl.*;
 import org.apache.jena.shared.impl.JenaParameters ;
 
 /**
@@ -67,8 +66,11 @@ public class TypeMapper {
     static { reset() ; }
     public static void reset() {
         theTypeMap = new TypeMapper();
-        theTypeMap.registerDatatype(XMLLiteralType.theXMLLiteralType);
         theTypeMap.registerDatatype(RDFLangString.rdfLangString) ;
+        theTypeMap.registerDatatype(RDFDirLangString.rdfDirLangString) ;
+        theTypeMap.registerDatatype(RDFjson.rdfJSON);
+        theTypeMap.registerDatatype(XMLLiteralType.theXMLLiteralType);
+        theTypeMap.registerDatatype(RDFhtml.rdfHTML);
         XSDDatatype.loadXSDSimpleTypes(theTypeMap);
 
         // add primitive types
@@ -189,7 +191,7 @@ public class TypeMapper {
             classToDT.put(jc, type);
         }
     }
-    
+
     /**
      * Remove a datatype registration.
      */
diff --git a/jena-core/src/main/java/org/apache/jena/datatypes/xsd/impl/RDFDirLangString.java b/jena-core/src/main/java/org/apache/jena/datatypes/xsd/impl/RDFDirLangString.java
new file mode 100644
index 0000000000..0676cd8984
--- /dev/null
+++ b/jena-core/src/main/java/org/apache/jena/datatypes/xsd/impl/RDFDirLangString.java
@@ -0,0 +1,59 @@
+/**
+ * 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.datatypes.xsd.impl;
+
+import org.apache.jena.datatypes.BaseDatatype ;
+import org.apache.jena.datatypes.RDFDatatype ;
+import org.apache.jena.graph.impl.LiteralLabel ;
+
+/**
+ * rdf:dirLangString (literal with language and initial text direction)
+ * This covers the unusual case of "foo"^^rdf:langString or "foo"^^rdf:dirLangString.
+ * When there is a language tag, there is a lexical form but it is in two parts lex@lang or lex@lang--ltr
+ */
+
+public class RDFDirLangString extends BaseDatatype implements RDFDatatype {
+
+    /** Singleton instance */
+    // Include the string for the RDF namespace, do not use RDF.getURI() to avoid an initializer circularity.
+    public static final RDFDatatype rdfDirLangString = new RDFDirLangString("http://www.w3.org/1999/02/22-rdf-syntax-ns#dirLangString");
+
+    /**
+     * Private constructor.
+     */
+    private RDFDirLangString(String uri) {
+        super(uri);
+    }
+
+    /**
+     * Compares two instances of values of the given datatype.
+     */
+    @Override
+    public boolean isEqual(LiteralLabel value1, LiteralLabel value2) {
+        return isEqualByTerm(value1, value2) ;
+    }
+
+    // This covers the unusual case of "foo"^^"rdf:langString" or "foo"^^rdf:dirLangString.
+    @Override
+    public Object parse(String lexicalForm) { return lexicalForm ; }
+
+    @Override
+    public String unparse(Object value) { return value.toString(); }
+}
+
diff --git a/jena-core/src/main/java/org/apache/jena/graph/Node.java b/jena-core/src/main/java/org/apache/jena/graph/Node.java
index 63f4c02539..b6ddf05253 100644
--- a/jena-core/src/main/java/org/apache/jena/graph/Node.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/Node.java
@@ -153,6 +153,14 @@ public abstract class Node implements Serializable {
     public String getLiteralLanguage()
     { throw new NotLiteral( this ); }
 
+    /** Return the initial text direction for an rdf:dirLangString literal.
+     * Does not return null if the literal is a rdf:dirLangString literal.
+     * Returns null if the text direction is not set (and the datatype won't be rdf:dirLangString).
+     * Otherwise die horribly.
+     */
+    public TextDirection getLiteralTextDirection()
+    { throw new NotLiteral( this ); }
+
     /**
      * Answer the data-type URI of this node's literal value, if it is a literal;
      * otherwise die horribly.
diff --git a/jena-core/src/main/java/org/apache/jena/graph/NodeFactory.java b/jena-core/src/main/java/org/apache/jena/graph/NodeFactory.java
index 2a872ab776..19a5e8d2b1 100644
--- a/jena-core/src/main/java/org/apache/jena/graph/NodeFactory.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/NodeFactory.java
@@ -18,12 +18,17 @@
 
 package org.apache.jena.graph;
 
+
+import static org.apache.jena.atlas.lib.Lib.isEmpty;
+import static org.apache.jena.graph.NodeFactory.noLangTag;
+
+import java.util.Locale;
 import java.util.Objects;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.jena.datatypes.RDFDatatype;
 import org.apache.jena.datatypes.TypeMapper;
 import org.apache.jena.datatypes.xsd.XSDDatatype;
+import org.apache.jena.datatypes.xsd.impl.RDFDirLangString;
 import org.apache.jena.datatypes.xsd.impl.RDFLangString;
 import org.apache.jena.graph.impl.LiteralLabel;
 import org.apache.jena.graph.impl.LiteralLabelFactory;
@@ -35,6 +40,10 @@ public class NodeFactory {
     static { JenaSystem.init(); }
     private NodeFactory() {}
 
+    // Constants
+    public static final String noLangTag = "";
+    public static final TextDirection noTextDirection = null;
+
     public static RDFDatatype getType(String s) {
         if ( s == null )
             return null;
@@ -83,17 +92,23 @@ public class NodeFactory {
      * Make literal which is a string (xsd:string)
      */
     public static Node createLiteral(String string) {
-        Objects.requireNonNull(string, "Argument to NodeFactory.createLiteral is null");
+        Objects.requireNonNull(string, "Argument to NodeFactory.createLiteralString is null");
         return new Node_Literal(string);
     }
 
+//    /** @deprecated Use {@link #createLiteral} */
+//    @Deprecated
+//    public static Node createLiteral(String string) {
+//        return createLiteralString(string);
+//    }
+
     /**
      * Make a literal with specified language. The lexical form must not be null.
      *
      * @param string  the lexical form of the literal
      * @param lang    the optional language tag
      *
-     * @deprecated Prefer using {@link #createLiteralLang(String, String)}.
+     * @deprecated Use {@link #createLiteralLang(String, String)}.
      */
     @Deprecated
     public static Node createLiteral(String string, String lang) {
@@ -108,10 +123,12 @@ public class NodeFactory {
      */
     public static Node createLiteralLang(String string, String lang) {
         Objects.requireNonNull(string, "null lexical form for literal");
-        if ( StringUtils.isEmpty(lang) )
+        if ( isEmpty(lang) )
             return new Node_Literal(string);
-        else
-            return new Node_Literal(string, lang);
+        else {
+           String langFmt = formatLanguageTag(lang);
+           return new Node_Literal(string, langFmt);
+        }
     }
 
     /**
@@ -121,16 +138,29 @@ public class NodeFactory {
      *
      * @param string  the lexical form of the literal
      * @param lang    the optional language tag
-     * @param langDir the optional language direction
+     * @param textDir the optional language direction
      */
-    public static Node createLiteralLang(String string, String lang, String langDir) {
+    public static Node createLiteralDirLang(String string, String lang, String textDir) {
+        TextDirection textDirEnum = initialTextDirection(textDir);
+        String langFmt = formatLanguageTag(lang);
+        return createLiteralDirLang(string, langFmt, textDirEnum);
+    }
+
+    private static boolean noTextDir(TextDirection textDir) {
+        return textDir == noTextDirection;
+    }
+
+    public static Node createLiteralDirLang(String string, String lang, TextDirection textDir) {
         Objects.requireNonNull(string, "null lexical form for literal");
-        if ( StringUtils.isEmpty(lang) ) {
-            if ( !StringUtils.isEmpty(langDir) )
+        if ( isEmpty(lang) ) {
+            if ( textDir != null )
                 throw new JenaException("The language must be gived for a language direction literal");
             return new Node_Literal(string);
-        } else
+        }
+        if ( noTextDir(textDir) )
             return new Node_Literal(string, lang);
+        String langFmt = formatLanguageTag(lang);
+        return new Node_Literal(string, langFmt, textDir);
     }
 
     /**
@@ -140,7 +170,7 @@ public class NodeFactory {
      * needing the caller to differentiate between the xsd:string, rdf:langString and other
      * datatype cases.
      * It calls {@link #createLiteral(String)},
-     * {@link #createLiteralLang(String, String, String)} or
+     * {@link #createLiteralDirLang(String, String, String)} or
      * {@link #createLiteral(String, RDFDatatype)}
      * as appropriate.
      *
@@ -149,7 +179,28 @@ public class NodeFactory {
      * @param dtype the type of the literal or null.
      */
     public static Node createLiteral(String lex, String lang, RDFDatatype dtype) {
-        return createLiteral(lex, lang, null, dtype);
+        return createLiteral(lex, lang, noTextDirection, dtype);
+    }
+
+    /**
+     * Build a literal node.
+     * <p>
+     * This is a convenience operation for passing in language and datatype without
+     * needing the caller to differentiate between the xsd:string, rdf:langString, and other
+     * datatype cases.
+     * It calls {@link #createLiteral(String)},
+     * {@link #createLiteralDirLang(String, String, String)} or
+     * {@link #createLiteral(String, RDFDatatype)}
+     * as appropriate.
+     *
+     * @param lex the lexical form of the literal
+     * @param lang the optional language tag or null or ""
+     * @param textDir the optional language direction or null
+     * @param dtype the type of the literal or null.
+     */
+    public static Node createLiteral(String lex, String lang, String textDir, RDFDatatype dtype) {
+        TextDirection textDirEnum = initialTextDirection(textDir);
+        return createLiteral(lex, lang, textDirEnum, dtype);
     }
 
     /**
@@ -159,34 +210,63 @@ public class NodeFactory {
      * needing the caller to differentiate between the xsd:string, rdf:langString, and other
      * datatype cases.
      * It calls {@link #createLiteral(String)},
-     * {@link #createLiteralLang(String, String, String)} or
+     * {@link #createLiteralDirLang(String, String, String)} or
      * {@link #createLiteral(String, RDFDatatype)}
      * as appropriate.
      *
      * @param lex the lexical form of the literal
      * @param lang the optional language tag or null or ""
-     * @param langDir the optional language direction or null
+     * @param textDir the optional language direction or null
      * @param dtype the type of the literal or null.
      */
-    public static Node createLiteral(String lex, String lang, String langDir, RDFDatatype dtype) {
+    public static Node createLiteral(String lex, String lang, TextDirection textDir, RDFDatatype dtype) {
         Objects.requireNonNull(lex, "null lexical form for literal");
-        boolean hasLang = ! StringUtils.isEmpty(lang);
+        boolean hasLang = ! isEmpty(lang);
         if ( hasLang ) {
-            if ( dtype != null && ! dtype.equals(RDFLangString.rdfLangString) )
-                throw new JenaException("Datatype is not rdf:langString but a language was given");
-            return createLiteralLang(lex, lang, langDir);
+            String langFmt = formatLanguageTag(lang);
+            if ( dtype != null ) {
+                if ( noTextDir(textDir) && dtype.equals(RDFLangString.rdfLangString) )
+                    throw new JenaException("Datatype is not rdf:langString but a language was given");
+                else
+                    throw new JenaException("Datatype is not rdf:dirLangString but a language and initial text direction was given");
+            }
+
+            return createLiteralDirLang(lex, langFmt, textDir);
         }
         if ( dtype == null )
             // No datatype, no lang (it is null or "") => xsd:string.
             return createLiteral(lex);
 
-        // No lang, with datatype and it's not rdf:langString
+        // No lang, with a datatype
         if ( dtype.equals(RDFLangString.rdfLangString) )
             throw new JenaException("Datatype is rdf:langString but no language given");
+        if ( dtype.equals(RDFDirLangString.rdfDirLangString) && noTextDir(textDir) )
+            throw new JenaException("Datatype is rdf:dirLangString but no initial text direction given");
         Node n = createLiteral(lex, dtype);
         return n;
     }
 
+    /** Prepare the initial text direction - apply formatting normalization */
+    private static TextDirection initialTextDirection(String input) {
+        if ( isEmpty(input) )
+            return noTextDirection;
+        // Throws JenaException on bad input.
+        TextDirection textDir = TextDirection.create(input);
+        return textDir;
+    }
+
+    /*package*/ static final boolean legacyLangTag = false;
+    /** Prepare the language tag - apply formatting normalization */
+    private static String formatLanguageTag(String input) {
+        if ( input == null )
+            return noLangTag;
+        if ( legacyLangTag )
+            return input;
+        if ( input.isEmpty() )
+            return input;
+        return input.toLowerCase(Locale.ROOT);
+    }
+
     /**
      * Build a typed literal node from its lexical form.
      *
diff --git a/jena-core/src/main/java/org/apache/jena/graph/Node_Literal.java b/jena-core/src/main/java/org/apache/jena/graph/Node_Literal.java
index 88e0bcc88f..b2c5389eec 100644
--- a/jena-core/src/main/java/org/apache/jena/graph/Node_Literal.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/Node_Literal.java
@@ -21,8 +21,9 @@ package org.apache.jena.graph;
 import java.util.Objects;
 
 import org.apache.jena.datatypes.RDFDatatype;
-import org.apache.jena.graph.impl.*;
-import org.apache.jena.shared.*;
+import org.apache.jena.graph.impl.LiteralLabel;
+import org.apache.jena.graph.impl.LiteralLabelFactory;
+import org.apache.jena.shared.PrefixMapping;
 
 /**
     An RDF node holding a literal value. Literals may have datatypes.
@@ -45,6 +46,13 @@ public class Node_Literal extends Node
         this.label = LiteralLabelFactory.createLang(string, lang);
     }
 
+    /*package*/ Node_Literal(String lex, String lang, TextDirection textDir) {
+        Objects.requireNonNull(lex, "null lexical form for literal");
+        Objects.requireNonNull(lang, "null language");
+        Objects.requireNonNull(textDir, "null text direction");
+        this.label = LiteralLabelFactory.createDirLang(lex, lang, textDir);
+    }
+
     /* package */ Node_Literal(String lex, RDFDatatype dtype) {
         Objects.requireNonNull(lex, "null lexical form for literal");
         Objects.requireNonNull(dtype, "null datatype");
@@ -71,6 +79,11 @@ public class Node_Literal extends Node
     public final String getLiteralLanguage()
     { return getLiteral().language(); }
 
+    @Override
+    public final TextDirection getLiteralTextDirection()
+    { return getLiteral().initialTextDirection(); }
+
+
     @Override
     public final String getLiteralDatatypeURI()
     { return getLiteral().getDatatypeURI(); }
diff --git a/jena-core/src/main/java/org/apache/jena/graph/TextDirection.java b/jena-core/src/main/java/org/apache/jena/graph/TextDirection.java
new file mode 100644
index 0000000000..09c109ff5b
--- /dev/null
+++ b/jena-core/src/main/java/org/apache/jena/graph/TextDirection.java
@@ -0,0 +1,55 @@
+/*
+ * 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.graph;
+
+import static org.apache.jena.atlas.lib.Lib.lowercase;
+
+import org.apache.jena.shared.JenaException;
+import org.apache.jena.vocabulary.RDF;
+
+public enum TextDirection {
+
+    LTR("ltr"), RTL("rtl") ;
+
+    // "name" is used by enum.
+    private final String direction;
+
+    private TextDirection(String string) {
+        this.direction = string;
+    }
+
+    public String direction() {
+        return direction;
+    }
+
+    @Override
+    public String toString() {
+        return direction;
+    }
+
+    public static TextDirection create(String label) {
+        String s = lowercase(label);
+        return switch(s) {
+            case "ltr" -> LTR;
+            case "rtl"-> RTL;
+            default ->
+                throw new JenaException(String .format("Initial text direction must be 'ltr' or 'rtl'", RDF.dirLTR, RDF.dirRTL));
+        };
+    }
+}
diff --git a/jena-core/src/main/java/org/apache/jena/graph/impl/LiteralLabel.java b/jena-core/src/main/java/org/apache/jena/graph/impl/LiteralLabel.java
index f4dffe0011..0e2f44fc22 100644
--- a/jena-core/src/main/java/org/apache/jena/graph/impl/LiteralLabel.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/impl/LiteralLabel.java
@@ -18,25 +18,30 @@
 
 package org.apache.jena.graph.impl;
 
+import static org.apache.jena.atlas.lib.Lib.isEmpty;
+
 import java.util.Arrays;
-import java.util.Locale ;
-import java.util.Objects ;
+import java.util.Objects;
 
 import org.apache.jena.atlas.lib.EscapeStr;
 import org.apache.jena.datatypes.DatatypeFormatException;
 import org.apache.jena.datatypes.RDFDatatype;
 import org.apache.jena.datatypes.xsd.XSDDatatype;
+import org.apache.jena.datatypes.xsd.impl.RDFhtml;
 import org.apache.jena.datatypes.xsd.impl.RDFjson;
 import org.apache.jena.datatypes.xsd.impl.XMLLiteralType;
-import org.apache.jena.shared.JenaException ;
+import org.apache.jena.graph.TextDirection;
+import org.apache.jena.shared.JenaException;
 import org.apache.jena.shared.PrefixMapping;
-import org.apache.jena.shared.impl.JenaParameters ;
-import org.apache.jena.vocabulary.RDF ;
+import org.apache.jena.shared.impl.JenaParameters;
+import org.apache.jena.vocabulary.RDF;
 
 /**
  * Represents the "contents" of a Node_Literal.
  * These contents comprise a lexical form, an optional language tag,
  * and optional datatype structure and a value.
+ * <p>
+ * Create via LiteralLabelFactory which does the checking and adjustments.
  */
 final public class LiteralLabel {
 
@@ -50,6 +55,12 @@ final public class LiteralLabel {
      */
     private String lang;
 
+    /**
+     * The initial text direction of a language literal.
+     * Datatype rdf:dirLangSring.
+     */
+    private TextDirection textDir;
+
     /**
      * The type of the literal. A null type indicates a classic "plain" literal.
      * The type of a literal is fixed when it is created.
@@ -82,7 +93,6 @@ final public class LiteralLabel {
     // Constructors
 
     // -- LiteralLabel by RDF term.
-    // The value is not checked as being valid until it is asked for (getValue).
 
     /**
      * Build a LiteralLabel with lexical form and datatype.
@@ -92,21 +102,23 @@ final public class LiteralLabel {
      * @param dtype the type of the literal
      */
     LiteralLabel(String lex, RDFDatatype dtype) {
-        this(lex, "", dtype) ;
+        this(lex, "", null, dtype);
     }
 
     /**
      * Build a LiteralLabel with lexical form, lang tag and datatype.
      * The validity of the lexical form a a value is not checked.
      *
-     * @param lex the lexical form of the literal
-     * @param lang the optional language tag, only relevant for rdf:rdfLangString
-     * @param dtype the type of the literal
+     * @param lex       the lexical form of the literal
+     * @param lang      the optional language tag, only relevant for rdf:langString and rdf:dirLangString
+     * @param dirLang   only relevant for rdf:langString and rdf:dirLangString
+     * @param dtype     the type of the literal
      */
-    /*package*/ LiteralLabel(String lex, String lang, RDFDatatype dtype) {
+    /*package*/ LiteralLabel(String lex, String lang, TextDirection textDir, RDFDatatype dtype) {
         this.lexicalForm = lex;
         this.dtype = Objects.requireNonNull(dtype);
-        this.lang = formLangTag(lang);
+        this.lang = lang;
+        this.textDir = textDir;
         hash = calcHashCode();
         if ( valueMode == ValueMode.EAGER ) {
             this.wellformed = setValue(lex, dtype);
@@ -116,24 +128,11 @@ final public class LiteralLabel {
             value = null;
     }
 
-    private static final boolean legacyLangTag = true;
-
-    /** Prepare the language tag - apply formatting normalization */
-    private static String formLangTag(String input) {
-        if ( legacyLangTag )
-            return (input == null ? "" : input);
-        // Format.
-        return (input == null ? "" : input.toLowerCase(Locale.ROOT));
-    }
-
     /** Calculate the indexing form for a language tag */
     private static String indexingLang(String lang) {
-        if ( legacyLangTag )
-            return lang.toLowerCase(Locale.ROOT);
         return lang;
     }
 
-
     /**
      * Build a typed literal label from its value form using
      * whatever datatype is currently registered as the default
@@ -203,7 +202,7 @@ final public class LiteralLabel {
     // Used by set-by-term.
     // set-by-value is always eager.
 
-    private volatile Object value1 = null ;
+    private volatile Object value1 = null;
     private static Object invalidValue = new Object();
 
     /** Does not return null - returns "invalidValue" */
@@ -254,13 +253,14 @@ final public class LiteralLabel {
     // Methods
 
     /**
-     * Answer true iff this is a well-formed literal.
+     * Answer true iff this is a well-formed literal (the lexical form conforms to the datatype).
+     * String literals (xsd:string, rdf:LangString,m rdf:dirLangString) are always well-formed.
      */
     public boolean isWellFormed() {
         return dtype != null && isWellFormedRaw();
     }
 
-    public boolean isWellFormedRaw() {
+    private boolean isWellFormedRaw() {
         if ( ! wellformed )
             return false;
         // Force initialization.
@@ -273,28 +273,28 @@ final public class LiteralLabel {
     }
 
     public String toString(PrefixMapping pmap, boolean quoting) {
-        StringBuilder b = new StringBuilder() ;
+        StringBuilder b = new StringBuilder();
         if ( ! quoting && simpleLiteral() )
             return getLexicalForm();
 
         quoting = true;
         // Always quoted for language strings and datatypes (not xsd:string).
         if ( quoting )
-            b.append('"') ;
+            b.append('"');
         String elex = EscapeStr.stringEsc(getLexicalForm());
-        b.append(elex) ;
+        b.append(elex);
         if ( quoting )
-            b.append('"') ;
+            b.append('"');
 
         if ( lang != null && !lang.equals("") )
-            b.append("@").append(lang) ;
+            b.append("@").append(lang);
         else if ( ! dtype.equals(XSDDatatype.XSDstring) ) {
                 String dtStr = (pmap != null)
                         ? PrefixMapping.Standard.shortForm(dtype.getURI())
                         : dtype.getURI();
                 b.append("^^").append(dtStr);
         }
-        return b.toString() ;
+        return b.toString();
     }
 
     private boolean simpleLiteral() {
@@ -336,13 +336,14 @@ final public class LiteralLabel {
     }
 
     /**
-     * Return true for datatype with large values (XML, JSON) and
+     * Return true for datatype with large values (XML, JSON, HTML) and
      * the value is the lexical form, the indexing value is this object.
      * Therefore getValueHashCode is the same as hashCode();
      */
     private boolean indexingValueIsSelf() {
         return dtype == XMLLiteralType.theXMLLiteralType ||
-               dtype == RDFjson.rdfJSON ;
+               dtype == RDFjson.rdfJSON ||
+               dtype == RDFhtml.rdfHTML ;
     }
 
     /**
@@ -351,7 +352,7 @@ final public class LiteralLabel {
      * (which is the case for literals with binary value).
      */
     static class ByteArray {
-        private int hashCode = 0 ;
+        private int hashCode = 0;
 
         private final byte[] bytes;
         /*package*/ ByteArray(byte[] bytes) {
@@ -389,6 +390,14 @@ final public class LiteralLabel {
         return lang;
     }
 
+    /**
+     * Answer the initial text direction associated with this literal (the empty string if there's
+     * no text direction).
+     */
+    public TextDirection initialTextDirection() {
+        return textDir;
+    }
+
     /**
      * Answer a suitable instance of a Java class representing this literal's value.
      * May throw an exception if the literal is ill-formed.
@@ -407,7 +416,7 @@ final public class LiteralLabel {
 
     private Object getValueInternal() {
         Object v = getValueLazy();
-        return (v == invalidValue ) ? null : v ;
+        return (v == invalidValue ) ? null : v;
     }
 
     /**
@@ -432,27 +441,27 @@ final public class LiteralLabel {
      */
     @Override
     public boolean equals(Object other) {
-        if ( this == other ) return true ;
+        if ( this == other ) return true;
         if (other == null || !(other instanceof LiteralLabel)) {
             return false;
         }
         LiteralLabel otherLiteral = (LiteralLabel) other;
 
-        boolean typeEquals = Objects.equals(dtype, otherLiteral.getDatatype()) ;
+        boolean typeEquals = Objects.equals(dtype, otherLiteral.getDatatype());
         if ( !typeEquals )
-            return false ;
+            return false;
 
         // Don't just use this.lexcialForm -- need to force delayed calculation from values.
         boolean lexEquals = Objects.equals(getLexicalForm(), otherLiteral.getLexicalForm());
         if ( ! lexEquals )
-            return false ;
+            return false;
 
-        boolean langEquals = Objects.equals(lang, otherLiteral.language()) ;
+        boolean langEquals = Objects.equals(lang, otherLiteral.language());
         if ( ! langEquals )
-            return false ;
+            return false;
         // Ignore xml flag as it is calculated from the lexical form + datatype
         // Ignore value as lexical form + datatype -> value is a function.
-        return true ;
+        return true;
     }
 
     /**
@@ -460,7 +469,7 @@ final public class LiteralLabel {
      * one.
      */
     public boolean sameValueAs( LiteralLabel other ) {
-        return sameValueAs(this, other) ;
+        return sameValueAs(this, other);
     }
     /**
      * Two literal labels are the "same value" if they are the same string,
@@ -470,61 +479,96 @@ final public class LiteralLabel {
      * @return
      */
     private static boolean sameValueAs(LiteralLabel lit1, LiteralLabel lit2) {
-        //return  lit1.sameValueAs(lit2) ;
+        //return  lit1.sameValueAs(lit2);
         if ( lit1 == null )
-            throw new NullPointerException() ;
+            throw new NullPointerException();
         if ( lit2 == null )
-            throw new NullPointerException() ;
-        // Strings.
+            throw new NullPointerException();
+        // -- Strings.
         if ( isStringValue(lit1) && isStringValue(lit2) )
-            return lit1.getLexicalForm().equals(lit2.getLexicalForm()) ;
-
-        if ( isStringValue(lit1) ) return false ;
-        if ( isStringValue(lit2) ) return false ;
+            return lit1.getLexicalForm().equals(lit2.getLexicalForm());
+        if ( isStringValue(lit1) ) return false;
+        if ( isStringValue(lit2) ) return false;
 
-        // Language tag strings
+        // -- Language tag strings
         if ( isLangString(lit1) && isLangString(lit2) ) {
-            String lex1 = lit1.getLexicalForm() ;
-            String lex2 = lit2.getLexicalForm() ;
-            return lex1.equals(lex2) && lit1.language().equalsIgnoreCase(lit2.language()) ;
+            String lex1 = lit1.getLexicalForm();
+            String lex2 = lit2.getLexicalForm();
+            //return lex1.equals(lex2) && lit1.language().equalsIgnoreCase(lit2.language());
+            // Normalized language tags.
+            return lex1.equals(lex2)
+                    && lit1.language().equals(lit2.language());
         }
-        if ( isLangString(lit1) ) return false ;
-        if ( isLangString(lit2) ) return false ;
+        if ( isLangString(lit1) ) return false;
+        if ( isLangString(lit2) ) return false;
+
+        // -- Language tag strings with initial text direction
+        if ( isLangStringDir(lit1) && isLangStringDir(lit2) ) {
+            String lex1 = lit1.getLexicalForm();
+            String lex2 = lit2.getLexicalForm();
+            return lex1.equals(lex2)
+                    && lit1.language().equals(lit2.language())
+                    && lit1.initialTextDirection().equals(lit2.initialTextDirection());
+        }
+        if ( isLangStringDir(lit1) ) return false;
+        if ( isLangStringDir(lit2) ) return false;
 
-        // Both not strings, not lang strings.
+        // -- datatypes.
+        // Both not strings, not lang strings and not dirlang strings.
         // Datatype set.
         if ( lit1.isWellFormedRaw() && lit2.isWellFormedRaw() )
             // Both well-formed.
-            return lit1.getDatatype().isEqual(lit1, lit2) ;
+            return lit1.getDatatype().isEqual(lit1, lit2);
         if ( ! lit1.isWellFormedRaw() && ! lit2.isWellFormedRaw() )
-            return lit1.equals(lit2) ;
+            return lit1.equals(lit2);
         // One is well formed, the other is not.
-        return false ;
+        return false;
     }
 
     /** Return true if the literal label is a string value (RDF 1.0 and RDF 1.1) */
     private static boolean isStringValue(LiteralLabel lit) {
         if ( lit.getDatatype() == null )
             // RDF 1.0
-            return ! isLangString(lit) ;
+            return ! isLangString(lit);
         if ( lit.getDatatype().equals(XSDDatatype.XSDstring)  )
             return true;
-        return false ;
+        return false;
     }
 
-    /** Return true if the literal label is a language string. */
+    /**
+     * Return true if the literal label is a well-formed language string (rdf:langString).
+     * Language strings do not have an initial text direction.
+     * This test excludes "abc"^^rdf:langString (not well-formed).
+     */
     private static boolean isLangString(LiteralLabel lit) {
         // Duplicate of Util.isLangString except for the additional consistency check.
-        String lang = lit.language() ;
-        if ( lang == null )
-            return false ;
-        // Check.
-        if ( lang.equals("") )
-            return false ;
-        // This is an additional check.
+        if ( isEmpty(lit.language()) )
+            return false;
+        if ( lit.initialTextDirection() != null )
+            // Has an initial text direction so it is n't
+            return false;
+        // Internal check.
         if ( ! Objects.equals(lit.getDatatype(), RDF.dtLangString) )
-            throw new JenaException("Literal with language string which is not rdf:langString: "+lit) ;
-        return true ;
+            throw new JenaException("Literal with language string which is not rdf:langString: "+lit);
+        return true;
+    }
+
+    /**
+     * Return true if the literal label is a well-formed language string with text direction.
+     * This excludes "abc"^^rdf:dirLangString.
+     */
+    private static boolean isLangStringDir(LiteralLabel lit) {
+        // Assume well formed.
+        String lang = lit.language();
+        // Allow "abc"@--rtl
+//        if ( isEmpty(lit.language()) )
+//            return false;
+        if ( lit.initialTextDirection() == null )
+            return false;
+        // Internal check.
+        if ( ! Objects.equals(lit.getDatatype(), RDF.dtDirLangString) )
+            throw new JenaException("Literal with language string and text direction which is not rdf:dirLangString: "+lit);
+        return true;
     }
 
     private int calcHashCode() {
@@ -537,7 +581,7 @@ final public class LiteralLabel {
      */
     @Override
     public int hashCode() {
-        return hash ;
+        return hash;
     }
 
     /**
diff --git a/jena-core/src/main/java/org/apache/jena/graph/impl/LiteralLabelFactory.java b/jena-core/src/main/java/org/apache/jena/graph/impl/LiteralLabelFactory.java
index 5264676143..c19432e196 100644
--- a/jena-core/src/main/java/org/apache/jena/graph/impl/LiteralLabelFactory.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/impl/LiteralLabelFactory.java
@@ -18,52 +18,74 @@
 
 package org.apache.jena.graph.impl;
 
+import static org.apache.jena.atlas.lib.Lib.isEmpty;
+import static org.apache.jena.graph.NodeFactory.noLangTag;
+import static org.apache.jena.graph.NodeFactory.noTextDirection;
+
 import org.apache.jena.datatypes.DatatypeFormatException;
 import org.apache.jena.datatypes.RDFDatatype;
 import org.apache.jena.datatypes.xsd.XSDDatatype;
 import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.graph.TextDirection;
 import org.apache.jena.vocabulary.RDF;
 
+/**
+ * This class is not in the public API.
+ */
 public class LiteralLabelFactory
 {
-    private static final RDFDatatype dtSLangString = NodeFactory.getType(RDF.Nodes.langString.getURI());
+    private static final RDFDatatype dtLangString = NodeFactory.getType(RDF.Nodes.langString.getURI());
+    private static final RDFDatatype dtDirLangString = NodeFactory.getType(RDF.Nodes.dirLangString.getURI());
 
-    private static RDFDatatype fixDatatype(RDFDatatype dtype, String lang) {
+//    /*package*/ static String noLang = "";
+//    /*package*/ static TextDirection noTextDirection = null;
+//
+    private static RDFDatatype fixDatatype(RDFDatatype dtype, String lang, TextDirection textDir) {
+        // lang is assumed to have correct case.
         if ( dtype != null )
             return dtype;
-        if ( lang != null && !lang.equals("") )
-            return dtSLangString;
-        return XSDDatatype.XSDstring;
+        if (isEmpty(lang) && textDir == null )
+            return XSDDatatype.XSDstring;
+        if ( textDir == null )
+            return dtLangString;
+        return dtDirLangString;
     }
 
     /** Create a string literal */
     public static LiteralLabel createString(String lex) {
-        return new LiteralLabel( lex, "", XSDDatatype.XSDstring);
+        return new LiteralLabel(lex, noLangTag, noTextDirection, XSDDatatype.XSDstring);
     }
 
     /**
-     * Build a plain literal label from its lexical form and language tag.
+     * Build a literal label from its lexical form and language tag.
      * @param lex the lexical form of the literal
-     * @param lang the optional language tag, only relevant for plain literals
+     * @param lang the optional language tag
      */
     public static LiteralLabel createLang(String lex, String lang) {
-        RDFDatatype dt = fixDatatype(null, lang);
-        return new LiteralLabel(lex, lang, dt);
+        RDFDatatype dt = fixDatatype(null, lang, noTextDirection);
+        return new LiteralLabel(lex, lang, noTextDirection, dt);
+    }
+
+    /**
+     * Build a literal label from its lexical form,language tag and initial text direction
+     * @param lex the lexical form of the literal
+     * @param lang the optional language tag
+     * @param textDir the optional initial text direction (lang required)
+     */
+    public static LiteralLabel createDirLang(String lex, String lang, TextDirection textDir) {
+        RDFDatatype dt = fixDatatype(null, lang, textDir);
+        return new LiteralLabel(lex, lang, textDir, dt);
     }
 
     /** Create a literal with a dtype. */
     public static LiteralLabel create(String lex, RDFDatatype dtype) {
-        return new LiteralLabel( lex, "", dtype );
+        return new LiteralLabel( lex, dtype );
     }
 
-    /** Using {@link #createLang(String, String)} or {@link #create(String, RDFDatatype)}
-     * where possible is preferred.
-     */
-    public static LiteralLabel createLiteralLabel( String lex, String lang, RDFDatatype dtype )
-        throws DatatypeFormatException
-    {
-        dtype = fixDatatype(dtype, lang);
-        return new LiteralLabel( lex, lang, dtype ); }
+    public static LiteralLabel createLiteralLabel( String lex, String lang, TextDirection textDir, RDFDatatype dtype ) {
+        dtype = fixDatatype(dtype, lang, textDir);
+        return new LiteralLabel(lex, lang, textDir, dtype);
+    }
 
     /**
      * Build a typed literal label from its value form. If the value is a string we
@@ -83,7 +105,7 @@ public class LiteralLabelFactory
      * @param dtype the type of the literal, null for old style "plain" literals (which become xsd:string in RDF 1.1)
      */
     public static LiteralLabel createByValue(Object value, RDFDatatype dtype) throws DatatypeFormatException {
-        dtype = fixDatatype(dtype, null);
+        dtype = fixDatatype(dtype, null, null);
         return new LiteralLabel(value, dtype);
     }
 
@@ -91,7 +113,7 @@ public class LiteralLabelFactory
      * Build a typed literal label from its value form using
      * whatever datatype is currently registered as the default
      * representation for this java class. No language tag is supplied.
-     * A plain string becomes an xsd:string.
+     * A Java string becomes an xsd:string.
      * @param value the literal value to encapsulate
      */
     public static LiteralLabel createTypedLiteral(Object value) {
diff --git a/jena-core/src/main/java/org/apache/jena/rdf/model/Literal.java b/jena-core/src/main/java/org/apache/jena/rdf/model/Literal.java
index 93884f663d..673fe2f839 100644
--- a/jena-core/src/main/java/org/apache/jena/rdf/model/Literal.java
+++ b/jena-core/src/main/java/org/apache/jena/rdf/model/Literal.java
@@ -172,11 +172,19 @@ public interface Literal extends RDFNode {
     public String getString() ;
 
     /**
-         If a language is defined for this literal return it
-         @return the language for this literal if it exists, or empty string if none
-    */
+     * If a language is defined for this literal return it
+     *
+     * @return the language for this literal if it exists, or empty string if none
+     */
     public String getLanguage();
 
+    /**
+     * If a text direction is defined for this literal return it
+     *
+     * @return the text direction for this literal if it exists, or null if none
+     */
+    public String getTextDirection();
+
     /** Test whether another object is equal to this object.
      *
      * <p>A plain Literal is equal to another object only if the object is
diff --git a/jena-core/src/main/java/org/apache/jena/rdf/model/impl/LiteralImpl.java b/jena-core/src/main/java/org/apache/jena/rdf/model/impl/LiteralImpl.java
index 1fea8d4b53..00cae4af9c 100644
--- a/jena-core/src/main/java/org/apache/jena/rdf/model/impl/LiteralImpl.java
+++ b/jena-core/src/main/java/org/apache/jena/rdf/model/impl/LiteralImpl.java
@@ -25,6 +25,7 @@ import org.apache.jena.enhanced.EnhGraph;
 import org.apache.jena.enhanced.EnhNode;
 import org.apache.jena.enhanced.Implementation;
 import org.apache.jena.graph.Node;
+import org.apache.jena.graph.TextDirection;
 import org.apache.jena.rdf.model.* ;
 import org.apache.jena.shared.BadBooleanException;
 import org.apache.jena.shared.BadCharLiteralException;
@@ -247,6 +248,15 @@ public class LiteralImpl extends EnhNode implements Literal {
         return asNode().getLiteralLanguage();
     }
 
+    @Override
+    public String getTextDirection() {
+        TextDirection textDir = asNode().getLiteralTextDirection();
+        if ( textDir == null )
+            return null;
+        return textDir.direction();
+    }
+
+
     /**
      * Test that two literals are semantically equivalent.
      * In some cases this may be the same as equals, in others
diff --git a/jena-core/src/main/java/org/apache/jena/rdf/model/impl/Util.java b/jena-core/src/main/java/org/apache/jena/rdf/model/impl/Util.java
index c8b1102393..0f06f9c455 100644
--- a/jena-core/src/main/java/org/apache/jena/rdf/model/impl/Util.java
+++ b/jena-core/src/main/java/org/apache/jena/rdf/model/impl/Util.java
@@ -17,16 +17,18 @@
  */
 
 package org.apache.jena.rdf.model.impl;
-import java.util.Objects ;
-import java.util.regex.Matcher ;
-import java.util.regex.Pattern ;
-
-import org.apache.jena.datatypes.RDFDatatype ;
-import org.apache.jena.datatypes.xsd.XSDDatatype ;
-import org.apache.jena.graph.Node ;
-import org.apache.jena.rdf.model.Literal ;
-import org.apache.jena.shared.CannotEncodeCharacterException ;
-import org.apache.jena.util.SplitIRI ;
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.jena.atlas.lib.Lib;
+import org.apache.jena.datatypes.RDFDatatype;
+import org.apache.jena.datatypes.xsd.XSDDatatype;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.TextDirection;
+import org.apache.jena.rdf.model.Literal;
+import org.apache.jena.shared.CannotEncodeCharacterException;
+import org.apache.jena.util.SplitIRI;
 import org.apache.jena.util.XMLChar;
 
 /** Some utility functions.
@@ -70,22 +72,22 @@ public class Util extends Object {
         int lg = uri.length();
         if (lg == 0)
             return 0;
-        int i = lg-1 ;
-        for ( ; i >= 1 ; i--) {
+        int i = lg-1;
+        for (; i >= 1; i--) {
             ch = uri.charAt(i);
             if (notNameChar(ch)) break;
         }
 
-        int j = i + 1 ;
+        int j = i + 1;
 
         if ( j >= lg )
-            return lg ;
+            return lg;
 
         // Check we haven't split up a %-encoding.
         if ( j >= 2 && uri.charAt(j-2) == '%' )
-            j = j+1 ;
+            j = j+1;
         if ( j >= 1 && uri.charAt(j-1) == '%' ) {
-            j = j+2 ;
+            j = j+2;
             if ( j > lg )
                 // JENA-1941: Protect against overshoot in the case of "%x"
                 // at end of a (bad) URI.
@@ -99,7 +101,7 @@ public class Util extends Object {
         for (; j < lg; j++) {
             ch = uri.charAt(j);
 //            if (XMLChar.isNCNameStart(ch))
-//                break ;
+//                break;
             if (XMLChar.isNCNameStart(ch))
             {
                 // "mailto:" is special.
@@ -135,7 +137,7 @@ public class Util extends Object {
                 .replaceAll( "\n", "&#xA;" )
                 .replaceAll( "\r", "&#xD;" )
                 .replaceAll( "\"", "&quot;" )
-                ;
+               ;
             }
         else
             return s;
@@ -153,7 +155,7 @@ public class Util extends Object {
              .replaceAll( "'", "&apos;" )
              .replaceAll( "%", "&#37;" )
              .replaceAll( "\"", "&quot;" )
-             ;
+            ;
          }
      else
          return s;
@@ -197,7 +199,7 @@ public class Util extends Object {
         }
 
     public static String replace(String s, String oldString, String newString) {
-        return s.replace(oldString, newString) ;
+        return s.replace(oldString, newString);
     }
 
     /**
@@ -208,27 +210,61 @@ public class Util extends Object {
      * </ul>
      */
     public static boolean isSimpleString(Node n) {
-        Objects.requireNonNull(n) ;
+        Objects.requireNonNull(n);
         if ( ! n.isLiteral() )
-            return false ;
-        RDFDatatype dt = n.getLiteralDatatype() ;
+            return false;
+        RDFDatatype dt = n.getLiteralDatatype();
         if ( dt == null )
-            return !isLangString(n) ;
-        return dt.equals(XSDDatatype.XSDstring) ;
+            return !hasLangTest(n);
+        return dt.equals(XSDDatatype.XSDstring);
     }
 
     /**
-     * A Node is a language string if it has a language tag.
-     * (RDF 1.0 and RDF 1.1)
+     * A Node is a well-formed language string if it has a language tag
+     * and it does not have an initial text direction.
+     * This excludes {@code "abc"^^rdf:langString} which is not well-formed.
      */
     public static boolean isLangString(Node n) {
-        Objects.requireNonNull(n) ;
+        Objects.requireNonNull(n);
         if ( ! n.isLiteral() )
-            return false ;
-        String lang = n.getLiteralLanguage() ;
-        if ( lang == null )
-            return false ;
-        return !lang.equals("") ;
+            return false;
+        return hasLangTest(n) && !hasDirectionText(n);
+    }
+
+    /**
+     * A Node is a well-formed directional language string if it has a language tag
+     * and it has an initial text direction.
+     */
+    public static boolean isDirLangString(Node n) {
+        Objects.requireNonNull(n);
+        if ( ! n.isLiteral() )
+            return false;
+        return hasDirectionText(n) && hasLangTest(n);
+    }
+
+    /** Test whether this node has a language (rdf:langString or rdf:dirLangString) */
+    public static boolean hasLang(Node n) {
+        if ( ! n.isLiteral() )
+            return false;
+        String lang = n.getLiteralLanguage();
+        return hasLangTest(n);
+    }
+
+    /** Test whether this node has an initial text language (rdf:dirLangString) */
+    public static boolean hasDirection(Node n) {
+        if ( ! n.isLiteral() )
+            return false;
+        return hasDirectionText(n);
+    }
+
+    private static boolean hasDirectionText(Node n) {
+        TextDirection textDir = n.getLiteralTextDirection();
+        return textDir != null;
+    }
+
+    private static boolean hasLangTest(Node n) {
+        String lang = n.getLiteralLanguage();
+        return ! Lib.isEmpty(lang);
     }
 
     /** Return true if the literal is a simple string.
@@ -236,19 +272,31 @@ public class Util extends Object {
      *  <p>RDF 1.1 {@literal =>} it has datatype xsd:string
      */
     public static boolean isSimpleString(Literal lit) {
-        Objects.requireNonNull(lit) ;
+        Objects.requireNonNull(lit);
         RDFDatatype dt = lit.getDatatype();
         if (  dt == null )
-            return ! isLangString(lit) ;
+            return ! isLangString(lit);
         return dt.equals(XSDDatatype.XSDstring);
     }
 
-    /** Return true if the literal has a language tag. (RDF 1.0 and RDF 1.1) */
+    /** Return true if the literal has a language tag. */
     public static boolean isLangString(Literal lit) {
-        Objects.requireNonNull(lit) ;
-        String lang = lit.getLanguage() ;
+        Objects.requireNonNull(lit);
+        String lang = lit.getLanguage();
+        if ( lang == null )
+            return false;
+        return ! lang.equals("");
+    }
+
+    /** Return true if the literal is well-formed, has a language tag and a text direction. */
+    public static boolean isDirLangString(Literal lit) {
+        Objects.requireNonNull(lit);
+        String lang = lit.getLanguage();
         if ( lang == null )
-            return false ;
-        return ! lang.equals("") ;
+            return false;
+        String textDir = lit.getTextDirection();
+        if ( textDir == null )
+            return false;
+        return true;
     }
 }
diff --git a/jena-core/src/main/java/org/apache/jena/vocabulary/RDF.java b/jena-core/src/main/java/org/apache/jena/vocabulary/RDF.java
index 081160c7a0..7b916188a6 100644
--- a/jena-core/src/main/java/org/apache/jena/vocabulary/RDF.java
+++ b/jena-core/src/main/java/org/apache/jena/vocabulary/RDF.java
@@ -19,11 +19,9 @@
 package org.apache.jena.vocabulary;
 
 import org.apache.jena.datatypes.RDFDatatype ;
-import org.apache.jena.datatypes.xsd.impl.RDFLangString ;
-import org.apache.jena.datatypes.xsd.impl.RDFhtml ;
-import org.apache.jena.datatypes.xsd.impl.RDFjson;
-import org.apache.jena.datatypes.xsd.impl.XMLLiteralType ;
+import org.apache.jena.datatypes.xsd.impl.*;
 import org.apache.jena.graph.Node ;
+import org.apache.jena.graph.TextDirection;
 import org.apache.jena.rdf.model.Property ;
 import org.apache.jena.rdf.model.Resource ;
 import org.apache.jena.rdf.model.ResourceFactory ;
@@ -54,51 +52,56 @@ public class RDF{
     public static Property li( int i )
         { return property( "_" + i ); }
 
-    public static final Resource    Alt          = Init.Alt();
-    public static final Resource    Bag          = Init.Bag();
-    public static final Resource    Property     = Init._Property();
-    public static final Resource    Seq          = Init.Seq();
-    public static final Resource    Statement    = Init.Statement();
-    public static final Resource    List         = Init.List();
-    public static final Resource    nil          = Init.nil();
-
-    public static final Property    first        = Init.first();
-    public static final Property    rest         = Init.rest();
-    public static final Property    subject      = Init.subject();
-    public static final Property    predicate    = Init.predicate();
-    public static final Property    object       = Init.object();
-    public static final Property    type         = Init.type();
-    public static final Property    value        = Init.value();
+    public static final Resource    Alt             = Init.Alt();
+    public static final Resource    Bag             = Init.Bag();
+    public static final Resource    Property        = Init._Property();
+    public static final Resource    Seq             = Init.Seq();
+    public static final Resource    Statement       = Init.Statement();
+    public static final Resource    List            = Init.List();
+    public static final Resource    nil             = Init.nil();
+
+    public static final Property    first           = Init.first();
+    public static final Property    rest            = Init.rest();
+    public static final Property    subject         = Init.subject();
+    public static final Property    predicate       = Init.predicate();
+    public static final Property    object          = Init.object();
+    public static final Property    type            = Init.type();
+    public static final Property    value           = Init.value();
 
     // RDF 1.1 - the datatypes of language strings
-    public static final Resource    langString   = Init.langString();
+    public static final Resource    langString      = Init.langString();
 
     // RDF 1.1 - rdf:HTML
-    public static final Resource    HTML         = Init.HTML();
+    public static final Resource    HTML            = Init.HTML();
 
     // rdf:XMLLiteral
-    public static final Resource    xmlLiteral   = Init.xmlLiteral();
+    public static final Resource    xmlLiteral      = Init.xmlLiteral();
 
-    public static final RDFDatatype dtRDFHTML    = Init.dtRDFHTML();
-    public static final RDFDatatype dtLangString = Init.dtLangString();
-    public static final RDFDatatype dtXMLLiteral = Init.dtXMLLiteral();
+    public static final RDFDatatype dtRDFHTML       = Init.dtRDFHTML();
+    public static final RDFDatatype dtLangString    = Init.dtLangString();
+    public static final RDFDatatype dtDirLangString = Init.dtDirLangString();
+    public static final RDFDatatype dtXMLLiteral    = Init.dtXMLLiteral();
 
     // Added to the RDF namespace December 2019
     // https://lists.w3.org/Archives/Public/semantic-web/2019Dec/0027.html
 
     // rdfs:comment "The datatype of RDF literals storing JSON content."
-    public static final RDFDatatype dtRDFJSON    = Init.dtRDFJSON();
-    public static final Resource JSON            = Init.JSON();
+    public static final RDFDatatype dtRDFJSON       = Init.dtRDFJSON();
+    public static final Resource JSON               = Init.JSON();
 
     // rdfs:comment "A class representing a compound literal."
-    public static final Resource CompoundLiteral = Init.CompoundLiteral();
+    public static final Resource CompoundLiteral    = Init.CompoundLiteral();
 
     // rdfs:comment "The language component of a CompoundLiteral."
-    public static final Property language        = Init.language();
+    public static final Property language           = Init.language();
 
     // rdfs:comment "The base direction component of a CompoundLiteral."
-    public static final Property direction       = Init.direction();
+    public static final Property direction          = Init.direction();
 
+    // The constant "ltr" (left to right)
+    public static final String dirLTR               = TextDirection.LTR.direction();
+    // The constant "rtl" (right to left)
+    public static final String dirRTL               = TextDirection.RTL.direction();
 
     /** RDF constants are used during Jena initialization.
      * <p>
@@ -111,39 +114,40 @@ public class RDF{
 
         // JENA-1294
         // Version that calculates the constant when called.
-        public static Resource Alt()              { return resource( "Alt" ); }
-        public static Resource Bag()              { return resource( "Bag" ); }
+        public static Resource Alt()                { return resource( "Alt" ); }
+        public static Resource Bag()                { return resource( "Bag" ); }
         // Java8 bug : https://bugzilla.redhat.com/show_bug.cgi?id=1423421
         // Can't have a method called Property() - it crashes the javadoc generation.
         //  https://bugzilla.redhat.com/show_bug.cgi?id=1423421 ==>
         //  https://bugs.openjdk.java.net/browse/JDK-8061305
-        public static Resource _Property()        { return resource( "Property" ); }
-        public static Resource Seq()              { return resource( "Seq" ); }
-        public static Resource Statement()        { return resource( "Statement" ); }
-        public static Resource List()             { return resource( "List" ); }
-        public static Resource nil()              { return resource( "nil" ); }
-        public static Property first()            { return property( "first" ); }
-        public static Property rest()             { return property( "rest" ); }
-        public static Property subject()          { return property( "subject" ); }
-        public static Property predicate()        { return property( "predicate" ); }
-        public static Property object()           { return property( "object" ); }
-        public static Property type()             { return property( "type" ); }
-        public static Property value()            { return property( "value" ); }
-
-        public static Resource langString()       { return ResourceFactory.createResource(dtLangString().getURI()); }
-        public static Resource HTML()             { return ResourceFactory.createResource(dtRDFHTML().getURI()); }
-        public static Resource xmlLiteral()       { return ResourceFactory.createResource(dtXMLLiteral().getURI()); }
-        public static Resource JSON()             { return ResourceFactory.createResource(dtRDFJSON().getURI()) ; }
-
-        public static Resource CompoundLiteral()  { return resource( "CompoundLiteral" ); }
-        public static Property language()         { return property( "language" ); }
-        public static Property direction()        { return property( "direction" ); }
-
-        public static RDFDatatype dtRDFHTML()     { return RDFhtml.rdfHTML; }
-        public static RDFDatatype dtLangString()  { return RDFLangString.rdfLangString; }
-        public static RDFDatatype dtXMLLiteral()  { return XMLLiteralType.theXMLLiteralType; }
-        public static RDFDatatype dtRDFJSON()     { return RDFjson.rdfJSON; }
-
+        public static Resource _Property()          { return resource( "Property" ); }
+        public static Resource Seq()                { return resource( "Seq" ); }
+        public static Resource Statement()          { return resource( "Statement" ); }
+        public static Resource List()               { return resource( "List" ); }
+        public static Resource nil()                { return resource( "nil" ); }
+        public static Property first()              { return property( "first" ); }
+        public static Property rest()               { return property( "rest" ); }
+        public static Property subject()            { return property( "subject" ); }
+        public static Property predicate()          { return property( "predicate" ); }
+        public static Property object()             { return property( "object" ); }
+        public static Property type()               { return property( "type" ); }
+        public static Property value()              { return property( "value" ); }
+
+        public static Resource langString()         { return ResourceFactory.createResource(dtLangString().getURI()); }
+        public static Resource dirLangString()      { return ResourceFactory.createResource(dtDirLangString().getURI()); }
+        public static Resource HTML()               { return ResourceFactory.createResource(dtRDFHTML().getURI()); }
+        public static Resource xmlLiteral()         { return ResourceFactory.createResource(dtXMLLiteral().getURI()); }
+        public static Resource JSON()               { return ResourceFactory.createResource(dtRDFJSON().getURI()) ; }
+
+        public static Resource CompoundLiteral()    { return resource( "CompoundLiteral" ); }
+        public static Property language()           { return property( "language" ); }
+        public static Property direction()          { return property( "direction" ); }
+
+        public static RDFDatatype dtRDFHTML()       { return RDFhtml.rdfHTML; }
+        public static RDFDatatype dtLangString()    { return RDFLangString.rdfLangString; }
+        public static RDFDatatype dtDirLangString() { return RDFDirLangString.rdfDirLangString; }
+        public static RDFDatatype dtXMLLiteral()    { return XMLLiteralType.theXMLLiteralType; }
+        public static RDFDatatype dtRDFJSON()       { return RDFjson.rdfJSON; }
     }
 
     /**
@@ -153,28 +157,29 @@ public class RDF{
     @SuppressWarnings("hiding")
     public static final class Nodes
     {
-        public static final Node Alt        = Init.Alt().asNode();
-        public static final Node Bag        = Init.Bag().asNode();
-        public static final Node Property   = Init._Property().asNode();
-        public static final Node Seq        = Init.Seq().asNode();
-        public static final Node Statement  = Init.Statement().asNode();
-        public static final Node List       = Init.List().asNode();
-        public static final Node nil        = Init.nil().asNode();
-        public static final Node first      = Init.first().asNode();
-        public static final Node rest       = Init.rest().asNode();
-        public static final Node subject    = Init.subject().asNode();
-        public static final Node predicate  = Init.predicate().asNode();
-        public static final Node object     = Init.object().asNode();
-        public static final Node type       = Init.type().asNode();
-        public static final Node value      = Init.value().asNode();
-        public static final Node langString = Init.langString().asNode();
-        public static final Node HTML       = Init.HTML().asNode();
-        public static final Node xmlLiteral = Init.xmlLiteral().asNode();
+        public static final Node Alt            = Init.Alt().asNode();
+        public static final Node Bag            = Init.Bag().asNode();
+        public static final Node Property       = Init._Property().asNode();
+        public static final Node Seq            = Init.Seq().asNode();
+        public static final Node Statement      = Init.Statement().asNode();
+        public static final Node List           = Init.List().asNode();
+        public static final Node nil            = Init.nil().asNode();
+        public static final Node first          = Init.first().asNode();
+        public static final Node rest           = Init.rest().asNode();
+        public static final Node subject        = Init.subject().asNode();
+        public static final Node predicate      = Init.predicate().asNode();
+        public static final Node object         = Init.object().asNode();
+        public static final Node type           = Init.type().asNode();
+        public static final Node value          = Init.value().asNode();
+        public static final Node langString     = Init.langString().asNode();
+        public static final Node dirLangString  = Init.dirLangString().asNode();
+        public static final Node HTML           = Init.HTML().asNode();
+        public static final Node xmlLiteral     = Init.xmlLiteral().asNode();
         // Added to the RDF namespace December 2019
         // https://lists.w3.org/Archives/Public/semantic-web/2019Dec/0027.html
-        public static final Node JSON       = Init.JSON().asNode();
+        public static final Node JSON           = Init.JSON().asNode();
         public static final Node CompoundLiteral = Init.CompoundLiteral().asNode();
-        public static final Node language   = Init.language().asNode();
-        public static final Node direction  = Init.direction().asNode();
+        public static final Node language       = Init.language().asNode();
+        public static final Node direction      = Init.direction().asNode();
     }
 }
diff --git a/jena-core/src/test/java/org/apache/jena/graph/test/NodeCreateUtils.java b/jena-core/src/test/java/org/apache/jena/graph/test/NodeCreateUtils.java
index ac8284211e..5c340691a0 100644
--- a/jena-core/src/test/java/org/apache/jena/graph/test/NodeCreateUtils.java
+++ b/jena-core/src/test/java/org/apache/jena/graph/test/NodeCreateUtils.java
@@ -24,8 +24,6 @@ import org.apache.jena.datatypes.xsd.XSDDatatype ;
 import org.apache.jena.graph.Node ;
 import org.apache.jena.graph.NodeFactory ;
 import org.apache.jena.graph.Triple ;
-import org.apache.jena.graph.impl.LiteralLabel ;
-import org.apache.jena.graph.impl.LiteralLabelFactory ;
 import org.apache.jena.shared.JenaException;
 import org.apache.jena.shared.PrefixMapping;
 
@@ -73,14 +71,13 @@ public class NodeCreateUtils
     @param x the string encoding the node to create
     @return a node with the appropriate type and label
     */
-    @SuppressWarnings("deprecation")
     public static Node create( PrefixMapping pm, String x )
         {
         if (x.equals( "" ))
             throw new JenaException( "Node.create does not accept an empty string as argument" );
         char first = x.charAt( 0 );
         if (first == '\'' || first == '\"')
-            return NodeFactory.createLiteral( newString( pm, first, x ) );
+            return newStringNode( pm, first, x);
         if (Character.isDigit( first ))
             return NodeFactory.createLiteral( x, XSDDatatype.XSDinteger );
         if (first == '_')
@@ -130,17 +127,17 @@ public class NodeCreateUtils
         	}
         }
 
-    public static LiteralLabel literal( PrefixMapping pm, String spelling, String langOrType )
+    public static Node literal( PrefixMapping pm, String spelling, String langOrType )
         {
         String content = unEscape( spelling );
         int colon = langOrType.indexOf( ':' );
         return colon < 0
-            ? LiteralLabelFactory.createLang( content, langOrType )
-            : LiteralLabelFactory.create( content, NodeFactory.getType( pm.expandPrefix( langOrType ) ) )
+            ? NodeFactory.createLiteralLang( content, langOrType )
+            : NodeFactory.createLiteral( content, NodeFactory.getType( pm.expandPrefix( langOrType )))
             ;
         }
 
-    public static LiteralLabel newString( PrefixMapping pm, char quote, String nodeString )
+    public static Node newStringNode( PrefixMapping pm, char quote, String nodeString )
         {
         int close = nodeString.lastIndexOf( quote );
         return literal( pm, nodeString.substring( 1, close ), nodeString.substring( close + 1 ) );
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/rewriters/NodeValueRewriterTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/rewriters/NodeValueRewriterTest.java
index 2aee91d07d..dcc8522849 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/rewriters/NodeValueRewriterTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/rewriters/NodeValueRewriterTest.java
@@ -238,7 +238,7 @@ public class NodeValueRewriterTest {
 
     @Test
     public void visitNodeValueLangNodeTest() {
-        Node n = NodeFactory.createLiteral("Hello", "fi");
+        Node n = NodeFactory.createLiteralLang("Hello", "fi");
         NodeValue nv = new NodeValueLang(n);
         nv.visit(rewriter);
         NodeValue result = rewriter.getResult();
diff --git a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredLiteralImpl.java b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredLiteralImpl.java
index e0ba5eebd0..6ce2dd6a88 100644
--- a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredLiteralImpl.java
+++ b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredLiteralImpl.java
@@ -211,6 +211,18 @@ public class SecuredLiteralImpl extends SecuredRDFNodeImpl implements SecuredLit
         return holder.getBaseItem().getLanguage();
     }
 
+    /**
+     * @sec.graph Read
+     * @throws ReadDeniedException
+     * @throws AuthenticationRequiredException if user is not authenticated and is
+     *                                         required to be.
+     */
+    @Override
+    public String getTextDirection() throws ReadDeniedException, AuthenticationRequiredException {
+        checkRead();
+        return holder.getBaseItem().getTextDirection();
+    }
+
     /**
      * @sec.graph Read
      * @throws ReadDeniedException


(jena) 06/10: GH-2039: Case insensitive langtags

Posted by an...@apache.org.
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 b13a79f8bee524742e8fba65092bea6c9fb02d89
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Sun Dec 24 15:56:40 2023 +0000

    GH-2039: Case insensitive langtags
---
 .../process/normalize/CanonicalizeLiteral.java     |   4 +-
 .../jena/sparql/engine/optimizer/StatsMatcher.java |   2 +-
 .../org/apache/jena/sparql/util/StringUtils.java   |  14 +-
 .../jena/riot/process/TestNormalization.java       |  21 +-
 .../apache/jena/sparql/expr/TestExpressions.java   |  26 +-
 .../apache/jena/sparql/expr/TestNodeFunctions.java | 315 +++++++++++----------
 .../org/apache/jena/sparql/expr/TestNodeValue.java |   6 +-
 .../org/apache/jena/sparql/expr/TestOrdering.java  |   3 +-
 .../apache/jena/sparql/expr/TestSortOrdering.java  |  13 +-
 .../jena/sparql/resultset/TestResultSet.java       |   3 +
 jena-arq/testing/ARQ/Sort/sort-result-2.ttl        | 252 ++++++++---------
 jena-arq/testing/ARQ/Sort/sort-result-3.ttl        | 252 ++++++++---------
 jena-arq/testing/DAWG/examples/ex11.2.3.7_0.rq     |   2 +-
 .../src/main/java/org/apache/jena/graph/Node.java  |  15 +-
 .../java/org/apache/jena/graph/NodeFactory.java    |  38 +--
 .../org/apache/jena/graph/impl/LiteralLabel.java   |  20 +-
 .../jena/graph/impl/LiteralLabelFactory.java       |   9 +-
 .../org/apache/jena/graph/langtag/LangTags.java    | 165 +++++++++++
 .../apache/jena/graph/test/AbstractTestGraph.java  |  20 +-
 .../graph/test/TestLiteralLabelSameValueAs.java    |   2 +
 .../apache/jena/graph/test/TestLiteralLabels.java  |   1 +
 .../java/org/apache/jena/graph/test/TestNode.java  |   7 +-
 22 files changed, 706 insertions(+), 484 deletions(-)

diff --git a/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/CanonicalizeLiteral.java b/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/CanonicalizeLiteral.java
index f581aac0f1..bc58af76d1 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/CanonicalizeLiteral.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/CanonicalizeLiteral.java
@@ -40,7 +40,7 @@ public class CanonicalizeLiteral implements Function<Node, Node>
     private CanonicalizeLiteral() {}
 
     /**
-     * Canonicaize a literal, both lexical form and language tag (RFc canonical).
+     * Canonicalize a literal, both lexical form and language tag (RFc canonical).
      */
     @Override
     public Node apply(Node node) {
@@ -64,7 +64,7 @@ public class CanonicalizeLiteral implements Function<Node, Node>
             // RDF 1.0 / no lang.
             n2 = NormalizeValue.dtSimpleLiteral.handle(node, node.getLiteralLexicalForm(), null) ;
         } else {
-            // Dataype, not rdf:langString (RDF 1.1).
+            // Datatype, not rdf:langString (RDF 1.1).
             DatatypeHandler handler = dispatch.get(dt) ;
             if ( handler == null )
                 return node ;
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/engine/optimizer/StatsMatcher.java b/jena-arq/src/main/java/org/apache/jena/sparql/engine/optimizer/StatsMatcher.java
index b56a91246a..9a333310f1 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/engine/optimizer/StatsMatcher.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/engine/optimizer/StatsMatcher.java
@@ -132,7 +132,7 @@ public final class StatsMatcher {
             // (<uri> weight)
             Node n = pat.getNode();
             if ( !n.isURI() ) {
-                log.warn("Not a preicate URI: " + pat.toString());
+                log.warn("Not a predicate URI: " + pat.toString());
                 return;
             }
             addAbbreviation(elt);
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/StringUtils.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/StringUtils.java
index dc40a3e2da..105f84bf91 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/util/StringUtils.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/StringUtils.java
@@ -36,7 +36,7 @@ public class StringUtils
     {
         return integerFormat.format(v) ;
     }
-    
+
     static FastDateFormat dateTimeFormat = FastDateFormat.getInstance( "yyyy/MM/dd HH:mm:ss") ;
     public static String str(Date date)
     {
@@ -48,19 +48,19 @@ public class StringUtils
     {
         return decimalFormat.format(value) ;
     }
-    
+
     public static String str(double value)
     {
         return decimalFormat.format(value) ;
     }
-    
+
     public static <T> String str(T[] array)
     {
         return Arrays.asList(array).toString() ;
     }
 
-    private static Pattern p = Pattern.compile("http:[^ \n]*[#/]([^/ \n]*)") ;
-    /** Abbreviate, crudely, URI in strings, leaving only their last component. */ 
+    private static Pattern p = Pattern.compile("https?:[^ \n]*[#/]([^/ \n]*)") ;
+    /** Abbreviate, crudely, URI in strings, leaving only their last component. */
     public static String printAbbrev(Object obj)
     {
         if ( obj==null )
@@ -68,8 +68,8 @@ public class StringUtils
         String x = obj.toString() ;
         return p.matcher(x).replaceAll("::$1") ;
     }
-    
-    /** Abbreviate, crudely, URI in strings, leaving only their last component. */ 
+
+    /** Abbreviate, crudely, URI in strings, leaving only their last component. */
     public static <T> String printAbbrevList(List<T> objs)
     {
         String x = Iter.asString(objs.iterator(), "\n") ;
diff --git a/jena-arq/src/test/java/org/apache/jena/riot/process/TestNormalization.java b/jena-arq/src/test/java/org/apache/jena/riot/process/TestNormalization.java
index 171323d1cb..58ebc8d842 100644
--- a/jena-arq/src/test/java/org/apache/jena/riot/process/TestNormalization.java
+++ b/jena-arq/src/test/java/org/apache/jena/riot/process/TestNormalization.java
@@ -37,7 +37,7 @@ public class TestNormalization
     @Test public void normalize_int_09()        { normalize("+00", "0") ; }
     @Test public void normalize_int_10()        { normalize("-0", "0") ; }
     @Test public void normalize_int_11()        { normalize("-000", "0") ; }
-    
+
     // Subtypes of integer
     @Test public void normalize_int_20()        { normalize("'-000'^^xsd:int", "'0'^^xsd:int") ; }
     @Test public void normalize_int_21()        { normalize("'0'^^xsd:int", "'0'^^xsd:int") ; }
@@ -45,7 +45,7 @@ public class TestNormalization
     @Test public void normalize_int_23()        { normalize("'0100'^^xsd:unsignedInt", "'100'^^xsd:unsignedInt") ; }
     @Test public void normalize_int_24()        { normalize("'-100'^^xsd:nonPositiveInteger", "'-100'^^xsd:nonPositiveInteger") ; }
     @Test public void normalize_int_25()        { normalize("'+100'^^xsd:positiveInteger", "'100'^^xsd:positiveInteger") ; }
-    
+
     @Test public void normalize_decimal_01()    { normalize("0.0", "0.0") ; }
     @Test public void normalize_decimal_02()    { normalize("'0'^^xsd:decimal", "0.0") ; }
     @Test public void normalize_decimal_03()    { normalize("1.0", "1.0") ; }
@@ -63,7 +63,7 @@ public class TestNormalization
     @Test public void normalize_decimal_13()    { normalize("-1.000100", "-1.0001") ; }
     @Test public void normalize_decimal_14()    { normalize("'-1'^^xsd:decimal", "-1.0") ; }
     @Test public void normalize_decimal_15()    { normalize("'0'^^xsd:decimal", "0.0") ; }
-    
+
     // Check - what about exponent normalization?
     @Test public void normalize_double_01()     { normalize("1e0", "1.0E0") ; }
     @Test public void normalize_double_02()     { normalize("0e0", "0.0E0") ; }
@@ -79,24 +79,23 @@ public class TestNormalization
     @Test public void normalize_double_15()     { normalize("-12345.6789e+9", "-1.23456789E13") ; }
     @Test public void normalize_double_16()     { normalize("+12345.6789e-9", "1.23456789E-5") ; }
     @Test public void normalize_double_17()     { normalize("-12345.6789e-9", "-1.23456789E-5") ; }
-    
+
     @Test public void normalize_datetime_01()   { normalizeDT("1984-01-01T07:07:07",    "1984-01-01T07:07:07") ; }
     @Test public void normalize_datetime_02()   { normalizeDT("1984-01-01T07:07:07.0",  "1984-01-01T07:07:07") ; }
     @Test public void normalize_datetime_03()   { normalizeDT("1984-01-01T07:07:07.00", "1984-01-01T07:07:07") ; }
     @Test public void normalize_datetime_04()   { normalizeDT("1984-01-01T07:07:07.01", "1984-01-01T07:07:07.01") ; }
     @Test public void normalize_datetime_05()   { normalizeDT("1984-01-01T07:07:07.010","1984-01-01T07:07:07.01") ; }
-    
+
     @Test public void normalize_boolean_01()    { normalize("'true'^^xsd:boolean",  "'true'^^xsd:boolean") ; }
     @Test public void normalize_boolean_02()    { normalize("'false'^^xsd:boolean", "'false'^^xsd:boolean") ; }
     @Test public void normalize_boolean_03()    { normalize("'1'^^xsd:boolean",     "'true'^^xsd:boolean") ; }
     @Test public void normalize_boolean_04()    { normalize("'0'^^xsd:boolean",     "'false'^^xsd:boolean") ; }
-    
+
     @Test public void normalize_lang_01()       { normalizeLang("''", "''") ; }
     @Test public void normalize_lang_02()       { normalizeLang("'abc'", "'abc'") ; }
     @Test public void normalize_lang_03()       { normalizeLang("'abc'@EN", "'abc'@en") ; }
-    @Test public void normalize_lang_04()       { normalizeLang("'abc'@EN-UK", "'abc'@en-UK") ; }
-    @Test public void normalize_lang_05()       { normalizeLang("'abc'@EN", "'abc'@EN", false) ; }
-    @Test public void normalize_lang_06()       { normalizeLang("'abc'@EN-UK", "'abc'@en-uk", false) ; }
+    @Test public void normalize_lang_04()       { normalizeLang("'abc'@EN-GB", "'abc'@en-GB") ; }
+    @Test public void normalize_lang_05()       { normalizeLang("'abc'@EN-LATN-GB", "'abc'@en-Latn-GB") ; }
 
     private static void normalize(String input, String expected) {
         Node n1 = NodeFactoryExtra.parseNode(input);
@@ -111,7 +110,7 @@ public class TestNormalization
 
     private static void normalizeLang(String input, String expected)
     { normalizeLang(input, expected, true) ; }
-    
+
     private static void normalizeLang(String input, String expected, boolean correct) {
         Node n1 = NodeFactoryExtra.parseNode(input);
         Node n2 = CanonicalizeLiteral.get().apply(n1);
@@ -124,7 +123,7 @@ public class TestNormalization
             assertNotEquals("Invalid canonicalization (node)", n3, n2);
         }
     }
-    
+
     private static void normalizeDT(String input, String expected) {
         normalize("'" + input + "'^^xsd:dateTime", "'" + expected + "'^^xsd:dateTime");
     }
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions.java b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions.java
index e3282f8964..245307a982 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExpressions.java
@@ -346,9 +346,29 @@ public class TestExpressions
     @Test public void boolean_126() { testBoolean("datatype('fred') = <"+XSD.xstring.getURI()+">", true) ; }
     @Test public void boolean_127() { testBoolean("datatype('fred'^^<urn:test:foo>) = <urn:test:foo>", true) ; }
     @Test public void boolean_128() { testBoolean("datatype('fred'^^<foo>) = <Foo>", false) ; }
-    @Test public void string_15() { testString("lang('fred'@en)", "en") ; }
-    @Test public void string_16() { testString("lang('fred'@en-uk)", "en-uk") ; }
-    @Test public void string_17() { testString("lang('fred')", "") ; }
+
+    @Test public void lang_01() { testString("LANG('tea time'@en)", "en") ; }
+    // Aside For some strange reason, the language code is GB not UK.
+    // The state is UK! "The United Kingdom of Great Britain and Norther Ireland."
+    // The four countries England, Scotland, Wales and Northern Ireland (since 1922).
+    // It's complicated: https://en.wikipedia.org/wiki/United_Kingdom
+    @Test public void lang_02() { testString("LANG('tea time'@en-gb)", "en-GB") ; }
+    @Test public void lang_03() { testString("LANG('tea time')", "") ; }
+
+    @Test public void langmatches_01() { testBoolean("LANGMATCHES('EN', 'en')", true) ; }
+    @Test public void langmatches_02() { testBoolean("LANGMATCHES('en', 'en')", true) ; }
+    @Test public void langmatches_03() { testBoolean("LANGMATCHES('EN', 'EN')", true) ; }
+    @Test public void langmatches_04() { testBoolean("LANGMATCHES('en', 'EN')", true) ; }
+    @Test public void langmatches_05() { testBoolean("LANGMATCHES('fr', 'EN')", false) ; }
+
+    @Test public void langmatches_06() { testBoolean("LANGMATCHES('en', 'en-gb')", false) ; }
+    @Test public void langmatches_07() { testBoolean("LANGMATCHES('en-GB', 'en-GB')", true) ; }
+    @Test public void langmatches_08() { testBoolean("LANGMATCHES('en-Latn-gb', 'en-Latn')", true) ; }
+    @Test public void langmatches_09() { testBoolean("LANGMATCHES('en-gb', 'en-Latn')", false) ; }
+
+    @Test public void langmatches_10() { testBoolean("LANGMATCHES('', '*')", false) ; }
+    @Test public void langmatches_11() { testBoolean("LANGMATCHES('en-us', '*')", true) ; }
+
     @Test public void boolean_129() { testBoolean("isURI(?x)", true, env) ; }
     @Test public void boolean_130() { testBoolean("isURI(?a)", false, env) ; }
     @Test public void boolean_131() { testBoolean("isURI(?b)", false, env) ; }
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeFunctions.java b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeFunctions.java
index e3f0bf5fd7..7028e1f26e 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeFunctions.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeFunctions.java
@@ -16,88 +16,88 @@
  * limitations under the License.
  */
 
-package org.apache.jena.sparql.expr ;
+package org.apache.jena.sparql.expr;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.*;
 
-import org.apache.jena.datatypes.xsd.XSDDatatype ;
-import org.apache.jena.graph.Node ;
-import org.apache.jena.graph.NodeFactory ;
+import org.apache.jena.datatypes.xsd.XSDDatatype;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.NodeFactory;
 import org.apache.jena.query.ARQ;
-import org.apache.jena.sparql.expr.nodevalue.NodeFunctions ;
-import org.apache.jena.sparql.graph.NodeConst ;
+import org.apache.jena.sparql.expr.nodevalue.NodeFunctions;
+import org.apache.jena.sparql.graph.NodeConst;
 import org.apache.jena.sparql.sse.SSE;
-import org.apache.jena.vocabulary.RDF ;
-import org.apache.jena.vocabulary.XSD ;
-import org.junit.Test ;
+import org.apache.jena.vocabulary.RDF;
+import org.apache.jena.vocabulary.XSD;
+import org.junit.Test;
 
 public class TestNodeFunctions {
-    private static final double accuracyExact = 0.0d ;
-    private static final double accuracyClose = 0.000001d ;
+    private static final double accuracyExact = 0.0d;
+    private static final double accuracyClose = 0.000001d;
 
     @Test public void testSameTerm1() {
-        Node n1 = NodeFactory.createLiteralString("xyz") ;
-        Node n2 = NodeFactory.createLiteralString("xyz") ;
-        assertTrue(NodeFunctions.sameTerm(n1, n2)) ;
+        Node n1 = NodeFactory.createLiteralString("xyz");
+        Node n2 = NodeFactory.createLiteralString("xyz");
+        assertTrue(NodeFunctions.sameTerm(n1, n2));
     }
 
     @Test public void testSameTerm2() {
-        Node n1 = NodeFactory.createLiteralString("xyz") ;
-        Node n2 = NodeFactory.createLiteralString("abc") ;
-        assertFalse(NodeFunctions.sameTerm(n1, n2)) ;
+        Node n1 = NodeFactory.createLiteralString("xyz");
+        Node n2 = NodeFactory.createLiteralString("abc");
+        assertFalse(NodeFunctions.sameTerm(n1, n2));
     }
 
     @Test public void testSameTerm3() {
-        Node n1 = NodeFactory.createLiteralString("xyz") ;
-        Node n2 = NodeFactory.createURI("xyz") ;
-        assertFalse(NodeFunctions.sameTerm(n1, n2)) ;
+        Node n1 = NodeFactory.createLiteralString("xyz");
+        Node n2 = NodeFactory.createURI("xyz");
+        assertFalse(NodeFunctions.sameTerm(n1, n2));
     }
 
     @Test public void testSameTerm4() {
-        Node n1 = NodeFactory.createLiteralString("xyz") ;
-        Node n2 = NodeFactory.createLiteral("xyz", XSDDatatype.XSDstring) ;
-        assertTrue(NodeFunctions.sameTerm(n1, n2)) ;
+        Node n1 = NodeFactory.createLiteralString("xyz");
+        Node n2 = NodeFactory.createLiteral("xyz", XSDDatatype.XSDstring);
+        assertTrue(NodeFunctions.sameTerm(n1, n2));
     }
 
     @Test public void testSameTerm5() {
-        Node n1 = NodeFactory.createLiteralLang("xyz", "en") ;
-        Node n2 = NodeFactory.createLiteralString("xyz") ;
-        assertFalse(NodeFunctions.sameTerm(n1, n2)) ;
+        Node n1 = NodeFactory.createLiteralLang("xyz", "en");
+        Node n2 = NodeFactory.createLiteralString("xyz");
+        assertFalse(NodeFunctions.sameTerm(n1, n2));
     }
 
     @Test public void testSameTerm6() {
-        Node n1 = NodeFactory.createLiteralLang("xyz", "en") ;
-        Node n2 = NodeFactory.createLiteralLang("xyz", "EN") ;
-        assertTrue(NodeFunctions.sameTerm(n1, n2)) ;
+        Node n1 = NodeFactory.createLiteralLang("xyz", "en");
+        Node n2 = NodeFactory.createLiteralLang("xyz", "EN");
+        assertTrue(NodeFunctions.sameTerm(n1, n2));
     }
 
     @Test public void testRDFtermEquals1() {
-        Node n1 = NodeFactory.createURI("xyz") ;
-        Node n2 = NodeFactory.createLiteralString("xyz") ;
-        assertFalse(NodeFunctions.rdfTermEquals(n1, n2)) ;
+        Node n1 = NodeFactory.createURI("xyz");
+        Node n2 = NodeFactory.createLiteralString("xyz");
+        assertFalse(NodeFunctions.rdfTermEquals(n1, n2));
     }
 
     @Test public void testRDFtermEquals2() {
-        Node n1 = NodeFactory.createLiteralLang("xyz", "en") ;
-        Node n2 = NodeFactory.createLiteralLang("xyz", "EN") ;
-        assertTrue(NodeFunctions.rdfTermEquals(n1, n2)) ;
+        Node n1 = NodeFactory.createLiteralLang("xyz", "en");
+        Node n2 = NodeFactory.createLiteralLang("xyz", "EN");
+        assertTrue(NodeFunctions.rdfTermEquals(n1, n2));
     }
 
     @Test(expected=ExprEvalException.class)
     public void testRDFtermEquals3() {
         // Unextended - not known to be same (no language tag support).
-        Node n1 = NodeFactory.createLiteralString("xyz") ;
-        Node n2 = NodeFactory.createLiteralLang("xyz", "en") ;
+        Node n1 = NodeFactory.createLiteralString("xyz");
+        Node n2 = NodeFactory.createLiteralLang("xyz", "en");
         NodeFunctions.rdfTermEquals(n1, n2);
     }
 
     @Test(expected=ExprEvalException.class)
     public void testRDFtermEquals4() {
         // Unextended - not known to be same.
-        Node n1 = NodeFactory.createLiteral("123", XSDDatatype.XSDinteger) ;
-        Node n2 = NodeFactory.createLiteral("456", XSDDatatype.XSDinteger) ;
+        Node n1 = NodeFactory.createLiteral("123", XSDDatatype.XSDinteger);
+        Node n2 = NodeFactory.createLiteral("456", XSDDatatype.XSDinteger);
         assertTrue(NodeFunctions.rdfTermEquals(n1, n2));
     }
 
@@ -139,21 +139,21 @@ public class TestNodeFunctions {
     }
 
     @Test public void testStr1() {
-        NodeValue nv = NodeValue.makeNodeInteger(56) ;
-        NodeValue s = NodeFunctions.str(nv) ;
-        assertEquals("56", s.getString()) ;
+        NodeValue nv = NodeValue.makeNodeInteger(56);
+        NodeValue s = NodeFunctions.str(nv);
+        assertEquals("56", s.getString());
     }
 
     @Test public void testStr2() {
-        NodeValue nv = NodeValue.makeInteger(56) ;
-        NodeValue s = NodeFunctions.str(nv) ;
-        assertEquals("56", s.getString()) ;
+        NodeValue nv = NodeValue.makeInteger(56);
+        NodeValue s = NodeFunctions.str(nv);
+        assertEquals("56", s.getString());
     }
 
     @Test public void testStr3() {
-        NodeValue nv = NodeValue.makeNode("abc", "fr", (String)null) ;
-        NodeValue s = NodeFunctions.str(nv) ;
-        assertEquals("abc", s.getString()) ;
+        NodeValue nv = NodeValue.makeNode("abc", "fr", (String)null);
+        NodeValue s = NodeFunctions.str(nv);
+        assertEquals("abc", s.getString());
     }
 
     // STR(BNODE())/strict
@@ -163,8 +163,8 @@ public class TestNodeFunctions {
         try {
             ARQ.set(ARQ.strictSPARQL, true);
             try {
-                Node n = NodeFactory.createBlankNode() ;
-                String s = NodeFunctions.str(n) ;
+                Node n = NodeFactory.createBlankNode();
+                String s = NodeFunctions.str(n);
                 fail("NodeFunctions.str did not fail");
             } catch (ExprEvalException ex) {}
         } finally {
@@ -175,226 +175,227 @@ public class TestNodeFunctions {
     // STR(BNODE())/notStrict
     @Test
     public void testStr5() {
-        Node n = NodeFactory.createBlankNode() ;
-        String s = NodeFunctions.str(n) ;
+        Node n = NodeFactory.createBlankNode();
+        String s = NodeFunctions.str(n);
         assertNotNull(s);
         assertEquals("_:"+n.getBlankNodeLabel(), s);
     }
 
     @Test public void testDatatype1() {
-        NodeValue nv = NodeValue.makeInteger(5) ;
-        Node n = nv.asNode() ;
-        Node r = NodeFunctions.datatype(n) ;
-        assertEquals(XSD.integer.asNode(), r) ;
+        NodeValue nv = NodeValue.makeInteger(5);
+        Node n = nv.asNode();
+        Node r = NodeFunctions.datatype(n);
+        assertEquals(XSD.integer.asNode(), r);
     }
 
     @Test public void testDatatype2() {
-        NodeValue nv = NodeValue.makeInteger(5) ;
-        NodeValue r = NodeFunctions.datatype(nv) ;
-        NodeValue e = NodeValue.makeNode(XSD.integer.asNode()) ;
-        assertEquals(e, r) ;
+        NodeValue nv = NodeValue.makeInteger(5);
+        NodeValue r = NodeFunctions.datatype(nv);
+        NodeValue e = NodeValue.makeNode(XSD.integer.asNode());
+        assertEquals(e, r);
     }
 
     @Test public void testDatatype3() {
-        NodeValue nv = NodeValue.makeString("abc") ;
-        NodeValue r = NodeFunctions.datatype(nv) ;
-        NodeValue e = NodeValue.makeNode(XSD.xstring.asNode()) ;
-        assertEquals(e, r) ;
+        NodeValue nv = NodeValue.makeString("abc");
+        NodeValue r = NodeFunctions.datatype(nv);
+        NodeValue e = NodeValue.makeNode(XSD.xstring.asNode());
+        assertEquals(e, r);
     }
 
     @Test public void testDatatype4() {
-        NodeValue nv = NodeValue.makeNode("abc", "fr", (String)null) ;
+        NodeValue nv = NodeValue.makeNode("abc", "fr", (String)null);
         // SPARQL 1.0
         // try {
-        //   NodeValue r = NodeFunctions.datatype(nv) ;
-        //   fail("Expect a type exception but call succeeded") ;
+        //   NodeValue r = NodeFunctions.datatype(nv);
+        //   fail("Expect a type exception but call succeeded");
         // }
         // catch (ExprTypeException ex) {}
         // SPARQL 1.1 / RDF 1.1
-        NodeValue r = NodeFunctions.datatype(nv) ;
-        NodeValue e = NodeValue.makeNode(NodeConst.rdfLangString) ;
-        assertEquals(e, r) ;
+        NodeValue r = NodeFunctions.datatype(nv);
+        NodeValue e = NodeValue.makeNode(NodeConst.rdfLangString);
+        assertEquals(e, r);
     }
 
     @Test(expected=ExprTypeException.class)
     public void testDatatype5() {
-        NodeValue nv = NodeValue.makeNode(NodeFactory.createURI("http://example")) ;
-        NodeValue r = NodeFunctions.datatype(nv) ;
+        NodeValue nv = NodeValue.makeNode(NodeFactory.createURI("http://example"));
+        NodeValue r = NodeFunctions.datatype(nv);
     }
 
     @Test(expected=ExprTypeException.class)
     public void testDatatype6() {
-        NodeValue nv = NodeValue.makeNode(NodeFactory.createBlankNode()) ;
-        NodeValue r = NodeFunctions.datatype(nv) ;
+        NodeValue nv = NodeValue.makeNode(NodeFactory.createBlankNode());
+        NodeValue r = NodeFunctions.datatype(nv);
     }
 
     @Test public void testLang1() {
-        Node n = NodeFactory.createLiteralLang("abc", "en-gb") ;
-        assertEquals("en-gb", NodeFunctions.lang(n)) ;
+        Node n = NodeFactory.createLiteralLang("abc", "en-gb");
+        // Jena5: Language tag formatting.
+        assertEquals("en-GB", NodeFunctions.lang(n));
     }
 
     @Test public void testLang2() {
-        NodeValue nv = NodeValue.makeNode("abc", "en", (String)null) ;
-        NodeValue r = NodeFunctions.lang(nv) ;
-        NodeValue e = NodeValue.makeString("en") ;
-        assertEquals(e, r) ;
+        NodeValue nv = NodeValue.makeNode("abc", "en", (String)null);
+        NodeValue r = NodeFunctions.lang(nv);
+        NodeValue e = NodeValue.makeString("en");
+        assertEquals(e, r);
     }
 
     @Test public void testLang3() {
-        NodeValue nv = NodeValue.makeInteger(5) ;
-        NodeValue r = NodeFunctions.lang(nv) ;
-        NodeValue e = NodeValue.makeString("") ;
-        assertEquals(e, r) ;
+        NodeValue nv = NodeValue.makeInteger(5);
+        NodeValue r = NodeFunctions.lang(nv);
+        NodeValue e = NodeValue.makeString("");
+        assertEquals(e, r);
     }
 
     @Test public void testLang4() {
-        NodeValue nv = NodeValue.makeNode(NodeFactory.createLiteralString("simple")) ;
-        NodeValue r = NodeFunctions.lang(nv) ;
-        NodeValue e = NodeValue.makeString("") ;
-        assertEquals(e, r) ;
+        NodeValue nv = NodeValue.makeNode(NodeFactory.createLiteralString("simple"));
+        NodeValue r = NodeFunctions.lang(nv);
+        NodeValue e = NodeValue.makeString("");
+        assertEquals(e, r);
     }
 
     @Test(expected=ExprTypeException.class)
     public void testLang5() {
-        NodeValue nv = NodeValue.makeNode(NodeFactory.createURI("http://example/")) ;
-        NodeValue r = NodeFunctions.lang(nv) ;
+        NodeValue nv = NodeValue.makeNode(NodeFactory.createURI("http://example/"));
+        NodeValue r = NodeFunctions.lang(nv);
     }
 
     @Test public void testLangMatches1() {
-        NodeValue nv = NodeValue.makeString("en") ;
-        NodeValue pat = NodeValue.makeString("en") ;
-        NodeValue r = NodeFunctions.langMatches(nv, pat) ;
-        assertEquals(NodeValue.TRUE, r) ;
-        assertFalse(NodeValue.FALSE.equals(r)) ;
+        NodeValue nv = NodeValue.makeString("en");
+        NodeValue pat = NodeValue.makeString("en");
+        NodeValue r = NodeFunctions.langMatches(nv, pat);
+        assertEquals(NodeValue.TRUE, r);
+        assertFalse(NodeValue.FALSE.equals(r));
     }
 
     @Test public void testLangMatches2() {
-        NodeValue nv = NodeValue.makeString("en") ;
-        NodeValue pat = NodeValue.makeString("fr") ;
-        NodeValue r = NodeFunctions.langMatches(nv, pat) ;
-        assertEquals(NodeValue.FALSE, r) ;
-        assertFalse(NodeValue.TRUE.equals(r)) ;
+        NodeValue nv = NodeValue.makeString("en");
+        NodeValue pat = NodeValue.makeString("fr");
+        NodeValue r = NodeFunctions.langMatches(nv, pat);
+        assertEquals(NodeValue.FALSE, r);
+        assertFalse(NodeValue.TRUE.equals(r));
     }
 
     @Test public void testLangMatches3() {
-        NodeValue nv = NodeValue.makeString("en-gb") ;
-        NodeValue pat = NodeValue.makeString("en-gb") ;
-        NodeValue r = NodeFunctions.langMatches(nv, pat) ;
-        assertEquals(NodeValue.TRUE, r) ;
+        NodeValue nv = NodeValue.makeString("en-gb");
+        NodeValue pat = NodeValue.makeString("en-gb");
+        NodeValue r = NodeFunctions.langMatches(nv, pat);
+        assertEquals(NodeValue.TRUE, r);
     }
 
     @Test public void testLangMatches4() {
-        NodeValue nv = NodeValue.makeString("en-gb") ;
-        NodeValue pat = NodeValue.makeString("en") ;
-        NodeValue r = NodeFunctions.langMatches(nv, pat) ;
-        assertEquals(NodeValue.TRUE, r) ;
+        NodeValue nv = NodeValue.makeString("en-gb");
+        NodeValue pat = NodeValue.makeString("en");
+        NodeValue r = NodeFunctions.langMatches(nv, pat);
+        assertEquals(NodeValue.TRUE, r);
     }
 
     @Test public void testLangMatches5() {
-        NodeValue nv = NodeValue.makeString("abc") ;
-        NodeValue pat = NodeValue.makeString("*") ;
-        NodeValue r = NodeFunctions.langMatches(nv, pat) ;
-        assertEquals(NodeValue.TRUE, r) ;
+        NodeValue nv = NodeValue.makeString("abc");
+        NodeValue pat = NodeValue.makeString("*");
+        NodeValue r = NodeFunctions.langMatches(nv, pat);
+        assertEquals(NodeValue.TRUE, r);
     }
 
     @Test public void testLangMatches6() {
-        NodeValue nv = NodeValue.makeString("x-y-z") ;
-        NodeValue pat = NodeValue.makeString("x") ;
-        NodeValue r = NodeFunctions.langMatches(nv, pat) ;
-        assertEquals(NodeValue.TRUE, r) ;
+        NodeValue nv = NodeValue.makeString("x-y-z");
+        NodeValue pat = NodeValue.makeString("x");
+        NodeValue r = NodeFunctions.langMatches(nv, pat);
+        assertEquals(NodeValue.TRUE, r);
     }
 
     @Test public void testLangMatches7() {
-        NodeValue nv = NodeValue.makeString("x") ;
-        NodeValue pat = NodeValue.makeString("x-y-z") ;
-        NodeValue r = NodeFunctions.langMatches(nv, pat) ;
-        assertEquals(NodeValue.FALSE, r) ;
+        NodeValue nv = NodeValue.makeString("x");
+        NodeValue pat = NodeValue.makeString("x-y-z");
+        NodeValue r = NodeFunctions.langMatches(nv, pat);
+        assertEquals(NodeValue.FALSE, r);
     }
 
     @Test public void testLangMatches8() {
         // The language tag of a plain literal is ""
         // A language tag is not allowed to be the empty string (by RFC 3066)
-        NodeValue nv = NodeValue.makeString("") ;
-        NodeValue pat = NodeValue.makeString("*") ;
-        NodeValue r = NodeFunctions.langMatches(nv, pat) ;
-        assertEquals(NodeValue.FALSE, r) ;
+        NodeValue nv = NodeValue.makeString("");
+        NodeValue pat = NodeValue.makeString("*");
+        NodeValue r = NodeFunctions.langMatches(nv, pat);
+        assertEquals(NodeValue.FALSE, r);
     }
 
     @Test
     public void testLangMatches9() {
         // The language-match of "" is not a legal by RFC 4647 but useful for language tags of ""
-        NodeValue nv = NodeValue.makeString("") ;
-        NodeValue pat = NodeValue.makeString("") ;
-        NodeValue r = NodeFunctions.langMatches(nv, pat) ;
-        assertEquals(NodeValue.TRUE, r) ;
+        NodeValue nv = NodeValue.makeString("");
+        NodeValue pat = NodeValue.makeString("");
+        NodeValue r = NodeFunctions.langMatches(nv, pat);
+        assertEquals(NodeValue.TRUE, r);
     }
 
     @Test
     public void testLangMatches10() {
         // The language-match of "" is not a legal by RFC 4647 but useful for language tags of ""
-        NodeValue nv = NodeValue.makeString("en") ;
-        NodeValue pat = NodeValue.makeString("") ;
-        NodeValue r = NodeFunctions.langMatches(nv, pat) ;
-        assertEquals(NodeValue.FALSE, r) ;
+        NodeValue nv = NodeValue.makeString("en");
+        NodeValue pat = NodeValue.makeString("");
+        NodeValue r = NodeFunctions.langMatches(nv, pat);
+        assertEquals(NodeValue.FALSE, r);
     }
 
     @Test public void testIsIRI_1() {
-        NodeValue nv = NodeValue.makeNode(NodeFactory.createURI("http://example/")) ;
-        NodeValue r = NodeFunctions.isIRI(nv) ;
-        assertEquals(NodeValue.TRUE, r) ;
+        NodeValue nv = NodeValue.makeNode(NodeFactory.createURI("http://example/"));
+        NodeValue r = NodeFunctions.isIRI(nv);
+        assertEquals(NodeValue.TRUE, r);
     }
 
     @Test public void testIsIRI_2() {
-        NodeValue nv = NodeValue.makeNode(NodeFactory.createLiteralString("http://example/")) ;
-        NodeValue r = NodeFunctions.isIRI(nv) ;
-        assertEquals(NodeValue.FALSE, r) ;
+        NodeValue nv = NodeValue.makeNode(NodeFactory.createLiteralString("http://example/"));
+        NodeValue r = NodeFunctions.isIRI(nv);
+        assertEquals(NodeValue.FALSE, r);
     }
 
     @Test public void testIsBlank1() {
-        NodeValue nv = NodeValue.makeNode(NodeFactory.createBlankNode()) ;
-        NodeValue r = NodeFunctions.isBlank(nv) ;
-        assertEquals(NodeValue.TRUE, r) ;
+        NodeValue nv = NodeValue.makeNode(NodeFactory.createBlankNode());
+        NodeValue r = NodeFunctions.isBlank(nv);
+        assertEquals(NodeValue.TRUE, r);
     }
 
     @Test public void testIsBlank2() {
-        NodeValue nv = NodeValue.makeNode(NodeFactory.createLiteralString("xyz")) ;
-        NodeValue r = NodeFunctions.isBlank(nv) ;
-        assertEquals(NodeValue.FALSE, r) ;
+        NodeValue nv = NodeValue.makeNode(NodeFactory.createLiteralString("xyz"));
+        NodeValue r = NodeFunctions.isBlank(nv);
+        assertEquals(NodeValue.FALSE, r);
     }
 
     @Test public void testIsBlank3() {
-        NodeValue nv = NodeValue.makeNode(NodeFactory.createURI("http://example/")) ;
-        NodeValue r = NodeFunctions.isBlank(nv) ;
-        assertEquals(NodeValue.FALSE, r) ;
+        NodeValue nv = NodeValue.makeNode(NodeFactory.createURI("http://example/"));
+        NodeValue r = NodeFunctions.isBlank(nv);
+        assertEquals(NodeValue.FALSE, r);
 
     }
 
     @Test public void testIsLiteral1() {
-        NodeValue nv = NodeValue.makeNode(NodeFactory.createLiteralString("xyz")) ;
-        NodeValue r = NodeFunctions.isLiteral(nv) ;
-        assertEquals(NodeValue.TRUE, r) ;
+        NodeValue nv = NodeValue.makeNode(NodeFactory.createLiteralString("xyz"));
+        NodeValue r = NodeFunctions.isLiteral(nv);
+        assertEquals(NodeValue.TRUE, r);
     }
 
     @Test public void testIsLiteral2() {
-        NodeValue nv = NodeValue.makeNode(NodeFactory.createURI("http://example/")) ;
-        NodeValue r = NodeFunctions.isLiteral(nv) ;
-        assertEquals(NodeValue.FALSE, r) ;
+        NodeValue nv = NodeValue.makeNode(NodeFactory.createURI("http://example/"));
+        NodeValue r = NodeFunctions.isLiteral(nv);
+        assertEquals(NodeValue.FALSE, r);
     }
 
     @Test public void testCheckAndGetStringLiteral1() {
-        NodeValue nv = NodeValue.makeNode("abc", XSDDatatype.XSDstring) ;
+        NodeValue nv = NodeValue.makeNode("abc", XSDDatatype.XSDstring);
         Node n = NodeFunctions.checkAndGetStringLiteral("Test", nv);
         assertEquals( "abc", n.getLiteralLexicalForm());
     }
 
     @Test public void testCheckAndGetStringLiteral2() {
-        NodeValue nv = NodeValue.makeNode("abc", XSDDatatype.XSDnormalizedString) ;
+        NodeValue nv = NodeValue.makeNode("abc", XSDDatatype.XSDnormalizedString);
         Node n = NodeFunctions.checkAndGetStringLiteral("Test", nv);
         assertEquals( "abc", n.getLiteralLexicalForm());
     }
 
     @Test public void testCheckAndGetStringLiteral3() {
-        NodeValue nv = NodeValue.makeString("abc") ;
+        NodeValue nv = NodeValue.makeString("abc");
         Node n = NodeFunctions.checkAndGetStringLiteral("Test", nv);
         assertEquals( "abc", n.getLiteralLexicalForm());
     }
@@ -402,7 +403,7 @@ public class TestNodeFunctions {
     @Test(expected=ExprEvalException.class)
     public void testCheckAndGetStringLiteral4() {
         // The form "abc"^^rdf:langString (no lang tag) is not derived from xsd:string.
-        NodeValue nv = NodeValue.makeNode("abc", RDF.dtLangString) ;
+        NodeValue nv = NodeValue.makeNode("abc", RDF.dtLangString);
         Node n = NodeFunctions.checkAndGetStringLiteral("Test", nv);
         assertEquals( "abc", n.getLiteralLexicalForm());
     }
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeValue.java b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeValue.java
index ffd01acb8d..1074c210ad 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeValue.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeValue.java
@@ -1123,7 +1123,8 @@ public class TestNodeValue
         Node n2 = org.apache.jena.graph.NodeFactory.createLiteralLang("xyz", "EN");
         NodeValue nv2 = NodeValue.makeNode(n2);
         assertTrue(NodeValue.sameValueAs(nv1, nv2));
-        assertFalse(nv1.equals(nv2));
+        // Jena5 - langtags are formatted on creation so node are unique upto case.
+        assertTrue(nv1.equals(nv2));
     }
 
     @Test
@@ -1140,7 +1141,8 @@ public class TestNodeValue
         NodeValue nv1 = parse("'xyz'@en");
         NodeValue nv2 = parse("'xyz'@EN");
         assertFalse(NodeValue.notSameValueAs(nv1, nv2));
-        assertFalse(nv1.equals(nv2));
+        // Jena5 - langtags are formatted on creation so node are unique upto case.
+        assertTrue(nv1.equals(nv2));
     }
 
     //Compare value first and then language tag
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestOrdering.java b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestOrdering.java
index 20f30731b9..484d4c29ca 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestOrdering.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestOrdering.java
@@ -175,8 +175,9 @@ public class TestOrdering {
         NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteralLang("abc", "en"));
         NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteralLang("abc", "EN"));
 
+        // Jena5: same langtag (there are the same RDF term)
         int x = NodeCmp.compareRDFTerms(nv1.asNode(), nv2.asNode());
-        assertTrue("Lang tags should sort by case", Expr.CMP_GREATER == x);
+        assertTrue("Lang tags should sort by case", Expr.CMP_EQUAL == x);
     }
 
     @Test
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestSortOrdering.java b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestSortOrdering.java
index fac929a908..724623d45e 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestSortOrdering.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestSortOrdering.java
@@ -93,12 +93,13 @@ public class TestSortOrdering {
         test(s1, s2, s3);
     }
 
-    @Test public void ordering_13() {
-        String s1 = "'a'@EN";
-        String s2 = "'a'@En";
-        String s3 = "'a'@en";
-        test(s1, s2, s3);
-    }
+//    // Jena5 : those are the same RDF term
+//    @Test public void ordering_13() {
+//        String s1 = "'a'@EN";
+//        String s2 = "'a'@En";
+//        String s3 = "'a'@en";
+//        test(s1, s2, s3);
+//    }
 
     @Test public void ordering_20() {
         String s1 = "<<:s1 :p :o>>";
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSet.java b/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSet.java
index 512473acdf..107d50ecff 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSet.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSet.java
@@ -537,10 +537,13 @@ public class TestResultSet
     {
         ResultSetRewindable rs1 = make(StrUtils.strjoinNL(rs1$));
         ResultSetRewindable rs2 = make(StrUtils.strjoinNL(rs2$));
+
         assertTrue(ResultSetCompare.isomorphic(rs1, rs2));
         rs1.reset();
         rs2.reset();
         assertTrue(ResultSetCompare.equalsByTerm(rs1, rs2));
+        rs1.reset();
+        rs2.reset();
         assertTrue(ResultSetCompare.equalsByValue(rs1, rs2));
     }
 
diff --git a/jena-arq/testing/ARQ/Sort/sort-result-2.ttl b/jena-arq/testing/ARQ/Sort/sort-result-2.ttl
index 180db2d42f..8c22bd8547 100644
--- a/jena-arq/testing/ARQ/Sort/sort-result-2.ttl
+++ b/jena-arq/testing/ARQ/Sort/sort-result-2.ttl
@@ -1,168 +1,168 @@
-@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
-@prefix rs:  <http://www.w3.org/2001/sw/DataAccess/tests/result-set#> .
-@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
+PREFIX rs:  <http://www.w3.org/2001/sw/DataAccess/tests/result-set#>
+PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
 
-[ rdf:type           rs:ResultSet ;
-  rs:resultVariable  "v" , "x" ;
-  rs:size            "20"^^xsd:int ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/x3> ;
-                                     rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "xyz"@FR ;
+[ rdf:type           rs:ResultSet;
+  rs:resultVariable  "x" , "v";
+  rs:size            "20"^^xsd:int;
+  rs:solution        [ rs:binding  [ rs:value     "xyz"@fr;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    12
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/z1> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/x4>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     1 ;
+                                   ];
+                       rs:index    13
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "xyz"@fr;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    16
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/x2> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/x3>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "xyz"@en ;
+                                   ];
+                       rs:index    12
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "abc"^^xsd:integer;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    11
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/x7> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/y5>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "xyz"^^xsd:integer ;
+                                   ];
+                       rs:index    18
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     1;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    20
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/x6> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/z1>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "xyz" ;
+                                   ];
+                       rs:index    16
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "abc"^^<http://example/unknown>;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    7
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/y7> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/y6>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     <http://example/abc> ;
+                                   ];
+                       rs:index    17
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "xyz"^^<http://example/unknown>;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    2
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/x8> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/x8>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "xyz"^^<http://example/unknown> ;
-                                     rs:variable  "v"
-                                   ] ;
+                                   ];
                        rs:index    19
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/x1> ;
-                                     rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "xyz" ;
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "xyz";
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    6
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/y2> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/x6>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "abc"@en ;
+                                   ];
+                       rs:index    7
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     <http://example/xyz>;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    9
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/y4> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/x10>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "abc" ;
+                                   ];
+                       rs:index    3
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "abc";
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    5
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/y1> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/y4>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "abc" ;
+                                   ];
+                       rs:index    5
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     [] ;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    4
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/x4> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/x9>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "xyz"@fr ;
+                                   ];
+                       rs:index    1
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     <http://example/abc>;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    13
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/x5> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/y7>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "xyz"@EN ;
+                                   ];
+                       rs:index    2
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "xyz"@en;
                                      rs:variable  "v"
-                                   ] ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/x2>;
+                                     rs:variable  "x"
+                                   ];
                        rs:index    10
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/y6> ;
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "abc";
+                                     rs:variable  "v"
+                                   ];
+                       rs:binding  [ rs:value     <http://example/y1>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "abc"^^<http://example/unknown> ;
+                                   ];
+                       rs:index    4
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     01;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    17
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/y3> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/z2>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "abc"@EN ;
+                                   ];
+                       rs:index    14
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "1"^^xsd:decimal;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    8
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/y5> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/z3>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "abc"^^xsd:integer ;
+                                   ];
+                       rs:index    15
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "xyz"@en;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    18
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/z3> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/x5>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "1"^^xsd:decimal ;
+                                   ];
+                       rs:index    11
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "xyz";
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    15
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/z2> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/x1>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     01 ;
+                                   ];
+                       rs:index    6
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "xyz"^^xsd:integer;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    14
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/x9> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/x7>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     []  ;
+                                   ];
+                       rs:index    20
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "abc"@en;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    1
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/x10> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/y2>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     <http://example/xyz> ;
+                                   ];
+                       rs:index    8
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "abc"@en;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    3
+                                   ];
+                       rs:binding  [ rs:value     <http://example/y3>;
+                                     rs:variable  "x"
+                                   ];
+                       rs:index    9
                      ]
 ] .
diff --git a/jena-arq/testing/ARQ/Sort/sort-result-3.ttl b/jena-arq/testing/ARQ/Sort/sort-result-3.ttl
index 18b70a4056..baa865ed7b 100644
--- a/jena-arq/testing/ARQ/Sort/sort-result-3.ttl
+++ b/jena-arq/testing/ARQ/Sort/sort-result-3.ttl
@@ -1,168 +1,168 @@
-@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
-@prefix rs:  <http://www.w3.org/2001/sw/DataAccess/tests/result-set#> .
-@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
+PREFIX rs:  <http://www.w3.org/2001/sw/DataAccess/tests/result-set#>
+PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
 
-[ rdf:type           rs:ResultSet ;
-  rs:resultVariable  "v" , "x" ;
-  rs:size            "20"^^xsd:int ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/x4> ;
-                                     rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "xyz"@fr ;
+[ rdf:type           rs:ResultSet;
+  rs:resultVariable  "x" , "v";
+  rs:size            "20"^^xsd:int;
+  rs:solution        [ rs:binding  [ rs:value     "abc"@en;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    8
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/x5> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/y2>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "xyz"@EN ;
+                                   ];
+                       rs:index    12
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "1"^^xsd:decimal;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    11
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/y1> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/z3>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "abc" ;
+                                   ];
+                       rs:index    6
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "abc";
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    16
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/y6> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/y1>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "abc"^^<http://example/unknown> ;
+                                   ];
+                       rs:index    16
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "abc";
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    4
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/x1> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/y4>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "xyz" ;
+                                   ];
+                       rs:index    17
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "xyz"^^xsd:integer;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    14
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/z1> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/x7>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     1 ;
+                                   ];
+                       rs:index    1
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     01;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    5
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/y7> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/z2>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     <http://example/abc> ;
+                                   ];
+                       rs:index    7
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "xyz";
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    19
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/x9> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/x6>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     []  ;
+                                   ];
+                       rs:index    15
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     1;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    20
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/x2> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/z1>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "xyz"@en ;
+                                   ];
+                       rs:index    5
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "xyz"@en;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    10
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/x10> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/x2>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     <http://example/xyz> ;
+                                   ];
+                       rs:index    10
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "xyz"^^<http://example/unknown>;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    18
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/x7> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/x8>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "xyz"^^xsd:integer ;
+                                   ];
+                       rs:index    2
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "xyz"@en;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    1
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/y3> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/x5>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "abc"@EN ;
+                                   ];
+                       rs:index    11
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     <http://example/abc>;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    13
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/x3> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/y7>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "xyz"@FR ;
+                                   ];
+                       rs:index    19
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "abc"^^xsd:integer;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    9
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/x6> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/y5>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "xyz" ;
+                                   ];
+                       rs:index    3
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "xyz";
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    15
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/y5> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/x1>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "abc"^^xsd:integer ;
+                                   ];
+                       rs:index    14
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     [] ;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    3
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/y2> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/x9>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "abc"@en ;
+                                   ];
+                       rs:index    20
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "abc"^^<http://example/unknown>;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    12
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/z3> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/y6>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "1"^^xsd:decimal ;
+                                   ];
+                       rs:index    4
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "xyz"@fr;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    6
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/z2> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/x3>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     01 ;
+                                   ];
+                       rs:index    8
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     <http://example/xyz>;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    7
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/y4> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/x10>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "abc" ;
+                                   ];
+                       rs:index    18
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "abc"@en;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    17
-                     ] ;
-  rs:solution        [ rs:binding  [ rs:value     <http://example/x8> ;
+                                   ];
+                       rs:binding  [ rs:value     <http://example/y3>;
                                      rs:variable  "x"
-                                   ] ;
-                       rs:binding  [ rs:value     "xyz"^^<http://example/unknown> ;
+                                   ];
+                       rs:index    13
+                     ];
+  rs:solution        [ rs:binding  [ rs:value     "xyz"@fr;
                                      rs:variable  "v"
-                                   ] ;
-                       rs:index    2
+                                   ];
+                       rs:binding  [ rs:value     <http://example/x4>;
+                                     rs:variable  "x"
+                                   ];
+                       rs:index    9
                      ]
 ] .
diff --git a/jena-arq/testing/DAWG/examples/ex11.2.3.7_0.rq b/jena-arq/testing/DAWG/examples/ex11.2.3.7_0.rq
index 48f716d558..830ecc4afb 100644
--- a/jena-arq/testing/DAWG/examples/ex11.2.3.7_0.rq
+++ b/jena-arq/testing/DAWG/examples/ex11.2.3.7_0.rq
@@ -2,4 +2,4 @@ PREFIX foaf: <http://xmlns.com/foaf/0.1/>
 SELECT ?name ?mbox
  WHERE { ?x foaf:name  ?name ;
             foaf:mbox  ?mbox .
-         FILTER ( lang(?name) = "ES" ) }
+         FILTER ( lang(?name) = "es" ) }
diff --git a/jena-core/src/main/java/org/apache/jena/graph/Node.java b/jena-core/src/main/java/org/apache/jena/graph/Node.java
index b6ddf05253..2f92e8c0d4 100644
--- a/jena-core/src/main/java/org/apache/jena/graph/Node.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/Node.java
@@ -25,6 +25,7 @@ import java.util.function.Function;
 
 import org.apache.jena.datatypes.RDFDatatype ;
 import org.apache.jena.graph.impl.LiteralLabel ;
+import org.apache.jena.rdf.model.impl.Util;
 import org.apache.jena.shared.JenaException ;
 import org.apache.jena.shared.PrefixMapping ;
 import org.apache.jena.sys.Serializer;
@@ -51,7 +52,19 @@ public abstract class Node implements Serializable {
      */
     public static final Node ANY = Node_ANY.nodeANY;
 
-    static final String RDFprefix = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+    /**
+     * The string used when a literal does not have a language tag.
+     * Accessing the language of a non-literal will throw an exception.
+     * @see Util#hasLang(Node)
+     */
+    public static final String noLangTag = "";
+
+    /**
+     * The TextDirection used when a literal does not have an initial text direction setting.
+     * Accessing the initial text direction of a non-literal will throw an exception.
+     * @see Util#hasDirection(Node)
+     */
+    public static final TextDirection noTextDirection = null;
 
     // Constants to separate hashes.
     // e.g. label is string so we perturb the hash code.
diff --git a/jena-core/src/main/java/org/apache/jena/graph/NodeFactory.java b/jena-core/src/main/java/org/apache/jena/graph/NodeFactory.java
index 8695860047..1a4ab9de71 100644
--- a/jena-core/src/main/java/org/apache/jena/graph/NodeFactory.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/NodeFactory.java
@@ -21,7 +21,6 @@ package org.apache.jena.graph;
 
 import static org.apache.jena.atlas.lib.Lib.isEmpty;
 
-import java.util.Locale;
 import java.util.Objects;
 
 import org.apache.jena.datatypes.RDFDatatype;
@@ -31,6 +30,7 @@ import org.apache.jena.datatypes.xsd.impl.RDFDirLangString;
 import org.apache.jena.datatypes.xsd.impl.RDFLangString;
 import org.apache.jena.graph.impl.LiteralLabel;
 import org.apache.jena.graph.impl.LiteralLabelFactory;
+import org.apache.jena.graph.langtag.LangTags;
 import org.apache.jena.shared.JenaException;
 import org.apache.jena.sys.JenaSystem;
 
@@ -39,10 +39,6 @@ public class NodeFactory {
     static { JenaSystem.init(); }
     private NodeFactory() {}
 
-    // Constants
-    public static final String noLangTag = "";
-    public static final TextDirection noTextDirection = null;
-
     public static RDFDatatype getType(String s) {
         if ( s == null )
             return null;
@@ -146,7 +142,7 @@ public class NodeFactory {
     }
 
     private static boolean noTextDir(TextDirection textDir) {
-        return textDir == noTextDirection;
+        return textDir == Node.noTextDirection;
     }
 
     public static Node createLiteralDirLang(String string, String lang, TextDirection textDir) {
@@ -178,7 +174,7 @@ public class NodeFactory {
      * @param dtype the type of the literal or null.
      */
     public static Node createLiteral(String lex, String lang, RDFDatatype dtype) {
-        return createLiteral(lex, lang, noTextDirection, dtype);
+        return createLiteral(lex, lang, Node.noTextDirection, dtype);
     }
 
     /**
@@ -224,10 +220,13 @@ public class NodeFactory {
         if ( hasLang ) {
             String langFmt = formatLanguageTag(lang);
             if ( dtype != null ) {
-                if ( noTextDir(textDir) && dtype.equals(RDFLangString.rdfLangString) )
-                    throw new JenaException("Datatype is not rdf:langString but a language was given");
-                else
-                    throw new JenaException("Datatype is not rdf:dirLangString but a language and initial text direction was given");
+                if ( noTextDir(textDir) ) {
+                    if ( ! dtype.equals(RDFLangString.rdfLangString) )
+                        throw new JenaException("Datatype is not rdf:langString but a language was given");
+                } else {
+                    if (  ! dtype.equals(RDFDirLangString.rdfDirLangString) )
+                        throw new JenaException("Datatype is not rdf:dirLangString but a language and initial text direction was given");
+                }
             }
 
             return createLiteralDirLang(lex, langFmt, textDir);
@@ -248,7 +247,7 @@ public class NodeFactory {
     /** Prepare the initial text direction - apply formatting normalization */
     private static TextDirection initialTextDirection(String input) {
         if ( isEmpty(input) )
-            return noTextDirection;
+            return Node.noTextDirection;
         // Throws JenaException on bad input.
         TextDirection textDir = TextDirection.create(input);
         return textDir;
@@ -256,14 +255,15 @@ public class NodeFactory {
 
     /*package*/ static final boolean legacyLangTag = false;
     /** Prepare the language tag - apply formatting normalization */
-    private static String formatLanguageTag(String input) {
-        if ( input == null )
-            return noLangTag;
+    private static String formatLanguageTag(String langTagStr) {
+        if ( langTagStr == null )
+            return Node.noLangTag;
         if ( legacyLangTag )
-            return input;
-        if ( input.isEmpty() )
-            return input;
-        return input.toLowerCase(Locale.ROOT);
+            return langTagStr;
+        if ( langTagStr.isEmpty() )
+            return langTagStr;
+        //return Lib.lowercase(langTagStr);
+        return LangTags.basicFormat(langTagStr);
     }
 
     /**
diff --git a/jena-core/src/main/java/org/apache/jena/graph/impl/LiteralLabel.java b/jena-core/src/main/java/org/apache/jena/graph/impl/LiteralLabel.java
index 0e2f44fc22..f023c8c471 100644
--- a/jena-core/src/main/java/org/apache/jena/graph/impl/LiteralLabel.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/impl/LiteralLabel.java
@@ -487,8 +487,10 @@ final public class LiteralLabel {
         // -- Strings.
         if ( isStringValue(lit1) && isStringValue(lit2) )
             return lit1.getLexicalForm().equals(lit2.getLexicalForm());
-        if ( isStringValue(lit1) ) return false;
-        if ( isStringValue(lit2) ) return false;
+        else {
+            if ( isStringValue(lit1) ) return false;
+            if ( isStringValue(lit2) ) return false;
+        }
 
         // -- Language tag strings
         if ( isLangString(lit1) && isLangString(lit2) ) {
@@ -497,21 +499,23 @@ final public class LiteralLabel {
             //return lex1.equals(lex2) && lit1.language().equalsIgnoreCase(lit2.language());
             // Normalized language tags.
             return lex1.equals(lex2)
-                    && lit1.language().equals(lit2.language());
+                    && lit1.language().equalsIgnoreCase(lit2.language());
+        } else {
+            if ( isLangString(lit1) ) return false;
+            if ( isLangString(lit2) ) return false;
         }
-        if ( isLangString(lit1) ) return false;
-        if ( isLangString(lit2) ) return false;
 
         // -- Language tag strings with initial text direction
         if ( isLangStringDir(lit1) && isLangStringDir(lit2) ) {
             String lex1 = lit1.getLexicalForm();
             String lex2 = lit2.getLexicalForm();
             return lex1.equals(lex2)
-                    && lit1.language().equals(lit2.language())
+                    && lit1.language().equalsIgnoreCase(lit2.language())
                     && lit1.initialTextDirection().equals(lit2.initialTextDirection());
+        } else {
+            if ( isLangStringDir(lit1) ) return false;
+            if ( isLangStringDir(lit2) ) return false;
         }
-        if ( isLangStringDir(lit1) ) return false;
-        if ( isLangStringDir(lit2) ) return false;
 
         // -- datatypes.
         // Both not strings, not lang strings and not dirlang strings.
diff --git a/jena-core/src/main/java/org/apache/jena/graph/impl/LiteralLabelFactory.java b/jena-core/src/main/java/org/apache/jena/graph/impl/LiteralLabelFactory.java
index c19432e196..ee5793f059 100644
--- a/jena-core/src/main/java/org/apache/jena/graph/impl/LiteralLabelFactory.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/impl/LiteralLabelFactory.java
@@ -19,12 +19,11 @@
 package org.apache.jena.graph.impl;
 
 import static org.apache.jena.atlas.lib.Lib.isEmpty;
-import static org.apache.jena.graph.NodeFactory.noLangTag;
-import static org.apache.jena.graph.NodeFactory.noTextDirection;
 
 import org.apache.jena.datatypes.DatatypeFormatException;
 import org.apache.jena.datatypes.RDFDatatype;
 import org.apache.jena.datatypes.xsd.XSDDatatype;
+import org.apache.jena.graph.Node;
 import org.apache.jena.graph.NodeFactory;
 import org.apache.jena.graph.TextDirection;
 import org.apache.jena.vocabulary.RDF;
@@ -53,7 +52,7 @@ public class LiteralLabelFactory
 
     /** Create a string literal */
     public static LiteralLabel createString(String lex) {
-        return new LiteralLabel(lex, noLangTag, noTextDirection, XSDDatatype.XSDstring);
+        return new LiteralLabel(lex, Node.noLangTag, Node.noTextDirection, XSDDatatype.XSDstring);
     }
 
     /**
@@ -62,8 +61,8 @@ public class LiteralLabelFactory
      * @param lang the optional language tag
      */
     public static LiteralLabel createLang(String lex, String lang) {
-        RDFDatatype dt = fixDatatype(null, lang, noTextDirection);
-        return new LiteralLabel(lex, lang, noTextDirection, dt);
+        RDFDatatype dt = fixDatatype(null, lang, Node.noTextDirection);
+        return new LiteralLabel(lex, lang, Node.noTextDirection, dt);
     }
 
     /**
diff --git a/jena-core/src/main/java/org/apache/jena/graph/langtag/LangTags.java b/jena-core/src/main/java/org/apache/jena/graph/langtag/LangTags.java
new file mode 100644
index 0000000000..118282fd3c
--- /dev/null
+++ b/jena-core/src/main/java/org/apache/jena/graph/langtag/LangTags.java
@@ -0,0 +1,165 @@
+/*
+ * 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.graph.langtag;
+
+import static org.apache.jena.atlas.lib.Lib.lowercase;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.jena.atlas.lib.Lib;
+import org.apache.jena.atlas.logging.Log;
+import org.apache.jena.graph.Node;
+
+public class LangTags {
+
+    /**
+     * Format language tag.
+     * This is the system-wide policy for formatting language tags.
+     */
+    public static String formatLangtag(String input) {
+        if ( input == null )
+            return Node.noLangTag;
+        if ( input.isEmpty() )
+            return input;
+        return lowercase(input);
+        //return basicFormat(input);
+    }
+
+    /**
+     * Basic language tag formatter.
+     * <a href="https://datatracker.ietf.org/doc/html/rfc5646#section-2.1.1">RFC 5646 section 2.1.1</a>
+     */
+    public static String format(String string) {
+        return basicFormat(string);
+    }
+
+    public static String basicFormat(String string) {
+        // with the interpretation that "after singleton" means anywhere after the singleton.
+        if ( string == null )
+            return null;
+        if ( string.isEmpty() )
+            return string;
+        List<String> strings = splitOnDash(string);
+        if ( strings == null ) {
+            return lowercase(string);
+            //error("Bad language string: %s", string);
+        }
+        StringBuilder sb = new StringBuilder(string.length());
+        boolean singleton = false;
+        boolean first = true;
+
+        for ( String s : strings ) {
+            if ( first ) {
+                // language
+                sb.append(lowercase(s));
+                first = false;
+                continue;
+            }
+            first = false;
+            // All subtags after language
+            sb.append('-');
+            if ( singleton )
+                // Always lowercase
+                sb.append(lowercase(s));
+            else {
+                // case depends on ;length
+                sb.append(strcase(s));
+                // is it the start of an extension or privateuse
+                // XXX s.length()==1?
+                if ( s.length() == 1 )
+                    singleton = true;
+            }
+        }
+        return sb.toString();
+    }
+
+    private static List<String> splitOnDash(String x) {
+        List<String> strings = new ArrayList<>(6);
+        // Split efficiently(?) based on [a-z][A-Z][0-9] units separated by "-"s
+        StringBuilder sb = new StringBuilder();
+
+        boolean start = true;
+        for ( int idx = 0; idx < x.length(); idx++ ) {
+            char ch = x.charAt(idx);
+            if ( isA2ZN(ch) ) {
+                sb.append(ch);
+                continue;
+            }
+            if ( ch == '-' ) {
+                String str = sb.toString();
+                strings.add(str);
+                sb.setLength(0);
+                continue;
+            }
+            error("Bad character: (0x%02X) '%c' index %d", (int)ch, str(ch), idx);
+        }
+        String strLast = sb.toString();
+        if ( strLast.isEmpty() ) {
+            // Ends in "-"
+            return null;
+            //error("Empty part: %s", x);
+        }
+        strings.add(strLast);
+        return strings;
+    }
+
+    private static void error(String msg, Object ... args) {
+        String x = String.format(msg, args);
+        //throw new LangTagException(x);
+        Log.warn("LangTag", x);
+    }
+
+    private static String strcase(String string) {
+        if ( string == null )
+            return null;
+        if ( string.length() == 2 )
+            return Lib.uppercase(string);
+        if ( string.length() == 4 )
+            return titlecase(string);
+        return lowercase(string);
+    }
+
+    private static String titlecase(String string) {
+        if ( string == null )
+            return null;
+        char ch1 = string.charAt(0);
+        ch1 = Character.toUpperCase(ch1);
+        string = lowercase(string.substring(1));
+        return ch1 + string;
+    }
+
+    private static String str(char ch) {
+        return String.format("'%s' U+%04X", Character.valueOf(ch), (int)ch);
+    }
+
+    /** ASCII A-Z */
+    /*package*/ static boolean isA2Z(int ch) {
+        return range(ch, 'a', 'z') || range(ch, 'A', 'Z');
+    }
+
+    /** ASCII A-Z or 0-9 */
+    /*package*/ static boolean isA2ZN(int ch) {
+        return range(ch, 'a', 'z') || range(ch, 'A', 'Z') || range(ch, '0', '9');
+    }
+
+    private static boolean range(int ch, char a, char b) {
+        return (ch >= a && ch <= b);
+    }
+}
diff --git a/jena-core/src/test/java/org/apache/jena/graph/test/AbstractTestGraph.java b/jena-core/src/test/java/org/apache/jena/graph/test/AbstractTestGraph.java
index 1b79ebd6d1..8100411d08 100644
--- a/jena-core/src/test/java/org/apache/jena/graph/test/AbstractTestGraph.java
+++ b/jena-core/src/test/java/org/apache/jena/graph/test/AbstractTestGraph.java
@@ -159,7 +159,8 @@ public abstract class AbstractTestGraph extends GraphTestBase
         if (m.getCapabilities().handlesLiteralTyping())
         {
             Node chaten = node( "'chat'en" ), chatEN = node( "'chat'EN" );
-            assertDiffer( chaten, chatEN );
+            //assertDiffer( chaten, chatEN ); // Up to Jena4.
+            assertEquals( chaten, chatEN ); // Jena5 -- the nodes are now the same due to normalized langtags
             assertTrue( chaten.sameValueAs( chatEN ) );
             assertEquals( chaten.getIndexingValue(), chatEN.getIndexingValue() );
             assertEquals( 1, m.find( Node.ANY, Node.ANY, chaten ).toList().size() );
@@ -173,11 +174,19 @@ public abstract class AbstractTestGraph extends GraphTestBase
         if (m.getCapabilities().handlesLiteralTyping())
         {
             Node chaten = node( "'chat'en" ), chatEN = node( "'chat'EN" );
-            assertDiffer( chaten, chatEN );
+            // Jena4.
+//            assertDiffer( chaten, chatEN ); // Up to Jena4.
+//            assertTrue( chaten.sameValueAs( chatEN ) );
+//            assertEquals( chaten.getIndexingValue(), chatEN.getIndexingValue() );
+//            assertEquals( 2, m.find( Node.ANY, Node.ANY, chaten ).toList().size() );
+//            assertEquals( 2, m.find( Node.ANY, Node.ANY, chatEN ).toList().size() );
+
+            // Jena5 -- the nodes are now the same due to normalized langtags
+            assertEquals( chaten, chatEN ); // Jena5 -- the nodes are now the same due to normalized langtags
             assertTrue( chaten.sameValueAs( chatEN ) );
             assertEquals( chaten.getIndexingValue(), chatEN.getIndexingValue() );
-            assertEquals( 2, m.find( Node.ANY, Node.ANY, chaten ).toList().size() );
-            assertEquals( 2, m.find( Node.ANY, Node.ANY, chatEN ).toList().size() );
+            assertEquals( 1, m.find( Node.ANY, Node.ANY, chaten ).toList().size() );
+            assertEquals( 1, m.find( Node.ANY, Node.ANY, chatEN ).toList().size() );
         }
     }
 
@@ -187,7 +196,8 @@ public abstract class AbstractTestGraph extends GraphTestBase
         if (m.getCapabilities().handlesLiteralTyping())
         {
             Node chaten = node( "'chat'en" ), chatEN = node( "'chat'EN" );
-            assertDiffer( chaten, chatEN );
+            //assertDiffer( chaten, chatEN ); // Up to Jena4.
+            assertEquals( chaten, chatEN ); // Jena5 -- the nodes are now the same due to normalized langtags
             assertTrue( chaten.sameValueAs( chatEN ) );
             assertEquals( chaten.getIndexingValue(), chatEN.getIndexingValue() );
             assertEquals( 1, m.find( Node.ANY, Node.ANY, chaten ).toList().size() );
diff --git a/jena-core/src/test/java/org/apache/jena/graph/test/TestLiteralLabelSameValueAs.java b/jena-core/src/test/java/org/apache/jena/graph/test/TestLiteralLabelSameValueAs.java
index 1e127821c9..62f581bda4 100644
--- a/jena-core/src/test/java/org/apache/jena/graph/test/TestLiteralLabelSameValueAs.java
+++ b/jena-core/src/test/java/org/apache/jena/graph/test/TestLiteralLabelSameValueAs.java
@@ -54,6 +54,8 @@ public class TestLiteralLabelSameValueAs
     }
 
     private static LiteralLabel gen(String lex, String lang) {
+        // LiteralLabels do not normalize language tags.
+        // That happens in NodeFactory.
         return LiteralLabelFactory.createLang(lex, lang) ;
     }
 
diff --git a/jena-core/src/test/java/org/apache/jena/graph/test/TestLiteralLabels.java b/jena-core/src/test/java/org/apache/jena/graph/test/TestLiteralLabels.java
index f3f46bd933..c4618c0b45 100644
--- a/jena-core/src/test/java/org/apache/jena/graph/test/TestLiteralLabels.java
+++ b/jena-core/src/test/java/org/apache/jena/graph/test/TestLiteralLabels.java
@@ -109,6 +109,7 @@ public class TestLiteralLabels extends GraphTestBase
     public void testEquality4() {
         LiteralLabel A = LiteralLabelFactory.createLang("xyz", "en-UK");
         LiteralLabel B = LiteralLabelFactory.createLang("xyz", "en-uk");
+        // Jena5: language tags are not normalized by LoiteralLabel but in NodeFactory.
         assertFalse(A.equals(B));
         assertTrue(A.sameValueAs(B));
     }
diff --git a/jena-core/src/test/java/org/apache/jena/graph/test/TestNode.java b/jena-core/src/test/java/org/apache/jena/graph/test/TestNode.java
index bccaffde53..a26adaac7f 100644
--- a/jena-core/src/test/java/org/apache/jena/graph/test/TestNode.java
+++ b/jena-core/src/test/java/org/apache/jena/graph/test/TestNode.java
@@ -354,7 +354,8 @@ public class TestNode extends GraphTestBase
         Node n1 = NodeCreateUtils.create( "'chat'en-UK" );
         Node n2 = NodeCreateUtils.create( "'chat'EN-UK" );
         assertTrue( n1.sameValueAs(n2) ) ;
-        assertFalse( n1.equals(n2) ) ;
+        // Jena5: normalized language tags.
+        assertTrue( n1.equals(n2) ) ;
     }
 
     public void testCreateLanguagedLiteralXY()
@@ -622,10 +623,10 @@ public class TestNode extends GraphTestBase
         TypeMapper tm = TypeMapper.getInstance();
         RDFDatatype dtInt = tm.getTypeByValue( Integer.valueOf( 10 ) );
         Node plain = NodeFactory.createLiteralLang( "rhubarb", "");
-        Node english = NodeFactory.createLiteralLang( "eccentric", "en_UK");
+        Node english = NodeFactory.createLiteralLang( "eccentric", "en-UK");
         Node typed = NodeFactory.createLiteral( "10", dtInt );
         assertEquals( "\"rhubarb\"", plain.toString() );
-        assertEquals( "\"eccentric\"@en_UK", english.toString() );
+        assertEquals( "\"eccentric\"@en-UK", english.toString() );
         assertEquals( "\"10\"^^xsd:int", typed.toString() );
     }
 


(jena) 02/10: GH-2126: Rename in NodeFactory: createLiteral(,lang) -> createLiteralLang(,lang)

Posted by an...@apache.org.
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 4965c755223885fdeed5ddde1cc875943c30b583
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Fri Dec 8 15:34:11 2023 +0000

    GH-2126: Rename in NodeFactory: createLiteral(,lang) -> createLiteralLang(,lang)
---
 .../org/apache/jena/riot/RDFParserBuilder.java     |  10 +-
 .../jena/riot/lang/rdfxml/ReaderRDFXML_ARP0.java   |   2 +-
 .../process/normalize/CanonicalizeLiteral.java     |   2 +-
 .../riot/process/normalize/NormalizeValue.java     |   2 +-
 .../process/normalize/StreamCanonicalLangTag.java  |   5 +-
 .../apache/jena/riot/protobuf/ProtobufConvert.java |   2 +-
 .../org/apache/jena/riot/system/FactoryRDFStd.java |   2 +-
 .../java/org/apache/jena/riot/tokens/Token.java    |   2 +-
 .../org/apache/jena/sparql/expr/NodeValue.java     |   2 +-
 .../jena/sparql/expr/nodevalue/NodeValueLang.java  |   2 +-
 .../jena/sparql/sse/lang/ParseHandlerPlain.java    |   2 +-
 .../org/apache/jena/sparql/expr/TestFunctions.java |   2 +-
 .../apache/jena/sparql/expr/TestNodeFunctions.java |  14 +-
 .../org/apache/jena/sparql/expr/TestNodeValue.java |  16 +-
 .../org/apache/jena/sparql/expr/TestOrdering.java  |  26 +-
 .../org/apache/jena/sparql/sse/TestSSE_Basic.java  |   2 +-
 .../java/org/apache/jena/graph/NodeFactory.java    |  66 ++++-
 .../apache/jena/graph/impl/CollectionGraph.java    |   2 +-
 .../org/apache/jena/rdf/model/ResourceFactory.java |   4 +-
 .../org/apache/jena/rdf/model/impl/AltImpl.java    |   2 +-
 .../apache/jena/rdf/model/impl/ContainerImpl.java  |   2 +-
 .../org/apache/jena/rdf/model/impl/ModelCom.java   |   4 +-
 .../org/apache/jena/rdf/model/impl/SeqImpl.java    |   2 +-
 .../apache/jena/rdf/model/impl/StatementBase.java  |   2 +-
 .../jena/rdfxml/xmlinput0/RDFXMLReader0.java       |   2 +-
 .../apache/jena/rdfxml/xmlinput1/RDFXMLReader.java |   2 +-
 .../org/apache/jena/reasoner/rulesys/Rule.java     |   2 +-
 .../java/org/apache/jena/graph/test/TestNode.java  |   4 +-
 .../apache/jena/graph/test/TestTypedLiterals.java  |   4 +-
 .../jena/reasoner/rulesys/test/TestFBRules.java    |   2 +-
 .../java/org/apache/jena/test/JenaTestBase.java    | 265 ++++++++++-----------
 .../apache/jena/commonsrdf/impl/JCR_Factory.java   |   2 +-
 .../permissions/model/impl/SecuredModelImpl.java   |   6 +-
 .../model/impl/SecuredResourceImpl.java            |   2 +-
 .../model/impl/SecuredStatementImpl.java           |   4 +-
 .../org/apache/jena/shex/parser/ParserShExC.java   |   2 +-
 .../store/nodetable/AbstractTestNodeTable.java     |   2 +-
 .../jena/tdb1/store/nodetable/TestNodec.java       |   2 +-
 .../apache/jena/query/text/TextIndexLucene.java    |   4 +-
 .../text/TestDatasetWithLuceneStoredLiterals.java  |   2 +-
 .../jena/query/text/TestTextHighlighting.java      |   2 +-
 41 files changed, 270 insertions(+), 216 deletions(-)

diff --git a/jena-arq/src/main/java/org/apache/jena/riot/RDFParserBuilder.java b/jena-arq/src/main/java/org/apache/jena/riot/RDFParserBuilder.java
index 3f6e956e2c..1c46c0ea79 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/RDFParserBuilder.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/RDFParserBuilder.java
@@ -369,7 +369,9 @@ public class RDFParserBuilder {
      * This option can slow parsing down.
      *
      * @see #langTagCanonical
+     * @deprecated In Jena5, language tags are always converted to RFC 5646 case format.
      */
+    @Deprecated
     public RDFParserBuilder langTagLowerCase() {
         return langTagForm(LangTagForm.LOWER_CASE);
     }
@@ -388,7 +390,9 @@ public class RDFParserBuilder {
      * This option can slow parsing down.
      * </p>
      * @see #langTagLowerCase
+     * @deprecated In Jena5, language tags are always converted to RFC 5646 case format.
      */
+    @Deprecated
     public RDFParserBuilder langTagCanonical() {
         return langTagForm(LangTagForm.CANONICAL);
     }
@@ -398,13 +402,17 @@ public class RDFParserBuilder {
      * This is the default behaviour of parsing.
      * @see #langTagLowerCase
      * @see #langTagCanonical
+     * @deprecated In Jena5, language tags are always converted to RFC 5646 case format.
      */
+    @Deprecated
     public RDFParserBuilder langTagAsGiven() {
         return langTagForm(LangTagForm.NONE);
     }
 
     private RDFParserBuilder langTagForm(LangTagForm form) {
-        this.langTagForm = form;
+        // Ignore!
+        // language tags are always converted to RFC 5646 case format.
+        //this.langTagForm = form;
         return this;
     }
 
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/lang/rdfxml/ReaderRDFXML_ARP0.java b/jena-arq/src/main/java/org/apache/jena/riot/lang/rdfxml/ReaderRDFXML_ARP0.java
index a0df7a14d3..f3ce3ea6be 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/lang/rdfxml/ReaderRDFXML_ARP0.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/lang/rdfxml/ReaderRDFXML_ARP0.java
@@ -217,7 +217,7 @@ public class ReaderRDFXML_ARP0 implements ReaderRIOT
         private static Node convert(ALiteral lit) {
             String dtURI = lit.getDatatypeURI();
             if (dtURI == null)
-                return NodeFactory.createLiteral(lit.toString(), lit.getLang());
+                return NodeFactory.createLiteralLang(lit.toString(), lit.getLang());
 
             if (lit.isWellFormedXML()) {
                 return NodeFactory.createLiteral(lit.toString(), null, XMLLiteralType.theXMLLiteralType);
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/CanonicalizeLiteral.java b/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/CanonicalizeLiteral.java
index 52e937f588..f581aac0f1 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/CanonicalizeLiteral.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/CanonicalizeLiteral.java
@@ -110,7 +110,7 @@ public class CanonicalizeLiteral implements Function<Node, Node>
         String langTag2 = LangTag.canonical(langTag);
         if ( langTag2.equals(langTag) )
             return null;
-        return NodeFactory.createLiteral(lexicalForm, langTag2);
+        return NodeFactory.createLiteralLang(lexicalForm, langTag2);
     }
 
     private static final RDFDatatype dtPlainLiteral = NodeFactory.getType(RDF.getURI()+"PlainLiteral") ;
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/NormalizeValue.java b/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/NormalizeValue.java
index e8c67f34a3..b29d10d06c 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/NormalizeValue.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/NormalizeValue.java
@@ -202,6 +202,6 @@ class NormalizeValue
         if ( idx == lexicalForm.length()-1 )
             return NodeFactory.createLiteral(lex) ;
         String lang = lexicalForm.substring(idx+1) ;
-        return NodeFactory.createLiteral(lex, lang) ;
+        return NodeFactory.createLiteralLang(lex, lang) ;
     } ;
 }
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/StreamCanonicalLangTag.java b/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/StreamCanonicalLangTag.java
index d593c52edd..da6bbea784 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/StreamCanonicalLangTag.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/process/normalize/StreamCanonicalLangTag.java
@@ -28,7 +28,7 @@ import org.apache.jena.riot.process.StreamRDFApplyObject;
 import org.apache.jena.riot.system.StreamRDF;
 import org.apache.jena.sparql.util.NodeUtils;
 
-/** {@link StreamRDF} that converts language tags to lower case o rto canokcal form (RFC 4646). */
+/** {@link StreamRDF} that converts language tags to lower case or to canonical form (RFC 4646, 5646). */
 public class StreamCanonicalLangTag extends StreamRDFApplyObject {
     /** Return a {@link StreamRDF} that converts language tags to lower case */
     public static StreamRDF toLC(StreamRDF other) {
@@ -58,11 +58,10 @@ public class StreamCanonicalLangTag extends StreamRDFApplyObject {
         String langTag2 = tagMapper.apply(locBuild, langTag);
         if ( langTag == langTag2 )
             return n;
-        Node obj2 = NodeFactory.createLiteral(n.getLiteralLexicalForm(), langTag2);
+        Node obj2 = NodeFactory.createLiteralLang(n.getLiteralLexicalForm(), langTag2);
         return obj2;
     }
 
-    // From taken from "xsd4ld" (which has an Apache License).
     public static String langTagCanonical(Locale.Builder locBuild, String str) {
         try {
             // Does not do conversion of language for ISO 639 codes that have changed.
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/protobuf/ProtobufConvert.java b/jena-arq/src/main/java/org/apache/jena/riot/protobuf/ProtobufConvert.java
index 99da5e67e2..7dd31d1cf4 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/protobuf/ProtobufConvert.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/protobuf/ProtobufConvert.java
@@ -176,7 +176,7 @@ public class ProtobufConvert
                             return NodeFactory.createLiteral(lex) ;
                         case LANGTAG : {
                             String lang = lit.getLangtag();
-                            return NodeFactory.createLiteral(lex, lang) ;
+                            return NodeFactory.createLiteralLang(lex, lang) ;
                         }
                         case DATATYPE : {
                             String dtString = lit.getDatatype();
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/system/FactoryRDFStd.java b/jena-arq/src/main/java/org/apache/jena/riot/system/FactoryRDFStd.java
index 76a24c4582..7cc7d87ad2 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/system/FactoryRDFStd.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/system/FactoryRDFStd.java
@@ -62,7 +62,7 @@ public class FactoryRDFStd implements FactoryRDF {
 
     @Override
     public Node createLangLiteral(String lexical, String langTag) {
-        return NodeFactory.createLiteral(lexical, langTag) ;
+        return NodeFactory.createLiteralLang(lexical, langTag) ;
     }
 
     @Override
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/tokens/Token.java b/jena-arq/src/main/java/org/apache/jena/riot/tokens/Token.java
index 4d86ecfeba..6218d85a0e 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/tokens/Token.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/tokens/Token.java
@@ -402,7 +402,7 @@ public final class Token
                 return NodeFactory.createLiteral(lexToken.getImage(), dt);
             }
             case LITERAL_LANG :
-                return NodeFactory.createLiteral(tokenImage, tokenImage2);
+                return NodeFactory.createLiteralLang(tokenImage, tokenImage2);
             case STRING :
                 return NodeFactory.createLiteral(tokenImage);
             case VAR :
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 b7cbb8685d..06f315e9ec 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
@@ -277,7 +277,7 @@ public abstract class NodeValue extends ExprNode
 
         Node n = null ;
         if ( langTag != null )
-            n = NodeFactory.createLiteral(lexicalForm, langTag) ;
+            n = NodeFactory.createLiteralLang(lexicalForm, langTag) ;
         else if ( datatype != null) {
             RDFDatatype dType = TypeMapper.getInstance().getSafeTypeByName(datatype) ;
             n = NodeFactory.createLiteral(lexicalForm, dType) ;
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueLang.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueLang.java
index 72ea820df6..ffae70c9f2 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueLang.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/nodevalue/NodeValueLang.java
@@ -65,7 +65,7 @@ public class NodeValueLang extends NodeValue {
     
     @Override
     protected Node makeNode()
-    { return NodeFactory.createLiteral(string, lang) ; }
+    { return NodeFactory.createLiteralLang(string, lang) ; }
     
     @Override
     public String toString() { 
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/sse/lang/ParseHandlerPlain.java b/jena-arq/src/main/java/org/apache/jena/sparql/sse/lang/ParseHandlerPlain.java
index 200f5a1da8..d85b4a4ff0 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/sse/lang/ParseHandlerPlain.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/sse/lang/ParseHandlerPlain.java
@@ -143,7 +143,7 @@ public class ParseHandlerPlain implements ParseHandler {
             RDFDatatype dType = TypeMapper.getInstance().getSafeTypeByName(datatypeIRI);
             n = NodeFactory.createLiteral(lexicalForm, dType);
         } else
-            n = NodeFactory.createLiteral(lexicalForm, langTag);
+            n = NodeFactory.createLiteralLang(lexicalForm, langTag);
         node(n, line, column);
     }
 
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestFunctions.java b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestFunctions.java
index d25b9e7e98..34830a7a73 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestFunctions.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestFunctions.java
@@ -244,7 +244,7 @@ public class TestFunctions
     @Test public void exprNotOneOf_06()  { test("57 not in (1,2,3)",                TRUE) ; }
 
 
-    static Node xyz_en = NodeFactory.createLiteral("xyz", "en") ;
+    static Node xyz_en = NodeFactory.createLiteralLang("xyz", "en") ;
     static NodeValue nv_xyz_en = NodeValue.makeNode(xyz_en) ;
 
     static Node xyz_xsd_string = NodeFactory.createLiteral("xyz", XSDDatatype.XSDstring) ;
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeFunctions.java b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeFunctions.java
index 713722bdb2..65140ac773 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeFunctions.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeFunctions.java
@@ -62,14 +62,14 @@ public class TestNodeFunctions {
     }
 
     @Test public void testSameTerm5() {
-        Node n1 = NodeFactory.createLiteral("xyz", "en") ;
+        Node n1 = NodeFactory.createLiteralLang("xyz", "en") ;
         Node n2 = NodeFactory.createLiteral("xyz") ;
         assertFalse(NodeFunctions.sameTerm(n1, n2)) ;
     }
 
     @Test public void testSameTerm6() {
-        Node n1 = NodeFactory.createLiteral("xyz", "en") ;
-        Node n2 = NodeFactory.createLiteral("xyz", "EN") ;
+        Node n1 = NodeFactory.createLiteralLang("xyz", "en") ;
+        Node n2 = NodeFactory.createLiteralLang("xyz", "EN") ;
         assertTrue(NodeFunctions.sameTerm(n1, n2)) ;
     }
 
@@ -80,8 +80,8 @@ public class TestNodeFunctions {
     }
 
     @Test public void testRDFtermEquals2() {
-        Node n1 = NodeFactory.createLiteral("xyz", "en") ;
-        Node n2 = NodeFactory.createLiteral("xyz", "EN") ;
+        Node n1 = NodeFactory.createLiteralLang("xyz", "en") ;
+        Node n2 = NodeFactory.createLiteralLang("xyz", "EN") ;
         assertTrue(NodeFunctions.rdfTermEquals(n1, n2)) ;
     }
 
@@ -89,7 +89,7 @@ public class TestNodeFunctions {
     public void testRDFtermEquals3() {
         // Unextended - not known to be same (no language tag support).
         Node n1 = NodeFactory.createLiteral("xyz") ;
-        Node n2 = NodeFactory.createLiteral("xyz", "en") ;
+        Node n2 = NodeFactory.createLiteralLang("xyz", "en") ;
         NodeFunctions.rdfTermEquals(n1, n2);
     }
 
@@ -229,7 +229,7 @@ public class TestNodeFunctions {
     }
 
     @Test public void testLang1() {
-        Node n = NodeFactory.createLiteral("abc", "en-gb") ;
+        Node n = NodeFactory.createLiteralLang("abc", "en-gb") ;
         assertEquals("en-gb", NodeFunctions.lang(n)) ;
     }
 
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeValue.java b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeValue.java
index 387fd5ecb3..67757c355b 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeValue.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeValue.java
@@ -742,14 +742,14 @@ public class TestNodeValue
     // EBV includes plain literals which includes language tagged literals.
     @Test
     public void testEBV7() {
-        Node x = NodeFactory.createLiteral("", "en");
+        Node x = NodeFactory.createLiteralLang("", "en");
         NodeValue v = NodeValue.makeNode(x);
         assertFalse("Not EBV false: " + v, XSDFuncOp.booleanEffectiveValue(v));
     }
 
     @Test
     public void testEBV8() {
-        Node x = NodeFactory.createLiteral("not empty", "en");
+        Node x = NodeFactory.createLiteralLang("not empty", "en");
         NodeValue v = NodeValue.makeNode(x);
         assertTrue("Not EBV true: " + v, XSDFuncOp.booleanEffectiveValue(v));
     }
@@ -1109,18 +1109,18 @@ public class TestNodeValue
 
     @Test
     public void testLang1() {
-        Node n1 = org.apache.jena.graph.NodeFactory.createLiteral("xyz", "en");
+        Node n1 = org.apache.jena.graph.NodeFactory.createLiteralLang("xyz", "en");
         NodeValue nv1 = NodeValue.makeNode(n1);
-        Node n2 = org.apache.jena.graph.NodeFactory.createLiteral("xyz", "en");
+        Node n2 = org.apache.jena.graph.NodeFactory.createLiteralLang("xyz", "en");
         NodeValue nv2 = NodeValue.makeNode(n2);
         assertTrue(NodeValue.sameValueAs(nv1, nv2));
     }
 
     @Test
     public void testLang2() {
-        Node n1 = org.apache.jena.graph.NodeFactory.createLiteral("xyz", "en");
+        Node n1 = org.apache.jena.graph.NodeFactory.createLiteralLang("xyz", "en");
         NodeValue nv1 = NodeValue.makeNode(n1);
-        Node n2 = org.apache.jena.graph.NodeFactory.createLiteral("xyz", "EN");
+        Node n2 = org.apache.jena.graph.NodeFactory.createLiteralLang("xyz", "EN");
         NodeValue nv2 = NodeValue.makeNode(n2);
         assertTrue(NodeValue.sameValueAs(nv1, nv2));
         assertFalse(nv1.equals(nv2));
@@ -1128,9 +1128,9 @@ public class TestNodeValue
 
     @Test
     public void testLang3() {
-        Node n1 = org.apache.jena.graph.NodeFactory.createLiteral("xyz", "en");
+        Node n1 = org.apache.jena.graph.NodeFactory.createLiteralLang("xyz", "en");
         NodeValue nv1 = NodeValue.makeNode(n1);
-        Node n2 = org.apache.jena.graph.NodeFactory.createLiteral("xyz", "en");
+        Node n2 = org.apache.jena.graph.NodeFactory.createLiteralLang("xyz", "en");
         NodeValue nv2 = NodeValue.makeNode(n2);
         assertFalse(NodeValue.notSameValueAs(nv1, nv2));
     }
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestOrdering.java b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestOrdering.java
index 1e4b7e9e64..ee152373d7 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestOrdering.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestOrdering.java
@@ -163,7 +163,7 @@ public class TestOrdering {
 
     @Test
     public void test_lang1() {
-        NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteral("abc", "en"));
+        NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteralLang("abc", "en"));
         NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteral("abc"));
 
         int x = NodeCmp.compareRDFTerms(nv1.asNode(), nv2.asNode());
@@ -172,8 +172,8 @@ public class TestOrdering {
 
     @Test
     public void test_lang2() {
-        NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteral("abc", "en"));
-        NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteral("abc", "EN"));
+        NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteralLang("abc", "en"));
+        NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteralLang("abc", "EN"));
 
         int x = NodeCmp.compareRDFTerms(nv1.asNode(), nv2.asNode());
         assertTrue("Lang tags should sort by case", Expr.CMP_GREATER == x);
@@ -181,8 +181,8 @@ public class TestOrdering {
 
     @Test
     public void test_lang3() {
-        NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteral("ABC", "en"));
-        NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteral("abc", "EN"));
+        NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteralLang("ABC", "en"));
+        NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteralLang("abc", "EN"));
 
         int x = NodeValue.compareAlways(nv1, nv2);
         assertTrue("Lang nodes should sort by lexical if tags value-same", Expr.CMP_LESS == x);
@@ -192,8 +192,8 @@ public class TestOrdering {
 
     @Test
     public void test_lang4() {
-        NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteral("ABC", "en"));
-        NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteral("abc", "en"));
+        NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteralLang("ABC", "en"));
+        NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteralLang("abc", "en"));
 
         int x = NodeValue.compareAlways(nv1, nv2);
         assertTrue("Lang nodes should sort by lexical if tags the same", Expr.CMP_LESS == x);
@@ -204,7 +204,7 @@ public class TestOrdering {
     @Test
     public void test_lang5() {
         NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteral("abc"));
-        NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteral("xyz", "en"));
+        NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteralLang("xyz", "en"));
 
         int x = NodeValue.compareAlways(nv1, nv2);
         assertTrue("Lang nodes should sort by lexical form if one is plain", Expr.CMP_LESS == x);
@@ -215,7 +215,7 @@ public class TestOrdering {
     @Test
     public void test_lang6() {
         NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteral("xyz"));
-        NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteral("abc", "en"));
+        NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteralLang("abc", "en"));
 
         int x = NodeValue.compareAlways(nv1, nv2);
         assertTrue("Lang nodes should sort by language before lexical form", Expr.CMP_LESS == x);
@@ -225,8 +225,8 @@ public class TestOrdering {
 
     @Test
     public void test_lang7() {
-        NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteral("xyz", "de"));
-        NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteral("abc", "en"));
+        NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteralLang("xyz", "de"));
+        NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteralLang("abc", "en"));
 
         int x = NodeValue.compareAlways(nv1, nv2);
         assertTrue("Lang nodes should sort by language before lexical form", Expr.CMP_LESS == x);
@@ -237,7 +237,7 @@ public class TestOrdering {
     @Test
     public void test_lang8() {
         NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteral("abc", XSDDatatype.XSDstring));
-        NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteral("xyz", "en"));
+        NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteralLang("xyz", "en"));
 
         int x = NodeValue.compareAlways(nv1, nv2);
         assertTrue("Lang nodes should sort by lexical form if other is XSD string", Expr.CMP_LESS == x);
@@ -248,7 +248,7 @@ public class TestOrdering {
     @Test
     public void test_lang9() {
         NodeValue nv1 = NodeValue.makeNode(NodeFactory.createLiteral("xyz", XSDDatatype.XSDstring));
-        NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteral("abc", "en"));
+        NodeValue nv2 = NodeValue.makeNode(NodeFactory.createLiteralLang("abc", "en"));
         // xsd:string (RDF 1.1) is a simple string and before @en.
         int x = NodeValue.compareAlways(nv1, nv2);
         assertTrue("Lang nodes should sort by lexical form if other is XSD string", Expr.CMP_LESS == x);
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/sse/TestSSE_Basic.java b/jena-arq/src/test/java/org/apache/jena/sparql/sse/TestSSE_Basic.java
index 66a7dce6dd..361f4346d4 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/sse/TestSSE_Basic.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/sse/TestSSE_Basic.java
@@ -34,7 +34,7 @@ public class TestSSE_Basic
     static Node int1 = org.apache.jena.graph.NodeFactory.createLiteral("1", XSDDatatype.XSDinteger) ;
     static Node int2 = org.apache.jena.graph.NodeFactory.createLiteral("2", XSDDatatype.XSDinteger) ;
     static Node int3 = org.apache.jena.graph.NodeFactory.createLiteral("3", XSDDatatype.XSDinteger) ;
-    static Node strLangEN = org.apache.jena.graph.NodeFactory.createLiteral("xyz", "en") ;
+    static Node strLangEN = org.apache.jena.graph.NodeFactory.createLiteralLang("xyz", "en") ;
 
     static Node typeLit1 = NodeFactoryExtra.createLiteralNode("123", null, "http://example/type") ;
 
diff --git a/jena-core/src/main/java/org/apache/jena/graph/NodeFactory.java b/jena-core/src/main/java/org/apache/jena/graph/NodeFactory.java
index 545148fd45..2a872ab776 100644
--- a/jena-core/src/main/java/org/apache/jena/graph/NodeFactory.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/NodeFactory.java
@@ -79,18 +79,34 @@ public class NodeFactory {
         return new Node_Literal( lit );
     }
 
+    /*
+     * Make literal which is a string (xsd:string)
+     */
     public static Node createLiteral(String string) {
         Objects.requireNonNull(string, "Argument to NodeFactory.createLiteral is null");
         return new Node_Literal(string);
     }
 
     /**
-     * Make a literal with specified language. lexical form must not be null.
+     * Make a literal with specified language. The lexical form must not be null.
      *
      * @param string  the lexical form of the literal
      * @param lang    the optional language tag
+     *
+     * @deprecated Prefer using {@link #createLiteralLang(String, String)}.
      */
+    @Deprecated
     public static Node createLiteral(String string, String lang) {
+        return createLiteralLang(string, lang);
+    }
+
+    /**
+     * Make a literal with specified language. The lexical form must not be null.
+     *
+     * @param string  the lexical form of the literal
+     * @param lang    the optional language tag
+     */
+    public static Node createLiteralLang(String string, String lang) {
         Objects.requireNonNull(string, "null lexical form for literal");
         if ( StringUtils.isEmpty(lang) )
             return new Node_Literal(string);
@@ -99,13 +115,32 @@ public class NodeFactory {
     }
 
     /**
-     * Build a literal node from its lexical form.
+     * Make a literal with specified language and language direction.
+     * The lexical form must not be null.
+     * The language must not be null if a non-direction is provided.
+     *
+     * @param string  the lexical form of the literal
+     * @param lang    the optional language tag
+     * @param langDir the optional language direction
+     */
+    public static Node createLiteralLang(String string, String lang, String langDir) {
+        Objects.requireNonNull(string, "null lexical form for literal");
+        if ( StringUtils.isEmpty(lang) ) {
+            if ( !StringUtils.isEmpty(langDir) )
+                throw new JenaException("The language must be gived for a language direction literal");
+            return new Node_Literal(string);
+        } else
+            return new Node_Literal(string, lang);
+    }
+
+    /**
+     * Build a literal node.
      * <p>
      * This is a convenience operation for passing in language and datatype without
-     * needing the caller to differentiate the xsd:string, rdf:langString and other
+     * needing the caller to differentiate between the xsd:string, rdf:langString and other
      * datatype cases.
      * It calls {@link #createLiteral(String)},
-     * {@link #createLiteral(String, String)} or
+     * {@link #createLiteralLang(String, String, String)} or
      * {@link #createLiteral(String, RDFDatatype)}
      * as appropriate.
      *
@@ -114,14 +149,33 @@ public class NodeFactory {
      * @param dtype the type of the literal or null.
      */
     public static Node createLiteral(String lex, String lang, RDFDatatype dtype) {
+        return createLiteral(lex, lang, null, dtype);
+    }
+
+    /**
+     * Build a literal node.
+     * <p>
+     * This is a convenience operation for passing in language and datatype without
+     * needing the caller to differentiate between the xsd:string, rdf:langString, and other
+     * datatype cases.
+     * It calls {@link #createLiteral(String)},
+     * {@link #createLiteralLang(String, String, String)} or
+     * {@link #createLiteral(String, RDFDatatype)}
+     * as appropriate.
+     *
+     * @param lex the lexical form of the literal
+     * @param lang the optional language tag or null or ""
+     * @param langDir the optional language direction or null
+     * @param dtype the type of the literal or null.
+     */
+    public static Node createLiteral(String lex, String lang, String langDir, RDFDatatype dtype) {
         Objects.requireNonNull(lex, "null lexical form for literal");
         boolean hasLang = ! StringUtils.isEmpty(lang);
         if ( hasLang ) {
             if ( dtype != null && ! dtype.equals(RDFLangString.rdfLangString) )
                 throw new JenaException("Datatype is not rdf:langString but a language was given");
-            return createLiteral(lex, lang);
+            return createLiteralLang(lex, lang, langDir);
         }
-
         if ( dtype == null )
             // No datatype, no lang (it is null or "") => xsd:string.
             return createLiteral(lex);
diff --git a/jena-core/src/main/java/org/apache/jena/graph/impl/CollectionGraph.java b/jena-core/src/main/java/org/apache/jena/graph/impl/CollectionGraph.java
index 6f392d489d..cf14b8c17e 100644
--- a/jena-core/src/main/java/org/apache/jena/graph/impl/CollectionGraph.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/impl/CollectionGraph.java
@@ -66,7 +66,7 @@ public class CollectionGraph extends GraphBase
         if ( node.isLiteral() ) {
             String lang = node.getLiteralLanguage();
             if ( lang != null && !lang.equals("") )
-                node = NodeFactory.createLiteral(node.getLiteralLexicalForm(), lang.toLowerCase(Locale.ROOT));
+                node = NodeFactory.createLiteralLang(node.getLiteralLexicalForm(), lang.toLowerCase(Locale.ROOT));
         }
         return node;
     }
diff --git a/jena-core/src/main/java/org/apache/jena/rdf/model/ResourceFactory.java b/jena-core/src/main/java/org/apache/jena/rdf/model/ResourceFactory.java
index 31fe2c7bfd..efe0185408 100644
--- a/jena-core/src/main/java/org/apache/jena/rdf/model/ResourceFactory.java
+++ b/jena-core/src/main/java/org/apache/jena/rdf/model/ResourceFactory.java
@@ -315,12 +315,12 @@ public class ResourceFactory {
 
         @Override
         public Literal createStringLiteral( String string ) {
-            return new LiteralImpl(  NodeFactory.createLiteral( string, "" ), null );
+            return new LiteralImpl(  NodeFactory.createLiteralLang( string, "" ), null );
         }
 
         @Override
         public Literal createLangLiteral( String string , String lang ) {
-            return new LiteralImpl(  NodeFactory.createLiteral( string, lang ), null );
+            return new LiteralImpl(  NodeFactory.createLiteralLang( string, lang ), null );
         }
 
         @Override
diff --git a/jena-core/src/main/java/org/apache/jena/rdf/model/impl/AltImpl.java b/jena-core/src/main/java/org/apache/jena/rdf/model/impl/AltImpl.java
index b625a6ddf2..ecb02d5258 100644
--- a/jena-core/src/main/java/org/apache/jena/rdf/model/impl/AltImpl.java
+++ b/jena-core/src/main/java/org/apache/jena/rdf/model/impl/AltImpl.java
@@ -188,7 +188,7 @@ public class AltImpl extends ContainerImpl implements Alt {
     
     @Override
     public Alt setDefault(String o, String l)  {
-        return setDefault( new LiteralImpl( NodeFactory.createLiteral( o, l ), getModelCom()) );
+        return setDefault( new LiteralImpl( NodeFactory.createLiteralLang( o, l ), getModelCom()) );
     }      
         
     protected Statement getDefaultStatement()  
diff --git a/jena-core/src/main/java/org/apache/jena/rdf/model/impl/ContainerImpl.java b/jena-core/src/main/java/org/apache/jena/rdf/model/impl/ContainerImpl.java
index 05f6f59dd0..aec6e04aa7 100644
--- a/jena-core/src/main/java/org/apache/jena/rdf/model/impl/ContainerImpl.java
+++ b/jena-core/src/main/java/org/apache/jena/rdf/model/impl/ContainerImpl.java
@@ -165,7 +165,7 @@ public class ContainerImpl extends ResourceImpl
     }
 
     private Literal literal( String s, String lang )
-        { return new LiteralImpl( NodeFactory.createLiteral( s, lang ), getModelCom() ); }
+        { return new LiteralImpl( NodeFactory.createLiteralLang( s, lang ), getModelCom() ); }
 
     @Override
     public NodeIterator iterator()
diff --git a/jena-core/src/main/java/org/apache/jena/rdf/model/impl/ModelCom.java b/jena-core/src/main/java/org/apache/jena/rdf/model/impl/ModelCom.java
index 7cabc1fc88..d95b42a287 100644
--- a/jena-core/src/main/java/org/apache/jena/rdf/model/impl/ModelCom.java
+++ b/jena-core/src/main/java/org/apache/jena/rdf/model/impl/ModelCom.java
@@ -132,7 +132,7 @@ public class ModelCom extends EnhGraph implements Model, PrefixMapping, Lock
     }
 
     private Literal literal( String s, String lang)
-    { return new LiteralImpl( NodeFactory.createLiteral( s, lang), this ); }
+    { return new LiteralImpl( NodeFactory.createLiteralLang( s, lang), this ); }
 
     private Literal literal( String lex, RDFDatatype datatype)
     { return new LiteralImpl( NodeFactory.createLiteral( lex, datatype), this ); }
@@ -377,7 +377,7 @@ public class ModelCom extends EnhGraph implements Model, PrefixMapping, Lock
         if (O != null) {
             // this is not OK when L is null: returns only the statements whose lang is ""
             // return listStatements( S, P, Node.createLiteral( O, L, false ) );
-            if (L != null) return listStatements( S, P, NodeFactory.createLiteral( O, L ) );
+            if (L != null) return listStatements( S, P, NodeFactory.createLiteralLang( O, L ) );
             // there's maybe a better way
             return new StringFilteredStmtIterator(O, listStatements(S, P, Node.ANY));
         } else {
diff --git a/jena-core/src/main/java/org/apache/jena/rdf/model/impl/SeqImpl.java b/jena-core/src/main/java/org/apache/jena/rdf/model/impl/SeqImpl.java
index 29810c42a7..fef164058f 100644
--- a/jena-core/src/main/java/org/apache/jena/rdf/model/impl/SeqImpl.java
+++ b/jena-core/src/main/java/org/apache/jena/rdf/model/impl/SeqImpl.java
@@ -342,7 +342,7 @@ public class SeqImpl extends ContainerImpl implements Seq {
     }
 
     private Literal literal( String s, String lang )
-        { return new LiteralImpl( NodeFactory.createLiteral( s, lang ), getModelCom() ); }
+        { return new LiteralImpl( NodeFactory.createLiteralLang( s, lang ), getModelCom() ); }
 
     protected void shiftUp(int start, int finish)  {
         Statement stmt = null;
diff --git a/jena-core/src/main/java/org/apache/jena/rdf/model/impl/StatementBase.java b/jena-core/src/main/java/org/apache/jena/rdf/model/impl/StatementBase.java
index 17d603d875..0d0044047d 100644
--- a/jena-core/src/main/java/org/apache/jena/rdf/model/impl/StatementBase.java
+++ b/jena-core/src/main/java/org/apache/jena/rdf/model/impl/StatementBase.java
@@ -61,7 +61,7 @@ public abstract class StatementBase
 	public abstract RDFNode getObject();
 
 	protected StatementImpl stringReplace(String s, String lang) {
-	    return replace(new LiteralImpl(NodeFactory.createLiteral(s, lang), model));
+	    return replace(new LiteralImpl(NodeFactory.createLiteralLang(s, lang), model));
 	}
 
 	/**
diff --git a/jena-core/src/main/java/org/apache/jena/rdfxml/xmlinput0/RDFXMLReader0.java b/jena-core/src/main/java/org/apache/jena/rdfxml/xmlinput0/RDFXMLReader0.java
index 5eed9df450..b452fa358d 100644
--- a/jena-core/src/main/java/org/apache/jena/rdfxml/xmlinput0/RDFXMLReader0.java
+++ b/jena-core/src/main/java/org/apache/jena/rdfxml/xmlinput0/RDFXMLReader0.java
@@ -124,7 +124,7 @@ public class RDFXMLReader0 implements RDFReaderI, ARPErrorNumbers {
     private static Node convert(ALiteral lit) {
         String dtURI = lit.getDatatypeURI();
         if (dtURI == null)
-            return NodeFactory.createLiteral(lit.toString(), lit.getLang());
+            return NodeFactory.createLiteralLang(lit.toString(), lit.getLang());
 
         if (lit.isWellFormedXML()) {
             return NodeFactory.createLiteral(lit.toString(), null, XMLLiteralType.theXMLLiteralType);
diff --git a/jena-core/src/main/java/org/apache/jena/rdfxml/xmlinput1/RDFXMLReader.java b/jena-core/src/main/java/org/apache/jena/rdfxml/xmlinput1/RDFXMLReader.java
index 03e7b895f6..2454ec6585 100644
--- a/jena-core/src/main/java/org/apache/jena/rdfxml/xmlinput1/RDFXMLReader.java
+++ b/jena-core/src/main/java/org/apache/jena/rdfxml/xmlinput1/RDFXMLReader.java
@@ -143,7 +143,7 @@ public class RDFXMLReader implements RDFReaderI, ARPErrorNumbers {
     private static Node convert(ALiteral lit) {
         String dtURI = lit.getDatatypeURI();
         if (dtURI == null)
-            return NodeFactory.createLiteral(lit.toString(), lit.getLang());
+            return NodeFactory.createLiteralLang(lit.toString(), lit.getLang());
 
         if (lit.isWellFormedXML()) {
             return NodeFactory.createLiteral(lit.toString(), null, XMLLiteralType.theXMLLiteralType);
diff --git a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/Rule.java b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/Rule.java
index bb22d17fb0..5a8dca72be 100755
--- a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/Rule.java
+++ b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/Rule.java
@@ -982,7 +982,7 @@ public class Rule implements ClauseEntry {
                 }
             }
             // Default is a plain literal
-            return NodeFactory.createLiteral(lit, "");
+            return NodeFactory.createLiteralLang(lit, "");
         }
 
         /**
diff --git a/jena-core/src/test/java/org/apache/jena/graph/test/TestNode.java b/jena-core/src/test/java/org/apache/jena/graph/test/TestNode.java
index 6385455030..bccaffde53 100644
--- a/jena-core/src/test/java/org/apache/jena/graph/test/TestNode.java
+++ b/jena-core/src/test/java/org/apache/jena/graph/test/TestNode.java
@@ -621,8 +621,8 @@ public class TestNode extends GraphTestBase
     {
         TypeMapper tm = TypeMapper.getInstance();
         RDFDatatype dtInt = tm.getTypeByValue( Integer.valueOf( 10 ) );
-        Node plain = NodeFactory.createLiteral( "rhubarb", "");
-        Node english = NodeFactory.createLiteral( "eccentric", "en_UK");
+        Node plain = NodeFactory.createLiteralLang( "rhubarb", "");
+        Node english = NodeFactory.createLiteralLang( "eccentric", "en_UK");
         Node typed = NodeFactory.createLiteral( "10", dtInt );
         assertEquals( "\"rhubarb\"", plain.toString() );
         assertEquals( "\"eccentric\"@en_UK", english.toString() );
diff --git a/jena-core/src/test/java/org/apache/jena/graph/test/TestTypedLiterals.java b/jena-core/src/test/java/org/apache/jena/graph/test/TestTypedLiterals.java
index 135e3178d4..50a31f61ee 100644
--- a/jena-core/src/test/java/org/apache/jena/graph/test/TestTypedLiterals.java
+++ b/jena-core/src/test/java/org/apache/jena/graph/test/TestTypedLiterals.java
@@ -18,8 +18,6 @@
 
 package org.apache.jena.graph.test;
 
-import static org.apache.jena.graph.NodeFactory.createLiteral;
-
 import java.math.BigDecimal ;
 import java.math.BigInteger ;
 import java.text.SimpleDateFormat ;
@@ -978,7 +976,7 @@ public class TestTypedLiterals extends TestCase {
      */
     public void testDateTimeBug3() {
         final String testLex = "-0001-02-03T04:05:06";
-        Node n = createLiteral(testLex, XSDDatatype.XSDdateTime);
+        Node n = NodeFactory.createLiteral(testLex, XSDDatatype.XSDdateTime);
         assertEquals("Got wrong XSDDateTime representation!", testLex, n.getLiteralValue().toString());
     }
 
diff --git a/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/test/TestFBRules.java b/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/test/TestFBRules.java
index 8c02ac41a8..55895fcc94 100644
--- a/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/test/TestFBRules.java
+++ b/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/test/TestFBRules.java
@@ -1027,7 +1027,7 @@ public class TestFBRules extends TestCase {
                        getSkolem(a, Util.makeIntNode(43)) );
 
         assertNotSame( getSkolem(a, NodeFactory.createLiteral("foo")),
-                       getSkolem(a, NodeFactory.createLiteral("foo", "en")) );
+                       getSkolem(a, NodeFactory.createLiteralLang("foo", "en")) );
 
         assertEquals( getSkolem(NodeFactory.createLiteral("foo")),
                 getSkolem(NodeFactory.createLiteral("foo")));
diff --git a/jena-core/src/test/java/org/apache/jena/test/JenaTestBase.java b/jena-core/src/test/java/org/apache/jena/test/JenaTestBase.java
index 0f50cad10e..ba51250053 100644
--- a/jena-core/src/test/java/org/apache/jena/test/JenaTestBase.java
+++ b/jena-core/src/test/java/org/apache/jena/test/JenaTestBase.java
@@ -29,177 +29,172 @@ import org.apache.jena.util.CollectionFactory ;
 import org.apache.jena.util.iterator.* ;
 
 /**
-    A basis for Jena test cases which provides assertFalse and assertDiffer.
-    Often the logic of the names is clearer than using a negation.
-*/
+ * A basis for Jena test cases which provides assertFalse and assertDiffer.
+ * Often the logic of the names is clearer than using a negation.
+ */
 public class JenaTestBase extends TestCase
-    {
-	static {
-		JenaSystem.init();
-	}
-    public JenaTestBase( String name )
-        { super( name ); }
-
-
-    /**
-        assert that the two objects must be unequal according to .equals().
-        @param title a labelling string for the assertion failure text
-        @param x an object to test; the subject of a .equals()
-        @param y the other object; the argument of the .equals()
-    */
-    public static void assertDiffer( String title, Object x, Object y )
-        {
-        if (x == null ? y == null : x.equals( y ))
-            fail( (title == null ? "objects should be different, but both were: " : title) + x );
-        }
+{
+	static { JenaSystem.init(); }
+
+    public JenaTestBase(String name) {
+        super(name);
+    }
 
     /**
-        assert that the two objects must be unequal according to .equals().
-        @param x an object to test; the subject of a .equals()
-        @param y the other object; the argument of the .equals()
-    */
-    public static void assertDiffer( Object x, Object y )
-        { assertDiffer( null, x, y ); }
+     * assert that the two objects must be unequal according to .equals().
+     *
+     * @param title a labelling string for the assertion failure text
+     * @param x an object to test; the subject of a .equals()
+     * @param y the other object; the argument of the .equals()
+     */
+    public static void assertDiffer(String title, Object x, Object y) {
+        if ( x == null ? y == null : x.equals(y) )
+            fail((title == null ? "objects should be different, but both were: " : title) + x);
+    }
 
     /**
-        assert that the object <code>x</code> must be of the class
-        <code>expected</code>.
-    */
-    public static void assertInstanceOf( Class<?> expected, Object x )
-        {
-        if (x == null)
-            fail( "expected instance of " + expected + ", but had null" );
-        if (!expected.isInstance( x ))
-            fail( "expected instance of " + expected + ", but had instance of " + x.getClass() );
-        }
+     * assert that the two objects must be unequal according to .equals().
+     *
+     * @param x an object to test; the subject of a .equals()
+     * @param y the other object; the argument of the .equals()
+     */
+    public static void assertDiffer(Object x, Object y) {
+        assertDiffer(null, x, y);
+    }
 
     /**
-    	Answer a Set formed from the elements of the List <code>L</code>.
-    */
-    public static <T> Set<T> listToSet( List<T> L )
-        { return CollectionFactory.createHashedSet( L ); }
+     * assert that the object <code>x</code> must be of the class
+     * <code>expected</code>.
+     */
+    public static void assertInstanceOf(Class<? > expected, Object x) {
+        if ( x == null )
+            fail("expected instance of " + expected + ", but had null");
+        if ( !expected.isInstance(x) )
+            fail("expected instance of " + expected + ", but had instance of " + x.getClass());
+    }
 
     /**
-        Answer a List of the substrings of <code>s</code> that are separated
-        by spaces.
-    */
-    public static List<String> listOfStrings( String s )
-        {
+     * Answer a Set formed from the elements of the List <code>L</code>.
+     */
+    public static <T> Set<T> listToSet(List<T> L) {
+        return CollectionFactory.createHashedSet(L);
+    }
+
+    /**
+     * Answer a List of the substrings of <code>s</code> that are separated by
+     * spaces.
+     */
+    public static List<String> listOfStrings(String s) {
         List<String> result = new ArrayList<>();
-        StringTokenizer st = new StringTokenizer( s );
-        while (st.hasMoreTokens()) result.add( st.nextToken() );
+        StringTokenizer st = new StringTokenizer(s);
+        while (st.hasMoreTokens())
+            result.add(st.nextToken());
         return result;
-        }
+    }
 
     /**
-        Answer a Set of the substrings of <code>s</code> that are separated
-        by spaces.
-    */
-    public static Set<String> setOfStrings( String s )
-        {
+     * Answer a Set of the substrings of <code>s</code> that are separated by spaces.
+     */
+    public static Set<String> setOfStrings(String s) {
         Set<String> result = new HashSet<>();
-        StringTokenizer st = new StringTokenizer( s );
-        while (st.hasMoreTokens()) result.add( st.nextToken() );
+        StringTokenizer st = new StringTokenizer(s);
+        while (st.hasMoreTokens())
+            result.add(st.nextToken());
         return result;
-        }
+    }
 
     /**
-        Answer a list containing the single object <code>x</code>.
-    */
-    public static <T> List<T> listOfOne( T x )
-        {
+     * Answer a list containing the single object <code>x</code>.
+     */
+    public static <T> List<T> listOfOne(T x) {
         List<T> result = new ArrayList<>();
-        result.add( x );
+        result.add(x);
         return result;
-        }
+    }
 
     /**
-        Answer a Set containing the single object <code>x</code>.
-    */
-    public static <T> Set<T> setOfOne( T x )
-        {
+     * Answer a Set containing the single object <code>x</code>.
+     */
+    public static <T> Set<T> setOfOne(T x) {
         Set<T> result = new HashSet<>();
-        result.add( x );
+        result.add(x);
         return result;
-        }
+    }
 
     /**
-        Answer a fresh list which is the concatenation of <code>L</code> then
-        <code>R</code>. Neither <code>L</code> nor <code>R</code> is updated.
-    */
-    public static <T> List<T> append( List<? extends T> L, List<? extends T> R )
-        { List<T> result = new ArrayList<>( L );
-        result.addAll( R );
-        return result; }
+     * Answer a fresh list which is the concatenation of <code>L</code> then
+     * <code>R</code>. Neither <code>L</code> nor <code>R</code> is updated.
+     */
+    public static <T> List<T> append(List<? extends T> L, List<? extends T> R) {
+        List<T> result = new ArrayList<>(L);
+        result.addAll(R);
+        return result;
+    }
 
     /**
-        Answer an iterator over the space-separated substrings of <code>s</code>.
-    */
-    protected static ExtendedIterator<String> iteratorOfStrings( String s )
-        { return WrappedIterator.create( listOfStrings( s ).iterator() ); }
+     * Answer an iterator over the space-separated substrings of <code>s</code>.
+     */
+    protected static ExtendedIterator<String> iteratorOfStrings(String s) {
+        return WrappedIterator.create(listOfStrings(s).iterator());
+    }
 
     /**
-        Do nothing; a way of notating that a test has succeeded, useful in the
-        body of a catch-block to silence excessively [un]helpful disgnostics.
-    */
-    public static void pass()
-        {}
+     * Do nothing; a way of notating that a test has succeeded, useful in the body of
+     * a catch-block to silence excessively [un]helpful disgnostics.
+     */
+    public static void pass() {}
 
     /**
-        Answer the constructor of the class <code>c</code> which takes arguments
-        of the type(s) in <code>args</code>, or <code>null</code> if there
-        isn't one.
-    */
-    public static Constructor<?> getConstructor( Class<?> c, Class<?> [] args )
-        {
-        try { return c.getConstructor( args ); }
-        catch (NoSuchMethodException e) { return null; }
+     * Answer the constructor of the class <code>c</code> which takes arguments of
+     * the type(s) in <code>args</code>, or <code>null</code> if there isn't one.
+     */
+    public static Constructor<? > getConstructor(Class<? > c, Class<? >[] args) {
+        try {
+            return c.getConstructor(args);
+        } catch (NoSuchMethodException e) {
+            return null;
         }
+    }
+
+    /**
+     * Answer true iff the method <code>m</code> is a public method which fits the
+     * pattern of being a test method, ie, test*() returning void.
+     */
+    public static boolean isPublicTestMethod(Method m) {
+        return Modifier.isPublic(m.getModifiers()) && isTestMethod(m);
+    }
+
+    /**
+     * Answer true iff the method <code>m</code> has a name starting "test", takes no
+     * arguments, and returns void; must catch junit tests, in other words.
+     */
+    public static boolean isTestMethod(Method m) {
+        return m.getName().startsWith("test") && m.getParameterTypes().length == 0 && m.getReturnType().equals(Void.TYPE);
+    }
 
     /**
-        Answer true iff the method <code>m</code> is a public method which fits
-        the pattern of being a test method, ie, test*() returning void.
-    */
-    public static boolean isPublicTestMethod( Method m )
-        { return Modifier.isPublic( m.getModifiers() ) && isTestMethod( m ); }
-
-    /**
-        Answer true iff the method <code>m</code> has a name starting "test",
-        takes no arguments, and returns void; must catch junit tests, in other
-        words.
-    */
-    public static boolean isTestMethod( Method m )
-        { return
-            m.getName().startsWith( "test" )
-            && m.getParameterTypes().length == 0
-            && m.getReturnType().equals( Void.TYPE ); }
-
-    /**
-         Answer true iff <code>subClass</code> is the same class as
-         <code>superClass</code>, if its superclass <i>is</i> <code>superClass</code>,
-         or if one of its interfaces hasAsInterface that class.
-    */
-    public static boolean hasAsParent( Class<?> subClass, Class<?> superClass )
-        {
-        if (subClass == superClass || subClass.getSuperclass() == superClass) return true;
-        Class<?> [] is = subClass.getInterfaces();
-            for ( Class<?> i1 : is )
-            {
-                if ( hasAsParent( i1, superClass ) )
-                {
-                    return true;
-                }
+     * Answer true iff <code>subClass</code> is the same class as
+     * <code>superClass</code>, if its superclass <i>is</i> <code>superClass</code>,
+     * or if one of its interfaces hasAsInterface that class.
+     */
+    public static boolean hasAsParent(Class<? > subClass, Class<? > superClass) {
+        if ( subClass == superClass || subClass.getSuperclass() == superClass )
+            return true;
+        Class<? >[] is = subClass.getInterfaces();
+        for ( Class<? > i1 : is ) {
+            if ( hasAsParent(i1, superClass) ) {
+                return true;
             }
-        return false;
         }
+        return false;
+    }
 
     /**
-         Fail unless <code>subClass</code> has <code>superClass</code> as a
-         parent, either a superclass or an implemented (directly or not) interface.
-    */
-    public static void assertHasParent( Class<?> subClass, Class<?> superClass )
-        {
-        if (hasAsParent( subClass, superClass ) == false)
-            fail( "" + subClass + " should have " + superClass + " as a parent" );
-        }
+     * Fail unless <code>subClass</code> has <code>superClass</code> as a parent,
+     * either a superclass or an implemented (directly or not) interface.
+     */
+    public static void assertHasParent(Class<? > subClass, Class<? > superClass) {
+        if ( hasAsParent(subClass, superClass) == false )
+            fail("" + subClass + " should have " + superClass + " as a parent");
     }
+}
diff --git a/jena-extras/jena-commonsrdf/src/main/java/org/apache/jena/commonsrdf/impl/JCR_Factory.java b/jena-extras/jena-commonsrdf/src/main/java/org/apache/jena/commonsrdf/impl/JCR_Factory.java
index 7c58d5c031..63577d4710 100644
--- a/jena-extras/jena-commonsrdf/src/main/java/org/apache/jena/commonsrdf/impl/JCR_Factory.java
+++ b/jena-extras/jena-commonsrdf/src/main/java/org/apache/jena/commonsrdf/impl/JCR_Factory.java
@@ -45,7 +45,7 @@ public class JCR_Factory {
 
     public static Literal createLiteralLang(String lexStr, String langTag) {
         langTag = LangTag.canonical(langTag);
-        return new JCR_Literal(NodeFactory.createLiteral(lexStr, langTag));
+        return new JCR_Literal(NodeFactory.createLiteralLang(lexStr, langTag));
     }
 
     public static BlankNode createBlankNode() {
diff --git a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredModelImpl.java b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredModelImpl.java
index b195ed6999..dce5207374 100644
--- a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredModelImpl.java
+++ b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredModelImpl.java
@@ -410,7 +410,7 @@ public class SecuredModelImpl extends SecuredItemImpl implements SecuredModel {
     public SecuredModel add(final Resource s, final Property p, final String o)
             throws UpdateDeniedException, AddDeniedException, AuthenticationRequiredException {
         checkUpdate();
-        checkCreate(Triple.create(s.asNode(), p.asNode(), NodeFactory.createLiteral(o, "")));
+        checkCreate(Triple.create(s.asNode(), p.asNode(), NodeFactory.createLiteralLang(o, "")));
         holder.getBaseItem().add(s, p, o);
         return holder.getSecuredItem();
     }
@@ -444,7 +444,7 @@ public class SecuredModelImpl extends SecuredItemImpl implements SecuredModel {
     public SecuredModel add(final Resource s, final Property p, final String o, final String l)
             throws UpdateDeniedException, AddDeniedException, AuthenticationRequiredException {
         checkUpdate();
-        checkCreate(Triple.create(s.asNode(), p.asNode(), NodeFactory.createLiteral(o, l)));
+        checkCreate(Triple.create(s.asNode(), p.asNode(), NodeFactory.createLiteralLang(o, l)));
         holder.getBaseItem().add(s, p, o, l);
         return holder.getSecuredItem();
     }
@@ -1428,7 +1428,7 @@ public class SecuredModelImpl extends SecuredItemImpl implements SecuredModel {
     @Override
     public SecuredStatement createStatement(final Resource s, final Property p, final String o, final String l)
             throws UpdateDeniedException, AddDeniedException, AuthenticationRequiredException {
-        Node n = NodeFactory.createLiteral(o, l);
+        Node n = NodeFactory.createLiteralLang(o, l);
         checkReadOrUpdate(s, p, holder.getBaseItem().getRDFNode(n));
         return SecuredStatementImpl.getInstance(holder.getSecuredItem(),
                 holder.getBaseItem().createStatement(s, p, o, l));
diff --git a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredResourceImpl.java b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredResourceImpl.java
index 03190f1890..cbde1532a9 100644
--- a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredResourceImpl.java
+++ b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredResourceImpl.java
@@ -274,7 +274,7 @@ public class SecuredResourceImpl extends SecuredRDFNodeImpl implements SecuredRe
     public SecuredResource addProperty(final Property p, final String o, final String l)
             throws UpdateDeniedException, AddDeniedException, AuthenticationRequiredException {
         checkUpdate();
-        checkCreate(Triple.create(holder.getBaseItem().asNode(), p.asNode(), NodeFactory.createLiteral(o, l)));
+        checkCreate(Triple.create(holder.getBaseItem().asNode(), p.asNode(), NodeFactory.createLiteralLang(o, l)));
         holder.getBaseItem().addProperty(p, o, l);
         return holder.getSecuredItem();
     }
diff --git a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredStatementImpl.java b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredStatementImpl.java
index 82817ad51c..59d800280b 100644
--- a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredStatementImpl.java
+++ b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredStatementImpl.java
@@ -265,7 +265,7 @@ public class SecuredStatementImpl extends SecuredItemImpl implements SecuredStat
         checkUpdate();
         final Triple base = holder.getBaseItem().asTriple();
         final Triple newBase = Triple.create(base.getSubject(), base.getPredicate(),
-                NodeFactory.createLiteral(o, l));
+                NodeFactory.createLiteralLang(o, l));
         checkUpdate(base, newBase);
         return SecuredStatementImpl.getInstance(getModel(), holder.getBaseItem().changeObject(o, l));
     }
@@ -442,7 +442,7 @@ public class SecuredStatementImpl extends SecuredItemImpl implements SecuredStat
     }
 
     private Triple getNewTriple(final Triple t, final Object o) {
-        return Triple.create(t.getSubject(), t.getPredicate(), NodeFactory.createLiteral(String.valueOf(o), ""));
+        return Triple.create(t.getSubject(), t.getPredicate(), NodeFactory.createLiteralLang(String.valueOf(o), ""));
     }
 
     /**
diff --git a/jena-shex/src/main/java/org/apache/jena/shex/parser/ParserShExC.java b/jena-shex/src/main/java/org/apache/jena/shex/parser/ParserShExC.java
index 3cf88cce99..30536733b1 100644
--- a/jena-shex/src/main/java/org/apache/jena/shex/parser/ParserShExC.java
+++ b/jena-shex/src/main/java/org/apache/jena/shex/parser/ParserShExC.java
@@ -715,7 +715,7 @@ public class ParserShExC extends LangParserBase {
         String lex = image.substring(quoteLen, idx-quoteLen);
         String lang = image.substring(idx+1);
         lex = unescapeStr(lex, line, column);
-        return NodeFactory.createLiteral(lex, lang);
+        return NodeFactory.createLiteralLang(lex, lang);
     }
 
     // Special case @ns: and @ns:foo.
diff --git a/jena-tdb1/src/test/java/org/apache/jena/tdb1/store/nodetable/AbstractTestNodeTable.java b/jena-tdb1/src/test/java/org/apache/jena/tdb1/store/nodetable/AbstractTestNodeTable.java
index ff2b8a9de3..23c0b292cf 100644
--- a/jena-tdb1/src/test/java/org/apache/jena/tdb1/store/nodetable/AbstractTestNodeTable.java
+++ b/jena-tdb1/src/test/java/org/apache/jena/tdb1/store/nodetable/AbstractTestNodeTable.java
@@ -82,7 +82,7 @@ public abstract class AbstractTestNodeTable
     @Test public void nodetable_07()    { testNode("'نواف'"); }
     @Test public void nodetable_08()    { testNode(SSE.parseNode("<<_:b :p 123>>")); }
 
-    static Node badNode1 = org.apache.jena.graph.NodeFactory.createLiteral("abc", "99bad");
+    static Node badNode1 = org.apache.jena.graph.NodeFactory.createLiteralLang("abc", "99bad");
 
     @Test public void nodetable_bad_01()    { testNodeBad(badNode1); }
     @Test public void nodetable_bad_02() {
diff --git a/jena-tdb1/src/test/java/org/apache/jena/tdb1/store/nodetable/TestNodec.java b/jena-tdb1/src/test/java/org/apache/jena/tdb1/store/nodetable/TestNodec.java
index eff1a071fa..fa54da6062 100644
--- a/jena-tdb1/src/test/java/org/apache/jena/tdb1/store/nodetable/TestNodec.java
+++ b/jena-tdb1/src/test/java/org/apache/jena/tdb1/store/nodetable/TestNodec.java
@@ -102,7 +102,7 @@ public class TestNodec
     @Test public void nodec_triple_terms_01()  {
         Node s = NodeFactory.createBlankNode("a");
         Node p = NodeFactory.createURI("http://ex/p");
-        Node o = NodeFactory.createLiteral("testcase", "en");
+        Node o = NodeFactory.createLiteralLang("testcase", "en");
         Node t = NodeFactory.createTripleNode(s, p, o);
         test (t);
     }
diff --git a/jena-text/src/main/java/org/apache/jena/query/text/TextIndexLucene.java b/jena-text/src/main/java/org/apache/jena/query/text/TextIndexLucene.java
index 599da2456b..7f69af11ae 100644
--- a/jena-text/src/main/java/org/apache/jena/query/text/TextIndexLucene.java
+++ b/jena-text/src/main/java/org/apache/jena/query/text/TextIndexLucene.java
@@ -559,7 +559,7 @@ public class TextIndexLucene implements TextIndex {
                         TypeMapper tmap = TypeMapper.getInstance();
                         literal = NodeFactory.createLiteral(lexical, tmap.getSafeTypeByName(datatype));
                     } else {
-                        literal = NodeFactory.createLiteral(lexical, doclang);
+                        literal = NodeFactory.createLiteralLang(lexical, doclang);
                     }
                 } else {
                     literal = NodeFactory.createLiteral(lexical);
@@ -666,7 +666,7 @@ public class TextIndexLucene implements TextIndex {
                 TextFragment[] frags = highlighter.getBestTextFragments(tokenStream, lexical, opts.joinFrags, opts.maxFrags);
                 String rez = frags2string(frags, opts);
                 log.trace("result: {}, #frags: {}", rez, frags.length) ;
-                literal = NodeFactory.createLiteral(rez, docLang);
+                literal = NodeFactory.createLiteralLang(rez, docLang);
             }
 
             String graf = docDef.getGraphField() != null ? doc.get(docDef.getGraphField()) : null ;
diff --git a/jena-text/src/test/java/org/apache/jena/query/text/TestDatasetWithLuceneStoredLiterals.java b/jena-text/src/test/java/org/apache/jena/query/text/TestDatasetWithLuceneStoredLiterals.java
index e5174d784a..f2983ccb6d 100644
--- a/jena-text/src/test/java/org/apache/jena/query/text/TestDatasetWithLuceneStoredLiterals.java
+++ b/jena-text/src/test/java/org/apache/jena/query/text/TestDatasetWithLuceneStoredLiterals.java
@@ -247,7 +247,7 @@ public class TestDatasetWithLuceneStoredLiterals extends AbstractTestDatasetWith
         Map<String,Literal> literals = doTestSearchWithLiterals(turtle, queryString, expectedURIs);
         Literal value = literals.get( RESOURCE_BASE + testName );
         assertNotNull(value);
-        assertEquals(NodeFactory.createLiteral("English language text", "en"), value.asNode());
+        assertEquals(NodeFactory.createLiteralLang("English language text", "en"), value.asNode());
     }
 
     @Test
diff --git a/jena-text/src/test/java/org/apache/jena/query/text/TestTextHighlighting.java b/jena-text/src/test/java/org/apache/jena/query/text/TestTextHighlighting.java
index 3c6c253151..e6ceab14eb 100644
--- a/jena-text/src/test/java/org/apache/jena/query/text/TestTextHighlighting.java
+++ b/jena-text/src/test/java/org/apache/jena/query/text/TestTextHighlighting.java
@@ -276,6 +276,6 @@ public class TestTextHighlighting extends AbstractTestDatasetWithTextIndexBase {
         
         Literal value = literals.get(RESOURCE_BASE + "testResultThreeInModelA");
         assertNotNull(value);
-        assertEquals(NodeFactory.createLiteral("bar ↦testResultThree↤ barfoo foo", "en"), value.asNode());
+        assertEquals(NodeFactory.createLiteralLang("bar ↦testResultThree↤ barfoo foo", "en"), value.asNode());
     }
 }


(jena) 08/10: Add tests (RDFString, ModelUtil, Lib)

Posted by an...@apache.org.
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 be56ea9e96295fe10e4291925db53272c01499bd
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Sun Dec 24 22:07:14 2023 +0000

    Add tests (RDFString, ModelUtil, Lib)
---
 .../main/java/org/apache/jena/atlas/lib/Lib.java   |   2 -
 .../java/org/apache/jena/atlas/lib/TS_Lib.java     |   8 +-
 .../org/apache/jena/atlas/lib/TestBaseLib.java     |  46 +++++++
 .../apache/jena/graph/test/TestPackage_graph.java  |   2 +
 .../jena/graph/test/TestRDFStringLiterals.java     | 145 +++++++++++++++++++++
 .../jena/rdf/model/test/AbstractTestPackage.java   |   4 +-
 .../java/org/apache/jena/test/TestModelUtil.java   |  96 ++++++++++++++
 .../org/apache/jena/test/TestPackage_core.java     |   2 +
 8 files changed, 295 insertions(+), 10 deletions(-)

diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java
index 5ae21d676d..0356e6c80f 100644
--- a/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java
+++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java
@@ -146,8 +146,6 @@ public class Lib
         return string.toUpperCase(Locale.ROOT);
     }
 
-
-
     public static final void sleep(int milliSeconds) {
         try  { Thread.sleep(milliSeconds); }
         catch (InterruptedException ex) { Log.warn(Lib.class, "interrupted", ex); }
diff --git a/jena-base/src/test/java/org/apache/jena/atlas/lib/TS_Lib.java b/jena-base/src/test/java/org/apache/jena/atlas/lib/TS_Lib.java
index df01eb86da..6d92b0e321 100644
--- a/jena-base/src/test/java/org/apache/jena/atlas/lib/TS_Lib.java
+++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/TS_Lib.java
@@ -28,7 +28,8 @@ import org.junit.runners.Suite ;
  */
 @RunWith(Suite.class)
 @Suite.SuiteClasses( {
-    TestAlg.class
+    TestBaseLib.class
+    , TestAlg.class
     , TestBitsLong.class
     , TestBitsInt.class
     , TestBytes.class
@@ -54,7 +55,4 @@ import org.junit.runners.Suite ;
     , TestPowerSet.class
 } )
 
-public class TS_Lib
-{
-
-}
+public class TS_Lib {}
diff --git a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestBaseLib.java b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestBaseLib.java
new file mode 100644
index 0000000000..a9aeeb50e9
--- /dev/null
+++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestBaseLib.java
@@ -0,0 +1,46 @@
+/*
+ * 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.atlas.lib;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+/** Tests for operations in {@link Lib} */
+public class TestBaseLib {
+    @Test public void lowercase_1() { assertEquals("",    Lib.lowercase("")); }
+    @Test public void lowercase_2() { assertEquals("abc", Lib.lowercase("AbC")); }
+    @Test public void lowercase_3() { assertEquals("abc", Lib.lowercase("ABC")); }
+    @Test public void lowercase_4() { assertEquals("abc", Lib.lowercase("abc")); }
+
+    @Test public void uppercase_1() { assertEquals("",    Lib.uppercase("")); }
+    @Test public void uppercase_2() { assertEquals("ABC", Lib.uppercase("AbC")); }
+    @Test public void uppercase_3() { assertEquals("ABC", Lib.uppercase("ABC")); }
+    @Test public void uppercase_4() { assertEquals("ABC", Lib.uppercase("abc")); }
+
+    @Test public void isEmpty_1() { assertEquals(true, Lib.isEmpty("")); }
+    @Test public void isEmpty_2() { assertEquals(true, Lib.isEmpty(null)); }
+    @Test public void isEmpty_3() { assertEquals(false, Lib.isEmpty("X")); }
+
+    @Test public void concatpaths_1() { assertEquals("A/B", Lib.concatPaths("A", "B")); }
+    @Test public void concatpaths_2() { assertEquals("A/B", Lib.concatPaths("A/", "B")); }
+    @Test public void concatpaths_3() { assertEquals("/B", Lib.concatPaths("A", "/B")); }
+    @Test public void concatpaths_4() { assertEquals("A", Lib.concatPaths("A", "")); }
+    @Test public void concatpaths_5() { assertEquals("A/", Lib.concatPaths("A/", "")); }
+}
diff --git a/jena-core/src/test/java/org/apache/jena/graph/test/TestPackage_graph.java b/jena-core/src/test/java/org/apache/jena/graph/test/TestPackage_graph.java
index 9431f4df45..5236ca13b5 100644
--- a/jena-core/src/test/java/org/apache/jena/graph/test/TestPackage_graph.java
+++ b/jena-core/src/test/java/org/apache/jena/graph/test/TestPackage_graph.java
@@ -54,8 +54,10 @@ public class TestPackage_graph extends TestSuite {
         addTestSuite( TestGraphEvents.class );
         addTestSuite( TestGraphBaseToString.class );
         addTest( new JUnit4TestAdapter(TestNodeExtras.class) );
+        addTest( new JUnit4TestAdapter(TestRDFStringLiterals.class) );
 
         // Has to be in a different package.
         addTest( new JUnit4TestAdapter(TestGraphUtil.class) );
+
     }
 }
diff --git a/jena-core/src/test/java/org/apache/jena/graph/test/TestRDFStringLiterals.java b/jena-core/src/test/java/org/apache/jena/graph/test/TestRDFStringLiterals.java
new file mode 100644
index 0000000000..49bbb0bed8
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/graph/test/TestRDFStringLiterals.java
@@ -0,0 +1,145 @@
+/*
+ * 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.graph.test;
+
+import static org.apache.jena.graph.TextDirection.*;
+import static org.junit.Assert.assertEquals;
+
+import org.apache.jena.datatypes.RDFDatatype;
+import org.apache.jena.datatypes.xsd.XSDDatatype;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.graph.TextDirection;
+import org.apache.jena.shared.JenaException;
+import org.apache.jena.vocabulary.RDF;
+import org.junit.Test;
+
+/** Tests for create RDF Terms (@link Node Nodes}) involving strings
+ * (xsd:string, rdf:langString, rdf:dirLangString).
+ * Initial text direction introduced in RDF 1.2.
+ */
+public class TestRDFStringLiterals {
+
+    private static TextDirection noTextDirection = Node.noTextDirection;
+    private static String noLangTag = Node.noLangTag;
+
+    // ---- xsd:string
+
+    @Test public void string01() {
+        Node n = NodeFactory.createLiteralString("abc");
+        test(n, "abc", "", noTextDirection , XSDDatatype.XSDstring, "abc");
+    }
+
+    @Test public void string02() {
+        Node n = NodeFactory.createLiteralLang("abc", null);
+        test(n, "abc", "", null, XSDDatatype.XSDstring, "abc");
+    }
+
+    @Test public void string03() {
+        Node n = NodeFactory.createLiteralDirLang("abc", null, (String)null);
+        test(n, "abc", "", null, XSDDatatype.XSDstring, "abc");
+    }
+
+    @Test public void string04() {
+        Node n = NodeFactory.createLiteralDirLang("abc", "", "");
+        test(n, "abc", "", null, XSDDatatype.XSDstring, "abc");
+    }
+
+    // ---- rdf:langString
+
+    @Test public void strLang01() {
+        Node n = NodeFactory.createLiteralLang("abc", "en");
+        test(n, "abc", "en", null, RDF.dtLangString, "abc@en");
+    }
+
+    @Test public void strLang02() {
+        Node n = NodeFactory.createLiteralLang("abc", "EN");
+        test(n, "abc", "en", null, RDF.dtLangString, "abc@en");
+    }
+
+    @Test public void strLang03() {
+        Node n = NodeFactory.createLiteralLang("abc", "");
+        test(n, "abc", "", null, XSDDatatype.XSDstring, "abc");
+    }
+
+    // Make with explicit no text direction.
+
+    @Test public void strLang04() {
+        Node n = NodeFactory.createLiteralDirLang("abc", null, (String)null);
+        test(n, "abc", "", null, XSDDatatype.XSDstring, "abc");
+    }
+
+    @Test public void strLang05() {
+        // "" is a convenience of no direction.
+        Node n = NodeFactory.createLiteralDirLang("abc", "", "");
+        test(n, "abc", "", null, XSDDatatype.XSDstring, "abc");
+    }
+
+
+    // ---- rdf:dirLangString
+
+    @Test public void dirLangString01() {
+        Node n = NodeFactory.createLiteralDirLang("abc", "en", "rtl");
+        test(n, "abc", "en", RTL, RDF.dtDirLangString, "abc@en");
+    }
+
+    @Test public void dirLangString02() {
+        Node n = NodeFactory.createLiteralDirLang("abc", "en", "LTR");
+        test(n, "abc", "en", LTR, RDF.dtDirLangString, "abc@en");
+    }
+
+    // Errors
+
+    @Test(expected=JenaException.class)
+    public void rdfStringBad01() {
+        // No lang but with a direction
+        Node n = NodeFactory.createLiteralDirLang("abc", null, TextDirection.LTR);
+    }
+
+    @Test(expected=JenaException.class)
+    public void rdfStringBad02() {
+        // No lang but with a direction
+        Node n = NodeFactory.createLiteralDirLang("abc", "", TextDirection.LTR);
+    }
+
+    @Test(expected=NullPointerException.class)
+    public void rdfStringBad03() {
+        Node n = NodeFactory.createLiteralString((String)null);
+    }
+
+    @Test(expected=NullPointerException.class)
+    public void rdfStringBad04() {
+        Node n = NodeFactory.createLiteralLang((String)null, "en");
+    }
+
+    @Test(expected=NullPointerException.class)
+    public void rdfStringBad05() {
+        Node n = NodeFactory.createLiteralDirLang((String)null, "en", TextDirection.LTR);
+    }
+
+    // ----
+
+    private static void test(Node node, String lexicalForm, String lang, TextDirection textDir, RDFDatatype datatype, String indexingValue) {
+        assertEquals("Lexical form:", lexicalForm, node.getLiteralLexicalForm());
+        assertEquals("Language:", lang, node.getLiteralLanguage());
+        assertEquals("Text Direction:", textDir, node.getLiteralTextDirection());
+        assertEquals("Datatype:", datatype, node.getLiteralDatatype());
+        assertEquals("Indexing:", indexingValue, node.getIndexingValue());
+    }
+}
diff --git a/jena-core/src/test/java/org/apache/jena/rdf/model/test/AbstractTestPackage.java b/jena-core/src/test/java/org/apache/jena/rdf/model/test/AbstractTestPackage.java
index 554c02daef..eb1ac6cf69 100644
--- a/jena-core/src/test/java/org/apache/jena/rdf/model/test/AbstractTestPackage.java
+++ b/jena-core/src/test/java/org/apache/jena/rdf/model/test/AbstractTestPackage.java
@@ -56,9 +56,7 @@ public abstract class AbstractTestPackage extends TestSuite
 	 * @throws IllegalAccessException
 	 * @throws InvocationTargetException
 	 */
-	protected AbstractTestPackage( final String suiteName,
-			final TestingModelFactory modelFactory )
-	{
+	protected AbstractTestPackage( String suiteName, TestingModelFactory modelFactory ) {
 		super(suiteName);
 
 		addTest(TestModelFactory.class);
diff --git a/jena-core/src/test/java/org/apache/jena/test/TestModelUtil.java b/jena-core/src/test/java/org/apache/jena/test/TestModelUtil.java
new file mode 100644
index 0000000000..a9d1b92b89
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/test/TestModelUtil.java
@@ -0,0 +1,96 @@
+/*
+ * 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.test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import junit.framework.TestSuite;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.rdf.model.impl.Util;
+import org.junit.Test;
+
+/** Tests for {@link org.apache.jena.rdf.model.impl.Util} */
+public class TestModelUtil extends TestSuite {
+
+    public static TestSuite suite() {
+        return new TestSuite(TestModelUtil.class);
+    }
+
+    // -- xsd:string
+
+    @Test public void testIsSimpleString1() {
+        Node n = NodeFactory.createLiteralString("abc");
+        assertTrue(Util.isSimpleString(n));
+        assertFalse(Util.isLangString(n));
+        assertFalse(Util.isDirLangString(n));
+        assertFalse(Util.hasLang(n));
+        assertFalse(Util.hasDirection(n));
+    }
+
+    @Test public void testIsSimpleString2() {
+        Node n = NodeFactory.createLiteralLang("abc", "");
+        assertTrue(Util.isSimpleString(n));
+        assertFalse(Util.isLangString(n));
+        assertFalse(Util.isDirLangString(n));
+        assertFalse(Util.hasLang(n));
+        assertFalse(Util.hasDirection(n));
+    }
+
+    @Test public void testIsSimpleString3() {
+        Node n = NodeFactory.createLiteralDirLang("abc", "", (String)null);
+        assertTrue(Util.isSimpleString(n));
+        assertFalse(Util.isLangString(n));
+        assertFalse(Util.isDirLangString(n));
+        assertFalse(Util.hasLang(n));
+        assertFalse(Util.hasDirection(n));
+    }
+
+    // -- rdf:langString
+
+    @Test public void testIsLangString1() {
+        Node n = NodeFactory.createLiteralLang("abc", "en-GB");
+        assertFalse(Util.isSimpleString(n));
+        assertTrue(Util.isLangString(n));
+        assertFalse(Util.isDirLangString(n));
+        assertTrue(Util.hasLang(n));
+        assertFalse(Util.hasDirection(n));
+    }
+
+    @Test public void testIsLangString2() {
+        Node n =  NodeFactory.createLiteralDirLang("abc", "en-GB", (String)null);
+        assertFalse(Util.isSimpleString(n));
+        assertTrue(Util.isLangString(n));
+        assertFalse(Util.isDirLangString(n));
+        assertTrue(Util.hasLang(n));
+        assertFalse(Util.hasDirection(n));
+    }
+
+    // -- rdf:dirLangString (only one way to make it)
+
+    @Test public void testIsDirLangString1() {
+        Node n =  NodeFactory.createLiteralDirLang("abc", "en-GB", "ltr");
+        assertFalse(Util.isSimpleString(n));
+        assertFalse(Util.isLangString(n));
+        assertTrue(Util.isDirLangString(n));
+        assertTrue(Util.hasLang(n));
+        assertTrue(Util.hasDirection(n));
+    }
+}
diff --git a/jena-core/src/test/java/org/apache/jena/test/TestPackage_core.java b/jena-core/src/test/java/org/apache/jena/test/TestPackage_core.java
index a953267149..cb3e7507be 100644
--- a/jena-core/src/test/java/org/apache/jena/test/TestPackage_core.java
+++ b/jena-core/src/test/java/org/apache/jena/test/TestPackage_core.java
@@ -43,6 +43,7 @@ public class TestPackage_core extends TestCase {
         addTest(ts,  "Mem", org.apache.jena.mem.test.TestMemPackage.suite() );
         addTest(ts,  "Mem2", org.apache.jena.mem.test.TestGraphMemPackage.suite() );
         addTest(ts,  "Model", org.apache.jena.rdf.model.test.TestPackage_model.suite());
+
         addTest(ts,  "StandardModels", org.apache.jena.rdf.model.test.TestStandardModels.suite() );
         // Currently, "ARP[IRIx]"
         addTest(ts,  "XML Input", org.apache.jena.rdfxml.xmlinput1.TestPackage_xmlinput1.suite());
@@ -62,6 +63,7 @@ public class TestPackage_core extends TestCase {
 
         // Local TTL parser for tests - not fully compliant.
         addTest(ts,  "Turtle", org.apache.jena.ttl_test.test.turtle.TurtleTestSuite.suite()) ;
+        addTest(ts,  "ModelUtils", org.apache.jena.test.TestModelUtil.suite());
 
         return ts ;
     }