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 2025/07/20 18:20:28 UTC

(jena) branch main updated (191ed13769 -> ed40acfe53)

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 191ed13769 CHANGES for Jena 5.5.0
     new 7ab18bd17b Remove out-of-date comments
     new 44959c1027 Replace use of TestEnv in TestGSP and TestDSP
     new 6ade8335a3 Address deprecation warnings
     new c349ea6892 Improve port warning about HTTP/HTTP
     new 8fdd316f2d Correct IRI user info message
     new af87ae0720 Tidy code
     new f03da03386 Make adding commands more robust
     new 754f6cf114 GH-3319: Write only the request mode, without assembler RDFS
     new ff9a14c6f6 Add G.listLength
     new 90067cd577 Allow override of ExprNode.getVarsMentioned()
     new b8b5864a05 Single-threaded LRU cache based on LinkedHashMap
     new abbb08b1c6 Include test with a JSON-LD document cache
     new 066dacaccd GH-3317: Suppress SIS warnings
     new ed40acfe53 GH-3318: Log duplicate database entries

The 14 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/sparql/expr/ExprNode.java |   2 +-
 .../java/org/apache/jena/sparql/expr/ExprVar.java  |   2 +-
 .../apache/jena/sparql/util/graph/GraphList.java   |  65 +++----
 .../src/main/java/org/apache/jena/system/G.java    |  10 +
 .../jena/riot/lang/TestLangJsonLD_DocLoader.java   |  52 +++++-
 .../java/org/apache/jena/atlas/lib/AlarmClock.java |   2 +-
 .../main/java/org/apache/jena/atlas/lib/Cache.java |   2 +-
 .../org/apache/jena/atlas/lib/CacheFactory.java    |   8 +
 .../org/apache/jena/atlas/lib/cache/CacheOps.java  |   6 +-
 .../apache/jena/atlas/lib/cache/CachePlainLRU.java | 122 ++++++++++++
 .../java/org/apache/jena/atlas/lib/TestCache.java  | 179 +++++++++---------
 .../java/org/apache/jena/atlas/lib/TestCache2.java |  25 ++-
 .../src/main/java/org/apache/jena/cmd/Cmds.java    |  12 +-
 .../xsd/impl/XSDAbstractDateTimeType.java          |  39 ++--
 .../main/java/org/apache/jena/util/FileUtils.java  |   5 +-
 .../org/apache/jena/rdfxml/xmlinput1/TestURIs.java |   2 +-
 .../apache/jena/fuseki/main/cmds/FusekiMain.java   |  40 ++--
 .../org/apache/jena/fuseki/mgt/ActionDatasets.java |   6 +-
 .../apache/jena/fuseki/mod/FusekiServerRunner.java |  14 +-
 .../apache/jena/fuseki/mod/admin/FMod_Admin.java   |  24 ++-
 .../mod/admin/TestAdminAddDatasetTemplate.java     |   2 +-
 .../org/apache/jena/geosparql/InitGeoSPARQL.java   |  11 +-
 .../org/apache/jena/sparql/exec/http/TestDSP.java  |  51 +++--
 .../org/apache/jena/sparql/exec/http/TestGSP.java  | 205 ++++++++++-----------
 .../java/org/apache/jena/test/conn/EnvTest.java    |   2 +-
 .../main/java/org/apache/jena/rfc3986/IRI3986.java |   6 +-
 .../java/org/apache/jena/shacl/test_vocab/SHT.java |  14 +-
 27 files changed, 548 insertions(+), 360 deletions(-)
 create mode 100644 jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CachePlainLRU.java


(jena) 07/14: Make adding commands more robust

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 f03da03386bfe833baca61f2811f5ff5066cfb20
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Tue Jul 15 21:18:04 2025 +0100

    Make adding commands more robust
---
 jena-cmds/src/main/java/org/apache/jena/cmd/Cmds.java | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/jena-cmds/src/main/java/org/apache/jena/cmd/Cmds.java b/jena-cmds/src/main/java/org/apache/jena/cmd/Cmds.java
index 8b9567867b..a879fd982f 100644
--- a/jena-cmds/src/main/java/org/apache/jena/cmd/Cmds.java
+++ b/jena-cmds/src/main/java/org/apache/jena/cmd/Cmds.java
@@ -18,8 +18,8 @@
 
 package org.apache.jena.cmd;
 
-import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Consumer;
 
 import org.apache.jena.sys.JenaSystem;
@@ -32,15 +32,11 @@ public class Cmds {
 
     static { JenaSystem.init(); }
 
-    private static Map<String, Consumer<String[]>> cmds;
+    private static Map<String, Consumer<String[]>> cmds = new ConcurrentHashMap<>();
+    private static Object lock = new Object();
 
     // Initialize via JenaSubsystemLifecycle and not rely on class initialization.
-    static void init() {
-        // Initialization should be minimal, just enough to allow modules to register commands.
-        // We may be inside some other place where JenaSystem.init() was called.
-        if ( cmds == null )
-            cmds = new HashMap<>();
-    }
+    static void init() {}
 
     public static void injectCmd(String name, Consumer<String[]> main) {
         cmds.put(name, main);


(jena) 08/14: GH-3319: Write only the request mode, without assembler RDFS

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 754f6cf114051cf3cd8146b7d718a28a1f4ccb90
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Wed Jul 16 12:24:08 2025 +0100

    GH-3319: Write only the request mode, without assembler RDFS
---
 .../src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java    | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java
index 5736235c3f..544eeaf081 100644
--- a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java
+++ b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java
@@ -247,7 +247,7 @@ public class ActionDatasets extends ActionContainerItem {
                 // Keep a persistent copy with a globally unique name.
                 // This is not used for anything other than being "for the record".
                 systemFileCopy = FusekiServerCtl.dirSystemFileArea.resolve(uuid.toString()).toString();
-                RDFWriter.source(model).lang(Lang.TURTLE).output(systemFileCopy);
+                RDFWriter.source(modelFromRequest).lang(Lang.TURTLE).output(systemFileCopy);
 
                 // ----
                 action.log.info(format("[%d] Create database : name = %s", action.id, datasetPath));
@@ -267,8 +267,8 @@ public class ActionDatasets extends ActionContainerItem {
                 }
                 dataAccessPoint.getDataService().setEndpointProcessors(action.getOperationRegistry());
 
-                // Write to configuration directory.
-                RDFWriter.source(model).lang(Lang.TURTLE).output(configFile);
+                // Write to configuration directory (without assembler additional details).
+                RDFWriter.source(modelFromRequest).lang(Lang.TURTLE).output(configFile);
 
                 if ( ! datasetPath.equals(dataAccessPoint.getName()) )
                     FmtLog.warn(action.log, "Inconsistent names: datasetPath = %s; DataAccessPoint name = %s", datasetPath, dataAccessPoint);


(jena) 12/14: Include test with a JSON-LD document cache

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 abbb08b1c6d6f1d172ae14fe1b7b7d2a52fdc544
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Fri Jul 18 12:06:50 2025 +0100

    Include test with a JSON-LD document cache
---
 .../jena/riot/lang/TestLangJsonLD_DocLoader.java   | 52 +++++++++++++++++++---
 1 file changed, 45 insertions(+), 7 deletions(-)

diff --git a/jena-arq/src/test/java/org/apache/jena/riot/lang/TestLangJsonLD_DocLoader.java b/jena-arq/src/test/java/org/apache/jena/riot/lang/TestLangJsonLD_DocLoader.java
index bc165f88b4..f0bd4fcffa 100644
--- a/jena-arq/src/test/java/org/apache/jena/riot/lang/TestLangJsonLD_DocLoader.java
+++ b/jena-arq/src/test/java/org/apache/jena/riot/lang/TestLangJsonLD_DocLoader.java
@@ -19,12 +19,15 @@
 package org.apache.jena.riot.lang;
 
 import static org.apache.jena.riot.Lang.JSONLD11;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.net.URI;
 
 import com.apicatalog.jsonld.JsonLdError;
 import com.apicatalog.jsonld.JsonLdOptions;
+import com.apicatalog.jsonld.context.cache.Cache;
+import com.apicatalog.jsonld.context.cache.LruCache;
 import com.apicatalog.jsonld.document.Document;
 import com.apicatalog.jsonld.document.JsonDocument;
 import com.apicatalog.jsonld.loader.DocumentLoader;
@@ -48,33 +51,68 @@ public class TestLangJsonLD_DocLoader {
 
     @Test
     public void testGetJsonLdOptions() {
+        TestDocumentLoader loader = new TestDocumentLoader();
+        Context context = setupContext(loader, false);
+
         StreamRDF sink = StreamRDFLib.sinkNull();
         RDFParser parser = RDFParserBuilder.create()
-                .context(setupContext())
+                .context(context)
                 .lang(JSONLD11)
                 .fromString(CONTENT)
                 .build();
         parser.parse(sink);
 
-        // Check called at least once.
-        assertTrue(TestDocumentLoader.COUNTER > 0, ()->"Custom DocumentLoader wasn't called to handle loading");
+        int count1 = loader.COUNTER;
+
+        // By observation, it's actually called twice
+        assertTrue(count1 >= 1 , ()->"Custom DocumentLoader wasn't called to handle loading");
+
+        parser.parse(sink);
+        int count2 = loader.COUNTER;
+        assertTrue(count2 > count1 , ()->"Custom DocumentLoader wasn't called during second parser run");
     }
 
-    private final Context setupContext() {
+    @Test
+    public void testGetJsonLdOptionsWithCache() {
         TestDocumentLoader loader = new TestDocumentLoader();
+        Context context = setupContext(loader, true);
+
+        StreamRDF sink = StreamRDFLib.sinkNull();
+        RDFParser parser = RDFParserBuilder.create()
+                .context(context)
+                .lang(JSONLD11)
+                .fromString(CONTENT)
+                .build();
+
+        parser.parse(sink);
+        int count1 = loader.COUNTER;
+
+        assertEquals(1, count1, ()->"Custom DocumentLoader wasn't called to handle loading");
+
+        parser.parse(sink);
+        int count2 = loader.COUNTER;
+
+        assertTrue(count2 == count1 , ()->"Custom DocumentCache wasn't used during second parser run");
+    }
+
+    private final Context setupContext(TestDocumentLoader docLoader, boolean withCache) {
         JsonLdOptions opts = new JsonLdOptions();
 
-        opts.setDocumentLoader(loader);
+        opts.setDocumentLoader(docLoader);
+
+        if ( withCache ) {
+            Cache<String, Document> documentCache = new LruCache<>(256);
+            opts.setDocumentCache(documentCache);
+        }
 
         Context context = new Context();
         context.set(LangJSONLD11.JSONLD_OPTIONS, opts);
-
         return context;
     }
 
     private final static class TestDocumentLoader implements DocumentLoader {
 
-        public static int COUNTER = 0;
+        public int COUNTER = 0;
 
         @Override
         public Document loadDocument(URI url, DocumentLoaderOptions options) throws JsonLdError {


(jena) 13/14: GH-3317: Suppress SIS warnings

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 066dacaccd2b21499e8ef3392d0dd3eb44a9db87
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Fri Jul 18 17:21:45 2025 +0100

    GH-3317: Suppress SIS warnings
---
 .../main/java/org/apache/jena/geosparql/InitGeoSPARQL.java    | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/jena-geosparql/src/main/java/org/apache/jena/geosparql/InitGeoSPARQL.java b/jena-geosparql/src/main/java/org/apache/jena/geosparql/InitGeoSPARQL.java
index e32482a1a6..72c41907fd 100644
--- a/jena-geosparql/src/main/java/org/apache/jena/geosparql/InitGeoSPARQL.java
+++ b/jena-geosparql/src/main/java/org/apache/jena/geosparql/InitGeoSPARQL.java
@@ -18,7 +18,10 @@
 
 package org.apache.jena.geosparql;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.apache.jena.assembler.Assembler;
+import org.apache.jena.atlas.logging.LogCtl;
 import org.apache.jena.atlas.logging.LogCtlJUL;
 import org.apache.jena.geosparql.assembler.GeoAssembler;
 import org.apache.jena.geosparql.assembler.VocabGeoSPARQL;
@@ -52,9 +55,13 @@ public class InitGeoSPARQL implements JenaSubsystemLifecycle {
             LogCtlJUL.routeJULtoSLF4J();
             JenaSystem.logLifecycle("InitGeoSPARQL - start");
             GeometryDatatype.registerDatatypes();
-            // Logs "SIS_DATA is not set"
-            GeoSPARQLConfig.loadFunctions();
+
+            // Logs "SIS_DATA is not set" on "org.apache.sis.system"
+            Logger SIS_SystemLogger = LoggerFactory.getLogger("org.apache.sis.system");
+            LogCtl.withLevel(SIS_SystemLogger, "ERROR", ()->GeoSPARQLConfig.loadFunctions());
+
             Assembler assembler = new GeoAssembler();
+
             AssemblerUtils.registerDataset(VocabGeoSPARQL.tGeoDataset,    assembler);
             AssemblerUtils.registerDataset(VocabGeoSPARQL.tGeoDatasetAlt, assembler);
             JenaSystem.logLifecycle("InitGeoSPARQL - finish");


(jena) 02/14: Replace use of TestEnv in TestGSP and TestDSP

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 44959c1027dc55aadc70cde4fa9121ea11ce4dda
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Mon Jul 14 07:48:17 2025 +0100

    Replace use of TestEnv in TestGSP and TestDSP
---
 .../org/apache/jena/sparql/exec/http/TestDSP.java  |  51 +++--
 .../org/apache/jena/sparql/exec/http/TestGSP.java  | 205 ++++++++++-----------
 .../java/org/apache/jena/test/conn/EnvTest.java    |   2 +-
 3 files changed, 127 insertions(+), 131 deletions(-)

diff --git a/jena-integration-tests/src/test/java/org/apache/jena/sparql/exec/http/TestDSP.java b/jena-integration-tests/src/test/java/org/apache/jena/sparql/exec/http/TestDSP.java
index 0ae8198fab..00e037912a 100644
--- a/jena-integration-tests/src/test/java/org/apache/jena/sparql/exec/http/TestDSP.java
+++ b/jena-integration-tests/src/test/java/org/apache/jena/sparql/exec/http/TestDSP.java
@@ -26,41 +26,52 @@ import static org.junit.Assert.assertTrue;
 
 import java.io.StringReader;
 
-import org.apache.jena.fuseki.main.ConfigureTests;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.jena.fuseki.main.FusekiServer;
 import org.apache.jena.http.HttpOp;
 import org.apache.jena.riot.Lang;
 import org.apache.jena.riot.RDFDataMgr;
 import org.apache.jena.sparql.core.DatasetGraph;
 import org.apache.jena.sparql.core.DatasetGraphFactory;
 import org.apache.jena.sparql.util.IsoMatcher;
-import org.apache.jena.test.conn.EnvTest;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
 
 public class TestDSP {
 
     static String DIR = "testing/RDFLink/";
 
-    private static EnvTest env;
-    @BeforeClass public static void beforeClass() {
-        env = EnvTest.create("/ds");
-    }
+    private FusekiServer server = null;
+    private final String dsName = "/data";
+    private final boolean verbose = false;
 
-    @Before public void before() {
-        env.clear();
+
+    @Before public void makeServer() {
+        DatasetGraph dsg = DatasetGraphFactory.createTxnMem();
+        server = FusekiServer.create()
+                .verbose(verbose)
+                .enablePing(true)
+                //.addServlet(data, holder)
+                .add(dsName, dsg)
+                .build()
+                .start();
     }
 
-    @AfterClass public static void afterClass() {
-        if ( ConfigureTests.CloseTestServers )
-            EnvTest.stop(env);
+    @After public void releaseServer() {
+        if ( server != null )
+            server.stop();
     }
 
-    private String url(String path) { return env.datasetPath(path); }
 
-    // Test DSP against the dataset itself.
-    static String dspServiceURL()   { return env.datasetPath("/"); }
+    private String url(String path) {
+        return server.datasetURL(path);
+    }
+
+    // GSP endpoint
+    private String dspServiceURL() {
+        return url(dsName);
+    }
 
     static DatasetGraph dataset = makeDatasetGraph();
     static DatasetGraph makeDatasetGraph() {
@@ -89,13 +100,13 @@ public class TestDSP {
     public void dsp_clear_01() {
         // DELETE on the GSP endpoint would be the default graph.
         // DELETE on the dataset endpoint is not supported by Fuseki - this does "CLER ALL"
-        DSP.service(env.datasetURL()).clear();
+        DSP.service(dspServiceURL()).clear();
     }
 
     @Test
     public void dsp_clear_02() {
         DSP.service(dspServiceURL()).POST(dataset);
-        DSP.service(env.datasetURL()).clear();
+        DSP.service(dspServiceURL()).clear();
         DatasetGraph dsg = DSP.service(dspServiceURL()).GET();
         assertFalse(dsg.find().hasNext());
     }
diff --git a/jena-integration-tests/src/test/java/org/apache/jena/sparql/exec/http/TestGSP.java b/jena-integration-tests/src/test/java/org/apache/jena/sparql/exec/http/TestGSP.java
index 942caa643b..7ad53c8a58 100644
--- a/jena-integration-tests/src/test/java/org/apache/jena/sparql/exec/http/TestGSP.java
+++ b/jena-integration-tests/src/test/java/org/apache/jena/sparql/exec/http/TestGSP.java
@@ -18,153 +18,145 @@
 
 package org.apache.jena.sparql.exec.http;
 
+import static org.apache.jena.fuseki.test.HttpTest.expect400;
+import static org.apache.jena.fuseki.test.HttpTest.expect404;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
-import java.io.StringReader;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
 
 import org.apache.jena.atlas.web.HttpException;
-import org.apache.jena.fuseki.main.ConfigureTests;
-
-import static org.apache.jena.fuseki.test.HttpTest.*;
+import org.apache.jena.fuseki.main.FusekiServer;
 import org.apache.jena.graph.Graph;
 import org.apache.jena.graph.Node;
 import org.apache.jena.graph.NodeFactory;
 import org.apache.jena.http.HttpOp;
 import org.apache.jena.riot.Lang;
-import org.apache.jena.riot.RDFDataMgr;
 import org.apache.jena.riot.RDFFormat;
+import org.apache.jena.riot.RDFParser;
 import org.apache.jena.riot.WebContent;
 import org.apache.jena.sparql.core.DatasetGraph;
 import org.apache.jena.sparql.core.DatasetGraphFactory;
 import org.apache.jena.sparql.graph.GraphFactory;
 import org.apache.jena.sparql.sse.SSE;
 import org.apache.jena.sparql.util.IsoMatcher;
-import org.apache.jena.test.conn.EnvTest;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
 
 public class TestGSP {
 
     static String DIR = "testing/RDFLink/";
 
-    private static EnvTest env;
-    @BeforeClass public static void beforeClass() {
-        env = EnvTest.create("/ds");
+    private FusekiServer server = null;
+    private final boolean verbose = false;
+
+    private final String dsName = "/data";
+
+    @Before public void makeServer() {
+        DatasetGraph dsg = DatasetGraphFactory.createTxnMem();
+        server = FusekiServer.create()
+                .verbose(verbose)
+                .enablePing(true)
+                //.addServlet(data, holder)
+                .add(dsName, dsg)
+                .build()
+                .start();
     }
 
-    @Before public void before() {
-        env.clear();
+    @After public void releaseServer() {
+        if ( server != null )
+            server.stop();
     }
 
-    @AfterClass public static void afterClass() {
-        if ( ConfigureTests.CloseTestServers )
-            EnvTest.stop(env);
+
+    private String url(String path) {
+        return server.datasetURL(path);
     }
 
-    private static Graph graph1 = SSE.parseGraph("(graph (:s :p :x) (:s :p 1))");
-    private static Graph graph2 = SSE.parseGraph("(graph (:s :p :x) (:s :p 2))");
+    // GSP endpoint
+    private String gspServiceURL() {
+        return url(dsName);
+    }
 
-    private String url(String path) { return env.datasetPath(path); }
+    private String defaultGraphURL() {
+        return gspServiceURL() + "?default";
+    }
 
-    // Test GSP against the /data endpoint (including dataset operations).
-    static String gspServiceURL()   { return env.datasetPath("/data"); }
+    private String namedGraphURL() {
+        return gspServiceURL() + "?graph=http://example/g";
+    }
 
-    static String defaultGraphURL() { return gspServiceURL()+"?default"; }
-    static String namedGraphURL()   { return gspServiceURL()+"?graph=http://example/g"; }
+    private static Graph graph1 = SSE.parseGraph("(graph (:s :p :x) (:s :p 1))");
+    private static Graph graph2 = SSE.parseGraph("(graph (:s :p :x) (:s :p 2))");
 
     // Graph, with one triple in it.
     static Graph graph = makeGraph();
     static Graph makeGraph() {
         Graph graph = GraphFactory.createDefaultGraph();
-        RDFDataMgr.read(graph, new StringReader("PREFIX : <http://example/> :s :p :o ."), null, Lang.TTL);
+        RDFParser.fromString("PREFIX : <http://example/> :s :p :o .", Lang.TTL).parse(graph);
         return graph;
     }
 
     static DatasetGraph dataset = makeDatasetGraph();
     static DatasetGraph makeDatasetGraph() {
         DatasetGraph dataset = DatasetGraphFactory.createTxnMem();
-        RDFDataMgr.read(dataset, new StringReader("PREFIX : <http://example/> :s :p :o . :g { :sg :pg :og }"), null, Lang.TRIG);
+        RDFParser.fromString("PREFIX : <http://example/> :s :p :o . :g { :sg :pg :og }", Lang.TRIG).parse(dataset);
         return dataset;
     }
 
-    @Test public void gsp_put_get_01() {
-        GSP.service(gspServiceURL())
-            .defaultGraph()
-            .PUT(graph);
-        Graph g = GSP.service(gspServiceURL())
-            .defaultGraph()
-            .GET();
+    @Test
+    public void gsp_put_get_01() {
+        GSP.service(gspServiceURL()).defaultGraph().PUT(graph);
+        Graph g = GSP.service(gspServiceURL()).defaultGraph().GET();
         assertNotNull(g);
-        assertTrue(IsoMatcher.isomorphic(graph,g));
+        assertTrue(IsoMatcher.isomorphic(graph, g));
     }
 
-    @Test(expected=HttpException.class)
+    @Test(expected = HttpException.class)
     public void gsp_bad_put_01() {
         // No .defaultGraph
         GSP.service(gspServiceURL()).PUT(graph);
     }
 
-    @Test(expected=HttpException.class)
+    @Test(expected = HttpException.class)
     public void gsp_bad_get_err_02() {
         // No .defaultGraph
         GSP.service(gspServiceURL()).GET();
     }
 
-    @Test public void gsp_post_get_ct_01() {
+    @Test
+    public void gsp_post_get_ct_01() {
         String graphName = "http://example/graph";
-        GSP.service(gspServiceURL())
-            .graphName(graphName)
-            .POST(graph);
-        Graph g1 = GSP.service(gspServiceURL())
-            .defaultGraph()
-            .acceptHeader("application/rdf+xml")
-            .GET();
+        GSP.service(gspServiceURL()).graphName(graphName).POST(graph);
+        Graph g1 = GSP.service(gspServiceURL()).defaultGraph().acceptHeader("application/rdf+xml").GET();
         assertNotNull(g1);
         assertTrue(g1.isEmpty());
 
-        Graph g2 = GSP.service(gspServiceURL())
-            .graphName(graphName)
-            .acceptHeader("application/rdf+xml")
-            .GET();
+        Graph g2 = GSP.service(gspServiceURL()).graphName(graphName).acceptHeader("application/rdf+xml").GET();
         assertNotNull(g2);
         assertFalse(g2.isEmpty());
-        assertTrue(IsoMatcher.isomorphic(graph,g2));
+        assertTrue(IsoMatcher.isomorphic(graph, g2));
     }
 
-    @Test public void gsp_put_get_ct_02() {
-        GSP.service(gspServiceURL())
-            .defaultGraph()
-            .contentType(RDFFormat.NTRIPLES)
-            .PUT(graph);
-        Graph g1 = GSP.service(gspServiceURL())
-            .defaultGraph()
-            .accept(Lang.RDFXML)
-            .GET();
+    @Test
+    public void gsp_put_get_ct_02() {
+        GSP.service(gspServiceURL()).defaultGraph().contentType(RDFFormat.NTRIPLES).PUT(graph);
+        Graph g1 = GSP.service(gspServiceURL()).defaultGraph().accept(Lang.RDFXML).GET();
         assertNotNull(g1);
         assertFalse(g1.isEmpty());
-        assertTrue(IsoMatcher.isomorphic(graph,g1));
+        assertTrue(IsoMatcher.isomorphic(graph, g1));
     }
 
-    @Test public void gsp_put_delete_01() {
-        GSP.service(gspServiceURL())
-            .defaultGraph()
-            .PUT(graph);
-        Graph g1 = GSP.service(gspServiceURL())
-             .defaultGraph()
-             .GET();
+    @Test
+    public void gsp_put_delete_01() {
+        GSP.service(gspServiceURL()).defaultGraph().PUT(graph);
+        Graph g1 = GSP.service(gspServiceURL()).defaultGraph().GET();
         assertFalse(g1.isEmpty());
 
-        GSP.service(gspServiceURL())
-            .defaultGraph()
-            .DELETE();
-        Graph g2 = GSP.service(gspServiceURL())
-            .defaultGraph()
-            .GET();
+        GSP.service(gspServiceURL()).defaultGraph().DELETE();
+        Graph g2 = GSP.service(gspServiceURL()).defaultGraph().GET();
         assertTrue(g2.isEmpty());
 
         // And just to make sure ...
@@ -173,32 +165,36 @@ public class TestGSP {
         assertTrue(s2.isEmpty());
     }
 
-    @Test public void gsp_dft_ct_1() {
-        GSP.service(url("/ds")).defaultGraph().contentType(RDFFormat.RDFXML).PUT(DIR+"data-rdfxml");
+    @Test
+    public void gsp_dft_ct_1() {
+        GSP.service(gspServiceURL()).defaultGraph().contentType(RDFFormat.RDFXML).PUT(DIR + "data-rdfxml");
     }
 
-    @Test public void gsp_dft_ct_2() {
-        GSP.service(url("/ds")).defaultGraph().contentTypeHeader(WebContent.contentTypeRDFXML).PUT(DIR+"data-rdfxml");
+    @Test
+    public void gsp_dft_ct_2() {
+        GSP.service(gspServiceURL()).defaultGraph().contentTypeHeader(WebContent.contentTypeRDFXML).PUT(DIR + "data-rdfxml");
     }
 
     // ----------------------------------------
 
-    @Test public void gspHead_dataset_1() {
+    @Test
+    public void gspHead_dataset_1() {
         // Base URL, default content type => N-Quads (dump format)
         String h = HttpOp.httpHead(gspServiceURL(), null);
         assertNotNull(h);
         assertEquals(Lang.NQUADS.getHeaderString(), h);
     }
 
-
-    @Test public void gspHead_dataset_2() {
+    @Test
+    public void gspHead_dataset_2() {
         String ct = Lang.TRIG.getHeaderString();
         String h = HttpOp.httpHead(gspServiceURL(), ct);
         assertNotNull(h);
         assertEquals(ct, h);
     }
 
-    @Test public void gspHead_graph_1() {
+    @Test
+    public void gspHead_graph_1() {
         String target = defaultGraphURL();
         String h = HttpOp.httpHead(target, null);
         assertNotNull(h);
@@ -206,7 +202,8 @@ public class TestGSP {
         assertEquals(Lang.RDFXML.getHeaderString(), h);
     }
 
-    @Test public void gspHead_graph_2() {
+    @Test
+    public void gspHead_graph_2() {
         String target = defaultGraphURL();
         String ct = Lang.TTL.getHeaderString();
         String h = HttpOp.httpHead(target, ct);
@@ -214,53 +211,41 @@ public class TestGSP {
         assertEquals(ct, h);
     }
 
-    @Test public void gsp_union_get() {
+    @Test
+    public void gsp_union_get() {
         Node gn1 = NodeFactory.createURI("http://example/graph1");
         Node gn2 = NodeFactory.createURI("http://example/graph2");
-        GSP.service(gspServiceURL())
-           .graphName(gn1)
-           .PUT(graph1);
-        GSP.service(gspServiceURL())
-           .graphName(gn2)
-            .PUT(graph2);
+        GSP.service(gspServiceURL()).graphName(gn1).PUT(graph1);
+        GSP.service(gspServiceURL()).graphName(gn2).PUT(graph2);
         // get union
 
         Graph g = GSP.service(gspServiceURL()).graphName("union").GET();
         assertEquals(3, g.size());
     }
 
-    @Test public void gsp_union_post() {
-        expect400(()->{
+    @Test
+    public void gsp_union_post() {
+        expect400(() -> {
             GSP.service(gspServiceURL()).graphName("union").POST(graph1);
         });
     }
 
     // 404
 
-    @Test public void gsp_404_put_delete_get() {
+    @Test
+    public void gsp_404_put_delete_get() {
         String graphName = "http://example/graph2";
         Node gn = NodeFactory.createURI("http://example/graph2");
-        GSP.service(gspServiceURL())
-            .graphName(gn)
-            .PUT(graph);
-        Graph g = GSP.service(gspServiceURL())
-            .graphName(graphName)
-            .GET();
+        GSP.service(gspServiceURL()).graphName(gn).PUT(graph);
+        Graph g = GSP.service(gspServiceURL()).graphName(graphName).GET();
         assertFalse(g.isEmpty());
-        GSP.service(gspServiceURL())
-            .graphName(gn)
-            .DELETE();
-        expect404(()->
-            GSP.service(gspServiceURL())
-                .graphName(graphName)
-                .GET()
-        );
+        GSP.service(gspServiceURL()).graphName(gn).DELETE();
+        expect404(() -> GSP.service(gspServiceURL()).graphName(graphName).GET());
     }
 
-    @Test public void gsp_404_graph() {
+    @Test
+    public void gsp_404_graph() {
         String graphName = "http://example/graph404";
-        expect404(
-            ()->GSP.service(gspServiceURL()).graphName(graphName).GET()
-        );
+        expect404(() -> GSP.service(gspServiceURL()).graphName(graphName).GET());
     }
 }
diff --git a/jena-integration-tests/src/test/java/org/apache/jena/test/conn/EnvTest.java b/jena-integration-tests/src/test/java/org/apache/jena/test/conn/EnvTest.java
index 7228c7d87c..7d503f50aa 100644
--- a/jena-integration-tests/src/test/java/org/apache/jena/test/conn/EnvTest.java
+++ b/jena-integration-tests/src/test/java/org/apache/jena/test/conn/EnvTest.java
@@ -73,7 +73,7 @@ public class EnvTest {
         return create(dsName, null);
     }
 
-    public static EnvTest create(String dsName, DatasetGraph dsg) {
+    private static EnvTest create(String dsName, DatasetGraph dsg) {
         return new EnvTest(dsName, dsg, null, null);
     }
 


(jena) 11/14: Single-threaded LRU cache based on LinkedHashMap

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 b8b5864a050a2150bbd880d44744b55c9f4c0a07
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Fri Jul 18 09:55:32 2025 +0100

    Single-threaded LRU cache based on LinkedHashMap
---
 .../main/java/org/apache/jena/atlas/lib/Cache.java |   2 +-
 .../org/apache/jena/atlas/lib/CacheFactory.java    |   8 +
 .../org/apache/jena/atlas/lib/cache/CacheOps.java  |   6 +-
 .../apache/jena/atlas/lib/cache/CachePlainLRU.java | 122 ++++++++++++++
 .../java/org/apache/jena/atlas/lib/TestCache.java  | 179 ++++++++++-----------
 .../java/org/apache/jena/atlas/lib/TestCache2.java |  25 ++-
 6 files changed, 235 insertions(+), 107 deletions(-)

diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/Cache.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/Cache.java
index 46dd53c63c..93437c424f 100644
--- a/jena-base/src/main/java/org/apache/jena/atlas/lib/Cache.java
+++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/Cache.java
@@ -76,7 +76,7 @@ public interface Cache<Key, Value>
      * @return Returns either the existing value or the calculated value.
      *         If callable is called and returns null, then null is returned.
      */
-    public Value get(Key key, Function<Key, Value> callable) ;
+    public Value get(Key key, Function<Key, Value> function) ;
 
     /**
      * Insert into the cache
diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/CacheFactory.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/CacheFactory.java
index 7ab9f09f60..6cc8ed9a1f 100644
--- a/jena-base/src/main/java/org/apache/jena/atlas/lib/CacheFactory.java
+++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/CacheFactory.java
@@ -88,6 +88,14 @@ public class CacheFactory {
         return new Cache1<>() ;
     }
 
+    /*
+     * Create a lightweight LRU cache.
+     * This cache is not thread-safe.
+     */
+    public static <Key, Value> Cache<Key, Value> createPlainCache(int size) {
+        return new CachePlainLRU<>(size) ;
+    }
+
     /**
      * Create set-cache, rather than a map-cache.
      * The cache is thread-safe for single operations.
diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheOps.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheOps.java
index 4a81269cfa..fe6c001188 100644
--- a/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheOps.java
+++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheOps.java
@@ -46,11 +46,7 @@ class CacheOps {
     public static <K,V> V getOrFill(Cache<K,V> cache, K key, Function<K,V> function) {
         V value = cache.getIfPresent(key) ;
         if ( value == null ) {
-            try { value = function.apply(key) ; }
-            catch (RuntimeException ex) { throw ex; }
-            catch (Exception e) {
-                throw new AtlasException("Exception on cache fill", e) ;
-            }
+            value = function.apply(key) ;
             if ( value != null )
                 cache.put(key, value) ;
         }
diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CachePlainLRU.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CachePlainLRU.java
new file mode 100644
index 0000000000..a6545cf74f
--- /dev/null
+++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CachePlainLRU.java
@@ -0,0 +1,122 @@
+/*
+ * 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.cache;
+
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.function.Function;
+
+import org.apache.jena.atlas.lib.Cache;
+
+/**
+ * Light-weight LRU cache based on {@link LinkedHashMap}.
+ * This cache implementation is for single-threaded use only.
+ */
+public class CachePlainLRU<K, V> implements Cache<K, V> {
+
+    private final Map<K, V> cache;
+    private final float loadFactor = 0.75f;
+    private final float initialCapacityFactory = 0.75f;
+
+
+    public CachePlainLRU(final int maxCapacity) {
+        int initialCapacity = (int)(maxCapacity / initialCapacityFactory + 1);
+        this.cache = new LinkedHashMap<K, V>(initialCapacity, loadFactor, true) {
+            @Override
+            protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
+                return size() > maxCapacity;
+            }
+        };
+    }
+
+    @Override
+    public boolean containsKey(K key) {
+        return cache.containsKey(key);
+    }
+
+
+    @Override
+    public V getIfPresent(K key) {
+        return cache.get(key);
+    }
+
+
+    @Override
+    public V get(K key, Function<K, V> function) {
+        return CacheOps.getOrFill(this, key, function);
+    }
+
+    @Override
+    public void put(K key, V thing) {
+        cache.put(key, thing);
+    }
+
+
+    @Override
+    public void remove(K key) {
+        this.remove(key);
+    }
+
+
+    @Override
+    public Iterator<K> keys() {
+        return cache.keySet().iterator();
+    }
+
+
+    @Override
+    public boolean isEmpty() {
+        return cache.isEmpty();
+    }
+
+
+    @Override
+    public void clear() {}
+
+
+    @Override
+    public long size() {
+        return 0;
+    }
+
+
+//
+//    @Override
+//    public boolean containsKey(final K key) {
+//        return cache.containsKey(key);
+//    }
+//
+//    @Override
+//    public V get(final K key) {
+//        return cache.get(key);
+//    }
+//
+//    @Override
+//    public void put(final K key, V value) {
+//        cache.put(key, value);
+//    }
+//
+//    public long size() {
+//        return cache.size();
+//    }
+
+
+
+}
diff --git a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestCache.java b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestCache.java
index bc1f7a6d94..6458c74f18 100644
--- a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestCache.java
+++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestCache.java
@@ -37,114 +37,103 @@ import org.junit.runners.Parameterized.Parameters ;
 public class TestCache
 {
     // Tests do not apply to cache1.
-    private static interface CacheMaker<K,V> { Cache<K,V> make(int size) ; String name() ; } 
-
-    private static CacheMaker<Integer, Integer> simple = 
-        new CacheMaker<Integer, Integer>()
-        { 
-        @Override
-        public Cache<Integer, Integer> make(int size) { return CacheFactory.createSimpleCache(size) ; }
-        @Override
-        public String name() { return "Simple" ; } 
-        } 
-    ;
-
-    private static CacheMaker<Integer, Integer> standard = 
-        new CacheMaker<Integer, Integer>()
-        {
-        @Override
-        public Cache<Integer, Integer> make(int size) { return CacheFactory.createCache(size) ; }
-        @Override
-        public String name() { return "Standard" ; } 
-        }
-    ;
-
-    @Parameters
+    private static interface CacheMaker<K,V> { Cache<K,V> make(int size) ; }
+
+    private static CacheMaker<Integer, Integer> oneSlot = (int size)->CacheFactory.createOneSlotCache();
+    private static CacheMaker<Integer, Integer> simple = (int size)->CacheFactory.createSimpleCache(size);
+    private static CacheMaker<Integer, Integer> standard = (int size)->CacheFactory.createCache(size);
+    private static CacheMaker<Integer, Integer> plainLRU = (int size)->CacheFactory.createCache(size);
+
+    @Parameters(name="{0}")
     public static Collection<Object[]> cacheMakers()
     {
-        return Arrays.asList(new Object[][] {
-            { simple , 10 }
-            , { simple , 2 } 
-            , { simple , 1 }
-            , { standard , 10 }
-            , { standard , 2 }
-            , { standard , 1 }
-        } ) ; 
+        return Arrays.asList(new Object[][]
+                { { "Simple(10)", simple , 10 }
+                , { "Simple(2)", simple , 2 }
+                , { "Simple(1)" , simple ,1 }
+                , { "Plain(10)", plainLRU , 10 }
+                , { "Plain(2)", plainLRU , 2 }
+                , { "Plain(1)" , plainLRU ,1 }
+                , { "Standard(10)" , standard, 10 }
+                , { "Standard(2)"  , standard, 2 }
+                , { "Standard(1)"  , standard, 1 }
+                , { "SingleSlot"  , oneSlot, 1 }
+                } ) ;
     }
 
-    Cache<Integer, Integer> cache ;
-    CacheMaker<Integer,Integer> cacheMaker ;
-    int size ;
-    
-    
-    public TestCache(CacheMaker<Integer,Integer> cacheMaker, int size)
-    {
-        this.cacheMaker = cacheMaker ;
-        this.size = size ;
-        
+    Cache<Integer, Integer> cache;
+    CacheMaker<Integer, Integer> cacheMaker;
+    int size;
+
+    public TestCache(String name, CacheMaker<Integer, Integer> cacheMaker, int size) {
+        this.cacheMaker = cacheMaker;
+        this.size = size;
     }
-    
-    @Before public void before() { cache = cacheMaker.make(size) ; }
-    
-    @Test public void cache_00()
-    {
-        assertEquals(0, cache.size()) ;
-        assertTrue(cache.isEmpty()) ;
+
+    @Before
+    public void before() {
+        cache = cacheMaker.make(size);
     }
-    
-    @Test public void cache_01()
-    {
-        Integer x = cache.getIfPresent(7) ;
-        cache.put(7, 7) ;
-        assertEquals(1, cache.size()) ;
-        assertNull(x) ;
-        assertTrue(cache.containsKey(7)) ;
-        assertEquals(Integer.valueOf(7), cache.getIfPresent(7)) ;
+
+    @Test
+    public void cache_00() {
+        assertEquals(0, cache.size());
+        assertTrue(cache.isEmpty());
     }
-    
-    @Test public void cache_02()
-    {
-        cache.put(7, 7) ;
-        cache.put(8, 8) ;
+
+    @Test
+    public void cache_01() {
+        Integer x = cache.getIfPresent(7);
+        cache.put(7, 7);
+        assertEquals(1, cache.size());
+        assertNull(x);
+        assertTrue(cache.containsKey(7));
+        assertEquals(Integer.valueOf(7), cache.getIfPresent(7));
+    }
+
+    @Test
+    public void cache_02() {
+        cache.put(7, 7);
+        cache.put(8, 8);
         // Not true for Cache1.
         if ( size > 2 )
-            assertEquals(2, cache.size()) ;
+            assertEquals(2, cache.size());
         if ( size > 2 )
-            assertTrue(cache.containsKey(7)) ;
-        
+            assertTrue(cache.containsKey(7));
+
         if ( size > 2 )
-            assertEquals(Integer.valueOf(7), cache.getIfPresent(7)) ;
-        
-        assertTrue(cache.containsKey(8)) ;
-        assertEquals(Integer.valueOf(8), cache.getIfPresent(8)) ;
+            assertEquals(Integer.valueOf(7), cache.getIfPresent(7));
+
+        assertTrue(cache.containsKey(8));
+        assertEquals(Integer.valueOf(8), cache.getIfPresent(8));
     }
-    
-    @Test public void cache_03()
-    {
-        cache.put(7, 7) ;
-        Integer x1 = cache.getIfPresent(7) ;
-        cache.put(7, 18) ;
-        assertEquals(1, cache.size()) ;
-        assertEquals(7, x1.intValue()) ;
-        assertTrue(cache.containsKey(7)) ;
-        assertEquals(Integer.valueOf(18), cache.getIfPresent(7)) ;
+
+    @Test
+    public void cache_03() {
+        cache.put(7, 7);
+        Integer x1 = cache.getIfPresent(7);
+        cache.put(7, 18);
+        assertEquals(1, cache.size());
+        assertEquals(7, x1.intValue());
+        assertTrue(cache.containsKey(7));
+        assertEquals(Integer.valueOf(18), cache.getIfPresent(7));
     }
-    
-    @Test public void cache_04()
-    {
-        cache.clear() ;
-        cache.put(7, 77) ;
-        List<Integer> x = Iter.toList(cache.keys()) ;
-        assertEquals(1, x.size()) ;
-        assertEquals(Integer.valueOf(7), x.get(0)) ;
+
+    @Test
+    public void cache_04() {
+        cache.clear();
+        cache.put(7, 77);
+        List<Integer> x = Iter.toList(cache.keys());
+        assertEquals(1, x.size());
+        assertEquals(Integer.valueOf(7), x.get(0));
     }
-    
-    @Test public void cache_05()
-    {
-        cache.clear() ;
-        cache.put(7, 77) ;
-        cache.clear() ;
-        assertEquals(0, cache.size()) ; 
-        assertTrue(cache.isEmpty()) ;
+
+    @Test
+    public void cache_05() {
+        cache.clear();
+        cache.put(7, 77);
+        cache.clear();
+        assertEquals(0, cache.size());
+        assertTrue(cache.isEmpty());
     }
 }
diff --git a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestCache2.java b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestCache2.java
index f66294016a..cc333fad95 100644
--- a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestCache2.java
+++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestCache2.java
@@ -25,9 +25,8 @@ import org.junit.Test;
 
 // Non-parameterized tests
 public class TestCache2 {
-    // Cache1
     @Test
-    public void cache_10() {
+    public void cache_oneSlot() {
         Cache<Integer, String> cache = CacheFactory.createOneSlotCache();
         String str = cache.getIfPresent(1);
         assertNull(str);
@@ -51,7 +50,7 @@ public class TestCache2 {
     @Test
     public void cacheGetter_1() {
         Cache<Integer, String> cache = CacheFactory.createCache(2);
-        String str = cache.get(1, k->k.toString());
+        String str = cache.get(1, k -> k.toString());
         assertEquals("1", str);
     }
 
@@ -59,9 +58,9 @@ public class TestCache2 {
     @Test
     public void cacheGetter_2() {
         Cache<Integer, String> cache = CacheFactory.createCache(2);
-        String str1 = cache.get(1, k->k.toString());
-        String str2 = cache.get(2, k->k.toString());
-        String str3 = cache.get(3, k->k.toString());
+        String str1 = cache.get(1, k -> k.toString());
+        String str2 = cache.get(2, k -> k.toString());
+        String str3 = cache.get(3, k -> k.toString());
         assertEquals("1", str1);
         assertEquals("2", str2);
         assertEquals("3", str3);
@@ -70,4 +69,18 @@ public class TestCache2 {
         assertEquals("10", str1);
     }
 
+    // Cache + getters
+    @Test
+    public void cacheGetter_3() {
+        Cache<Integer, String> cache = CacheFactory.createPlainCache(2);
+        String str1 = cache.get(1, k -> k.toString());
+        String str2 = cache.get(2, k -> k.toString());
+        String str3 = cache.get(3, k -> k.toString());
+        assertEquals("1", str1);
+        assertEquals("2", str2);
+        assertEquals("3", str3);
+        cache.put(1, "10");
+        str1 = cache.getIfPresent(1);
+        assertEquals("10", str1);
+    }
 }


(jena) 14/14: GH-3318: Log duplicate database entries

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 ed40acfe53a45c3d332d54ca3a0d4eb789746c44
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Wed Jul 16 12:48:23 2025 +0100

    GH-3318: Log duplicate database entries
---
 .../apache/jena/fuseki/mod/admin/FMod_Admin.java   | 24 +++++++++++++++++-----
 .../mod/admin/TestAdminAddDatasetTemplate.java     |  2 +-
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/admin/FMod_Admin.java b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/admin/FMod_Admin.java
index 518aa62608..a4f45325d7 100644
--- a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/admin/FMod_Admin.java
+++ b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/admin/FMod_Admin.java
@@ -22,7 +22,10 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.List;
 import java.util.Set;
+import java.util.StringJoiner;
+import java.util.stream.Collectors;
 
+import org.apache.commons.collections4.SetUtils;
 import org.apache.jena.atlas.logging.FmtLog;
 import org.apache.jena.cmd.ArgDecl;
 import org.apache.jena.cmd.ArgModuleGeneral;
@@ -145,21 +148,32 @@ public class FMod_Admin implements FusekiModule {
         String configDir = FusekiServerCtl.dirConfiguration.toString();
         List<DataAccessPoint> directoryDatabases = FusekiConfig.readConfigurationDirectory(configDir);
 
+        // Check there are no collisions between the command line (datasetNames)
+        // and existing configurations.
         if ( directoryDatabases.isEmpty() && datasetNames.isEmpty() )
             FmtLog.info(LOG, "No databases: dir=%s", configDir);
         else {
+            if ( ! datasetNames.isEmpty() ) {
+                // Check no clashes of command line and configuration
+                Set<String> directoryDatabasesNames = directoryDatabases.stream().map(dap->dap.getName()).collect(Collectors.toSet());
+                Set<String> both = SetUtils.intersection(datasetNames, directoryDatabasesNames);
+                if ( ! both.isEmpty() ) {
+                    StringJoiner sj = new StringJoiner(", ");
+                    both.forEach(sj::add);
+                    String dups = sj.toString();
+                    //both.forEach(dbName -> FmtLog.error(LOG, "Duplicate database '%s' (command line and existing configuration)", dbName));
+                    throw new FusekiConfigException("Duplicate database entries for "+dups);
+                }
+            }
+            // Now log information
             datasetNames.forEach(n->FmtLog.info(Fuseki.configLog, "Database: %s", n));
             directoryDatabases.forEach(dap -> FmtLog.info(Fuseki.configLog, "Database: %s", dap.getName()));
         }
 
         directoryDatabases.forEach(db -> {
             String dbName = db.getName();
-            if ( datasetNames.contains(dbName) ) {
-                FmtLog.warn(LOG, "Database '%s' already added to the Fuseki server builder", dbName);
-                // ?? builder.remove(dbName);
-            }
+            // Names have been checked for uniqueness.
             builder.add(dbName, db.getDataService());
-            // ** builder.add(DataAccessPoint);
         });
 
         // Modify the server to include the admin operations.
diff --git a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/admin/TestAdminAddDatasetTemplate.java b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/admin/TestAdminAddDatasetTemplate.java
index a566dd9995..3f8a06f375 100644
--- a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/admin/TestAdminAddDatasetTemplate.java
+++ b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/admin/TestAdminAddDatasetTemplate.java
@@ -113,7 +113,7 @@ public class TestAdminAddDatasetTemplate extends FusekiServerPerTestClass {
         badAddDataserverRequest("//bad_10");
     }
 
-    //@Test 
+    @Test
     public void noOverwriteExistingConfigFile() {
         withServer(server->{
             try {


(jena) 01/14: Remove out-of-date comments

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 7ab18bd17b0f845f441233fd6bedfe654e464136
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Sun Jul 13 20:46:48 2025 +0100

    Remove out-of-date comments
---
 jena-core/src/test/java/org/apache/jena/rdfxml/xmlinput1/TestURIs.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/jena-core/src/test/java/org/apache/jena/rdfxml/xmlinput1/TestURIs.java b/jena-core/src/test/java/org/apache/jena/rdfxml/xmlinput1/TestURIs.java
index 2bf4b83556..b0abbb5e42 100644
--- a/jena-core/src/test/java/org/apache/jena/rdfxml/xmlinput1/TestURIs.java
+++ b/jena-core/src/test/java/org/apache/jena/rdfxml/xmlinput1/TestURIs.java
@@ -31,7 +31,7 @@ import org.apache.jena.irix.IRIx;
 
 public class TestURIs
 	extends TestCase {
-    // TODO: not for 2.3 relative/absolute tests
+
 	static public Test suite() {
 		TestSuite suite = new TestSuite(TestURIs.class.getCanonicalName());
 		suite.addTest(new TestURIs("testNoDomain"));


(jena) 09/14: Add G.listLength

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 ff9a14c6f65297be8af1e2ca568216f64253d84c
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Wed Jul 16 22:01:31 2025 +0100

    Add G.listLength
---
 .../apache/jena/sparql/util/graph/GraphList.java   | 65 ++++++++++------------
 .../src/main/java/org/apache/jena/system/G.java    | 10 ++++
 2 files changed, 40 insertions(+), 35 deletions(-)

diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/GraphList.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/GraphList.java
index cb56d73218..65690fcdbc 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/GraphList.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/GraphList.java
@@ -40,6 +40,36 @@ import org.apache.jena.vocabulary.RDF;
 
 public class GraphList
 {
+    public static List<Node> members(GNode gnode) {
+        List<Node> x = new ArrayList<>();
+        members(gnode, x);
+        return x;
+    }
+
+    public static void members(GNode gnode, final Collection<Node> acc) {
+        if ( !isListNode(gnode) )
+            return;
+
+        while (!listEnd(gnode)) {
+            Node n = car(gnode);
+            if ( n != null )
+                acc.add(n);
+            gnode = next(gnode);
+        }
+    }
+
+    public static int length(GNode gnode) {
+        if ( !isListNode(gnode) )
+            return -1;
+
+        int len = 0;
+        while (!listEnd(gnode)) {
+            len++;
+            gnode = next(gnode);
+        }
+        return len;
+    }
+
     // ----------------------
     /** Starting at a list element, find the heads of lists it is in */
     public static List<Node> listFromMember(GNode gnode)
@@ -144,41 +174,6 @@ public class GraphList
         return x == null || Node.ANY.equals(x);
     }
 
-    public static List<Node> members(GNode gnode)
-    {
-        List<Node> x = new ArrayList<>();
-        members(gnode, x);
-        return x;
-    }
-
-    public static void members(GNode gnode, final Collection<Node> acc)
-    {
-        if ( ! isListNode(gnode) )
-            return;
-
-        while( ! listEnd(gnode) )
-        {
-            Node n = car(gnode);
-            if ( n != null )
-                acc.add(n);
-            gnode = next(gnode);
-        }
-    }
-
-    public static int length(GNode gnode)
-    {
-        if ( ! isListNode(gnode) )
-            return -1;
-
-        int len = 0;
-        while ( ! listEnd(gnode) )
-        {
-            len++;
-            gnode = next(gnode);
-        }
-        return len;
-    }
-
     public static int occurs(GNode gnode, Node item)
     { return indexes(gnode, item).size(); }
 
diff --git a/jena-arq/src/main/java/org/apache/jena/system/G.java b/jena-arq/src/main/java/org/apache/jena/system/G.java
index 6d91a2999e..5c4c15b1c9 100644
--- a/jena-arq/src/main/java/org/apache/jena/system/G.java
+++ b/jena-arq/src/main/java/org/apache/jena/system/G.java
@@ -490,6 +490,16 @@ public class G {
         return GraphList.members(gNode);
     }
 
+    /** Return a the length of an RDF list. */
+    public static int listLength(Graph graph, Node node) {
+        Objects.requireNonNull(graph, "graph");
+        Objects.requireNonNull(node, "node");
+        GNode gNode = GNode.create(graph, node);
+        if ( ! GraphList.isListNode(gNode) )
+            return -1;
+        return GraphList.length(gNode);
+    }
+
     /**
      * Return a java list where the {@code node} is an RDF list of nodes or a single
      * node (returned a singleton list).


(jena) 10/14: Allow override of ExprNode.getVarsMentioned()

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 90067cd5774833f5d2ea1a78e566a0048cc1d16b
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Wed Jul 16 22:02:09 2025 +0100

    Allow override of ExprNode.getVarsMentioned()
---
 jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprNode.java | 2 +-
 jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprVar.java  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprNode.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprNode.java
index 85e8190aae..d365ca3a28 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprNode.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprNode.java
@@ -61,7 +61,7 @@ public abstract class ExprNode implements Expr
     public abstract NodeValue eval(Binding binding, FunctionEnv env);
 
     @Override
-    public final Set<Var> getVarsMentioned() {
+    public Set<Var> getVarsMentioned() {
         return ExprVars.getVarsMentioned(this);
     }
 
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprVar.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprVar.java
index 79ee47a5d5..dec63dc6e2 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprVar.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprVar.java
@@ -32,7 +32,7 @@ import org.apache.jena.sparql.graph.NodeTransform;
 public class ExprVar extends ExprNode
 {
     // AKA ExprFunction0
-    protected Var varNode = null;
+    protected final Var varNode;
 
     public ExprVar(String name) { varNode = Var.alloc(name); }
 


(jena) 04/14: Improve port warning about HTTP/HTTP

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 c349ea6892705df250f0d8220958915a33835364
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Mon Jul 14 18:36:34 2025 +0100

    Improve port warning about HTTP/HTTP
---
 jena-iri3986/src/main/java/org/apache/jena/rfc3986/IRI3986.java | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/jena-iri3986/src/main/java/org/apache/jena/rfc3986/IRI3986.java b/jena-iri3986/src/main/java/org/apache/jena/rfc3986/IRI3986.java
index 9397f990a5..9e44077221 100644
--- a/jena-iri3986/src/main/java/org/apache/jena/rfc3986/IRI3986.java
+++ b/jena-iri3986/src/main/java/org/apache/jena/rfc3986/IRI3986.java
@@ -1634,13 +1634,13 @@ public class IRI3986 implements IRI {
                         if ( port == 80 )
                             schemeReport(this, Issue.http_omit_well_known_port, scheme, "Default port 80 should be omitted");
                         else if ( port < 1024 && port != 80 )
-                            schemeReport(this, Issue.http_port_not_advised, scheme, "HTTP ports under 1024 should only be 80, not "+port);
+                            schemeReport(this, Issue.http_port_not_advised, scheme, "An HTTP port under 1024 should only be 80, not "+port);
                         break;
                     case HTTPS :
                         if ( port == 443 )
                             schemeReport(this, Issue.http_omit_well_known_port, scheme, "Default port 443 should be omitted");
                         else if ( port < 1024 && port != 443 )
-                            schemeReport(this, Issue.http_port_not_advised, scheme, "HTTPS ports under 1024 should only be 443, not "+port);
+                            schemeReport(this, Issue.http_port_not_advised, scheme, "An HTTPS ports under 1024 should only be 443, not "+port);
                         break;
                     default :
                         throw new IllegalStateException();


(jena) 06/14: Tidy code

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 af87ae0720f21b2f0693b53ece3feb850f9af3c8
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Tue Jul 15 21:17:07 2025 +0100

    Tidy code
---
 .../xsd/impl/XSDAbstractDateTimeType.java          | 39 ++++++++++-----------
 .../apache/jena/fuseki/main/cmds/FusekiMain.java   | 40 +++++++++++-----------
 .../apache/jena/fuseki/mod/FusekiServerRunner.java | 14 +++++---
 .../java/org/apache/jena/shacl/test_vocab/SHT.java | 14 ++++----
 4 files changed, 56 insertions(+), 51 deletions(-)

diff --git a/jena-core/src/main/java/org/apache/jena/datatypes/xsd/impl/XSDAbstractDateTimeType.java b/jena-core/src/main/java/org/apache/jena/datatypes/xsd/impl/XSDAbstractDateTimeType.java
index af4b5e6a3e..8f9a4fedc3 100644
--- a/jena-core/src/main/java/org/apache/jena/datatypes/xsd/impl/XSDAbstractDateTimeType.java
+++ b/jena-core/src/main/java/org/apache/jena/datatypes/xsd/impl/XSDAbstractDateTimeType.java
@@ -35,35 +35,35 @@ public class XSDAbstractDateTimeType extends XSDDatatype {
     public XSDAbstractDateTimeType(String typename) {
         super(typename);
     }
-     
+
     /**
      * Compares two instances of values of the given datatype.
-     * This ignores lang tags and just uses the java.lang.Number 
+     * This ignores lang tags and just uses the java.lang.Number
      * equality.
      */
     @Override
     public boolean isEqual(LiteralLabel value1, LiteralLabel value2) {
        return value1.getValue().equals(value2.getValue());
     }
-    
+
     /** Mask to indicate whether year is present */
     public static final short YEAR_MASK = 0x1;
-    
+
     /** Mask to indicate whether month is present */
     public static final short MONTH_MASK = 0x2;
-    
+
     /** Mask to indicate whether day is present */
     public static final short DAY_MASK = 0x4;
-    
+
     /** Mask to indicate whether time is present */
     public static final short TIME_MASK = 0x8;
-    
+
     /** Mask to indicate all date/time are present */
     public static final short FULL_MASK = 0xf;
-    
-    
+
+
 //  --------------------------------------------------------------------
-//  This code is adapated from Xerces 2.6.0 AbstractDateTimeDV.    
+//  This code is adapated from Xerces 2.6.0 AbstractDateTimeDV.
 //  Copyright (c) 1999-2003 The Apache Software Foundation.  All rights
 //  reserved.
 //  --------------------------------------------------------------------
@@ -71,7 +71,7 @@ public class XSDAbstractDateTimeType extends XSDDatatype {
      //define constants
      protected final static int CY = 0,  M = 1, D = 2, h = 3,
      m = 4, s = 5, ms = 6, msscale=8, utc=7, hh=0, mm=1;
-        
+
      //size for all objects must have the same fields:
      //CCYY, MM, DD, h, m, s, ms + timeZone
      protected final static int TOTAL_SIZE = 9;
@@ -82,7 +82,6 @@ public class XSDAbstractDateTimeType extends XSDDatatype {
      protected final static int MONTH=01;
      protected final static int DAY = 15;
 
-
      /**
       * Parses time hh:mm:ss.sss and time zone if any
       *
@@ -117,7 +116,7 @@ public class XSDAbstractDateTimeType extends XSDDatatype {
 
          if (stop == end)
              return;
-        
+
          //get miliseconds (ms)
          start = stop;
          int millisec = buffer.charAt(start) == '.' ? start : -1;
@@ -284,7 +283,7 @@ public class XSDAbstractDateTimeType extends XSDDatatype {
      public static final boolean isDigit(char ch) {
          return ch >= '0' && ch <= '9';
      }
-    
+
      // if the character is in the range 0x30 ~ 0x39, return its int value (0~9),
      // otherwise, return -1
      public static final int getDigit(char ch) {
@@ -397,7 +396,7 @@ public class XSDAbstractDateTimeType extends XSDDatatype {
          append(message, (char)date[utc], 0);
          return message.toString();
      }
-    
+
      /** Append the fraction time part of a date/time vector to
       * a string buffer.
       */
@@ -412,7 +411,7 @@ public class XSDAbstractDateTimeType extends XSDDatatype {
          while (trunc > 0 && msString.charAt(trunc-1) == '0') trunc --;
          buff.append(msString.substring(0, trunc));
      }
-     
+
      protected void append(StringBuilder message, int value, int nch) {
          if (value < 0) {
              message.append('-');
@@ -438,15 +437,15 @@ public class XSDAbstractDateTimeType extends XSDDatatype {
          }
      }
 
-    
+
 //  --------------------------------------------------------------------
-//  End of code is adapated from Xerces 2.6.0 AbstractDateTimeDV.    
+//  End of code is adapated from Xerces 2.6.0 AbstractDateTimeDV.
 //  --------------------------------------------------------------------
-     
+
      /**
      * Normalization. If the value is narrower than the current data type
      * (e.g. value is xsd:date but the time is xsd:datetime) returns
-     * the narrower type for the literal. 
+     * the narrower type for the literal.
      * If the type is narrower than the value then it may normalize
      * the value (e.g. set the mask of an XSDDateTime)
      * Currently only used to narrow gener XSDDateTime objects
diff --git a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/cmds/FusekiMain.java b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/cmds/FusekiMain.java
index 015d97f9b0..7a2f85939c 100644
--- a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/cmds/FusekiMain.java
+++ b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/cmds/FusekiMain.java
@@ -62,6 +62,26 @@ public class FusekiMain extends CmdARQ {
     /** Default HTTPS port when running from the command line. */
     public static int defaultHttpsPort     = 3043;
 
+    /**
+     * Build, but do not start, a server based on command line syntax.
+     */
+    public static FusekiServer build(String... args) {
+        FusekiServer.Builder builder = builder(args);
+        return builder.build();
+    }
+
+    /**
+     * Create a server and run, within the same JVM.
+     * This is the command line entry point.
+     * This function does not return.
+     * See also {@link #build} to create and return a server.
+     */
+    public static void run(String... argv) {
+        JenaSystem.init();
+        InitFusekiMain.init();
+        new FusekiMain(argv).mainRun();
+    }
+
     private static ArgDecl  argMem          = new ArgDecl(ArgDecl.NoValue,  "mem");
     private static ArgDecl  argUpdate       = new ArgDecl(ArgDecl.NoValue,  "update", "allowUpdate");
     private static ArgDecl  argFile         = new ArgDecl(ArgDecl.HasValue, "file");
@@ -140,26 +160,6 @@ public class FusekiMain extends CmdARQ {
         return builder;
     }
 
-    /**
-     * Build, but do not start, a server based on command line syntax.
-     */
-    public static FusekiServer build(String... args) {
-        FusekiServer.Builder builder = builder(args);
-        return builder.build();
-    }
-
-    /**
-     * Create a server and run, within the same JVM.
-     * This is the command line entry point.
-     * This function does not return.
-     * See also {@link #build} to create and return a server.
-     */
-    public static void run(String... argv) {
-        JenaSystem.init();
-        InitFusekiMain.init();
-        new FusekiMain(argv).mainRun();
-    }
-
     /**
      * Registers a custom arguments module.
      *
diff --git a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/FusekiServerRunner.java b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/FusekiServerRunner.java
index e6443a2def..fc4a158166 100644
--- a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/FusekiServerRunner.java
+++ b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/FusekiServerRunner.java
@@ -40,11 +40,14 @@ import org.apache.jena.fuseki.mod.ui.FMod_UI;
 public class FusekiServerRunner {
 
     public static void main(String... args) {
-        //runAsync(args).join();
-        prepareFusekiMain();
+        prepareFusekiServerConstruct();
         FusekiMain.run(args);
+        // Does not return.
     }
 
+    /**
+     * Run {@link FusekiServer} with {@link FusekiModules} as given by {@link #serverModules()}.
+     */
     public static FusekiServer runAsync(String... args) {
         FusekiServer server = construct(args);
         try {
@@ -64,15 +67,18 @@ public class FusekiServerRunner {
         }
     }
 
+    /**
+     * Build but do not start, a {@link FusekiServer} with {@link FusekiModules} as given by {@link #serverModules()}.
+     */
     public static FusekiServer construct(String... args) {
-        prepareFusekiMain();
+        prepareFusekiServerConstruct();
         // Make server
         FusekiServer server = FusekiServer.construct(args);
         resetFusekiMain();
         return server;
     }
 
-    private static void prepareFusekiMain() {
+    private static void prepareFusekiServerConstruct() {
         String fusekiBase = Lib.getenv(FusekiServerCtl.envFusekiBase);
         if ( fusekiBase == null )
             fusekiBase = FusekiServerCtl.dftFusekiBase;
diff --git a/jena-shacl/src/test/java/org/apache/jena/shacl/test_vocab/SHT.java b/jena-shacl/src/test/java/org/apache/jena/shacl/test_vocab/SHT.java
index 06ede09786..2f6ffb2abf 100644
--- a/jena-shacl/src/test/java/org/apache/jena/shacl/test_vocab/SHT.java
+++ b/jena-shacl/src/test/java/org/apache/jena/shacl/test_vocab/SHT.java
@@ -25,18 +25,18 @@ import org.apache.jena.rdf.model.ResourceFactory;
 public class SHT {
 
 	public static final String BASE_URI = "http://www.w3.org/ns/shacl-test";
-	
+
 	public static final String NS = BASE_URI + "#";
-	
+
 	public final static Resource CoreOnly = ResourceFactory.createResource(NS + "CoreOnly");
-	
+
 	public final static Property dataGraph = ResourceFactory.createProperty(NS + "dataGraph");
-	
+
 	public final static Resource Failure = ResourceFactory.createResource(NS + "Failure");
-	
+
 	public final static Resource proposed = ResourceFactory.createResource(NS + "proposed");
-	
+
 	public final static Property shapesGraph = ResourceFactory.createProperty(NS + "shapesGraph");
-	
+
 	public final static Resource Validate = ResourceFactory.createResource(NS + "Validate");
 }


(jena) 03/14: Address deprecation warnings

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 6ade8335a360a7c408576342689ba8029574184a
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Mon Jul 14 17:23:14 2025 +0100

    Address deprecation warnings
---
 jena-base/src/main/java/org/apache/jena/atlas/lib/AlarmClock.java | 2 +-
 jena-core/src/main/java/org/apache/jena/util/FileUtils.java       | 5 ++---
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/AlarmClock.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/AlarmClock.java
index e920aa0979..93284d3372 100644
--- a/jena-base/src/main/java/org/apache/jena/atlas/lib/AlarmClock.java
+++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/AlarmClock.java
@@ -29,7 +29,7 @@ import org.apache.commons.lang3.concurrent.BasicThreadFactory ;
  */
 public class AlarmClock {
     // A ThreadFactory that creates daemons
-    private static ThreadFactory threadFactory = new BasicThreadFactory.Builder()
+    private static ThreadFactory threadFactory = BasicThreadFactory.builder()
         .daemon(true)
         .namingPattern("alarm-clock-%d")
         //.uncaughtExceptionHandler(null)
diff --git a/jena-core/src/main/java/org/apache/jena/util/FileUtils.java b/jena-core/src/main/java/org/apache/jena/util/FileUtils.java
index 0d02c0b3c3..abaa6b0f1c 100644
--- a/jena-core/src/main/java/org/apache/jena/util/FileUtils.java
+++ b/jena-core/src/main/java/org/apache/jena/util/FileUtils.java
@@ -18,8 +18,6 @@
 
 package org.apache.jena.util;
 
-import static org.apache.commons.lang3.StringUtils.startsWithIgnoreCase;
-
 import java.io.* ;
 import java.net.URL ;
 import java.nio.charset.Charset ;
@@ -29,6 +27,7 @@ import java.nio.file.Path;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.Strings;
 import org.apache.jena.irix.IRIs;
 import org.apache.jena.shared.JenaException ;
 import org.apache.jena.shared.WrappedIOException ;
@@ -241,7 +240,7 @@ public class FileUtils
      *
      */
     private static String pathname(String filename) {
-        if ( !startsWithIgnoreCase(filename, "http:") && !startsWithIgnoreCase(filename, "https:") )
+        if ( !Strings.CI.startsWith(filename, "http:") && !Strings.CI.startsWith(filename, "https:") )
             return filename;
         return StringUtils.substringBefore(filename, "?");
     }


(jena) 05/14: Correct IRI user info message

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 8fdd316f2d6b986aa77b0d156b167509b45b60b2
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Tue Jul 15 09:55:02 2025 +0100

    Correct IRI user info message
---
 jena-iri3986/src/main/java/org/apache/jena/rfc3986/IRI3986.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/jena-iri3986/src/main/java/org/apache/jena/rfc3986/IRI3986.java b/jena-iri3986/src/main/java/org/apache/jena/rfc3986/IRI3986.java
index 9e44077221..2657c72ee4 100644
--- a/jena-iri3986/src/main/java/org/apache/jena/rfc3986/IRI3986.java
+++ b/jena-iri3986/src/main/java/org/apache/jena/rfc3986/IRI3986.java
@@ -1491,7 +1491,7 @@ public class IRI3986 implements IRI {
         // See also rfc7230#section-2.7.1
 
         if ( hasUserInfo() ) {
-            schemeReport(this,  Issue.iri_user_info_present, URIScheme.GENERAL, "Deprectaed; user info");
+            schemeReport(this,  Issue.iri_user_info_present, URIScheme.GENERAL, "Use of user info is deprecated");
             int idx = contains(iriStr, ':',  userinfo0, userinfo1);
             if ( idx >= 0 && idx < userinfo1-1 )
                 schemeReport(this,  Issue.iri_password, URIScheme.GENERAL, "Non-empty password");