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 3f3e36559fb17e0848e1aab036481ac5af63f4b3
Author: Andy Seaborne <[email protected]>
AuthorDate: Wed Dec 4 18:38:22 2024 +0000

    Record configuration before wiring modifications
---
 .../jena/sparql/util/ContextAccumulator.java       |  8 ++---
 .../main/java/org/apache/jena/atlas/io/IOX.java    | 26 ++++++++++++++--
 .../org/apache/jena/fuseki/ctl/ActionStats.java    |  1 -
 .../org/apache/jena/fuseki/main/FusekiServer.java  | 28 +++++++++++++----
 .../apache/jena/fuseki/main/cmds/FusekiMain.java   | 35 ++++++++++++----------
 .../org/apache/jena/fuseki/mgt/ActionDatasets.java | 10 ++++---
 .../org/apache/jena/fuseki/TS_FusekiWebapp.java    |  5 ++--
 .../{TestAdmin.java => TestWebappAdmin.java}       |  2 +-
 .../{TestAdminAPI.java => TestWebappAdminAPI.java} |  2 +-
 .../apache/jena/fuseki/TestWebappFileUpload.java   |  1 +
 10 files changed, 80 insertions(+), 38 deletions(-)

diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/util/ContextAccumulator.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/util/ContextAccumulator.java
index 74998f5adb..52e91147a6 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/util/ContextAccumulator.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/ContextAccumulator.java
@@ -43,7 +43,7 @@ public class ContextAccumulator {
     private Context      baseContext        = null;
 
     // Context when built
-    private Context      builtContext        = null;
+    private Context      builtContext       = null;
 
     public static ContextAccumulator newBuilder() {
         return new ContextAccumulator();
@@ -77,7 +77,7 @@ public class ContextAccumulator {
 
     /**
      * If no explicit base, this is the default. It will be copied to isolate 
it at the build point.
-     * Default implement is to return ARQ.getContext().
+     * Default implementation is to return ARQ.getContext().
      */
     protected Context baseContext() { return ARQ.getContext(); }
 
@@ -108,7 +108,7 @@ public class ContextAccumulator {
      */
     public Context context() {
         // Freeze and return.
-        return getOrBuiltContext();
+        return getOrBuildContext();
     }
 
     /**
@@ -129,7 +129,7 @@ public class ContextAccumulator {
     }
 
     // Build once.
-    private Context getOrBuiltContext() {
+    private Context getOrBuildContext() {
         if ( builtContext == null )
             builtContext = buildProcess();
         return builtContext;
diff --git a/jena-base/src/main/java/org/apache/jena/atlas/io/IOX.java 
b/jena-base/src/main/java/org/apache/jena/atlas/io/IOX.java
index 02b09e1bba..b5ea543111 100644
--- a/jena-base/src/main/java/org/apache/jena/atlas/io/IOX.java
+++ b/jena-base/src/main/java/org/apache/jena/atlas/io/IOX.java
@@ -337,9 +337,31 @@ public class IOX {
             throw exceptionMaker.apply("File not found: "+path);
         if ( Files.isDirectory(path) )
             throw exceptionMaker.apply("Is a directory: "+path);
-        if ( !Files.isRegularFile(path) )
+        if ( ! Files.isRegularFile(path) )
             throw exceptionMaker.apply("Not a regular file: "+path);
-        if ( !Files.isReadable(path) )
+        if ( ! Files.isReadable(path) )
+            throw exceptionMaker.apply("Not readable: "+path);
+    }
+
+    /**
+     * Check whether a file path points to a readable directory.
+     * Generate an exception if not.
+     */
+    public static void checkReadableDirectory(String directory, 
Function<String, RuntimeException> exceptionMaker) {
+        Path path = Path.of(directory);
+        checkReadableDirectory(path, exceptionMaker);
+    }
+
+    /**
+     * Check whether a file path points to a readable directory.
+     * Generate an exception if not.
+     */
+    public static void checkReadableDirectory(Path path, Function<String, 
RuntimeException> exceptionMaker) {
+        if ( ! Files.exists(path) )
+            throw exceptionMaker.apply("File not found: "+path);
+        if ( ! Files.isDirectory(path) )
+            throw exceptionMaker.apply("Not a directory: "+path);
+        if ( ! Files.isReadable(path) )
             throw exceptionMaker.apply("Not readable: "+path);
     }
 }
diff --git 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionStats.java
 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionStats.java
index 5a674354c0..3972c9e6fa 100644
--- 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionStats.java
+++ 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionStats.java
@@ -40,7 +40,6 @@ public class ActionStats extends ActionContainerItem
     @Override
     public void validate(HttpAction action) {}
 
-    // This does not consult the system database for dormant etc.
     protected JsonValue execCommonContainer(HttpAction action) {
         if ( action.verbose )
             action.log.info(format("[%d] GET stats all", action.id));
diff --git 
a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/FusekiServer.java
 
b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/FusekiServer.java
index 9ed7ef42b0..812d26b1f2 100644
--- 
a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/FusekiServer.java
+++ 
b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/FusekiServer.java
@@ -61,6 +61,7 @@ import org.apache.jena.rdf.model.*;
 import org.apache.jena.sparql.core.DatasetGraph;
 import org.apache.jena.sparql.core.assembler.AssemblerUtils;
 import org.apache.jena.sparql.util.Context;
+import org.apache.jena.sparql.util.ContextAccumulator;
 import org.apache.jena.sys.JenaSystem;
 import org.apache.jena.system.G;
 import org.apache.jena.system.RDFDataException;
@@ -142,11 +143,26 @@ public class FusekiServer {
      * still be created for the server to be able to provide the action. An 
endpoint
      * dispatches to an operation, and an operation maps to an implementation. 
This is a
      * specialised operation - normal use is the operation {@link #create()}.
+     * @deprecated Use {@link #create(OperationRegistry, Context)}.
      */
+    @Deprecated(forRemoval = true)
     public static Builder create(OperationRegistry serviceDispatchRegistry) {
-        return new Builder(serviceDispatchRegistry);
+        return create(serviceDispatchRegistry, Fuseki.getContext());
     }
 
+    /**
+     * Return a builder, with a custom set of operation-action mappings. An 
endpoint must
+     * still be created for the server to be able to provide the action. An 
endpoint
+     * dispatches to an operation, and an operation maps to an implementation. 
This is a
+     * specialised operation - normal use is the operation {@link #create()}.
+     */
+    public static Builder create(OperationRegistry serviceDispatchRegistry, 
Context context) {
+        if ( context == null )
+            context = Fuseki.getContext();
+        return new Builder(serviceDispatchRegistry, context);
+    }
+
+
     /**
      * Default port when running in Java via {@code FusekiServer....build()}.
      * The server will be http://localhost:3330.
@@ -446,7 +462,7 @@ public class FusekiServer {
         private SecurityHandler          securityHandler    = null;
         private Map<String, Object>      servletAttr        = new HashMap<>();
 
-        //private Context                  context            = null;
+        private final ContextAccumulator context;
 
         // The default CORS settings.
         private static final Map<String, String> corsInitParamsDft = new 
LinkedHashMap<>();
@@ -467,13 +483,13 @@ public class FusekiServer {
         // Builder with standard operation-action mapping.
         private Builder() {
             this.operationRegistry = OperationRegistry.createStd();
+            this.context = 
ContextAccumulator.newBuilder(()->Fuseki.getContext().copy());
         }
 
         // Builder with provided operation-action mapping.
-        private Builder(OperationRegistry operationRegistry) {
-            // Isolate.
-            this.operationRegistry = OperationRegistry.createEmpty();
-            OperationRegistry.copyConfig(operationRegistry, 
this.operationRegistry);
+        private Builder(OperationRegistry operationRegistry, Context context) {
+            this.operationRegistry = new OperationRegistry(operationRegistry);
+            this.context = ContextAccumulator.newBuilder(()->context.copy());
         }
 
         /**
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 b7a754cd64..f3966f5cc8 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
@@ -240,9 +240,11 @@ public class FusekiMain extends CmdARQ {
     }
 
     private void argumentsSetup() {
-        getUsage().startCategory("Fuseki Main");
+        getUsage().startCategory("Fuseki");
 
-        // Control the order!
+        add(argConfig, "--config=FILE",
+            "Use a configuration file to determine the services");
+        // ---- Describe the dataset on the command line.
         add(argMem, "--mem",
             "Create an in-memory, non-persistent dataset for the server");
         add(argFile, "--file=FILE",
@@ -257,25 +259,33 @@ public class FusekiMain extends CmdARQ {
             "Create an in-memory, non-persistent dataset using TDB (testing 
only)");
         add(argRDFS, "--rdfs=FILE",
             "Apply RDFS on top of the dataset");
-        add(argConfig, "--config=FILE",
-            "Use a configuration file to determine the services");
+        add(argUpdate, "--update",
+                "Allow updates (via SPARQL Update and SPARQL HTTP Update)");
         addModule(modDataset);
 
+        // ---- Server setup
         add(argEmpty); // Hidden
         add(argPort, "--port",
             "Listen on this port number");
         add(argLocalhost, "--localhost",
             "Listen only on the localhost interface");
-        add(argTimeout, "--timeout=",
-            "Global timeout applied to queries (value in ms) -- format is 
X[,Y] ");
-        add(argUpdate, "--update",
-            "Allow updates (via SPARQL Update and SPARQL HTTP Update)");
         add(argGZip, "--gzip=on|off",
-            "Enable GZip compression (HTTP Accept-Encoding) if request header 
set");
+                "Enable GZip compression (HTTP Accept-Encoding) if request 
header set");
         add(argBase, "--base=DIR",
             "Directory for static content");
         add(argContextPath, "--contextPath=PATH",
             "Context path for the server");
+        add(argHttps, "--https=CONF",
+                "https certificate access details. JSON file { \"cert\":FILE , 
\"passwd\"; SECRET } ");
+        add(argHttpsPort, "--httpsPort=NUM",
+                "https port (default port is 3043)");
+        add(argPasswdFile, "--passwd=FILE",
+                "Password file");
+
+        add(argTimeout, "--timeout=",
+                "Global timeout applied to queries (value in ms) -- format is 
X[,Y] ");
+
+        // ---- Servlets
         add(argSparqler, "--sparqler=DIR",
             "Run with SPARQLer services Directory for static content");
         add(argValidators, "--validators",
@@ -285,13 +295,6 @@ public class FusekiMain extends CmdARQ {
 
         add(argAuth, "--auth=[basic|digest]",
             "Run the server using basic or digest authentication");
-        add(argHttps, "--https=CONF",
-            "https certificate access details. JSON file { \"cert\":FILE , 
\"passwd\"; SECRET } ");
-        add(argHttpsPort, "--httpsPort=NUM",
-            "https port (default port is 3043)");
-
-        add(argPasswdFile, "--passwd=FILE",
-            "Password file");
         add(argJettyConfig, "--jetty=FILE",
             "jetty.xml server configuration");
         add(argCORS, "--cors=FILE", "Configure CORS settings from file");
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 109332f8ad..a6a48657b0 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
@@ -141,10 +141,6 @@ public class ActionDatasets extends ActionContainerItem {
                 else
                     assemblerFromBody(action, dest);
 
-                Model model = ModelFactory.createDefaultModel();
-                model.add(modelData);
-                AssemblerUtils.addRegistered(model);
-
                 // ----
                 // Keep a persistent copy immediately.  This is not used for
                 // anything other than being "for the record".
@@ -152,6 +148,12 @@ public class ActionDatasets extends ActionContainerItem {
                 try ( OutputStream outCopy = IO.openOutputFile(systemFileCopy) 
) {
                     RDFDataMgr.write(outCopy, modelData, Lang.TURTLE);
                 }
+
+                Model model = ModelFactory.createDefaultModel();
+                model.add(modelData);
+                // Add the dataset and graph wiring.
+                AssemblerUtils.addRegistered(model);
+
                 // ----
                 // Process configuration.
 
diff --git 
a/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TS_FusekiWebapp.java
 
b/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TS_FusekiWebapp.java
index 03220d4027..cb517c964c 100644
--- 
a/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TS_FusekiWebapp.java
+++ 
b/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TS_FusekiWebapp.java
@@ -26,15 +26,14 @@ import org.junit.BeforeClass;
 import org.junit.runner.RunWith;
 import org.junit.runners.Suite;
 
-
 @RunWith(Suite.class)
 @Suite.SuiteClasses( {
       TestWebappSPARQLProtocol.class
     , TestWebappAuthQuery_JDK.class
     , TestWebappAuthUpdate_JDK.class
     , TestWebappFileUpload.class
-    , TestAdmin.class
-    , TestAdminAPI.class
+    , TestWebappAdmin.class
+    , TestWebappAdminAPI.class
     , TestWebappServerReadOnly.class
     , TestWebappMetrics.class
 })
diff --git 
a/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestAdmin.java
 
b/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestWebappAdmin.java
similarity index 99%
rename from 
jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestAdmin.java
rename to 
jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestWebappAdmin.java
index 7a89107326..fc60dda045 100644
--- 
a/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestAdmin.java
+++ 
b/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestWebappAdmin.java
@@ -56,7 +56,7 @@ import org.awaitility.Awaitility;
 import org.junit.*;
 
 /** Tests of the admin functionality */
-public class TestAdmin extends AbstractFusekiWebappTest {
+public class TestWebappAdmin extends AbstractFusekiWebappTest {
 
     // Name of the dataset in the assembler file.
     static String dsTest      = "test-ds1";
diff --git 
a/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestAdminAPI.java
 
b/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestWebappAdminAPI.java
similarity index 98%
rename from 
jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestAdminAPI.java
rename to 
jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestWebappAdminAPI.java
index 729ff40ac5..7c1ba82d44 100644
--- 
a/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestAdminAPI.java
+++ 
b/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestWebappAdminAPI.java
@@ -38,7 +38,7 @@ import org.junit.Test;
 /** More tests of the admin functionality
  * See also TestAdmin.
  */
-public class TestAdminAPI extends AbstractFusekiWebappTest {
+public class TestWebappAdminAPI extends AbstractFusekiWebappTest {
 
     @Test public void add_delete_api_1() throws Exception {
         if ( org.apache.jena.tdb1.sys.SystemTDB.isWindows )
diff --git 
a/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestWebappFileUpload.java
 
b/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestWebappFileUpload.java
index b834966b37..15fc83787a 100644
--- 
a/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestWebappFileUpload.java
+++ 
b/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestWebappFileUpload.java
@@ -40,6 +40,7 @@ import org.junit.Test;
  * Tests for multi-part file upload.
  */
 public class TestWebappFileUpload extends AbstractFusekiWebappTest {
+
     @Test
     public void upload_gsp_01() {
         FileSender x = new FileSender(ServerCtl.serviceGSP() + "?default");

Reply via email to