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 2019/06/07 11:16:21 UTC
[jena] branch master updated: JENA-1715: Fuseki dispatch
This is an automated email from the ASF dual-hosted git repository.
andy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jena.git
The following commit(s) were added to refs/heads/master by this push:
new 2299725 JENA-1715: Fuseki dispatch
new 5bf2bed Merge pull request #573 from afs/fuseki-dispatch
2299725 is described below
commit 229972507a2dab26a8572a8f537fa33c77c50cd4
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Sun May 5 17:24:06 2019 +0100
JENA-1715: Fuseki dispatch
---
.../org/apache/jena/atlas/json/JsonObject.java | 28 +-
.../org/apache/jena/atlas/web/HttpException.java | 21 +-
.../main/java/org/apache/jena/riot/web/HttpOp.java | 8 +-
.../apache/jena/sparql/core/DatasetGraphBase.java | 8 +-
.../jena/sparql/core/DatasetGraphWrapper.java | 7 +-
.../apache/jena/sparql/engine/http/HttpQuery.java | 22 +-
.../sparql/engine/http/QueryExceptionHTTP.java | 29 +-
.../apache/jena/web/DatasetGraphAccessorHTTP.java | 6 +-
.../src/main/java/org/apache/jena/web/HttpSC.java | 7 +-
.../org/apache/jena/atlas/io/InStreamUTF8.java | 58 +-
.../org/apache/jena/atlas/io/OutStreamUTF8.java | 58 +-
.../java/org/apache/jena/atlas/lib/Registry.java | 1 -
.../jena/fuseki/access/AccessCtl_AllowGET.java | 74 +++
...PARQL_Update.java => AccessCtl_DenyUpdate.java} | 56 +-
...sCtl_SPARQL_GSP_R.java => AccessCtl_GSP_R.java} | 8 +-
.../jena/fuseki/access/AccessCtl_REST_Quads_R.java | 43 --
.../fuseki/access/AccessCtl_REST_Quads_RW.java | 49 --
.../fuseki/access/AccessCtl_SPARQL_GSP_RW.java | 49 --
.../access/AccessCtl_SPARQL_QueryDataset.java | 29 +-
.../fuseki/access/AccessCtl_SPARQL_Upload.java | 49 --
.../jena/fuseki/access/AssemblerAccessDataset.java | 28 +-
.../fuseki/access/AssemblerSecurityRegistry.java | 66 +--
.../jena/fuseki/access/AuthorizationService.java | 2 +-
.../apache/jena/fuseki/access/DataAccessCtl.java | 22 +-
.../apache/jena/fuseki/access/DataAccessLib.java | 12 +-
.../fuseki/access/DatasetGraphAccessControl.java | 16 +-
.../org/apache/jena/fuseki/access/GraphFilter.java | 16 +-
.../apache/jena/fuseki/access/GraphFilterTDB1.java | 8 +-
.../apache/jena/fuseki/access/GraphFilterTDB2.java | 6 +-
.../apache/jena/fuseki/access/InitSecurity.java | 6 +-
.../apache/jena/fuseki/access/SecurityContext.java | 18 +-
.../fuseki/access/SecurityContextAllowAll.java | 12 +-
.../access/SecurityContextAllowNamedGraphs.java | 12 +-
.../fuseki/access/SecurityContextAllowNone.java | 16 +-
.../jena/fuseki/access/SecurityContextView.java | 24 +-
.../jena/fuseki/access/SecurityRegistry.java | 14 +-
.../apache/jena/fuseki/access/VocabSecurity.java | 12 +-
.../org/apache/jena/fuseki/access/TS_Access.java | 2 +-
.../fuseki/access/TestSecurityFilterLocal.java | 80 +--
.../jena/fuseki/access/TestSecurityRegistry.java | 14 +-
jena-fuseki2/jena-fuseki-core/pom.xml | 15 +-
.../src/main/java/org/apache/jena/fuseki/DEF.java | 65 +--
.../main/java/org/apache/jena/fuseki/Fuseki.java | 191 +++----
.../apache/jena/fuseki/FusekiConfigException.java | 8 +-
.../org/apache/jena/fuseki/FusekiException.java | 10 +-
.../org/apache/jena/fuseki/async/AsyncPool.java | 82 +--
.../org/apache/jena/fuseki/async/AsyncTask.java | 108 ++--
.../java/org/apache/jena/fuseki/auth/Auth.java | 22 +-
.../org/apache/jena/fuseki/auth/AuthPolicy.java | 2 +-
.../apache/jena/fuseki/auth/AuthPolicyList.java | 18 +-
.../org/apache/jena/fuseki/auth/AuthUserList.java | 10 +-
.../java/org/apache/jena/fuseki/auth/Users.java | 6 +-
.../build/{FusekiBuildLib.java => BuildLib.java} | 120 ++--
...ionRegistry.java => DatasetDescriptionMap.java} | 24 +-
.../apache/jena/fuseki/build/FusekiBuilder.java | 172 ------
.../org/apache/jena/fuseki/build/FusekiConfig.java | 537 +++++++++++-------
.../{FusekiConst.java => FusekiPrefixes.java} | 6 +-
.../apache/jena/fuseki/ctl/ActionAsyncTask.java | 40 +-
.../jena/fuseki/ctl/ActionContainerItem.java | 124 ++---
.../java/org/apache/jena/fuseki/ctl/ActionCtl.java | 118 ++--
.../apache/jena/fuseki/ctl/ActionDumpRequest.java | 37 +-
.../org/apache/jena/fuseki/ctl/ActionItem.java | 18 +-
.../org/apache/jena/fuseki/ctl/ActionMetrics.java | 25 +-
.../org/apache/jena/fuseki/ctl/ActionPing.java | 44 +-
.../org/apache/jena/fuseki/ctl/ActionSleep.java | 84 +--
.../org/apache/jena/fuseki/ctl/ActionStats.java | 261 ++++-----
.../org/apache/jena/fuseki/ctl/ActionTasks.java | 121 ++--
.../java/org/apache/jena/fuseki/ctl/Async.java | 50 +-
.../org/apache/jena/fuseki/ctl/JsonConstCtl.java | 10 +-
.../apache/jena/fuseki/ctl/JsonDescription.java | 68 +--
.../java/org/apache/jena/fuseki/ctl/TaskBase.java | 24 +-
.../jena/fuseki/jetty/FusekiErrorHandler.java | 64 +--
.../jena/fuseki/jetty/FusekiErrorHandler1.java | 49 +-
.../org/apache/jena/fuseki/jetty/JettyHttps.java | 16 +-
.../org/apache/jena/fuseki/jetty/JettyLib.java | 34 +-
.../jena/fuseki/jetty/JettyServerConfig.java | 30 +-
.../java/org/apache/jena/fuseki/package-info.java | 8 +-
.../org/apache/jena/fuseki/server/Counter.java | 14 +-
.../org/apache/jena/fuseki/server/CounterName.java | 20 +-
.../org/apache/jena/fuseki/server/CounterSet.java | 37 +-
.../org/apache/jena/fuseki/server/Counters.java | 4 +-
.../apache/jena/fuseki/server/DataAccessPoint.java | 49 +-
.../fuseki/server/DataAccessPointRegistry.java | 40 +-
.../org/apache/jena/fuseki/server/DataService.java | 153 ++++--
.../jena/fuseki/server/DataServiceStatus.java | 24 +-
.../apache/jena/fuseki/server/DatasetMXBean.java | 35 --
.../org/apache/jena/fuseki/server/Endpoint.java | 14 +-
.../org/apache/jena/fuseki/server/EndpointSet.java | 119 ++++
.../org/apache/jena/fuseki/server/FusekiInfo.java | 34 +-
.../jena/fuseki/server/FusekiInitialConfig.java | 54 +-
.../org/apache/jena/fuseki/server/FusekiVocab.java | 21 +-
.../org/apache/jena/fuseki/server/NameMgr.java | 4 +-
.../org/apache/jena/fuseki/server/Operation.java | 37 +-
.../org/apache/jena/fuseki/server/RequestLog.java | 142 ++---
.../org/apache/jena/fuseki/server/ServerConst.java | 30 +-
.../org/apache/jena/fuseki/server/ServiceOnly.java | 44 --
.../apache/jena/fuseki/servlets/ActionBase.java | 283 ++--------
.../jena/fuseki/servlets/ActionErrorException.java | 16 +-
.../apache/jena/fuseki/servlets/ActionExecLib.java | 310 +++++++++++
.../org/apache/jena/fuseki/servlets/ActionLib.java | 248 ++++++---
.../ActionLifecycle.java} | 15 +-
.../jena/fuseki/servlets/ActionProcessor.java | 52 ++
.../apache/jena/fuseki/servlets/ActionREST.java | 156 +++---
.../apache/jena/fuseki/servlets/ActionService.java | 282 +---------
.../jena/fuseki/servlets/CrossOriginFilter.java | 10 +-
.../apache/jena/fuseki/servlets/Dispatcher.java | 416 ++++++++++++++
.../apache/jena/fuseki/servlets/FusekiFilter.java | 85 +--
.../org/apache/jena/fuseki/servlets/GSPTarget.java | 105 ++++
.../org/apache/jena/fuseki/servlets/GSP_Base.java | 164 ++++++
.../org/apache/jena/fuseki/servlets/GSP_R.java | 177 ++++++
.../org/apache/jena/fuseki/servlets/GSP_RW.java | 364 ++++++++++++
.../apache/jena/fuseki/servlets/HttpAction.java | 386 ++++++-------
.../servlets/HttpServletResponseTracker.java | 20 +-
...ispatchRegistry.java => OperationRegistry.java} | 84 ++-
.../apache/jena/fuseki/servlets/REST_Quads.java | 62 ---
.../apache/jena/fuseki/servlets/REST_Quads_R.java | 121 ----
.../apache/jena/fuseki/servlets/REST_Quads_RW.java | 150 -----
.../jena/fuseki/servlets/ResponseCallback.java | 4 +-
.../jena/fuseki/servlets/ResponseDataset.java | 122 ++---
.../apache/jena/fuseki/servlets/ResponseJson.java | 133 ++---
.../apache/jena/fuseki/servlets/ResponseOps.java | 90 ++-
.../jena/fuseki/servlets/ResponseResultSet.java | 190 +++----
.../jena/fuseki/servlets/SPARQLProtocol.java | 104 ++++
...SPARQL_Query.java => SPARQLQueryProcessor.java} | 290 +++++-----
.../apache/jena/fuseki/servlets/SPARQL_GSP.java | 225 --------
.../apache/jena/fuseki/servlets/SPARQL_GSP_R.java | 140 -----
.../apache/jena/fuseki/servlets/SPARQL_GSP_RW.java | 216 --------
.../jena/fuseki/servlets/SPARQL_Protocol.java | 111 ----
.../jena/fuseki/servlets/SPARQL_QueryDataset.java | 51 +-
.../jena/fuseki/servlets/SPARQL_QueryGeneral.java | 246 +++++----
.../apache/jena/fuseki/servlets/SPARQL_Update.java | 278 +++++-----
.../apache/jena/fuseki/servlets/SPARQL_Upload.java | 136 +++--
.../apache/jena/fuseki/servlets/ServiceRouter.java | 360 ------------
.../apache/jena/fuseki/servlets/ServletAction.java | 62 +++
.../apache/jena/fuseki/servlets/ServletBase.java | 69 +--
.../apache/jena/fuseki/servlets/ServletOps.java | 153 +++---
.../jena/fuseki/servlets/ServletProcessor.java | 60 ++
.../java/org/apache/jena/fuseki/system/ConNeg.java | 217 ++++----
.../apache/jena/fuseki/system/FusekiLogging.java | 132 ++---
.../apache/jena/fuseki/system/FusekiNetLib.java | 167 +++---
.../apache/jena/fuseki/system/GraphLoadUtils.java | 63 +--
.../jena/fuseki/system/StreamRDFLimited.java | 36 +-
.../java/org/apache/jena/fuseki/system/Upload.java | 258 ++++-----
.../apache/jena/fuseki/system/UploadDetails.java | 74 +--
.../jena/fuseki/system/UploadDetailsWithName.java | 12 +-
.../jena/fuseki/validation/ValidatorBase.java | 154 +++---
.../jena/fuseki/validation/ValidatorBaseJson.java | 230 ++++----
.../fuseki/validation/html/DataValidatorHTML.java | 236 ++++----
.../fuseki/validation/html/IRIValidatorHTML.java | 127 +++--
.../fuseki/validation/html/QueryValidatorHTML.java | 300 +++++-----
.../validation/html/UpdateValidatorHTML.java | 152 +++---
.../fuseki/validation/html/ValidatorHtmlLib.java | 148 +++--
.../fuseki/validation/json/DataValidatorJSON.java | 108 ++--
.../fuseki/validation/json/IRIValidatorJSON.java | 112 ++--
.../fuseki/validation/json/QueryValidatorJSON.java | 154 +++---
.../validation/json/UpdateValidatorJSON.java | 94 ++--
.../fuseki/validation/json/ValidationAction.java | 95 ++--
.../fuseki/validation/json/ValidatorJsonLib.java | 69 ++-
.../test/java/org/apache/jena/fuseki/Dummy.java | 4 +-
.../org/apache/jena/fuseki/test/FusekiTest.java | 150 +++++
jena-fuseki2/jena-fuseki-main/pom.xml | 8 +
.../org/apache/jena/fuseki/main/FusekiLib.java | 64 +--
.../org/apache/jena/fuseki/main/FusekiServer.java | 303 ++++++----
.../org/apache/jena/fuseki/main/JettyServer.java | 21 +-
.../apache/jena/fuseki/main/cmds/FusekiMain.java | 150 ++---
.../jena/fuseki/main/cmds/FusekiMainCmd.java | 6 +-
.../apache/jena/fuseki/main/cmds/PlatformInfo.java | 22 +-
.../apache/jena/fuseki/main/cmds/ServerConfig.java | 22 +-
.../apache/jena/fuseki/main/CustomTestService.java | 6 +-
.../org/apache/jena/fuseki/main/FusekiTestLib.java | 119 ++++
.../apache/jena/fuseki/main/FusekiTestServer.java | 146 ++---
.../main/{TC_Fuseki.java => TC_FusekiMain.java} | 13 +-
.../org/apache/jena/fuseki/main/TS_FusekiMain.java | 24 +-
.../jena/fuseki/main/TestEmbeddedFuseki.java | 387 +++++++------
.../fuseki/main/TestFusekiCustomOperation.java | 52 +-
.../apache/jena/fuseki/main/TestFusekiMainCmd.java | 18 +-
.../jena/fuseki/main/TestFusekiTestServer.java | 61 ---
.../jena/fuseki/main/TestMultipleEmbedded.java | 170 +++---
.../org/apache/jena/fuseki/main/TestStdSetup.java | 170 ++++++
.../AbstractTestFusekiSecurityAssembler.java | 71 +--
.../access/AbstractTestServiceDatasetAuth.java | 112 ++++
.../jena/fuseki/main/access/AccessTestLib.java | 24 +-
.../jena/fuseki/main/access/TS_SecurityFuseki.java | 17 +-
.../jena/fuseki/main/access/TestAuthorized.java | 26 +-
.../jena/fuseki/main/access/TestPasswdOnly.java | 103 ++++
.../main/access/TestSecurityBuilderSetup.java | 50 +-
.../fuseki/main/access/TestSecurityConfig.java | 52 +-
.../main/access/TestSecurityFilterFuseki.java | 68 +--
.../main/access/TestServiceDataAuthBuild.java} | 31 +-
.../main/access/TestServiceDataAuthConfig.java | 60 ++
.../jena/fuseki/main/examples/ExampleService.java | 6 +-
.../main/examples/ExtendFuseki_AddService_1.java | 46 +-
.../main/examples/ExtendFuseki_AddService_2.java | 48 +-
.../main/examples/ExtendFuseki_AddService_3.java | 36 +-
.../jena/fuseki/main/{ => old}/FusekiTestAuth.java | 115 ++--
.../TestFusekiTestAuthOld.java} | 38 +-
.../testing/Access/config-auth.ttl | 44 ++
.../jena-fuseki-main/testing/Access/passwd | 4 +-
jena-fuseki2/jena-fuseki-webapp/pom.xml | 8 +
.../jena/fuseki/authz/AuthorizationFilter403.java | 44 +-
.../org/apache/jena/fuseki/authz/DenyFilter.java | 8 +-
.../apache/jena/fuseki/authz/LocalhostFilter.java | 30 +-
.../java/org/apache/jena/fuseki/cmd/FusekiCmd.java | 324 +++++------
.../apache/jena/fuseki/cmd/JettyFusekiWebapp.java | 292 +++++-----
.../org/apache/jena/fuseki/mgt/ActionBackup.java | 44 +-
.../apache/jena/fuseki/mgt/ActionBackupList.java | 88 +--
.../org/apache/jena/fuseki/mgt/ActionDatasets.java | 484 ++++++++--------
.../org/apache/jena/fuseki/mgt/ActionLogs.java | 48 +-
.../apache/jena/fuseki/mgt/ActionServerStatus.java | 91 +--
.../java/org/apache/jena/fuseki/mgt/Backup.java | 98 ++--
.../org/apache/jena/fuseki/mgt/ServerMgtConst.java | 26 +-
.../java/org/apache/jena/fuseki/mgt/Template.java | 51 +-
.../apache/jena/fuseki/mgt/TemplateFunctions.java | 60 +-
.../org/apache/jena/fuseki/webapp/FusekiEnv.java | 144 ++---
.../fuseki/webapp/FusekiServerEnvironmentInit.java | 22 +-
.../jena/fuseki/webapp/FusekiServerListener.java | 60 +-
.../apache/jena/fuseki/webapp/FusekiWebapp.java | 419 +++++++-------
.../jena/fuseki/webapp/ShiroEnvironmentLoader.java | 140 ++---
.../org/apache/jena/fuseki/webapp/SystemState.java | 84 +--
.../apache/jena/fuseki/webapp/templates/config-mem | 4 +
.../jena/fuseki/webapp/templates/config-service | 23 -
.../apache/jena/fuseki/webapp/templates/config-tdb | 21 +-
.../jena/fuseki/webapp/templates/config-tdb-dir | 20 +-
.../jena/fuseki/webapp/templates/config-tdb-mem | 20 +-
.../jena/fuseki/webapp/templates/config-tdb2 | 21 +-
.../jena/fuseki/webapp/templates/config-tdb2-dir | 21 +-
.../jena/fuseki/webapp/templates/config-tdb2-mem | 22 +-
.../org/apache/jena/fuseki/AbstractFusekiTest.java | 16 +-
.../java/org/apache/jena/fuseki/FileSender.java | 72 +--
.../java/org/apache/jena/fuseki/FusekiTest.java | 101 ----
.../java/org/apache/jena/fuseki/ServerCtl.java | 216 ++++----
.../java/org/apache/jena/fuseki/ServerTest.java | 34 +-
.../org/apache/jena/fuseki/TS_FusekiWebapp.java | 34 +-
.../java/org/apache/jena/fuseki/TestAdmin.java | 608 +++++++++++----------
.../java/org/apache/jena/fuseki/TestAdminAPI.java | 38 +-
.../test/java/org/apache/jena/fuseki/TestAuth.java | 96 ++--
.../java/org/apache/jena/fuseki/TestBuilder.java | 8 +-
.../jena/fuseki/TestDatasetAccessorHTTP.java | 456 ++++++++--------
.../jena/fuseki/TestDatasetGraphAccessorHTTP.java | 18 +-
.../org/apache/jena/fuseki/TestDatasetOps.java | 137 +++--
.../org/apache/jena/fuseki/TestFileUpload.java | 176 +++---
.../java/org/apache/jena/fuseki/TestHttpOp.java | 199 +++----
.../org/apache/jena/fuseki/TestHttpOperations.java | 90 +--
.../org/apache/jena/fuseki/TestHttpOptions.java | 25 +-
.../java/org/apache/jena/fuseki/TestQuery.java | 164 +++---
.../org/apache/jena/fuseki/TestSPARQLProtocol.java | 12 +-
.../org/apache/jena/fuseki/TestServerReadOnly.java | 88 +--
jena-jdbc/jena-jdbc-driver-remote/pom.xml | 6 +-
.../jena/jdbc/remote/RemoteEndpointDriver.java | 8 +-
.../TestRemoteEndpointConnectionWithAuth.java | 2 +-
.../results/TestRemoteEndpointResultsWithAuth.java | 2 +-
.../jena/rdfconnection/RDFConnectionRemote.java | 2 +-
252 files changed, 11402 insertions(+), 10766 deletions(-)
diff --git a/jena-arq/src/main/java/org/apache/jena/atlas/json/JsonObject.java b/jena-arq/src/main/java/org/apache/jena/atlas/json/JsonObject.java
index b7e89db..b134122 100644
--- a/jena-arq/src/main/java/org/apache/jena/atlas/json/JsonObject.java
+++ b/jena-arq/src/main/java/org/apache/jena/atlas/json/JsonObject.java
@@ -18,9 +18,10 @@
package org.apache.jena.atlas.json;
-import java.util.* ;
+import java.util.*;
import java.util.Map.Entry ;
import java.util.function.BiConsumer ;
+import java.util.stream.Stream;
public class JsonObject extends JsonValue
{
@@ -71,6 +72,31 @@ public class JsonObject extends JsonValue
return get(key).getAsObject() ;
}
+ /** For walking structures */
+ public Number getNumber(String key) {
+ return get(key).getAsNumber().value();
+ }
+
+ /** For walking structures */
+ public String getString(String key) {
+ return get(key).getAsString().value();
+ }
+
+ /** For walking structures */
+ public boolean getBoolean(String key) {
+ return get(key).getAsBoolean().value();
+ }
+
+ /** For walking structures */
+ public Stream<JsonValue> getArray(String key) {
+ return get(key).getAsArray().stream();
+ }
+
+ /** For walking structures */
+ public Iterator<JsonValue> getIterator(String key) {
+ return get(key).getAsArray().iterator();
+ }
+
public boolean isEmpty() {
return map.isEmpty() ;
}
diff --git a/jena-arq/src/main/java/org/apache/jena/atlas/web/HttpException.java b/jena-arq/src/main/java/org/apache/jena/atlas/web/HttpException.java
index 212c64f..1ce157c 100644
--- a/jena-arq/src/main/java/org/apache/jena/atlas/web/HttpException.java
+++ b/jena-arq/src/main/java/org/apache/jena/atlas/web/HttpException.java
@@ -23,14 +23,13 @@ package org.apache.jena.atlas.web;
*
*/
public class HttpException extends RuntimeException {
- private static final long serialVersionUID = -7224224620679594095L;
- private int responseCode = -1;
+ private int statusCode = -1;
private String statusLine = null ;
private String response;
- public HttpException(int responseCode, String statusLine, String response) {
- super(responseCode + " - " + statusLine);
- this.responseCode = responseCode;
+ public HttpException(int statusCode, String statusLine, String response) {
+ super(statusCode + " - " + statusLine);
+ this.statusCode = statusCode;
this.statusLine = statusLine ;
this.response = response;
}
@@ -49,11 +48,21 @@ public class HttpException extends RuntimeException {
}
/**
+ * Gets the status code, may be -1 if unknown
+ * @return Status Code if known, -1 otherwise
+ */
+ public int getStatusCode() {
+ return this.statusCode;
+ }
+
+ /**
* Gets the response code, may be -1 if unknown
* @return Response Code if known, -1 otherwise
+ * @deprecated Use {@link #getStatusCode()}
*/
+ @Deprecated
public int getResponseCode() {
- return this.responseCode;
+ return getStatusCode();
}
/**
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/web/HttpOp.java b/jena-arq/src/main/java/org/apache/jena/riot/web/HttpOp.java
index 412e372..8a06cf5 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/web/HttpOp.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/web/HttpOp.java
@@ -380,7 +380,7 @@ public class HttpOp {
try {
execHttpGet(url, acceptHeader, handler, httpClient, httpContext);
} catch (HttpException ex) {
- if (ex.getResponseCode() == HttpSC.NOT_FOUND_404)
+ if (ex.getStatusCode() == HttpSC.NOT_FOUND_404)
return null;
throw ex;
}
@@ -414,7 +414,7 @@ public class HttpOp {
try {
execHttpGet(url, acceptHeader, handler);
} catch (HttpException ex) {
- if (ex.getResponseCode() == HttpSC.NOT_FOUND_404)
+ if (ex.getStatusCode() == HttpSC.NOT_FOUND_404)
return null;
throw ex;
}
@@ -479,7 +479,7 @@ public class HttpOp {
try {
execHttpPost(url, contentType, content, acceptType, handler, httpClient, httpContext);
} catch (HttpException ex) {
- if (ex.getResponseCode() == HttpSC.NOT_FOUND_404)
+ if (ex.getStatusCode() == HttpSC.NOT_FOUND_404)
return null;
throw ex;
}
@@ -810,7 +810,7 @@ public class HttpOp {
try {
execHttpPostForm(url, params, acceptHeader, handler, httpClient, httpContext);
} catch (HttpException ex) {
- if (ex.getResponseCode() == HttpSC.NOT_FOUND_404)
+ if (ex.getStatusCode() == HttpSC.NOT_FOUND_404)
return null;
throw ex;
}
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphBase.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphBase.java
index 9b4f4e5..1caa874 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphBase.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphBase.java
@@ -68,10 +68,10 @@ abstract public class DatasetGraphBase implements DatasetGraph
@Override
public Graph getUnionGraph() {
- // Implementations are encouraged to implement an efficent
- // named graph for Quad.unionGraph, and this operation that
- // does not require the full "distinct()" used by the general purpose
- // GraphUnionRead. See also
+ // Implementations are encouraged to implement an efficient named graph for
+ // Quad.unionGraph that does not require the full "distinct()" used by this
+ // general purpose implementation.
+ // See also
// {@code DatasetGraphBase.findQuadsInUnionGraph} and
// {@code findNG(Quad.unionGraph, Node.ANY, Node.ANY, Node.ANY)}
return GraphOps.unionGraph(this);
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWrapper.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWrapper.java
index 4249248..c47c28a 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWrapper.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWrapper.java
@@ -69,11 +69,12 @@ public class DatasetGraphWrapper implements DatasetGraph, Sync
}
/** The dataset to use for redirection - can be overridden.
- * It is also guarantee that this is called only once per
+ * It is also guaranteed that this is called only once per
* delegated call. Changes to the wrapped object can be
- * made based on that contract.
+ * made based on that contract.
*/
protected DatasetGraph get() { return dsg; }
+
protected Context getCxt() { return context; }
/** For operations that only read the DatasetGraph. */
@@ -213,7 +214,7 @@ public class DatasetGraphWrapper implements DatasetGraph, Sync
@Override
public void sync() {
// Pass down sync.
- SystemARQ.sync(getW());
+ SystemARQ.sync(getW());
}
@Override
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/engine/http/HttpQuery.java b/jena-arq/src/main/java/org/apache/jena/sparql/engine/http/HttpQuery.java
index 427ddbb..860af23 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/engine/http/HttpQuery.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/engine/http/HttpQuery.java
@@ -18,6 +18,8 @@
package org.apache.jena.sparql.engine.http;
+import static org.apache.jena.web.HttpSC.*;
+
import java.io.InputStream ;
import java.net.MalformedURLException ;
import java.net.URL ;
@@ -34,9 +36,12 @@ import org.apache.jena.atlas.web.TypedInputStream ;
import org.apache.jena.query.ARQ ;
import org.apache.jena.query.QueryExecException ;
import org.apache.jena.riot.WebContent ;
+import org.apache.jena.riot.web.HttpCaptureResponse;
import org.apache.jena.riot.web.HttpOp ;
+import org.apache.jena.riot.web.HttpOp.CaptureInput;
import org.apache.jena.shared.JenaException ;
import org.apache.jena.sparql.util.Context;
+import org.apache.jena.web.HttpSC;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
@@ -322,13 +327,13 @@ public class HttpQuery extends Params {
try {
try {
// Get the actual response stream
- TypedInputStream stream = HttpOp.execHttpGet(target.toString(), contentTypeResult, client, getContext());
+ TypedInputStream stream = execHttpGet(target.toString(), contentTypeResult, client, getContext());
if (stream == null)
- throw new QueryExceptionHTTP(404);
+ throw new QueryExceptionHTTP(NOT_FOUND_404, HttpSC.getMessage(NOT_FOUND_404));
return execCommon(stream);
} catch (HttpException httpEx) {
// Back-off and try POST if something complain about long URIs
- if (httpEx.getResponseCode() == 414)
+ if (httpEx.getStatusCode() == REQUEST_URI_TOO_LONG_414)
return execPost();
throw httpEx;
}
@@ -336,6 +341,13 @@ public class HttpQuery extends Params {
throw rewrap(httpEx);
}
}
+
+ // With exception.
+ private static TypedInputStream execHttpGet(String url, String acceptHeader, HttpClient httpClient, HttpContext httpContext) {
+ HttpCaptureResponse<TypedInputStream> handler = new CaptureInput();
+ HttpOp.execHttpGet(url, acceptHeader, handler, httpClient, httpContext);
+ return handler.get();
+ }
private InputStream execPost() throws QueryExceptionHTTP {
URL target = null;
@@ -363,11 +375,11 @@ public class HttpQuery extends Params {
// The historical contract of HTTP Queries has been to throw QueryExceptionHTTP however using the standard
// ARQ HttpOp machinery we use these days means the internal HTTP errors come back as HttpException
// Therefore we need to wrap appropriately
- responseCode = httpEx.getResponseCode();
+ responseCode = httpEx.getStatusCode();
if (responseCode != -1) {
// Was an actual HTTP error
String responseLine = httpEx.getStatusLine() != null ? httpEx.getStatusLine() : "No Status Line";
- return new QueryExceptionHTTP(responseCode, "HTTP " + responseCode + " error making the query: " + responseLine, httpEx);
+ return new QueryExceptionHTTP(responseCode, responseLine, httpEx);
} else if (httpEx.getMessage() != null) {
// Some non-HTTP error with a valid message e.g. Socket Communications failed, IO error
return new QueryExceptionHTTP(responseCode, "Unexpected error making the query: " + httpEx.getMessage(), httpEx);
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/engine/http/QueryExceptionHTTP.java b/jena-arq/src/main/java/org/apache/jena/sparql/engine/http/QueryExceptionHTTP.java
index 0a36ca5..c601540 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/engine/http/QueryExceptionHTTP.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/engine/http/QueryExceptionHTTP.java
@@ -25,9 +25,8 @@ import org.apache.jena.query.QueryException ;
* Error codes are as HTTP status codes. */
public class QueryExceptionHTTP extends QueryException
{
- private static final long serialVersionUID = 99L; // Serializable.
- public static final int noResponseCode = -1234 ;
- private int responseCode = noResponseCode ;
+ public static final int noStatusCode = -1234 ;
+ private int statusCode = noStatusCode ;
private final String responseMessage ;
private String statusLine ;
private String response;
@@ -44,7 +43,7 @@ public class QueryExceptionHTTP extends QueryException
public QueryExceptionHTTP(int responseCode, String responseMessage)
{
super(responseMessage) ;
- this.responseCode = responseCode ;
+ this.statusCode = responseCode ;
this.responseMessage = responseMessage ;
}
@@ -56,15 +55,21 @@ public class QueryExceptionHTTP extends QueryException
public QueryExceptionHTTP(int responseCode)
{
super() ;
- this.responseCode = responseCode ;
+ this.statusCode = responseCode ;
this.responseMessage = null ;
}
/** The code for the reason for this exception
+ * @return statusCode
+ */
+ public int getStatusCode() { return statusCode ; }
+
+ /** The code for the reason for this exception
* @return responseCode
+ * @deprecated Use {@link #getStatusCode()}
*/
- public int getResponseCode() { return responseCode ; }
-
+ @Deprecated
+ public int getResponseCode() { return getStatusCode(); }
/** The message for the reason for this exception
* @return message
@@ -88,20 +93,20 @@ public class QueryExceptionHTTP extends QueryException
public QueryExceptionHTTP(Throwable cause)
{
super(cause);
- this.responseCode = noResponseCode ;
+ this.statusCode = noStatusCode ;
this.responseMessage = null ;
}
public QueryExceptionHTTP(String msg, Throwable cause)
{
super(msg, cause);
- this.responseCode = noResponseCode ;
+ this.statusCode = noStatusCode ;
this.responseMessage = msg ;
}
public QueryExceptionHTTP(int responseCode, String message, Throwable cause) {
this(message, cause);
- this.responseCode = responseCode;
+ this.statusCode = responseCode;
}
public QueryExceptionHTTP(int responseCode, String message, final HttpException ex) {
@@ -115,8 +120,8 @@ public class QueryExceptionHTTP extends QueryException
{
StringBuilder sb = new StringBuilder() ;
sb.append("HttpException: ") ;
- int code = getResponseCode() ;
- if ( code != QueryExceptionHTTP.noResponseCode )
+ int code = getStatusCode() ;
+ if ( code != QueryExceptionHTTP.noStatusCode )
{
sb.append(code) ;
if ( getResponseMessage() != null )
diff --git a/jena-arq/src/main/java/org/apache/jena/web/DatasetGraphAccessorHTTP.java b/jena-arq/src/main/java/org/apache/jena/web/DatasetGraphAccessorHTTP.java
index 32afa09..24c4f9c 100644
--- a/jena-arq/src/main/java/org/apache/jena/web/DatasetGraphAccessorHTTP.java
+++ b/jena-arq/src/main/java/org/apache/jena/web/DatasetGraphAccessorHTTP.java
@@ -115,7 +115,7 @@ public class DatasetGraphAccessorHTTP implements DatasetGraphAccessor {
try {
HttpOp.execHttpGet(url, graphAcceptHeader, graph, client, null) ;
} catch (HttpException ex) {
- if ( ex.getResponseCode() == HttpSC.NOT_FOUND_404 )
+ if ( ex.getStatusCode() == HttpSC.NOT_FOUND_404 )
return null ;
throw ex ;
}
@@ -137,7 +137,7 @@ public class DatasetGraphAccessorHTTP implements DatasetGraphAccessor {
HttpOp.execHttpHead(url, WebContent.defaultGraphAcceptHeader, noResponse, client, null) ;
return true ;
} catch (HttpException ex) {
- if ( ex.getResponseCode() == HttpSC.NOT_FOUND_404 )
+ if ( ex.getStatusCode() == HttpSC.NOT_FOUND_404 )
return false ;
throw ex ;
}
@@ -172,7 +172,7 @@ public class DatasetGraphAccessorHTTP implements DatasetGraphAccessor {
try {
HttpOp.execHttpDelete(url, noResponse, client, null) ;
} catch (HttpException ex) {
- if ( ex.getResponseCode() == HttpSC.NOT_FOUND_404 )
+ if ( ex.getStatusCode() == HttpSC.NOT_FOUND_404 )
return ;
}
}
diff --git a/jena-arq/src/main/java/org/apache/jena/web/HttpSC.java b/jena-arq/src/main/java/org/apache/jena/web/HttpSC.java
index 025c7bc..b15d6e5 100644
--- a/jena-arq/src/main/java/org/apache/jena/web/HttpSC.java
+++ b/jena-arq/src/main/java/org/apache/jena/web/HttpSC.java
@@ -694,13 +694,14 @@ public class HttpSC
}
}
-
public enum Code
{
/*
* --------------------------------------------------------------------
- * Informational messages in 1xx series. As defined by ... RFC 1945 -
- * HTTP/1.0 RFC 2616 - HTTP/1.1 RFC 2518 - WebDAV
+ * Informational messages in 1xx series. As defined by ...
+ * RFC 1945 - HTTP/1.0
+ * RFC 2616 - HTTP/1.1
+ * RFC 2518 - WebDAV
* and RFC2324
*/
diff --git a/jena-base/src/main/java/org/apache/jena/atlas/io/InStreamUTF8.java b/jena-base/src/main/java/org/apache/jena/atlas/io/InStreamUTF8.java
index 0b2347a..e45595b 100644
--- a/jena-base/src/main/java/org/apache/jena/atlas/io/InStreamUTF8.java
+++ b/jena-base/src/main/java/org/apache/jena/atlas/io/InStreamUTF8.java
@@ -29,59 +29,58 @@ import org.apache.jena.atlas.AtlasException ;
public final class InStreamUTF8 extends Reader implements CharStream
{
// TODO Add line and col counts.
- // See arq.utf8.
+ // See arq.utf8.
// TODO Better ready()/available() in InputStreamBuffered
-
+ // TODO: chars > 16 bits -> convert to surrogate pairs.
+
// The standard Java way of doing this is via charset decoders.
// One small disadvantage is that bad UTF-8 does not get flagged as to
// the byte position of the error.
-
+
// This class collects knowledge of how UTF-8 encoding works;
// the Java classes are usually slightly faster compared to using
// this class with an InputStreamBuffered but the difference is small.
// This class generated meaningful error messages (when line/col added).
-
+
// The Java classes copy-convert a byte buffer into a char buffer.
// Sometimes, for example in a parser, this isn't a convenient model
// because the app is looking one character at a time and accumulating
// the chars until it sees the end of a token of arbitrary length
- // or processes escape sequences.
+ // or processes escape sequences.
//
// The app might use a StringBuilder so the bytes get copied into
// a char buffer and out again. Instead, this code assumes the
// app is in charge of that.
-
- // UTF-8 (UTF-16) is different from other character sets because
+
+ // UTF-8 (UTF-16) is different from other character sets because
// the relationship with Java's internal character representation is
- // arithmetic, not a character mapping.
-
- // Todo: chars > 16 bits -> surrogate pairs.
-
+ // arithmetic, not a character mapping.
+
/*
* http://en.wikipedia.org/wiki/UTF-8
* http://tools.ietf.org/html/rfc3629
* http://www.ietf.org/rfc/rfc3629.txt
- *
+ *
* Unicode Byte1 Byte2 Byte3 Byte4
* U+0000–U+007F 0 to 127 0xxxxxxx
- * U+0080–U+07FF 128 to 2,047 110yyyxx 10xxxxxx
+ * U+0080–U+07FF 128 to 2,047 110yyyxx 10xxxxxx
* U+0800–U+FFFF 2,048 to 65,535 1110yyyy 10yyyyxx 10xxxxxx
* U+10000–U+10FFFF 65,536 to 1,114,111 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx
- *
+ *
* Restricted cases (RFC 3629)
* 11110101-11110111 F5-F7 245-247 start of 4-byte sequence for codepoint above 10FFFF
* 11111000-11111011 F8-FB 248-251 start of 5-byte sequence
* 11111100-11111101 FC-FD 252-253 start of 6-byte sequence
- *
+ *
* Illegal:
* 11000000-11000001 C0-C1 192-193 Overlong encoding: start of a 2-byte sequence, but code point <= 127
* 11111110-11111111 FE-FF 254-255 Invalid: not defined by original UTF-8 specification
*/
-
- // There is some sort of stream decoder backing the Sun implementation
+
+ // There is some sort of stream decoder backing the Sun implementation
// of CharsetDecoder (sun.io.StreamDecoder) but it's not on all platforms
// I want a known decoder specifically for UTF8
-
+
private InputStreamBuffered input ;
//private long count = 0 ;
@@ -94,20 +93,19 @@ public final class InStreamUTF8 extends Reader implements CharStream
}
input = new InputStreamBuffered(in) ;
}
-
+
public InStreamUTF8(InputStreamBuffered in) { input = in ; }
-
@Override
public boolean ready() throws IOException
{
return input.available() > 0 ;
}
-
+
@Override
public void close() throws IOException
{ input.close() ; }
-
+
@Override
public void closeStream()
{ IO.close(input) ; }
@@ -133,26 +131,26 @@ public final class InStreamUTF8 extends Reader implements CharStream
// if ( ! Character.isDefined(ch) ) throw new
// AtlasException(String.format("Undefined codepoint: 0x%04X", ch)) ;
return ch;
- }
-
+ }
+
/** Next codepoint, given the first byte of any UTF-8 byte sequence is already known.
* Not necessarily a valid char (this function can be used a straight UTF8 decoder
*/
@Override
public final int advance()
{ return advance(input) ; }
-
+
/** Next codepoint */
public static final int advance(InputStreamBuffered input) {
int x = input.advance() ;
if ( x == -1 ) return -1 ;
return advance(input, x) ;
}
-
+
/** Next codepoint, given the first byte of any UTF-8 byte sequence is already known.
* Not necessarily a valid char (this function can be used as a straight UTF8 decoder).
*/
-
+
private static final int advance(InputStreamBuffered input, int x) {
//count++ ;
// ASCII Fastpath
@@ -199,19 +197,19 @@ public final class InStreamUTF8 extends Reader implements CharStream
throw new AtlasException(String.format("Undefined codepoint: 0x%04X", ch));
return ch;
}
-
+
private static int readMultiBytes(InputStreamBuffered input, int start, int len) {
int x = start ;
for ( int i = 0 ; i < len-1 ; i++ ) {
int x2 = input.advance() ;
if ( x2 == -1 )
throw new AtlasException("Premature end to UTF-8 sequence at end of input") ;
-
+
if ( (x2 & 0xC0) != 0x80 )
//throw new AtlasException("Illegal UTF-8 processing character "+count+": "+x2) ;
throw new AtlasException(String.format("Illegal UTF-8 processing character: 0x%04X",x2)) ;
// 6 bits of x2
- x = (x << 6) | (x2 & 0x3F);
+ x = (x << 6) | (x2 & 0x3F);
}
return x ;
}
diff --git a/jena-base/src/main/java/org/apache/jena/atlas/io/OutStreamUTF8.java b/jena-base/src/main/java/org/apache/jena/atlas/io/OutStreamUTF8.java
index 36c078f..fbafce0 100644
--- a/jena-base/src/main/java/org/apache/jena/atlas/io/OutStreamUTF8.java
+++ b/jena-base/src/main/java/org/apache/jena/atlas/io/OutStreamUTF8.java
@@ -24,9 +24,9 @@ import java.io.Writer ;
/** Output UTF-8 encoded data.
* This class implements the "Modified UTF8" encoding rules (null {@literal ->} C0 80)
- * It will encode any 16 bit value.
- * It can be used as a pure UTf-8 encoder.
- *
+ * It will encode any 16 bit value.
+ * It can be used as a pure UTF-8 encoder.
+ *
* @see InStreamUTF8
*/
public final class OutStreamUTF8 extends Writer
@@ -38,26 +38,26 @@ public final class OutStreamUTF8 extends Writer
// Buffer?
this.out = out ;
}
-
+
@Override
public void write(char[] cbuf, int off, int len) throws IOException
{
for ( int i = 0 ; i < len; i++ )
write(cbuf[off+i]) ;
}
-
+
@Override
public void write(int ch) throws IOException
{ output(out, ch) ; }
-
+
@Override
public void write(char[] b) throws IOException
{ write(b, 0, b.length) ; }
-
+
@Override
public void write(String str) throws IOException
{ write(str,0, str.length()) ; }
-
+
@Override
public void write(String str, int idx, int len) throws IOException
{
@@ -66,15 +66,15 @@ public final class OutStreamUTF8 extends Writer
}
public void output(int x)
- {
- try {
+ {
+ try {
output(out, x) ;
} catch (IOException ex) { IO.exception(ex) ; }
}
-
+
/*
- * Bits
- * 7 U+007F 1 to 127 0xxxxxxx
+ * Bits
+ * 7 U+007F 1 to 127 0xxxxxxx
* 11 U+07FF 128 to 2,047 110xxxxx 10xxxxxx
* 16 U+FFFF 2,048 to 65,535 1110xxxx 10xxxxxx 10xxxxxx
* 21 U+1FFFFF 65,536 to 1,114,111 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
@@ -89,7 +89,7 @@ public final class OutStreamUTF8 extends Writer
out.write(ch) ;
return ;
}
-
+
if ( ch == 0 )
{
// Modified UTF-8.
@@ -97,14 +97,14 @@ public final class OutStreamUTF8 extends Writer
out.write(0x80) ;
return ;
}
-
- // Better? output(int HiMask, int byte length, int value)
-
+
+ // Better? output(int HiMask, int byte length, int value)
+
if ( ch <= 0x07FF )
{
// 11 bits : 110yyyyy 10xxxxxx
// int x1 = ( ((ch>>(11-5))&0x7) | 0xC0 ) ; outputBytes(out, x1, 2, ch) ; return ;
- int x1 = ( ((ch>>(11-5))&0x01F ) | 0xC0 ) ;
+ int x1 = ( ((ch>>(11-5))&0x01F ) | 0xC0 ) ;
int x2 = ( (ch&0x3F) | 0x80 ) ;
out.write(x1) ;
out.write(x2) ;
@@ -122,12 +122,12 @@ public final class OutStreamUTF8 extends Writer
out.write(x3) ;
return ;
}
-
+
// if ( Character.isDefined(ch) )
// throw new AtlasException("not a character") ;
-
+
//if ( true ) throw new InternalErrorException("Valid code point for Java but not encodable") ;
-
+
// Not java, where chars are 16 bit.
if ( ch <= 0x1FFFFF )
{
@@ -152,15 +152,25 @@ public final class OutStreamUTF8 extends Writer
return ;
}
}
-
+
+ /**
+ * Write a total of {@code byteLength bytes}; first, value {@code x1}, then the
+ * remaining bytes of {@code ch}.
+ * <pre>
+ * byte x1
+ * 10xxxxxx
+ * 10xxxxxx
+ * ...
+ * </pre>
+ */
private static void outputBytes(OutputStream out, int x1, int byteLength, int ch) throws IOException
{
- // ByteLength = 3 => 2 byteLenth => shift=6 and shift=0
+ // ByteLength = 3 => 2 byteLength => shift=6 and shift=0
out.write(x1) ;
byteLength-- ; // remaining bytes
for ( int i = 0 ; i < byteLength ; i++ )
{
- // 6 Bits, loop from high to low
+ // 6 Bits, loop from high to low
int shift = 6*(byteLength-i-1) ;
int x = (ch>>shift) & 0x3F ;
x = x | 0x80 ; // 10xxxxxx
diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/Registry.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/Registry.java
index 5288844..b2d825c 100644
--- a/jena-base/src/main/java/org/apache/jena/atlas/lib/Registry.java
+++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/Registry.java
@@ -34,7 +34,6 @@ public class Registry<K,T>
public boolean isRegistered(K key) { return registry.containsKey(key) ; }
public void remove(K key) { registry.remove(key) ; }
public Collection<K> keys() { return registry.keySet() ; }
- //public Iterator<String> keys() { return registry.keySet().iterator() ; }
public int size() { return registry.size() ; }
public boolean isEmpty() { return registry.isEmpty() ; }
public void clear() { registry.clear() ; }
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_AllowGET.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_AllowGET.java
new file mode 100644
index 0000000..0d54c52
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_AllowGET.java
@@ -0,0 +1,74 @@
+/*
+ * 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.fuseki.access;
+
+import static org.apache.jena.riot.web.HttpNames.*;
+
+import java.util.function.Function;
+
+import org.apache.jena.atlas.lib.InternalErrorException;
+import org.apache.jena.fuseki.servlets.ActionService;
+import org.apache.jena.fuseki.servlets.HttpAction;
+import org.apache.jena.fuseki.servlets.ServletOps;
+
+/**
+ * Wrapper for an {@link ActionService} that rejects a request with a "write" HTTP
+ * method to an graph-access-controlled dataset. Graph-access-controlled dataset only
+ * support read (query and GSP GET).
+ */
+public class AccessCtl_AllowGET extends ActionService {
+
+ private final ActionService other;
+ private final Function<HttpAction, String> requestUser;
+ private final String label;
+
+ public AccessCtl_AllowGET(ActionService other, String label,
+ Function<HttpAction, String> determineUser) {
+ this.other = other;
+ this.label = label;
+ this.requestUser = determineUser;
+ }
+
+ @Override
+ public void validate(HttpAction action) {
+ String requestMethod = action.getMethod();
+ switch ( requestMethod ) {
+ case METHOD_GET:
+ case METHOD_HEAD:
+ case METHOD_OPTIONS:
+ break;
+ case METHOD_DELETE:
+ case METHOD_PATCH:
+ case METHOD_POST:
+ case METHOD_PUT:
+ case METHOD_TRACE: {
+ if ( label == null )
+ ServletOps.errorBadRequest("Not supported");
+ ServletOps.errorBadRequest(label+" : not supported");
+ throw new InternalErrorException("AccessCtl_DenyUpdate: "+ "didn't reject request");
+ }
+ }
+ other.validate(action);
+ }
+
+ @Override
+ public void execute(HttpAction action) {
+ other.execute(action);
+ }
+}
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_SPARQL_Update.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_DenyUpdate.java
similarity index 50%
rename from jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_SPARQL_Update.java
rename to jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_DenyUpdate.java
index 5af9988..301c037 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_SPARQL_Update.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_DenyUpdate.java
@@ -18,52 +18,46 @@
package org.apache.jena.fuseki.access;
-import java.io.InputStream;
import java.util.function.Function;
+import org.apache.jena.atlas.lib.InternalErrorException;
import org.apache.jena.fuseki.servlets.ActionService;
import org.apache.jena.fuseki.servlets.HttpAction;
-import org.apache.jena.fuseki.servlets.SPARQL_Update;
import org.apache.jena.fuseki.servlets.ServletOps;
import org.apache.jena.sparql.core.DatasetGraph;
-/** An Update {@link ActionService} that denies SPARQL Update in access controlled datasets. */
-final
-public class AccessCtl_SPARQL_Update extends SPARQL_Update {
+/**
+ * Wrapper for an {@link ActionService} that rejects a request to a graph-access-controlled dataset.
+ * Typically, that's one of the update operations -
+ * Graph-access-controlled dataset only support read (query and GSP GET).
+ */
+public class AccessCtl_DenyUpdate extends ActionService {
+
+ private final ActionService other;
private final Function<HttpAction, String> requestUser;
+ private final String label;
- public AccessCtl_SPARQL_Update(Function<HttpAction, String> requestUser) {
- this.requestUser = requestUser;
+ public AccessCtl_DenyUpdate(ActionService other, String label,
+ Function<HttpAction, String> determineUser) {
+ this.other = other;
+ this.label = label;
+ this.requestUser = determineUser;
}
@Override
- protected void validate(HttpAction action) {
- super.validate(action);
-
+ public void validate(HttpAction action) {
DatasetGraph dsg = action.getDataset();
- if ( ! DataAccessCtl.isAccessControlled(dsg) )
- return;
- ServletOps.errorBadRequest("SPARQL Update not supported");
- }
-
- @Override
- protected void perform(HttpAction action) {
- DatasetGraph dsg = action.getDataset() ;
- if ( ! DataAccessCtl.isAccessControlled(dsg) ) {
- super.perform(action);
- return;
+ if ( DataAccessCtl.isAccessControlled(dsg) ) {
+ if ( label == null )
+ ServletOps.errorBadRequest("Not supported");
+ ServletOps.errorBadRequest(label+" : not supported");
+ throw new InternalErrorException("AccessCtl_DenyUpdate: "+ "didn't reject request");
}
- ServletOps.errorBadRequest("SPARQL Update not supported");
+ other.validate(action);
}
-
+
@Override
- protected void execute(HttpAction action, InputStream input) {
- DatasetGraph dsg = action.getDataset() ;
- if ( ! DataAccessCtl.isAccessControlled(dsg) ) {
- super.execute(action, input);
- return;
- }
- ServletOps.errorBadRequest("SPARQL Update not supported");
+ public void execute(HttpAction action) {
+ other.execute(action);
}
}
-
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_SPARQL_GSP_R.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_GSP_R.java
similarity index 86%
rename from jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_SPARQL_GSP_R.java
rename to jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_GSP_R.java
index cc7a5de..ff28014 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_SPARQL_GSP_R.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_GSP_R.java
@@ -20,15 +20,15 @@ package org.apache.jena.fuseki.access;
import java.util.function.Function;
+import org.apache.jena.fuseki.servlets.GSP_R;
import org.apache.jena.fuseki.servlets.HttpAction;
-import org.apache.jena.fuseki.servlets.SPARQL_GSP_R;
import org.apache.jena.sparql.core.DatasetGraph;
-public class AccessCtl_SPARQL_GSP_R extends SPARQL_GSP_R {
-
+public class AccessCtl_GSP_R extends GSP_R {
+
private final Function<HttpAction, String> requestUser;
- public AccessCtl_SPARQL_GSP_R(Function<HttpAction, String> determineUser) {
+ public AccessCtl_GSP_R(Function<HttpAction, String> determineUser) {
this.requestUser = determineUser;
}
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_REST_Quads_R.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_REST_Quads_R.java
deleted file mode 100644
index d96807a..0000000
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_REST_Quads_R.java
+++ /dev/null
@@ -1,43 +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.fuseki.access;
-
-import java.util.function.Function;
-
-import org.apache.jena.fuseki.servlets.HttpAction;
-import org.apache.jena.fuseki.servlets.REST_Quads_R;
-import org.apache.jena.sparql.core.DatasetGraph;
-
-/**
- * Filter for {@link REST_Quads_R} that inserts a security filter on read-access to the
- * {@link DatasetGraph}.
- */
-public class AccessCtl_REST_Quads_R extends REST_Quads_R {
-
- private final Function<HttpAction, String> requestUser;
-
- public AccessCtl_REST_Quads_R(Function<HttpAction, String> determineUser) {
- this.requestUser = determineUser;
- }
-
- @Override
- protected DatasetGraph decideDataset(HttpAction action) {
- return DataAccessLib.decideDataset(action, requestUser);
- }
-}
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_REST_Quads_RW.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_REST_Quads_RW.java
deleted file mode 100644
index b36765c..0000000
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_REST_Quads_RW.java
+++ /dev/null
@@ -1,49 +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.fuseki.access;
-
-import java.util.function.Function;
-
-import org.apache.jena.fuseki.servlets.HttpAction;
-import org.apache.jena.fuseki.servlets.REST_Quads_R;
-import org.apache.jena.fuseki.servlets.REST_Quads_RW;
-import org.apache.jena.fuseki.servlets.ServletOps;
-import org.apache.jena.sparql.core.DatasetGraph;
-
-/**
- * Filter for {@link REST_Quads_R} that inserts a security filter on read-access to the
- * {@link DatasetGraph}.
- */
-public class AccessCtl_REST_Quads_RW extends REST_Quads_RW {
-
- private final Function<HttpAction, String> requestUser;
-
- public AccessCtl_REST_Quads_RW(Function<HttpAction, String> determineUser) {
- this.requestUser = determineUser;
- }
-
- @Override
- protected void validate(HttpAction action) {
- super.validate(action);
- DatasetGraph dsg = action.getDataset();
- if ( ! DataAccessCtl.isAccessControlled(dsg) )
- return;
- ServletOps.errorBadRequest("REST update of the dataset not supported");
- }
-}
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_SPARQL_GSP_RW.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_SPARQL_GSP_RW.java
deleted file mode 100644
index ce95290..0000000
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_SPARQL_GSP_RW.java
+++ /dev/null
@@ -1,49 +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.fuseki.access;
-
-import java.util.function.Function;
-
-import org.apache.jena.fuseki.servlets.HttpAction;
-import org.apache.jena.fuseki.servlets.REST_Quads_R;
-import org.apache.jena.fuseki.servlets.SPARQL_GSP_RW;
-import org.apache.jena.fuseki.servlets.ServletOps;
-import org.apache.jena.sparql.core.DatasetGraph;
-
-/**
- * Filter for {@link REST_Quads_R} that inserts a security filter on read-access to the
- * {@link DatasetGraph}.
- */
-public class AccessCtl_SPARQL_GSP_RW extends SPARQL_GSP_RW {
-
- private final Function<HttpAction, String> requestUser;
-
- public AccessCtl_SPARQL_GSP_RW(Function<HttpAction, String> determineUser) {
- this.requestUser = determineUser;
- }
-
- @Override
- protected void validate(HttpAction action) {
- super.validate(action);
- DatasetGraph dsg = action.getDataset();
- if ( ! DataAccessCtl.isAccessControlled(dsg) )
- return;
- ServletOps.errorBadRequest("SPARQL Graph Store Protocol update not supported");
- }
-}
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_SPARQL_QueryDataset.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_SPARQL_QueryDataset.java
index 54948a9..19d54e7 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_SPARQL_QueryDataset.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_SPARQL_QueryDataset.java
@@ -26,10 +26,7 @@ import java.util.List;
import java.util.function.Function;
import org.apache.jena.atlas.lib.Pair;
-import org.apache.jena.fuseki.servlets.ActionService;
-import org.apache.jena.fuseki.servlets.HttpAction;
-import org.apache.jena.fuseki.servlets.SPARQL_QueryDataset;
-import org.apache.jena.fuseki.servlets.ServletOps;
+import org.apache.jena.fuseki.servlets.*;
import org.apache.jena.query.Query;
import org.apache.jena.query.QueryExecution;
import org.apache.jena.sparql.core.*;
@@ -41,10 +38,10 @@ public class AccessCtl_SPARQL_QueryDataset extends SPARQL_QueryDataset {
private final Function<HttpAction, String> requestUser;
public AccessCtl_SPARQL_QueryDataset(Function<HttpAction, String> requestUser) {
- this.requestUser = requestUser;
+ this.requestUser = requestUser;
}
- private static boolean ALLOW_FROM = true;
+ private static boolean ALLOW_FROM = true;
@Override
protected Collection<String> customParams() {
@@ -61,7 +58,7 @@ public class AccessCtl_SPARQL_QueryDataset extends SPARQL_QueryDataset {
if ( ! DataAccessCtl.isAccessControlled(dsg) )
return super.decideDataset(action, query, queryStringLog);
- DatasetDescription dsDesc0 = getDatasetDescription(action, query);
+ DatasetDescription dsDesc0 = SPARQLProtocol.getDatasetDescription(action, query);
SecurityContext sCxt = DataAccessLib.getSecurityContext(action, dsg, requestUser);
DatasetGraph dsg2 = dynamicDataset(action, query, dsg, dsDesc0, sCxt);
return Pair.create(dsg2, query);
@@ -72,7 +69,7 @@ public class AccessCtl_SPARQL_QueryDataset extends SPARQL_QueryDataset {
return dsg0;
if ( ! ALLOW_FROM )
ServletOps.errorBadRequest("Use GRAPH. (FROM/FROM NAMED is not compatible with data access control.)");
-
+
DatasetDescription dsDesc1 = DatasetDescription.create(
mask(dsDesc0.getDefaultGraphURIs(), sCxt),
mask(dsDesc0.getNamedGraphURIs(), sCxt));
@@ -85,26 +82,26 @@ public class AccessCtl_SPARQL_QueryDataset extends SPARQL_QueryDataset {
dsDesc1.getDefaultGraphURIs().remove(Quad.unionGraph.getURI());
dsDesc1.getDefaultGraphURIs().addAll(sCxt.visibleGraphNames());
}
-
- DatasetGraph dsg1 = DynamicDatasets.dynamicDataset(dsDesc1, dsg0, false) ;
+
+ DatasetGraph dsg1 = DynamicDatasets.dynamicDataset(dsDesc1, dsg0, false);
if ( query.hasDatasetDescription() ) {
- query.getGraphURIs().clear() ;
- query.getNamedGraphURIs().clear() ;
+ query.getGraphURIs().clear();
+ query.getNamedGraphURIs().clear();
}
- return dsg1 ;
+ return dsg1;
}
// Pass only those graphURIs in the security context.
private List<String> mask(List<String> graphURIs, SecurityContext sCxt) {
Collection<String> names = sCxt.visibleGraphNames();
if ( names == null )
- return graphURIs;
+ return graphURIs;
return graphURIs.stream()
.filter(gn->names.contains(gn)
|| ( sCxt.visableDefaultGraph() && Quad.defaultGraphIRI.getURI().equals(gn))
|| ( Quad.unionGraph.getURI().equals(gn) )
)
- .collect(toList()) ;
+ .collect(toList());
}
@Override
@@ -115,7 +112,7 @@ public class AccessCtl_SPARQL_QueryDataset extends SPARQL_QueryDataset {
// but specialised setups might have DynamicDatasetGraph as the base dataset.
ServletOps.errorBadRequest("FROM/FROM NAMED is not compatible with data access control.");
}
-
+
// Dataset of the service, not computed by decideDataset.
DatasetGraph dsg = action.getActiveDSG();
if ( dsg == null )
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_SPARQL_Upload.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_SPARQL_Upload.java
deleted file mode 100644
index c4e926a..0000000
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_SPARQL_Upload.java
+++ /dev/null
@@ -1,49 +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.fuseki.access;
-
-import java.util.function.Function;
-
-import org.apache.jena.fuseki.servlets.HttpAction;
-import org.apache.jena.fuseki.servlets.REST_Quads_R;
-import org.apache.jena.fuseki.servlets.SPARQL_Upload;
-import org.apache.jena.fuseki.servlets.ServletOps;
-import org.apache.jena.sparql.core.DatasetGraph;
-
-/**
- * Filter for {@link REST_Quads_R} that inserts a security filter on read-access to the
- * {@link DatasetGraph}.
- */
-public class AccessCtl_SPARQL_Upload extends SPARQL_Upload {
-
- private final Function<HttpAction, String> requestUser;
-
- public AccessCtl_SPARQL_Upload(Function<HttpAction, String> determineUser) {
- this.requestUser = determineUser;
- }
-
- @Override
- protected void validate(HttpAction action) {
- super.validate(action);
- DatasetGraph dsg = action.getDataset();
- if ( ! DataAccessCtl.isAccessControlled(dsg) )
- return;
- ServletOps.errorBadRequest("Upload not supported");
- }
-}
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AssemblerAccessDataset.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AssemblerAccessDataset.java
index 67ccec1..71363bc 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AssemblerAccessDataset.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AssemblerAccessDataset.java
@@ -30,35 +30,35 @@ import org.apache.jena.sparql.core.DatasetGraph;
import org.apache.jena.sparql.util.graph.GraphUtils;
public class AssemblerAccessDataset extends AssemblerBase {
-
+
/*
- * <#access_dataset> rdf:type access:AccessControlledDataset ;
- * access:registry <#securityRegistry> ;
- * access:dataset <#tdb_dataset_read> ;
+ * <#access_dataset> rdf:type access:AccessControlledDataset;
+ * access:registry <#securityRegistry>;
+ * access:dataset <#tdb_dataset_read>;
* .
*/
@Override
public Dataset open(Assembler a, Resource root, Mode mode) {
if ( ! GraphUtils.exactlyOneProperty(root, VocabSecurity.pSecurityRegistry) )
- throw new AssemblerException(root, "Expected exactly one access:registry property");
+ throw new AssemblerException(root, "Expected exactly one access:registry property");
if ( ! GraphUtils.exactlyOneProperty(root, VocabSecurity.pDataset) )
- throw new AssemblerException(root, "Expected exactly one access:dataset property");
-
+ throw new AssemblerException(root, "Expected exactly one access:dataset property");
+
RDFNode rnRegistry = root.getProperty(VocabSecurity.pSecurityRegistry).getObject();
RDFNode rnDataset = root.getProperty(VocabSecurity.pDataset).getObject();
-
- AuthorizationService sr = (AuthorizationService)a.open(rnRegistry.asResource()) ;
+
+ AuthorizationService sr = (AuthorizationService)a.open(rnRegistry.asResource());
DatasetGraph dsgBase = ((Dataset)a.open(rnDataset.asResource())).asDatasetGraph();
-
+
DatasetGraph dsg = new DatasetGraphAccessControl(dsgBase, sr);
-
+
// Add marker
// ds.getContext().set(DataAccessCtl.symControlledAccess, true);
-
+
// Add security registry : if this dataset is wrapped then this means the AuthorizationService is still accessible.
- // But adding to DatasetGraphAccessControl (currently) pushes it down to the wrapped base DSG.
+ // But adding to DatasetGraphAccessControl (currently) pushes it down to the wrapped base DSG.
//dsg.getContext().set(DataAccessCtl.symAuthorizationService, sr);
return DatasetFactory.wrap(dsg);
}
-
+
}
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AssemblerSecurityRegistry.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AssemblerSecurityRegistry.java
index c0ef33c..156f6c7 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AssemblerSecurityRegistry.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AssemblerSecurityRegistry.java
@@ -44,20 +44,20 @@ import org.apache.jena.sparql.util.graph.GraphList;
import org.apache.jena.sparql.util.graph.GraphUtils;
public class AssemblerSecurityRegistry extends AssemblerBase {
-
+
/**
* SecurityRegistry.
- * Builds a SecurityRegistry - a map fron user name to
- *
- * <#securityRegistry> rdf:type access:SecurityRegistry ;
- * access:entry ("user1" <http://host/graphname1> <http://host/graphname2> ) ;) ;
- * access:entry ("user1" <http://host/graphname3> ) ;
- * access:entry ("user2" <http://host/graphname3> ) ;
- *
+ * Builds a SecurityRegistry - a map fron user name to
+ *
+ * <#securityRegistry> rdf:type access:SecurityRegistry;
+ * access:entry ("user1" <http://host/graphname1> <http://host/graphname2> ););
+ * access:entry ("user1" <http://host/graphname3> );
+ * access:entry ("user2" <http://host/graphname3> );
+ *
* .
- *
+ *
* ## Drop?
- * access:entry [ :user "user2" ; :graphs (<http://host/graphname3> ) ] ;
+ * access:entry [ :user "user2"; :graphs (<http://host/graphname3> ) ];
*/
@Override
@@ -68,33 +68,33 @@ public class AssemblerSecurityRegistry extends AssemblerBase {
if ( ! sIter.hasNext() )
throw new AssemblerException(root, "No access entries");
Multimap<String, Node> map = ArrayListMultimap.create();
-
+
sIter.forEachRemaining(s->{
- RDFNode n = s.getObject();
+ RDFNode n = s.getObject();
if ( ! n.isResource())
throw new AssemblerException(root, "Found access:entry with non-resource");
-
+
Resource r = (Resource)n;
GNode entry = new GNode(root.getModel().getGraph(), n.asNode());
if ( GraphList.isListNode(entry) ) {
- // Format:: access:entry ("user1" <http://host/graphname1> <http://host/graphname2> ) ;
+ // Format:: access:entry ("user1" <http://host/graphname1> <http://host/graphname2> );
parseList(map, root, entry);
} else if ( r.hasProperty(VocabSecurity.pUser) || r.hasProperty(VocabSecurity.pGraphs) ) {
- // Format:: access:entry [ :user "user2" ; :graphs (<http://host/graphname3> ) ]
+ // Format:: access:entry [ :user "user2"; :graphs (<http://host/graphname3> ) ]
parseStruct(map, root, r);
} else
throw new AssemblerException(root, "Found access:entry but failed to parse the object: "+s.getSubject());
});
-
+
map.keySet().forEach(u->{
SecurityContext sCxt = new SecurityContextView(map.get(u));
registry.put(u, sCxt);
});
-
+
return registry;
}
- /** Format:: access:entry ("user1" <http://host/graphname1> <http://host/graphname2> ) ; */
+ /** Format:: access:entry ("user1" <http://host/graphname1> <http://host/graphname2> ); */
private void parseList(Multimap<String, Node> map, Resource root, GNode entry) {
List<Node> members = GraphList.members(entry);
// string, then URIs.
@@ -108,13 +108,13 @@ public class AssemblerSecurityRegistry extends AssemblerBase {
accessEntries(root, map, user, graphs);
}
- /** Format:: access:entry [ :user "user2" ; :graphs (<http://host/graphname3> ) ] */
+ /** Format:: access:entry [ :user "user2"; :graphs (<http://host/graphname3> ) ] */
private void parseStruct(Multimap<String, Node> map, Resource root, Resource r) {
if ( ! GraphUtils.exactlyOneProperty(r, VocabSecurity.pUser) )
- throw new AssemblerException(root, "Expected exactly one access:user property for "+r);
+ throw new AssemblerException(root, "Expected exactly one access:user property for "+r);
if ( ! GraphUtils.exactlyOneProperty(r, VocabSecurity.pGraphs) )
- throw new AssemblerException(root, "Expected exactly one access:graphs property for "+r);
-
+ throw new AssemblerException(root, "Expected exactly one access:graphs property for "+r);
+
String user = GraphUtils.getStringValue(r, VocabSecurity.pUser);
r.listProperties(VocabSecurity.pGraphs).mapWith(s->s.getObject()).forEachRemaining(x->{
List<Node> graphs = new ArrayList<>();
@@ -131,7 +131,7 @@ public class AssemblerSecurityRegistry extends AssemblerBase {
accessEntries(root, map, user, graphs);
});
}
-
+
private Node graphLabel(Node x, Resource root) {
if ( SecurityContext.allGraphsStr.equals(x) ) x = SecurityContext.allGraphs;
if ( SecurityContext.allNamedGraphsStr.equals(x) ) x = SecurityContext.allNamedGraphs;
@@ -139,12 +139,12 @@ public class AssemblerSecurityRegistry extends AssemblerBase {
throw new AssemblerException(root, "Not a graph name: "+x);
return x;
}
-
+
// Unfinished.
- private final static boolean SKIP_ALLGRAPH = true;
-
+ private final static boolean SKIP_ALLGRAPH = true;
+
private void accessEntries(Resource root, Multimap<String, Node> map, String user, List<Node> _graphs) {
- // Convert string names for graphs to URIs.
+ // Convert string names for graphs to URIs.
Set<Node> graphs = _graphs.stream().map(n->graphLabel(n, root)).collect(Collectors.toSet());
if ( graphs.contains(SecurityContext.allGraphs) ) {
@@ -156,29 +156,29 @@ public class AssemblerSecurityRegistry extends AssemblerBase {
boolean dft = dftPresent(graphs);
Node x = SecurityContext.allNamedGraphs;
if ( dft )
- // Put in "*" instead.
+ // Put in "*" instead.
x = SecurityContext.allGraphs;
map.removeAll(user);
map.put(user, x);
return;
}
-
+
if ( SKIP_ALLGRAPH ) {
if ( graphs.contains(SecurityContext.allGraphs) ) {
- Log.warn(this, "Graph name '"+SecurityContext.allGraphsStr+"' not supported yet");
+ Log.warn(this, "Graph name '"+SecurityContext.allGraphsStr+"' not supported yet");
graphs.remove(SecurityContext.allGraphs);
}
if ( graphs.contains(SecurityContext.allNamedGraphs) ) {
- Log.warn(this, "Graph name '"+SecurityContext.allNamedGraphsStr+"' not supported yet");
+ Log.warn(this, "Graph name '"+SecurityContext.allNamedGraphsStr+"' not supported yet");
graphs.remove(SecurityContext.allNamedGraphs);
}
}
-
+
map.putAll(user, graphs);
}
private boolean dftPresent(Collection<Node> nodes) {
return nodes.stream().anyMatch(n->Quad.isDefaultGraph(n));
}
-
+
}
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AuthorizationService.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AuthorizationService.java
index dd8e7c6..fa262f5 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AuthorizationService.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AuthorizationService.java
@@ -22,7 +22,7 @@ import java.util.concurrent.ConcurrentHashMap;
/**
* A {@link AuthorizationService} implemented with a {@link ConcurrentHashMap}.
- */
+ */
public interface AuthorizationService {
/** Return the security context for a geiven actor (user) */
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/DataAccessCtl.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/DataAccessCtl.java
index d49e2ab..4eff68b 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/DataAccessCtl.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/DataAccessCtl.java
@@ -35,17 +35,17 @@ import org.apache.jena.sparql.util.Context;
import org.apache.jena.sparql.util.Symbol;
import org.apache.jena.sys.JenaSystem;
-/** A library of operations related to data access security for Fuseki */
+/** A library of operations related to data access security for Fuseki */
public class DataAccessCtl {
static { JenaSystem.init(); }
-
+
// /**
// * Flag for whether this is data access controlled or not - boolean false or undef for "not
// * controlled". This is an alternative to {@link DatasetGraphAccessControl}.
// * @see #isAccessControlled(DatasetGraph)
// */
// public static final Symbol symControlledAccess = Symbol.create(VocabSecurity.getURI() + "controlled");
-
+
/**
* Symbol for the {@link AuthorizationService}.
* This is an alternative to {@link DatasetGraphAccessControl}.
@@ -53,7 +53,7 @@ public class DataAccessCtl {
*/
public static final Symbol symAuthorizationService = Symbol.create(VocabSecurity.getURI() + "authService");
- /** Get the user from the servlet context via {@link HttpServletRequest#getRemoteUser} */
+ /** Get the user from the servlet context via {@link HttpServletRequest#getRemoteUser} */
public static final Function<HttpAction, String> requestUserServlet = (action)->action.getUser();
/**
@@ -72,14 +72,14 @@ public class DataAccessCtl {
}
/**
- * Return a {@link DatasetGraph} with added data access control.
+ * Return a {@link DatasetGraph} with added data access control.
* Use of the original {@code DatasetGraph} is not controlled.
*/
public static Dataset controlledDataset(Dataset dsBase, AuthorizationService reg) {
DatasetGraph dsg = controlledDataset(dsBase.asDatasetGraph(), reg);
return DatasetFactory.wrap(dsg);
}
-
+
/**
* Return a {@link DatasetGraph} with added data access control. Use of the original
* {@code DatasetGraph} is not controlled.
@@ -91,10 +91,10 @@ public class DataAccessCtl {
return dsgx;
throw new IllegalArgumentException("DatasetGraph is alerady wrapped on a DatasetGraphAccessControl with a different AuthorizationService");
}
-
+
DatasetGraphAccessControl dsg1 = new DatasetGraphAccessControl(dsgBase, reg);
return dsg1;
- }
+ }
/**
* Return whether a {@code DatasetGraph} has access control, either because it is wrapped in
@@ -125,12 +125,12 @@ public class DataAccessCtl {
// Unfortunately that means find all named graphs.
// if ( sCxt instanceof SecurityContextAllowNamedGraphs ) {
// }
-
+
Collection<Node> names = sCxt.visibleGraphs();
if ( names == null )
- // XXX does not scale.
+ // TODO does not scale.
names = Iter.toList(dsg.listGraphNodes());
-
+
return new DatasetGraphFilteredView(dsg, sCxt.predicateQuad(), sCxt.visibleGraphs());
}
}
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/DataAccessLib.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/DataAccessLib.java
index 0f04b81..e663ec9 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/DataAccessLib.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/DataAccessLib.java
@@ -29,8 +29,8 @@ import org.apache.jena.sparql.core.DatasetGraph;
/** Package-only operations */
class DataAccessLib {
-
- /** Determine the {@link SecurityContext} for this request */
+
+ /** Determine the {@link SecurityContext} for this request */
static SecurityContext getSecurityContext(HttpAction action, DatasetGraph dataset, Function<HttpAction, String> requestUser) {
AuthorizationService registry = getAuthorizationService(action, dataset);
if ( registry == null )
@@ -38,15 +38,15 @@ class DataAccessLib {
SecurityContext sCxt = null;
String user = requestUser.apply(action);
-
+
// User "*", users "_";
-
+
sCxt = registry.get(user);
if ( sCxt == null )
sCxt = noSecurityPolicy();
return sCxt;
}
-
+
/** Get the {@link AuthorizationService} for an action/query/dataset */
static AuthorizationService getAuthorizationService(HttpAction action, DatasetGraph dsg) {
if ( dsg instanceof DatasetGraphAccessControl )
@@ -59,7 +59,7 @@ class DataAccessLib {
// Should not get here.
throw new InternalError();
}
-
+
static DatasetGraph decideDataset(HttpAction action, Function<HttpAction, String> requestUser) {
DatasetGraph dsg = action.getDataset();
if ( dsg == null )
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/DatasetGraphAccessControl.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/DatasetGraphAccessControl.java
index 44a8147..6dee5ae 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/DatasetGraphAccessControl.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/DatasetGraphAccessControl.java
@@ -23,27 +23,27 @@ import java.util.Objects;
import org.apache.jena.sparql.core.DatasetGraph;
import org.apache.jena.sparql.core.DatasetGraphWrapper;
-/** DatasetGraph layer that carries an {@link AuthorizationService}. */
+/** DatasetGraph layer that carries an {@link AuthorizationService}. */
public class DatasetGraphAccessControl extends DatasetGraphWrapper {
-
- private AuthorizationService registry = null;
+
+ private AuthorizationService registry = null;
/*package*/ DatasetGraphAccessControl(DatasetGraph dsg, AuthorizationService authService) {
super(Objects.requireNonNull(dsg));
- this.registry = Objects.requireNonNull(authService);
+ this.registry = Objects.requireNonNull(authService);
}
-
+
public AuthorizationService getAuthService() {
return registry;
}
- // XXX Settings will be pushed down to the wrapped dataset.
+ // TODO Settings will be pushed down to the wrapped dataset.
// A problem for DataAccessCtl.symAuthorizationService.
// @Override
// public Context getContext() {
// return super.getContext();
// }
-
+
/**
* Return the underlying {@code DatasetGraph}. If the argument is not a
* {@code DatasetGraphAccessControl}, return the argument.
@@ -53,7 +53,7 @@ public class DatasetGraphAccessControl extends DatasetGraphWrapper {
return dsg;
return ((DatasetGraphAccessControl)dsg).getWrapped();
}
-
+
/**
* Return the underlying {@code DatasetGraph}. If the argument is not a
* {@code DatasetGraphAccessControl}, return null.
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/GraphFilter.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/GraphFilter.java
index 6059ed1..0e6248e 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/GraphFilter.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/GraphFilter.java
@@ -34,7 +34,7 @@ import org.apache.jena.sparql.util.Symbol;
* {@link #test(Tuple)} if the tuple graph slot is in the collection of graph names or
* matchDefaultGraph is true. It can be used as an "allow" filter; it can be negated to
* become a "deny" filter.
- *
+ *
* @see GraphFilterTDB1#graphFilter
* @see GraphFilterTDB2#graphFilter
*/
@@ -43,29 +43,29 @@ public abstract class GraphFilter<X> implements Predicate<Tuple<X>> {
private final boolean matchDefaultGraph;
// // This makes the GraphFilter stateful.
// private X slot = null;
-
+
protected GraphFilter(Collection<X> matches, boolean matchDefaultGraph) {
this.graphs = new HashSet<X>(matches);
this.matchDefaultGraph = matchDefaultGraph;
}
-
+
public static Symbol getContextKey(DatasetGraph dsg) {
dsg = DatasetGraphAccessControl.removeWrapper(dsg);
-
+
if ( org.apache.jena.tdb.sys.TDBInternal.isTDB1(dsg) )
return org.apache.jena.tdb.sys.SystemTDB.symTupleFilter;
if ( org.apache.jena.tdb2.sys.TDBInternal.isTDB2(dsg) )
return org.apache.jena.tdb2.sys.SystemTDB.symTupleFilter;
throw new IllegalArgumentException("Not a TDB database");
}
-
+
public abstract Symbol getContextKey();
-
+
@Override
public boolean test(Tuple<X> t) {
if ( t.len() == 3 ) {
// Default graph.
- return matchDefaultGraph;
+ return matchDefaultGraph;
}
X g = t.get(0);
boolean b = perGraphTest(g);
@@ -81,7 +81,7 @@ public abstract class GraphFilter<X> implements Predicate<Tuple<X>> {
// }
// boolean b = matches.contains(g);
// if ( b )
-// slot = g ;
+// slot = g;
// return b;
}
}
\ No newline at end of file
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/GraphFilterTDB1.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/GraphFilterTDB1.java
index 8fb94c5..70de136 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/GraphFilterTDB1.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/GraphFilterTDB1.java
@@ -32,7 +32,7 @@ import org.apache.jena.tdb.store.nodetable.NodeTable;
import org.apache.jena.tdb.sys.SystemTDB;
import org.apache.jena.tdb.sys.TDBInternal;
-/** {@link GraphFilter} for TDB1 */
+/** {@link GraphFilter} for TDB1 */
class GraphFilterTDB1 extends GraphFilter<NodeId> {
private GraphFilterTDB1(Collection<NodeId> matches, boolean matchDefaultGraph) {
@@ -43,7 +43,7 @@ class GraphFilterTDB1 extends GraphFilter<NodeId> {
public Symbol getContextKey() {
return SystemTDB.symTupleFilter;
}
-
+
/**
* Create a graph filter for a TDB1 {@link DatasetGraph}. The filter matches (returns
* true) for Tuples where the graph slot in quad is in the collection or for triples in the default
@@ -52,10 +52,10 @@ class GraphFilterTDB1 extends GraphFilter<NodeId> {
public static GraphFilterTDB1 graphFilter(DatasetGraph dsg, Collection<Node> namedGraphs, boolean matchDefaultGraph) {
if ( ! TDBInternal.isTDB1(dsg) )
throw new IllegalArgumentException("DatasetGraph is not TDB1-backed");
- List<NodeId> x =
+ List<NodeId> x =
Txn.calculateRead(dsg, ()->{
NodeTable nt = TDBInternal.getDatasetGraphTDB(dsg).getQuadTable().getNodeTupleTable().getNodeTable();
- return
+ return
ListUtils.toList(
namedGraphs.stream()
.map(n->nt.getNodeIdForNode(n))
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/GraphFilterTDB2.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/GraphFilterTDB2.java
index a336ffd..bcfcb9f 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/GraphFilterTDB2.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/GraphFilterTDB2.java
@@ -43,7 +43,7 @@ class GraphFilterTDB2 extends GraphFilter<NodeId> {
public Symbol getContextKey() {
return SystemTDB.symTupleFilter;
}
-
+
/**
* Create a graph filter for a TDB2 {@link DatasetGraph}. The filter matches (returns
* true) for Tuples where the graph slot in quad is in the collection or for triples in the default
@@ -52,10 +52,10 @@ class GraphFilterTDB2 extends GraphFilter<NodeId> {
public static GraphFilterTDB2 graphFilter(DatasetGraph dsg, Collection<Node> namedGraphs, boolean matchDefaultGraph) {
if ( ! TDBInternal.isTDB2(dsg) )
throw new IllegalArgumentException("DatasetGraph is not TDB2-backed");
- List<NodeId> x =
+ List<NodeId> x =
Txn.calculateRead(dsg, ()->{
NodeTable nt = TDBInternal.getDatasetGraphTDB(dsg).getQuadTable().getNodeTupleTable().getNodeTable();
- return
+ return
ListUtils.toList(
namedGraphs.stream()
.map(n->nt.getNodeIdForNode(n))
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/InitSecurity.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/InitSecurity.java
index 55e760e..ad81e2c 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/InitSecurity.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/InitSecurity.java
@@ -25,14 +25,14 @@ public class InitSecurity implements JenaSubsystemLifecycle {
@Override
public void start() {
- JenaSystem.logLifecycle("InitSecurity - start") ;
+ JenaSystem.logLifecycle("InitSecurity - start");
VocabSecurity.init();
- JenaSystem.logLifecycle("InitSecurity - finish") ;
+ JenaSystem.logLifecycle("InitSecurity - finish");
}
@Override
public void stop() {}
-
+
@Override
public int level() { return 100; }
}
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 d6ae465..45ccafc 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
@@ -32,14 +32,14 @@ import org.apache.jena.sparql.core.DatasetGraph;
import org.apache.jena.sparql.core.Quad;
import org.apache.jena.sparql.util.Context;
-/** A {@link SecurityContext} is the things actor (user, role) is allowed to do.
+/** A {@link SecurityContext} is the things actor (user, role) is allowed to do.
* Currently version: the set of graphs, by graph name, they can access.
* It can be inverted into a "deny" policy with {@link Predicate#negate()}.
- */
+ */
public interface SecurityContext {
public static final SecurityContext NONE = new SecurityContextAllowNone();
public static final SecurityContext ALL = new SecurityContextAllowAll();
- public static SecurityContext ALL_NG(DatasetGraph dsg) {
+ public static SecurityContext ALL_NG(DatasetGraph dsg) {
Collection<Node> names = Iter.toList(dsg.listGraphNodes());
//return new SecurityContextAllowNamedGraphs(dsg);
return new SecurityContextView(names);
@@ -49,13 +49,13 @@ public interface SecurityContext {
public static final Node allNamedGraphs = NodeFactory.createURI("urn:jena:accessAllNamedGraphs");
public static final Node allNamedGraphsStr = NodeFactory.createLiteral("*");
public static final Node allGraphsStr = NodeFactory.createLiteral("**");
-
+
/**
* Collection of visible graph names. This method return null for null for "all" to avoid
* needing to calculate the current set of named graph names.
*/
public Collection<Node> visibleGraphs();
-
+
/**
* Collection of visible graph URI names. This method return null for null for "all" to avoid
* needing to calculate the current set of named graph names.
@@ -66,15 +66,15 @@ public interface SecurityContext {
return visibleGraphs().stream()
.filter(Node::isURI)
.map(Node::getURI)
- .collect(Collectors.toList()) ;
+ .collect(Collectors.toList());
}
-
+
public boolean visableDefaultGraph();
public default QueryExecution createQueryExecution(String queryString, DatasetGraph dsg) {
return createQueryExecution(QueryFactory.create(queryString), dsg);
}
-
+
public QueryExecution createQueryExecution(Query query, DatasetGraph dsg);
/**
@@ -83,7 +83,7 @@ public interface SecurityContext {
* efficient.
*/
public Predicate<Quad> predicateQuad();
-
+
/**
* Apply a filter suitable for the TDB-backed {@link DatasetGraph}, to the {@link Context} of the
* {@link QueryExecution}. This does not modify the {@link DatasetGraph}.
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContextAllowAll.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContextAllowAll.java
index 9ab7053..125b984 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContextAllowAll.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContextAllowAll.java
@@ -28,19 +28,19 @@ import org.apache.jena.query.QueryExecutionFactory;
import org.apache.jena.sparql.core.DatasetGraph;
import org.apache.jena.sparql.core.Quad;
-/** A {@link SecurityContext} that allow any graph, default or named. */
+/** A {@link SecurityContext} that allow any graph, default or named. */
public class SecurityContextAllowAll implements SecurityContext {
-
+
public SecurityContextAllowAll() {}
-
+
@Override
public Collection<Node> visibleGraphs() {
// null means "all".
return null;
}
-
+
@Override
- public boolean visableDefaultGraph() { return true; }
+ public boolean visableDefaultGraph() { return true; }
@Override
public QueryExecution createQueryExecution(Query query, DatasetGraph dsg) {
@@ -54,7 +54,7 @@ public class SecurityContextAllowAll implements SecurityContext {
*/
@Override
public Predicate<Quad> predicateQuad() { return q->true; }
-
+
@Override
public void filterTDB(DatasetGraph dsg, QueryExecution qExec) {
// No filter necessary.
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContextAllowNamedGraphs.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContextAllowNamedGraphs.java
index bae61bb..da5c21b 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContextAllowNamedGraphs.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContextAllowNamedGraphs.java
@@ -28,23 +28,23 @@ import org.apache.jena.query.QueryExecutionFactory;
import org.apache.jena.sparql.core.DatasetGraph;
import org.apache.jena.sparql.core.Quad;
-/** A {@link SecurityContext} that allow to named graph but not the default graph. */
+/** A {@link SecurityContext} that allow to named graph but not the default graph. */
public class SecurityContextAllowNamedGraphs implements SecurityContext {
-
+
public SecurityContextAllowNamedGraphs() {}
-
+
@Override
public Collection<Node> visibleGraphs() {
// null means "all".
return null;
}
-
+
@Override
- public boolean visableDefaultGraph() { return true; }
+ public boolean visableDefaultGraph() { return true; }
@Override
public QueryExecution createQueryExecution(Query query, DatasetGraph dsg) {
-
+
return QueryExecutionFactory.create(query, dsg);
}
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContextAllowNone.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContextAllowNone.java
index ed5defb..f24cc24 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContextAllowNone.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContextAllowNone.java
@@ -30,27 +30,27 @@ import org.apache.jena.sparql.core.DatasetGraph;
import org.apache.jena.sparql.core.DatasetGraphSink;
import org.apache.jena.sparql.core.Quad;
-/** A {@link SecurityContext} that does not allow any access. */
+/** A {@link SecurityContext} that does not allow any access. */
public class SecurityContextAllowNone implements SecurityContext {
-
+
public SecurityContextAllowNone() {}
-
+
@Override
public Collection<Node> visibleGraphs() {
return Collections.emptyList();
}
-
+
@Override
- public boolean visableDefaultGraph() { return false; }
+ public boolean visableDefaultGraph() { return false; }
@Override
public QueryExecution createQueryExecution(Query query, DatasetGraph dsg) {
return QueryExecutionFactory.create(query, new DatasetGraphSink());
}
-
+
@Override
- public Predicate<Quad> predicateQuad() { return q -> false ; }
-
+ public Predicate<Quad> predicateQuad() { return q -> false; }
+
@Override
public void filterTDB(DatasetGraph dsg, QueryExecution qExec) {
Predicate<?> pred = tuple->false;
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContextView.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContextView.java
index 8660b2c..869279f 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContextView.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityContextView.java
@@ -36,18 +36,18 @@ import org.apache.jena.sparql.util.NodeUtils;
import org.apache.jena.tdb.TDBFactory;
import org.apache.jena.tdb2.DatabaseMgr;
-/** A {@link SecurityContextView} is the things actor (user, role) is allowed to do.
+/** A {@link SecurityContextView} is the things actor (user, role) is allowed to do.
* Currently version: the set of graphs, by graph name, they can access.
* It can be inverted into a "deny" policy with {@link Predicate#negate()}.
- */
+ */
public class SecurityContextView implements SecurityContext {
-
+
public static SecurityContextView NONE = new SecurityContextView();
public static SecurityContextView DFT_GRAPH = new SecurityContextView(true);
private final Collection<Node> graphNames;
private final boolean matchDefaultGraph;
-
+
private SecurityContextView() {
this(false);
}
@@ -75,12 +75,12 @@ public class SecurityContextView implements SecurityContext {
}
this.graphNames = Collections.unmodifiableCollection(x);
}
-
+
@Override
public Collection<Node> visibleGraphs() {
return graphNames;
}
-
+
@Override
public boolean visableDefaultGraph() {
return matchDefaultGraph;
@@ -90,7 +90,7 @@ public class SecurityContextView implements SecurityContext {
public QueryExecution createQueryExecution(String queryString, DatasetGraph dsg) {
return createQueryExecution(QueryFactory.create(queryString), dsg);
}
-
+
@Override
public QueryExecution createQueryExecution(Query query, DatasetGraph dsg) {
if ( isAccessControlledTDB(dsg) ) {
@@ -102,7 +102,7 @@ public class SecurityContextView implements SecurityContext {
DatasetGraph dsgA = DataAccessCtl.filteredDataset(dsg, this);
return QueryExecutionFactory.create(query, dsgA);
}
-
+
/**
* Apply a filter suitable for the TDB-backed {@link DatasetGraph}, to the {@link Context} of the
* {@link QueryExecution}. This does not modify the {@link DatasetGraph}.
@@ -123,7 +123,7 @@ public class SecurityContextView implements SecurityContext {
return quad -> {
if ( quad.isDefaultGraph() )
return matchDefaultGraph;
- if ( quad.isUnionGraph() )
+ if ( quad.isUnionGraph() )
// Union graph is automatically there but its visible contents are different.
return true;
return graphNames.contains(quad.getGraph());
@@ -132,7 +132,7 @@ public class SecurityContextView implements SecurityContext {
/**
* Create a GraphFilter for a TDB backed dataset.
- *
+ *
* @return GraphFilter
* @throws IllegalArgumentException
* if not a TDB database, or a {@link DatasetGraphAccessControl} wrapped
@@ -141,7 +141,7 @@ public class SecurityContextView implements SecurityContext {
protected GraphFilter<?> predicate(DatasetGraph dsg) {
dsg = DatasetGraphAccessControl.removeWrapper(dsg);
// dsg has to be the database dataset, not wrapped.
- // DatasetGraphSwitchable is wrapped but should not be unwrapped.
+ // DatasetGraphSwitchable is wrapped but should not be unwrapped.
if ( TDBFactory.isTDB1(dsg) )
return GraphFilterTDB1.graphFilter(dsg, graphNames, matchDefaultGraph);
if ( DatabaseMgr.isTDB2(dsg) )
@@ -159,7 +159,7 @@ public class SecurityContextView implements SecurityContext {
return true;
return false;
}
-
+
@Override
public String toString() {
return "dft:"+matchDefaultGraph+" / "+graphNames.toString();
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityRegistry.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityRegistry.java
index 1810d1a..7a1823c 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityRegistry.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/SecurityRegistry.java
@@ -26,11 +26,11 @@ import org.apache.jena.atlas.lib.Registry;
* A registry mapping from a string (typically a user name or role
* name) to a {@link SecurityContext}, where the {@link SecurityContext}
* is the access control operations for that user/role.
- */
+ */
public class SecurityRegistry extends Registry<String, SecurityContext> implements AuthorizationService {
-
+
public SecurityRegistry() {}
-
+
@Override
public SecurityContext get(String actor) {
if ( actor == null )
@@ -40,12 +40,12 @@ public class SecurityRegistry extends Registry<String, SecurityContext> implemen
sCxt = SecurityContext.NONE;
return sCxt;
}
-
- @Override
+
+ @Override
public String toString() {
return "SecurityRegistry"+keys();
- }
-
+ }
+
public String toLongString() {
// Long form.
StringJoiner sj1 = new StringJoiner("\n", "{ SecurityRegistry\n", "\n}");
diff --git a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/VocabSecurity.java b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/VocabSecurity.java
index 14ed959..f6caf0b 100644
--- a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/VocabSecurity.java
+++ b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/VocabSecurity.java
@@ -25,8 +25,8 @@ import org.apache.jena.tdb.assembler.Vocab;
public class VocabSecurity {
private static final String NS = "http://jena.apache.org/access#";
-
- public static String getURI() { return NS ; }
+
+ public static String getURI() { return NS; }
// Types
public static final Resource tAccessControlledDataset = Vocab.type(NS, "AccessControlledDataset");
@@ -40,10 +40,10 @@ public class VocabSecurity {
public static final Property pUser = Vocab.property(NS, "user");
public static final Property pGraphs = Vocab.property(NS, "graphs");
- private static boolean initialized = false ;
-
- static { init() ; }
-
+ private static boolean initialized = false;
+
+ static { init(); }
+
static synchronized public void init() {
if ( initialized )
return;
diff --git a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TS_Access.java b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TS_Access.java
index 103f75e..ee84e6e 100644
--- a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TS_Access.java
+++ b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TS_Access.java
@@ -28,6 +28,6 @@ import org.junit.runners.Suite;
TestSecurityFilterLocal.class
, TestSecurityRegistry.class
})
-
+
public class TS_Access {
}
diff --git a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityFilterLocal.java b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityFilterLocal.java
index 0f9bd11..91c334f 100644
--- a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityFilterLocal.java
+++ b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityFilterLocal.java
@@ -71,13 +71,13 @@ public class TestSecurityFilterLocal {
Object[] obj1 = { "TDB/db", c1, true};
Object[] obj2 = { "TDB2/db", c2, true };
-
+
// By adding the general, but slower, DatasetGraphFilter
Object[] obj3 = { "TDB/filtered", c1, false };
Object[] obj4 = { "TDB2/filtered", c2, false };
Object[] obj5 = { "TIM/filtered", c3, false };
Object[] obj6 = { "Plain/filtered", c4, false };
-
+
List<Object[]> x = new ArrayList<>();
return Arrays.asList(obj1, obj2, obj3, obj4, obj5, obj6);
// x.add(obj1);
@@ -85,12 +85,12 @@ public class TestSecurityFilterLocal {
// x.add(obj5);
// return x;
}
-
+
private final DatasetGraph testdsg;
private SecurityRegistry reg = new SecurityRegistry();
private final boolean applyFilterDSG;
private final boolean applyFilterTDB;
-
+
public TestSecurityFilterLocal(String name, Creator<DatasetGraph> source, boolean applyFilterTDB) {
DatasetGraph dsgBase = source.create();
addTestData(dsgBase);
@@ -99,17 +99,17 @@ public class TestSecurityFilterLocal {
reg.put("user0", new SecurityContextView(Quad.defaultGraphIRI.getURI()));
reg.put("user1", new SecurityContextView("http://test/g1", Quad.defaultGraphIRI.getURI()));
reg.put("user2", new SecurityContextView("http://test/g1", "http://test/g2", "http://test/g3"));
-
- // and graphs "**", "*"
+
+ // and graphs "**", "*"
reg.put("*", new SecurityContextView("http://test/g1"));
reg.put("_", new SecurityContextView("http://test/g1"));
-
-
+
+
testdsg = DataAccessCtl.controlledDataset(dsgBase, reg);
this.applyFilterTDB = applyFilterTDB;
this.applyFilterDSG = ! applyFilterTDB;
}
-
+
private static String queryAll = "SELECT * { { ?s ?p ?o } UNION { GRAPH ?g { ?s ?p ?o } } }";
private static String queryDft = "SELECT * { ?s ?p ?o }";
private static String queryNamed = "SELECT * { GRAPH ?g { ?s ?p ?o } }";
@@ -139,7 +139,7 @@ public class TestSecurityFilterLocal {
}
});
}
-
+
private Set<Node> subjects(DatasetGraph dsg, Function<DatasetGraph, Graph> graphChoice, String queryString, SecurityContext sCxt) {
final DatasetGraph dsg1 = applyFilterDSG
? DataAccessCtl.filteredDataset(dsg, sCxt)
@@ -225,37 +225,37 @@ public class TestSecurityFilterLocal {
@Test public void graph_names_userNone() {
SecurityContext sCxt = reg.get("userNone");
- Set<Node> visible = graphs(testdsg, sCxt);
+ Set<Node> visible = graphs(testdsg, sCxt);
assertSeen(visible);
}
-
+
@Test public void graph_names_userDft() {
SecurityContext sCxt = reg.get("userDft");
- Set<Node> visible = graphs(testdsg, sCxt);
+ Set<Node> visible = graphs(testdsg, sCxt);
assertSeen(visible);
}
-
+
@Test public void graph_names_user0() {
SecurityContext sCxt = reg.get("user0");
- Set<Node> visible = graphs(testdsg, sCxt);
+ Set<Node> visible = graphs(testdsg, sCxt);
assertSeen(visible);
}
-
+
@Test public void graph_names_user1() {
SecurityContext sCxt = reg.get("user1");
- Set<Node> visible = graphs(testdsg, sCxt);
+ Set<Node> visible = graphs(testdsg, sCxt);
assertSeen(visible, g1);
}
@Test public void graph_names_user2() {
SecurityContext sCxt = reg.get("user2");
- Set<Node> visible = graphs(testdsg, sCxt);
+ Set<Node> visible = graphs(testdsg, sCxt);
assertSeen(visible, g1, g2, g3);
}
@Test public void graph_names_userX() {
SecurityContext sCxt = reg.get("userX");
- Set<Node> visible = graphs(testdsg, sCxt);
+ Set<Node> visible = graphs(testdsg, sCxt);
assertSeen(visible);
}
@@ -279,11 +279,11 @@ public class TestSecurityFilterLocal {
}
assertSeen(visible, expected);
}
-
+
@Test public void filter_union_userNone() {
filter_union_user("userNone");
}
-
+
@Test public void filter_union_userDft() {
// Storage default graph not visible with a union query.
filter_union_user("userDft");
@@ -293,25 +293,25 @@ public class TestSecurityFilterLocal {
// Storage default graph not visible with a union query.
filter_union_user("user0");
}
-
+
@Test public void filter_union_user1() {
filter_union_user("user1", s1);
}
-
+
@Test public void filter_union_user2() {
filter_union_user("user2", s1, s2, s3);
}
-
+
@Test public void filter_union_userX() {
filter_union_user("userX");
}
-
-
+
+
// Graph/Model
@Test public void query_model_userNone() {
query_model_user(testdsg, dsg->dsg.getDefaultGraph(), "userNone");
}
-
+
@Test public void query_model_userDft() {
query_model_user(testdsg, dsg->dsg.getDefaultGraph(), "userDft", s0);
}
@@ -347,7 +347,7 @@ public class TestSecurityFilterLocal {
@Test public void query_model_ng_user22() {
query_model_user(testdsg, dsg->dsg.getGraph(g2), "user2", s2);
}
-
+
@Test public void query_model_userXa() {
query_model_user(testdsg, dsg->dsg.getDefaultGraph(), "userX");
}
@@ -361,8 +361,8 @@ public class TestSecurityFilterLocal {
Set<Node> visible = subjects(dsg, graphChoice, queryDft, sCxt);
assertSeen(visible, expected);
}
-
- private static String dataStr = StrUtils.strjoinNL
+
+ private static String dataStr = StrUtils.strjoinNL
("PREFIX : <http://test/>"
,""
,":s0 :p 0 ."
@@ -373,23 +373,23 @@ public class TestSecurityFilterLocal {
);
- public static Node s0 = SSE.parseNode("<http://test/s0>");
- public static Node s1 = SSE.parseNode("<http://test/s1>");
- public static Node s2 = SSE.parseNode("<http://test/s2>");
- public static Node s3 = SSE.parseNode("<http://test/s3>");
- public static Node s4 = SSE.parseNode("<http://test/s4>");
+ public static Node s0 = SSE.parseNode("<http://test/s0>");
+ public static Node s1 = SSE.parseNode("<http://test/s1>");
+ public static Node s2 = SSE.parseNode("<http://test/s2>");
+ public static Node s3 = SSE.parseNode("<http://test/s3>");
+ public static Node s4 = SSE.parseNode("<http://test/s4>");
- public static Node g1 = SSE.parseNode("<http://test/g1>");
- public static Node g2 = SSE.parseNode("<http://test/g2>");
- public static Node g3 = SSE.parseNode("<http://test/g3>");
- public static Node g4 = SSE.parseNode("<http://test/g4>");
+ public static Node g1 = SSE.parseNode("<http://test/g1>");
+ public static Node g2 = SSE.parseNode("<http://test/g2>");
+ public static Node g3 = SSE.parseNode("<http://test/g3>");
+ public static Node g4 = SSE.parseNode("<http://test/g4>");
public static void addTestData(DatasetGraph dsg) {
Txn.executeWrite(dsg, ()->{
RDFParser.create().fromString(dataStr).lang(Lang.TRIG).parse(dsg);
});
}
-
+
public static void assertSeen(Set<Node> visible, Node ... expected) {
Set<Node> expectedNodes = new HashSet<>(Arrays.asList(expected));
assertEquals(expectedNodes, visible);
diff --git a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityRegistry.java b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityRegistry.java
index 0e62bd7..f3bf5d9 100644
--- a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityRegistry.java
+++ b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityRegistry.java
@@ -26,7 +26,7 @@ import org.apache.jena.sparql.core.assembler.AssemblerUtils;
import org.apache.jena.sys.JenaSystem;
import org.junit.Test;
-/** Test parsing of assemblers with security aspects */
+/** Test parsing of assemblers with security aspects */
public class TestSecurityRegistry {
static { JenaSystem.init(); }
static final String DIR = "testing/SecurityRegistry/";
@@ -38,10 +38,10 @@ public class TestSecurityRegistry {
assertEquals(4, sReg.keys().size());
assertEquals(3, sReg.get("user1").visibleGraphs().size());
}
-
+
@Test public void assemblerFile_2() {
// WIP
- // user1, all named graphs
+ // user1, all named graphs
// user2, all graphs
// user3, all named graphs +dft == all graphs
// any user, graph1
@@ -54,26 +54,26 @@ public class TestSecurityRegistry {
Node x = sCxt.visibleGraphs().stream().findFirst().get();
assertEquals(SecurityContext.allNamedGraphs, x);
}
-
+
{
SecurityContext sCxt = authService.get("user2");
assertEquals(1, sCxt.visibleGraphs().size());
Node x = sCxt.visibleGraphs().stream().findFirst().get();
assertEquals(SecurityContext.allGraphs, x);
}
-
+
{
SecurityContext sCxt = authService.get("user3");
assertEquals(1, sCxt.visibleGraphs().size());
Node x = sCxt.visibleGraphs().stream().findFirst().get();
assertEquals(SecurityContext.allGraphs, x);
}
-
+
{
SecurityContext sCxt = authService.get("*");
assertEquals(1, sCxt.visibleGraphs().size());
String x = sCxt.visibleGraphNames().stream().findFirst().get();
assertEquals("http://host/graphname1", x);
- }
+ }
}
}
diff --git a/jena-fuseki2/jena-fuseki-core/pom.xml b/jena-fuseki2/jena-fuseki-core/pom.xml
index 8cc4e29..d233ebb 100644
--- a/jena-fuseki2/jena-fuseki-core/pom.xml
+++ b/jena-fuseki2/jena-fuseki-core/pom.xml
@@ -135,6 +135,12 @@
<goal>jar-no-fork</goal>
</goals>
</execution>
+ <execution>
+ <id>attach-sources-test</id>
+ <goals>
+ <goal>test-jar-no-fork</goal>
+ </goals>
+ </execution>
</executions>
</plugin>
@@ -156,7 +162,14 @@
<Automatic-Module-Name>${automatic.module.name}</Automatic-Module-Name>
</manifestEntries>
</archive>
- </configuration>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>test-jar</goal>
+ </goals>
+ </execution>
+ </executions>
</plugin>
<plugin>
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/DEF.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/DEF.java
index 05e9bf9..67442fd 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/DEF.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/DEF.java
@@ -18,21 +18,21 @@
package org.apache.jena.fuseki;
-import org.apache.jena.atlas.web.AcceptList ;
-import org.apache.jena.atlas.web.MediaType ;
-import static org.apache.jena.riot.WebContent.* ;
+import org.apache.jena.atlas.web.AcceptList;
+import org.apache.jena.atlas.web.MediaType;
+import static org.apache.jena.riot.WebContent.*;
public class DEF
{
- public static final MediaType acceptRDFXML = MediaType.create(contentTypeRDFXML) ;
- public static final MediaType acceptNQuads = MediaType.create(contentTypeNQuads) ;
- public static final MediaType acceptRSXML = MediaType.create(contentTypeResultsXML) ;
- public static final MediaType acceptJSON = MediaType.create(contentTypeJSON) ;
- public static final MediaType acceptTurtle = MediaType.create(contentTypeTurtle) ;
-
- public static final AcceptList jsonOffer = AcceptList.create(contentTypeJSON) ;
+ public static final MediaType acceptRDFXML = MediaType.create(contentTypeRDFXML);
+ public static final MediaType acceptNQuads = MediaType.create(contentTypeNQuads);
+ public static final MediaType acceptRSXML = MediaType.create(contentTypeResultsXML);
+ public static final MediaType acceptJSON = MediaType.create(contentTypeJSON);
+ public static final MediaType acceptTurtle = MediaType.create(contentTypeTurtle);
- public static final AcceptList constructOffer = AcceptList.create(contentTypeTurtle,
+ public static final AcceptList jsonOffer = AcceptList.create(contentTypeJSON);
+
+ public static final AcceptList constructOffer = AcceptList.create(contentTypeTurtle,
contentTypeTurtleAlt1,
contentTypeTurtleAlt2,
contentTypeNTriples,
@@ -43,16 +43,16 @@ public class DEF
contentTypeJSONLD,
contentTypeRDFJSON,
contentTypeRDFThrift,
-
+
contentTypeTriG,
contentTypeTriGAlt1,
contentTypeTriGAlt2,
contentTypeNQuads,
contentTypeNQuadsAlt1,
contentTypeNQuadsAlt2
- ) ;
-
- public static final AcceptList rdfOffer = AcceptList.create(contentTypeTurtle,
+ );
+
+ public static final AcceptList rdfOffer = AcceptList.create(contentTypeTurtle,
contentTypeTurtleAlt1,
contentTypeTurtleAlt2,
contentTypeNTriples,
@@ -63,19 +63,19 @@ public class DEF
contentTypeJSONLD,
contentTypeRDFJSON,
contentTypeRDFThrift
- ) ;
-
+ );
+
public static final AcceptList quadsOffer = AcceptList.create(contentTypeTriG,
contentTypeTriGAlt1,
contentTypeTriGAlt2,
contentTypeJSONLD,
contentTypeNQuads,
contentTypeNQuadsAlt1,
- contentTypeNQuadsAlt2,
+ contentTypeNQuadsAlt2,
contentTypeTriX,
contentTypeTriXxml
- ) ;
-
+ );
+
// Offer for SELECT
// This include application/xml and application/json.
public static final AcceptList rsOfferTable = AcceptList.create(contentTypeResultsJSON,
@@ -86,10 +86,10 @@ public class DEF
contentTypeXML,
contentTypeResultsThrift,
contentTypeTextPlain
- ) ;
-
+ );
+
// Offer for ASK
- // This includes application/xml and application/json and excludes application/sparql-results+thrift
+ // This includes application/xml and application/json and excludes application/sparql-results+thrift
public static final AcceptList rsOfferBoolean = AcceptList.create(contentTypeResultsJSON,
contentTypeJSON,
contentTypeTextCSV,
@@ -97,14 +97,17 @@ public class DEF
contentTypeResultsXML,
contentTypeXML,
contentTypeTextPlain
- ) ;
+ );
+
-
// Names for services in the default configuration
- public static final String ServiceQuery = "query" ;
- public static final String ServiceQueryAlt = "sparql" ;
- public static final String ServiceUpdate = "update" ;
- public static final String ServiceData = "data" ;
- public static final String ServiceUpload = "upload" ;
- public static final String ServiceGeneralQuery = "/sparql" ;
+ public static final String ServiceQuery = "query";
+ public static final String ServiceQueryAlt = "sparql";
+ public static final String ServiceUpdate = "update";
+
+ public static final String ServiceDataset = "dataset";
+ public static final String ServiceDatasetAlt = "quads";
+ public static final String ServiceData = "data";
+ public static final String ServiceUpload = "upload";
+ public static final String ServiceGeneralQuery = "/sparql";
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/Fuseki.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/Fuseki.java
index 3d781c8..9105958 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/Fuseki.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/Fuseki.java
@@ -16,12 +16,12 @@
* limitations under the License.
*/
-package org.apache.jena.fuseki ;
+package org.apache.jena.fuseki;
import java.io.IOException;
-import java.util.Calendar ;
-import java.util.TimeZone ;
-import java.util.concurrent.TimeUnit ;
+import java.util.Calendar;
+import java.util.TimeZone;
+import java.util.concurrent.TimeUnit;
import javax.servlet.ServletContext;
@@ -31,79 +31,82 @@ import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpOptions;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HttpContext;
-import org.apache.jena.atlas.lib.DateTimeUtils ;
+import org.apache.jena.atlas.lib.DateTimeUtils;
import org.apache.jena.atlas.logging.Log;
import org.apache.jena.atlas.web.HttpException;
import org.apache.jena.fuseki.system.FusekiNetLib;
-import org.apache.jena.query.ARQ ;
+import org.apache.jena.query.ARQ;
import org.apache.jena.rdfconnection.RDFConnectionRemote;
-import org.apache.jena.riot.system.stream.LocatorFTP ;
-import org.apache.jena.riot.system.stream.LocatorHTTP ;
-import org.apache.jena.riot.system.stream.StreamManager ;
+import org.apache.jena.riot.system.stream.LocatorFTP;
+import org.apache.jena.riot.system.stream.LocatorHTTP;
+import org.apache.jena.riot.system.stream.StreamManager;
import org.apache.jena.riot.web.HttpOp;
-import org.apache.jena.sparql.SystemARQ ;
-import org.apache.jena.sparql.mgt.SystemInfo ;
-import org.apache.jena.sparql.util.Context ;
-import org.apache.jena.sparql.util.MappingRegistry ;
-import org.apache.jena.sys.JenaSystem ;
-import org.apache.jena.tdb.TDB ;
-import org.apache.jena.tdb.transaction.TransactionManager ;
+import org.apache.jena.sparql.SystemARQ;
+import org.apache.jena.sparql.mgt.SystemInfo;
+import org.apache.jena.sparql.util.Context;
+import org.apache.jena.sparql.util.MappingRegistry;
+import org.apache.jena.sys.JenaSystem;
+import org.apache.jena.tdb.TDB;
+import org.apache.jena.tdb.transaction.TransactionManager;
import org.apache.jena.util.Metadata;
-import org.slf4j.Logger ;
-import org.slf4j.LoggerFactory ;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class Fuseki {
// General fixed constants.
// See also FusekiServer for the naming on the filesystem
/** Path as package name */
- static public String PATH = "org.apache.jena.fuseki" ;
+ static public String PATH = "org.apache.jena.fuseki";
/** a unique IRI for the Fuseki namespace */
- static public String FusekiIRI = "http://jena.apache.org/Fuseki" ;
+ static public String FusekiIRI = "http://jena.apache.org/Fuseki";
/**
* a unique IRI including the symbol notation for which properties should be
* appended
*/
- static public String FusekiSymbolIRI = "http://jena.apache.org/fuseki#" ;
+ static public String FusekiSymbolIRI = "http://jena.apache.org/fuseki#";
/** Default location of the pages for the Fuseki UI */
- static public String PagesStatic = "pages" ;
+ static public String PagesStatic = "pages";
/** Dummy base URi string for parsing SPARQL Query and Update requests */
- static public final String BaseParserSPARQL = "http://server/unset-base/" ;
+ static public final String BaseParserSPARQL = "http://server/unset-base/";
/** Dummy base URi string for parsing SPARQL Query and Update requests */
- static public final String BaseUpload = "http://server/unset-base/" ;
+ static public final String BaseUpload = "http://server/unset-base/";
+ /** Add CORS header */
+ static public final boolean CORS_ENABLED = false;
+
/**
* A relative resources path to the location of
* <code>fuseki-properties.xml</code> file.
*/
- static private String metadataLocation = "org/apache/jena/fuseki/fuseki-properties.xml" ;
+ static private String metadataLocation = "org/apache/jena/fuseki/fuseki-properties.xml";
/**
* Object which holds metadata specified within
* {@link Fuseki#metadataLocation}
*/
- static private Metadata metadata = initMetadata() ;
+ static private Metadata metadata = initMetadata();
private static Metadata initMetadata() {
- Metadata m = new Metadata() ;
- // m.addMetadata(metadataDevLocation) ;
- m.addMetadata(metadataLocation) ;
- return m ;
+ Metadata m = new Metadata();
+ // m.addMetadata(metadataDevLocation);
+ m.addMetadata(metadataLocation);
+ return m;
}
- /** The name of the Fuseki server.*/
- static public final String NAME = "Apache Jena Fuseki" ;
+ /** The name of the Fuseki server.*/
+ static public final String NAME = "Apache Jena Fuseki";
/** Version of this Fuseki instance */
- static public final String VERSION = metadata.get(PATH + ".version", "development") ;
+ static public final String VERSION = metadata.get(PATH + ".version", "development");
/** Date when Fuseki was built */
- static public final String BUILD_DATE = metadata.get(PATH + ".build.datetime", "unknown") ;
+ static public final String BUILD_DATE = metadata.get(PATH + ".build.datetime", "unknown");
/** Supporting Graph Store Protocol direct naming.
* <p>
@@ -123,84 +126,84 @@ public class Fuseki {
* </ul>
* <p>
* <b>Note</b><br/>
- * GSP Direct Naming was implemented to provide two implementations for the SPARQL 1.1 implementation report.
+ * GSP Direct Naming was implemented to provide two implementations for the SPARQL 1.1 implementation report.
*/
- static public final boolean GSP_DIRECT_NAMING = false ;
+ static public final boolean GSP_DIRECT_NAMING = false;
/** Are we in development mode? That means a SNAPSHOT, or no VERSION
* because maven has not filtered the fuseki-properties.xml file.
*/
- public static boolean developmentMode ;
+ public static boolean developmentMode;
static {
// See ServletBase.setCommonheaders
// If it look like a SNAPSHOT, or it's not set, we are in development mode.
- developmentMode = ( VERSION == null || VERSION.equals("development") || VERSION.contains("SNAPSHOT") ) ;
+ developmentMode = ( VERSION == null || VERSION.equals("development") || VERSION.contains("SNAPSHOT") );
}
- public static boolean outputJettyServerHeader = developmentMode ;
- public static boolean outputFusekiServerHeader = developmentMode ;
-
+ public static boolean outputJettyServerHeader = developmentMode;
+ public static boolean outputFusekiServerHeader = developmentMode;
+
/** An identifier for the HTTP Fuseki server instance */
- static public final String serverHttpName = NAME + " (" + VERSION + ")" ;
-
+ static public final String serverHttpName = NAME + " (" + VERSION + ")";
+
/** Logger name for operations */
- public static final String actionLogName = PATH + ".Fuseki" ;
+ public static final String actionLogName = PATH + ".Fuseki";
/** Instance of log for operations */
- public static final Logger actionLog = LoggerFactory.getLogger(actionLogName) ;
+ public static final Logger actionLog = LoggerFactory.getLogger(actionLogName);
/** Logger name for standard webserver log file request log */
- public static final String requestLogName = PATH + ".Request" ;
+ public static final String requestLogName = PATH + ".Request";
// See HttpAction.finishRequest.
// Normally OFF
/** Instance of a log for requests: format is NCSA. */
- public static final Logger requestLog = LoggerFactory.getLogger(requestLogName) ;
+ public static final Logger requestLog = LoggerFactory.getLogger(requestLogName);
/** Admin log file for operations. */
- public static final String adminLogName = PATH + ".Admin" ;
+ public static final String adminLogName = PATH + ".Admin";
/** Instance of log for operations. */
- public static final Logger adminLog = LoggerFactory.getLogger(adminLogName) ;
+ public static final Logger adminLog = LoggerFactory.getLogger(adminLogName);
/** Admin log file for operations. */
- public static final String builderLogName = PATH + ".Builder" ;
+ public static final String builderLogName = PATH + ".Builder";
/** Instance of log for operations. */
- public static final Logger builderLog = LoggerFactory.getLogger(builderLogName) ;
+ public static final Logger builderLog = LoggerFactory.getLogger(builderLogName);
/** Validation log file for operations. */
- public static final String validationLogName = PATH + ".Validate" ;
+ public static final String validationLogName = PATH + ".Validate";
/** Instance of log for validation. */
- public static final Logger validationLog = LoggerFactory.getLogger(adminLogName) ;
+ public static final Logger validationLog = LoggerFactory.getLogger(adminLogName);
/** Actual log file for general server messages. */
- public static final String serverLogName = PATH + ".Server" ;
+ public static final String serverLogName = PATH + ".Server";
/** Instance of log for general server messages. */
- public static final Logger serverLog = LoggerFactory.getLogger(serverLogName) ;
+ public static final Logger serverLog = LoggerFactory.getLogger(serverLogName);
/** Logger used for the servletContent.log operations (if settable -- depends on environment) */
- public static final String servletRequestLogName = PATH + ".Servlet" ;
+ public static final String servletRequestLogName = PATH + ".Servlet";
/** Actual log file for config server messages. */
- public static final String configLogName = PATH + ".Config" ;
+ public static final String configLogName = PATH + ".Config";
/** Instance of log for config server messages. */
- public static final Logger configLog = LoggerFactory.getLogger(configLogName) ;
+ public static final Logger configLog = LoggerFactory.getLogger(configLogName);
/** Instance of log for config server messages.
* This is the global default used to set attribute
* in each server created.
*/
- public static boolean verboseLogging = false ;
+ public static boolean verboseLogging = false;
// Servlet context attribute names,
public static final String attrVerbose = "org.apache.jena.fuseki:verbose";
public static final String attrNameRegistry = "org.apache.jena.fuseki:DataAccessPointRegistry";
- public static final String attrServiceRegistry = "org.apache.jena.fuseki:ServiceDispatchRegistry";
+ public static final String attrOperationRegistry = "org.apache.jena.fuseki:OperationRegistry";
public static final String attrAuthorizationService = "org.apache.jena.fuseki:AuthorizationService";
public static void setVerbose(ServletContext cxt, boolean verbose) {
@@ -216,65 +219,65 @@ public class Fuseki {
* through a location mapper whereby a name (e.g. URL) is redirected to
* another name (e.g. local file).
* */
- public static final StreamManager webStreamManager ;
+ public static final StreamManager webStreamManager;
static {
- webStreamManager = new StreamManager() ;
+ webStreamManager = new StreamManager();
// Only know how to handle http URLs
- webStreamManager.addLocator(new LocatorHTTP()) ;
- webStreamManager.addLocator(new LocatorFTP()) ;
+ webStreamManager.addLocator(new LocatorHTTP());
+ webStreamManager.addLocator(new LocatorFTP());
}
/** Default (and development) root of the Fuseki installation for fixed files. */
- public static String DFT_FUSEKI_HOME = "." ;
+ public static String DFT_FUSEKI_HOME = ".";
/** Default (and development) root of the varying files in this deployment. */
- public static String DFT_FUSEKI_BASE = "." ;
+ public static String DFT_FUSEKI_BASE = ".";
- private static boolean initialized = false ;
+ private static boolean initialized = false;
// Server start time and uptime.
- private static final long startMillis = System.currentTimeMillis() ;
+ private static final long startMillis = System.currentTimeMillis();
// Hide server locale
- private static final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("00:00")) ;
- static { cal.setTimeInMillis(startMillis) ; } // Exactly the same start point!
+ private static final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("00:00"));
+ static { cal.setTimeInMillis(startMillis); } // Exactly the same start point!
- private static final String startDateTime = DateTimeUtils.calendarToXSDDateTimeString(cal) ;
+ private static final String startDateTime = DateTimeUtils.calendarToXSDDateTimeString(cal);
/** Return the number of milliseconds since the server started */
public static long serverUptimeMillis() {
- return System.currentTimeMillis() - startMillis ;
+ return System.currentTimeMillis() - startMillis;
}
/** Server uptime in seconds */
public static long serverUptimeSeconds() {
- long x = System.currentTimeMillis() - startMillis ;
- return TimeUnit.MILLISECONDS.toSeconds(x) ;
+ long x = System.currentTimeMillis() - startMillis;
+ return TimeUnit.MILLISECONDS.toSeconds(x);
}
/** XSD DateTime for when the server started */
public static String serverStartedAt() {
- return startDateTime ;
+ return startDateTime;
}
/**
* Initialize an instance of the Fuseki server stack.
* This is not done via Jena's initialization mechanism
* but done explicitly to give more control.
- * Touching this class causes this to happen
- * (see static block at the end of this class).
+ * Touching this class causes this to happen
+ * (see static block at the end of this class).
*/
public synchronized static void init() {
if ( initialized )
- return ;
- initialized = true ;
- JenaSystem.init() ;
- SystemInfo sysInfo = new SystemInfo(FusekiIRI, PATH, VERSION, BUILD_DATE) ;
- SystemARQ.registerSubSystem(sysInfo) ;
- MappingRegistry.addPrefixMapping("fuseki", FusekiSymbolIRI) ;
-
- TDB.setOptimizerWarningFlag(false) ;
+ return;
+ initialized = true;
+ JenaSystem.init();
+ SystemInfo sysInfo = new SystemInfo(FusekiIRI, PATH, VERSION, BUILD_DATE);
+ SystemARQ.registerSubSystem(sysInfo);
+ MappingRegistry.addPrefixMapping("fuseki", FusekiSymbolIRI);
+
+ TDB.setOptimizerWarningFlag(false);
// Don't set TDB batch commits.
// This can be slower, but it less memory hungry and more predictable.
- TransactionManager.QueueBatchSize = 0 ;
+ TransactionManager.QueueBatchSize = 0;
}
/**
@@ -283,19 +286,19 @@ public class Fuseki {
* @return {@link org.apache.jena.query.ARQ#getContext()}
*/
public static Context getContext() {
- return ARQ.getContext() ;
+ return ARQ.getContext();
}
// Force a call to init.
static {
- init() ;
+ init();
}
/** Retrun a free port */
public static int choosePort() {
return FusekiNetLib.choosePort();
}
-
+
/**
* Test whether a URL identifies a Fuseki server. This operation can not guarantee to
* detect a Fuseki server - for example, it may be behind a reverse proxy that masks
@@ -304,7 +307,7 @@ public class Fuseki {
public static boolean isFuseki(String datasetURL) {
HttpOptions request = new HttpOptions(datasetURL);
HttpClient httpClient = HttpOp.getDefaultHttpClient();
- if ( httpClient == null )
+ if ( httpClient == null )
httpClient = HttpClients.createSystem();
return isFuseki(request, httpClient, null);
}
@@ -317,7 +320,7 @@ public class Fuseki {
public static boolean isFuseki(RDFConnectionRemote connection) {
HttpOptions request = new HttpOptions(connection.getDestination());
HttpClient httpClient = connection.getHttpClient();
- if ( httpClient == null )
+ if ( httpClient == null )
httpClient = HttpClients.createSystem();
HttpContext httpContext = connection.getHttpContext();
return isFuseki(request, httpClient, httpContext);
@@ -328,11 +331,11 @@ public class Fuseki {
HttpResponse response = httpClient.execute(request);
// Fuseki does not send "Server" in release mode.
// (best practice).
- // All we can do is try for the "Fuseki-Request-ID"
+ // All we can do is try for the "Fuseki-Request-ID"
String reqId = safeGetHeader(response, "Fuseki-Request-ID");
if ( reqId != null )
return true;
-
+
// If returning "Server"
String serverIdent = safeGetHeader(response, "Server");
if ( serverIdent != null ) {
@@ -342,7 +345,7 @@ public class Fuseki {
isFuseki = serverIdent.toLowerCase().contains("fuseki");
return isFuseki;
}
- return false;
+ return false;
} catch (IOException ex) {
throw new HttpException("Failed to check for a Fuseki server", ex);
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/FusekiConfigException.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/FusekiConfigException.java
index 69d1e87..37d81db 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/FusekiConfigException.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/FusekiConfigException.java
@@ -20,8 +20,8 @@ package org.apache.jena.fuseki;
public class FusekiConfigException extends FusekiException
{
- public FusekiConfigException(String msg, Throwable cause) { super(msg, cause) ; }
- public FusekiConfigException(String msg) { super(msg) ; }
- public FusekiConfigException(Throwable cause) { super(cause) ; }
- public FusekiConfigException() { super() ; }
+ public FusekiConfigException(String msg, Throwable cause) { super(msg, cause); }
+ public FusekiConfigException(String msg) { super(msg); }
+ public FusekiConfigException(Throwable cause) { super(cause); }
+ public FusekiConfigException() { super(); }
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/FusekiException.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/FusekiException.java
index fcf5361..50a5f70 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/FusekiException.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/FusekiException.java
@@ -18,12 +18,12 @@
package org.apache.jena.fuseki;
-import org.apache.jena.sparql.ARQException ;
+import org.apache.jena.sparql.ARQException;
public class FusekiException extends ARQException
{
- public FusekiException(String msg, Throwable cause) { super(msg, cause) ; }
- public FusekiException(String msg) { super(msg) ; }
- public FusekiException(Throwable cause) { super(cause) ; }
- public FusekiException() { super() ; }
+ public FusekiException(String msg, Throwable cause) { super(msg, cause); }
+ public FusekiException(String msg) { super(msg); }
+ public FusekiException(Throwable cause) { super(cause); }
+ public FusekiException() { super(); }
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/async/AsyncPool.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/async/AsyncPool.java
index 2cca42e..0161ba2 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/async/AsyncPool.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/async/AsyncPool.java
@@ -18,83 +18,83 @@
package org.apache.jena.fuseki.async;
-import static java.lang.String.format ;
+import static java.lang.String.format;
-import java.util.* ;
-import java.util.concurrent.* ;
+import java.util.*;
+import java.util.concurrent.*;
-import org.apache.jena.fuseki.Fuseki ;
-import org.apache.jena.fuseki.server.DataService ;
+import org.apache.jena.fuseki.Fuseki;
+import org.apache.jena.fuseki.server.DataService;
/** The set of currently active and recently completed tasks. */
public class AsyncPool
{
// Max concurrent tasks.
- private static int nMaxThreads = 4 ;
+ private static int nMaxThreads = 4;
// Number of finished tasks kept.
- private static int MAX_FINISHED = 20 ;
-
- // See Executors.newCachedThreadPool and Executors.newFixedThreadPool
+ private static int MAX_FINISHED = 20;
+
+ // See Executors.newCachedThreadPool and Executors.newFixedThreadPool
private ExecutorService executor = new ThreadPoolExecutor(0, nMaxThreads,
120L, TimeUnit.SECONDS,
- new LinkedBlockingQueue<Runnable>()) ;
- private final Object mutex = new Object() ;
- private long counter = 0 ;
- private Map<String, AsyncTask> runningTasks = new LinkedHashMap<>() ;
- private Map<String, AsyncTask> finishedTasks = new LinkedHashMap<>() ;
- // Finite FIFO of finished tasks.
+ new LinkedBlockingQueue<Runnable>());
+ private final Object mutex = new Object();
+ private long counter = 0;
+ private Map<String, AsyncTask> runningTasks = new LinkedHashMap<>();
+ private Map<String, AsyncTask> finishedTasks = new LinkedHashMap<>();
+ // Finite FIFO of finished tasks.
private LinkedList<AsyncTask> finishedTasksList = new LinkedList<>();
-
- private static AsyncPool instance = new AsyncPool() ;
- public static AsyncPool get() { return instance ; }
+ private static AsyncPool instance = new AsyncPool();
+
+ public static AsyncPool get() { return instance; }
private AsyncPool() { }
-
- public AsyncTask submit(Runnable task, String displayName, DataService dataService, long requestId) {
+
+ public AsyncTask submit(Runnable task, String displayName, DataService dataService, long requestId) {
synchronized(mutex) {
- String taskId = Long.toString(++counter) ;
- Fuseki.serverLog.info(format("Task : %s : %s",taskId, displayName)) ;
+ String taskId = Long.toString(++counter);
+ Fuseki.serverLog.info(format("Task : %s : %s",taskId, displayName));
Callable<Object> c = ()->{
- try { task.run(); }
+ try { task.run(); }
catch (Throwable th) {
Fuseki.serverLog.error(format("Exception in task %s execution", taskId), th);
}
- return null;
+ return null;
};
- AsyncTask asyncTask = new AsyncTask(c, this, taskId, displayName, dataService, requestId) ;
+ AsyncTask asyncTask = new AsyncTask(c, this, taskId, displayName, dataService, requestId);
/* Future<Object> future = */ executor.submit(asyncTask);
- runningTasks.put(taskId, asyncTask) ;
- return asyncTask ;
+ runningTasks.put(taskId, asyncTask);
+ return asyncTask;
}
}
-
+
public Collection<AsyncTask> tasks() {
synchronized(mutex) {
- List<AsyncTask> x = new ArrayList<>(runningTasks.size()+finishedTasks.size()) ;
- x.addAll(runningTasks.values()) ;
- x.addAll(finishedTasks.values()) ;
- return x ;
+ List<AsyncTask> x = new ArrayList<>(runningTasks.size()+finishedTasks.size());
+ x.addAll(runningTasks.values());
+ x.addAll(finishedTasks.values());
+ return x;
}
}
-
- public void finished(AsyncTask task) {
+
+ public void finished(AsyncTask task) {
synchronized(mutex) {
- String id = task.getTaskId() ;
- runningTasks.remove(id) ;
+ String id = task.getTaskId();
+ runningTasks.remove(id);
// Reduce old tasks list
while ( finishedTasksList.size() >= MAX_FINISHED ) {
AsyncTask oldTask = finishedTasksList.removeFirst();
finishedTasks.remove(oldTask.getTaskId());
}
- finishedTasks.put(id, task) ;
+ finishedTasks.put(id, task);
finishedTasksList.add(task);
}
}
public AsyncTask getRunningTask(String taskId) {
synchronized(mutex) {
- return runningTasks.get(taskId) ;
+ return runningTasks.get(taskId);
}
}
@@ -104,10 +104,10 @@ public class AsyncPool
*/
public AsyncTask getTask(String taskId) {
synchronized(mutex) {
- AsyncTask task = runningTasks.get(taskId) ;
+ AsyncTask task = runningTasks.get(taskId);
if ( task != null )
- return task ;
- return finishedTasks.get(taskId) ;
+ return task;
+ return finishedTasks.get(taskId);
}
}
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/async/AsyncTask.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/async/AsyncTask.java
index b25f238..f224ed9 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/async/AsyncTask.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/async/AsyncTask.java
@@ -18,103 +18,103 @@
package org.apache.jena.fuseki.async;
-import static java.lang.String.format ;
+import static java.lang.String.format;
-import java.util.concurrent.Callable ;
+import java.util.concurrent.Callable;
-import org.apache.jena.atlas.lib.DateTimeUtils ;
-import org.apache.jena.atlas.lib.InternalErrorException ;
-import org.apache.jena.atlas.logging.Log ;
-import org.apache.jena.fuseki.Fuseki ;
-import org.apache.jena.fuseki.server.DataService ;
-import org.slf4j.Logger ;
+import org.apache.jena.atlas.lib.DateTimeUtils;
+import org.apache.jena.atlas.lib.InternalErrorException;
+import org.apache.jena.atlas.logging.Log;
+import org.apache.jena.fuseki.Fuseki;
+import org.apache.jena.fuseki.server.DataService;
+import org.slf4j.Logger;
-/** An asynchronous task */
-public class AsyncTask implements Callable<Object>
+/** An asynchronous task */
+public class AsyncTask implements Callable<Object>
{
- private static Logger log = Fuseki.serverLog ;
-
- private final Callable<Object> callable ;
- private final AsyncPool pool ;
+ private static Logger log = Fuseki.serverLog;
- private final String displayName ;
- private final DataService dataService ;
+ private final Callable<Object> callable;
+ private final AsyncPool pool;
- private String startPoint = null ;
- private String finishPoint = null ;
+ private final String displayName;
+ private final DataService dataService;
- private final String taskId ;
+ private String startPoint = null;
+ private String finishPoint = null;
- private long requestId ;
+ private final String taskId;
- /*package*/ AsyncTask(Callable<Object> callable,
+ private long requestId;
+
+ /*package*/ AsyncTask(Callable<Object> callable,
AsyncPool pool,
String taskId,
String displayName,
DataService dataService,
long requestId) {
- this.callable = callable ;
- this.pool = pool ;
- this.taskId = taskId ;
- this.displayName = displayName ;
- this.dataService = dataService ;
- this.requestId = requestId ;
+ this.callable = callable;
+ this.pool = pool;
+ this.taskId = taskId;
+ this.displayName = displayName;
+ this.dataService = dataService;
+ this.requestId = requestId;
}
/** Unique task id */
- public String getTaskId() { return taskId ; }
-
+ public String getTaskId() { return taskId; }
+
/** Request id that caused this task (may be -1 for N/A) */
- public long getOriginatingRequestId() { return requestId ; }
+ public long getOriginatingRequestId() { return requestId; }
/** Display name - no newlines */
- public String displayName() { return displayName ; }
-
- public DataService getDataService() { return dataService ; }
+ public String displayName() { return displayName; }
+
+ public DataService getDataService() { return dataService; }
private void start() {
if ( startPoint != null ) {
- String msg = format("[Task %s] Async task has already been started", taskId) ;
- Log.warn(Fuseki.serverLog, msg) ;
- throw new InternalErrorException("Finish has already been called ["+getTaskId()+"]") ;
+ String msg = format("[Task %s] Async task has already been started", taskId);
+ Log.warn(Fuseki.serverLog, msg);
+ throw new InternalErrorException("Finish has already been called ["+getTaskId()+"]");
}
-
- Fuseki.serverLog.info(format("[Task %s] starts : %s",taskId, displayName)) ;
- startPoint = DateTimeUtils.nowAsXSDDateTimeString() ;
+
+ Fuseki.serverLog.info(format("[Task %s] starts : %s",taskId, displayName));
+ startPoint = DateTimeUtils.nowAsXSDDateTimeString();
}
-
+
public void finish() {
if ( finishPoint != null ) {
- String msg = format("[Task %s] Async task has already been finished", taskId) ;
- Log.warn(Fuseki.serverLog, msg) ;
- throw new InternalErrorException("Finish has already been called ["+getTaskId()+"]") ;
+ String msg = format("[Task %s] Async task has already been finished", taskId);
+ Log.warn(Fuseki.serverLog, msg);
+ throw new InternalErrorException("Finish has already been called ["+getTaskId()+"]");
}
- finishPoint = DateTimeUtils.nowAsXSDDateTimeString() ;
- Fuseki.serverLog.info(format("[Task %s] finishes : %s",taskId, displayName)) ;
+ finishPoint = DateTimeUtils.nowAsXSDDateTimeString();
+ Fuseki.serverLog.info(format("[Task %s] finishes : %s",taskId, displayName));
}
-
+
@Override
public Object call() {
try {
- start() ;
- return callable.call() ;
+ start();
+ return callable.call();
}
catch (Exception ex) {
- log.error("Async task threw an expection", ex) ;
- return null ;
+ log.error("Async task threw an expection", ex);
+ return null;
}
finally {
- finish() ;
- pool.finished(this) ;
+ finish();
+ pool.finished(this);
}
}
public String getStartPoint() {
- return startPoint ;
+ return startPoint;
}
public String getFinishPoint() {
- return finishPoint ;
+ return finishPoint;
}
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/auth/Auth.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/auth/Auth.java
index c0b1d52..c163e11 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/auth/Auth.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/auth/Auth.java
@@ -29,7 +29,7 @@ import org.apache.jena.fuseki.FusekiConfigException;
* See {@link Users} for special user names.
*/
public class Auth {
- public static final String dftRealm = "TripleStore";
+ public static final String dftRealm = "TripleStore";
/** Any authenticated user. */
public static AuthPolicy ANY_USER = (user) -> user != null;
@@ -40,18 +40,18 @@ public class Auth {
/** Never allow. */
public static AuthPolicy DENY = (user) -> false;
- /** A policy that allows specific users (convenience wrapped for {@link #policyAllowSpecific(Collection)}). */
+ /** A policy that allows specific users (convenience wrapped for {@link #policyAllowSpecific(Collection)}). */
public static AuthPolicy policyAllowSpecific(String... allowedUsers) {
return Auth.policyAllowSpecific(Arrays.asList(allowedUsers));
}
-
- /**
+
+ /**
* A policy that allows specific users.
* <ul>
* <li>If any user is {@linkplain Users#UserAnyLoggedIn}, then this policy is the same as {@linkplain #ANY_USER}.
* <li>If any user is {@linkplain Users#UserAnyAnon}, then this policy is the same as {@linkplain #ANY_ANON}.
* </ul>
- */
+ */
public static AuthPolicy policyAllowSpecific(Collection<String> allowedUsers) {
Objects.requireNonNull(allowedUsers, "allowedUsers");
if ( allowedUsers.contains(Users.UserAnyLoggedIn) ) {
@@ -66,14 +66,16 @@ public class Auth {
}
if ( allowedUsers.stream().anyMatch(Objects::isNull) )
- throw new FusekiConfigException("null user found : "+allowedUsers);
+ throw new FusekiConfigException("null user found : "+allowedUsers);
+ if ( allowedUsers.isEmpty() )
+ return Auth.DENY;
return new AuthUserList(allowedUsers);
}
/**
- * Test whether a user (principal) is allowed by a authorization policy.
+ * Test whether a user (principal) is allowed by a authorization policy.
* The policy can be null, meaning no restrictions, and the function returns true.
- * {@code user} maybe null, meaning unauthenticated and any policy must deal with this.
+ * {@code user} maybe null, meaning unauthenticated and any policy must deal with this.
* @param user
* @param policy
* @return boolean True if the policy is null or allows the user.
@@ -83,14 +85,14 @@ public class Auth {
return true;
return policy.isAllowed(user);
}
-
+
/**
* Test whether a user (principal) is allowed by a authorization policy
* and perform an action if the policy does not allow the user.
* The action can throw an exception.
* Additional, return true/false - see {@link #allow(String, AuthPolicy)}.
* The policy can be null, meaning no restrictions, and the function returns true.
- * {@code user} maybe null, meaning unauthenticated and any policy must deal with this.
+ * {@code user} maybe null, meaning unauthenticated and any policy must deal with this.
* @param user
* @param policy
* @param notAllowed Runnable to execute if the policy does not allow the user.
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/auth/AuthPolicy.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/auth/AuthPolicy.java
index 5a14025..a828833 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/auth/AuthPolicy.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/auth/AuthPolicy.java
@@ -23,7 +23,7 @@ package org.apache.jena.fuseki.auth;
* Assumes the user has already been authenticated.
*/
public interface AuthPolicy {
- /**
+ /**
* Is the use authorized for this resource?
*/
public boolean isAllowed(String user);
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/auth/AuthPolicyList.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/auth/AuthPolicyList.java
index 1e00320..6dffcc8 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/auth/AuthPolicyList.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/auth/AuthPolicyList.java
@@ -21,16 +21,16 @@ package org.apache.jena.fuseki.auth;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
-/**
+/**
* An {@link AuthPolicy} that combines a number of {@link AuthPolicy AuthPolicies}.
* All policies must authorize access for this policy to allow access.
- */
+ */
public class AuthPolicyList implements AuthPolicy {
// Thread safe.
- // Use a
+ // Use a
private final Queue<AuthPolicy> policies = new ConcurrentLinkedQueue<>();
-
+
/**
* Merge {@link AuthPolicy AuthPolicies}, returning a combination of the two if both are non-null.
* If either is null, return the other.
@@ -38,7 +38,7 @@ public class AuthPolicyList implements AuthPolicy {
*/
public static AuthPolicy merge(AuthPolicy policy1, AuthPolicy policy2) {
if ( policy1 == null )
- return policy2 ;
+ return policy2;
if ( policy2 == null )
return policy1;
if ( policy1 instanceof AuthPolicyList) {
@@ -51,13 +51,13 @@ public class AuthPolicyList implements AuthPolicy {
x.add(policy2);
return x;
}
-
- private AuthPolicyList(AuthPolicyList other) {
+
+ private AuthPolicyList(AuthPolicyList other) {
policies.addAll(other.policies);
}
-
+
public AuthPolicyList() { }
-
+
public void add(AuthPolicy policy) {
policies.add(policy);
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/auth/AuthUserList.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/auth/AuthUserList.java
index 55aae72..1b91bb6 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/auth/AuthUserList.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/auth/AuthUserList.java
@@ -21,7 +21,7 @@ package org.apache.jena.fuseki.auth;
import java.util.*;
/**
- * Policy for allowing users to execute a request.
+ * Policy for allowing users to execute a request.
* Assumes the user has been authenticated.
*/
class AuthUserList implements AuthPolicy {
@@ -31,7 +31,7 @@ class AuthUserList implements AuthPolicy {
/*package*/ AuthUserList(Collection<String> allowed) {
this.allowedUsers = (allowed == null) ? Collections.emptySet() : new HashSet<>(allowed);
}
-
+
@Override
public boolean isAllowed(String user) {
if ( user == null )
@@ -49,12 +49,12 @@ class AuthUserList implements AuthPolicy {
static <T> boolean isNullOrEmpty(Collection<T> collection) {
if ( collection == null )
return true;
- return collection.isEmpty();
+ return collection.isEmpty();
}
-
+
static <T> boolean contains(Collection<T> collection, T obj) {
if ( collection == null )
return false;
- return collection.contains(obj);
+ return collection.contains(obj);
}
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/auth/Users.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/auth/Users.java
index 7b6c5fd..bf9aa2c 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/auth/Users.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/auth/Users.java
@@ -23,11 +23,11 @@ public class Users {
* Reserved user role name: Name of the user role for any authenticated user of the system.
* In the servlet API, this equates to {@code getRemoteUser() != null}.
*/
- public static String UserAnyLoggedIn = "*";
+ public static String UserAnyLoggedIn = "*";
- /**
+ /**
* Reserved user role name: Name of the user role for any authenticated user of the system
* In the servlet API, this includes {@code getRemoteUser() == null}
*/
- public static String UserAnyAnon = "_" ;
+ public static String UserAnyAnon = "_";
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiBuildLib.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/BuildLib.java
similarity index 54%
rename from jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiBuildLib.java
rename to jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/BuildLib.java
index f2f71c4..dd061eb 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiBuildLib.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/BuildLib.java
@@ -18,32 +18,34 @@
package org.apache.jena.fuseki.build;
+import static org.apache.jena.fuseki.build.FusekiPrefixes.PREFIXES;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.jena.fuseki.FusekiConfigException;
-import org.apache.jena.query.* ;
+import org.apache.jena.query.*;
import org.apache.jena.rdf.model.*;
import org.apache.jena.shared.JenaException;
-import org.apache.jena.shared.PrefixMapping ;
-import org.apache.jena.vocabulary.RDFS ;
+import org.apache.jena.shared.PrefixMapping;
+import org.apache.jena.vocabulary.RDFS;
/**
* Library code for operations related to building Fuseki servers and services.
*/
-public class FusekiBuildLib {
+class BuildLib {
// ---- Helper code
- public static ResultSet query(String string, Model m) {
- return query(string, m, null, null) ;
+ /*package*/ static ResultSet query(String string, Model m) {
+ return query(string, m, null, null);
}
- public static RDFNode queryOne(String string, Model m, String varname) {
- ResultSet rs = query(string, m) ;
+ /*package*/ static RDFNode queryOne(String string, Model m, String varname) {
+ ResultSet rs = query(string, m);
return getExactlyOne(rs, varname);
}
-
+
private static RDFNode getExactlyOne(ResultSet rs, String varname) {
if ( ! rs.hasNext() )
return null;
@@ -53,49 +55,49 @@ public class FusekiBuildLib {
return qs.get(varname);
}
- public static ResultSet query(String string, Dataset ds) {
- return query(string, ds, null, null) ;
+ /*package*/ static ResultSet query(String string, Dataset ds) {
+ return query(string, ds, null, null);
}
- public static ResultSet query(String string, Model m, String varName, RDFNode value) {
- Query query = QueryFactory.create(FusekiConst.PREFIXES + string) ;
- QuerySolutionMap initValues = null ;
+ /*package*/ static ResultSet query(String string, Model m, String varName, RDFNode value) {
+ Query query = QueryFactory.create(PREFIXES + string);
+ QuerySolutionMap initValues = null;
if ( varName != null && value != null )
- initValues = querySolution(varName, value) ;
+ initValues = querySolution(varName, value);
try ( QueryExecution qExec = QueryExecutionFactory.create(query, m, initValues) ) {
- return ResultSetFactory.copyResults(qExec.execSelect()) ;
+ return ResultSetFactory.copyResults(qExec.execSelect());
}
}
- public static ResultSet query(String string, Dataset ds, String varName, RDFNode value) {
- Query query = QueryFactory.create(FusekiConst.PREFIXES + string) ;
- QuerySolutionMap initValues = null ;
+ /*package*/ static ResultSet query(String string, Dataset ds, String varName, RDFNode value) {
+ Query query = QueryFactory.create(PREFIXES + string);
+ QuerySolutionMap initValues = null;
if ( varName != null && value != null )
- initValues = querySolution(varName, value) ;
+ initValues = querySolution(varName, value);
try ( QueryExecution qExec = QueryExecutionFactory.create(query, ds, initValues) ) {
- return ResultSetFactory.copyResults(qExec.execSelect()) ;
+ return ResultSetFactory.copyResults(qExec.execSelect());
}
}
private static QuerySolutionMap querySolution(String varName, RDFNode value) {
- QuerySolutionMap qsm = new QuerySolutionMap() ;
- querySolution(qsm, varName, value) ;
- return qsm ;
+ QuerySolutionMap qsm = new QuerySolutionMap();
+ querySolution(qsm, varName, value);
+ return qsm;
}
- public static QuerySolutionMap querySolution(QuerySolutionMap qsm, String varName, RDFNode value) {
- qsm.add(varName, value) ;
- return qsm ;
+ /*package*/ static QuerySolutionMap querySolution(QuerySolutionMap qsm, String varName, RDFNode value) {
+ qsm.add(varName, value);
+ return qsm;
}
- public static RDFNode getOne(Resource svc, String property) {
- ResultSet rs = FusekiBuildLib.query("SELECT * { ?svc " + property + " ?x}", svc.getModel(), "svc", svc) ;
+ /*package*/ static RDFNode getOne(Resource svc, String property) {
+ ResultSet rs = BuildLib.query("SELECT * { ?svc " + property + " ?x}", svc.getModel(), "svc", svc);
if ( !rs.hasNext() )
- throw new FusekiConfigException("No property '" + property + "' for service " + FusekiBuildLib.nodeLabel(svc)) ;
- RDFNode x = rs.next().get("x") ;
+ throw new FusekiConfigException("No property '" + property + "' for service " + BuildLib.nodeLabel(svc));
+ RDFNode x = rs.next().get("x");
if ( rs.hasNext() )
- throw new FusekiConfigException("Multiple properties '" + property + "' for service " + FusekiBuildLib.nodeLabel(svc)) ;
- return x ;
+ throw new FusekiConfigException("Multiple properties '" + property + "' for service " + BuildLib.nodeLabel(svc));
+ return x;
}
/**
@@ -103,8 +105,8 @@ public class FusekiBuildLib {
* mixture. If the subject/property isn't present, return null, so a caller can tell
* the difference between "not present" and an empty list value.
*/
- public static Collection<RDFNode> getAll(Resource resource, String property) {
- ResultSet rs = FusekiBuildLib.query("SELECT * { ?subject " + property + " ?x}", resource.getModel(), "subject", resource) ;
+ /*package*/ static Collection<RDFNode> getAll(Resource resource, String property) {
+ ResultSet rs = BuildLib.query("SELECT * { ?subject " + property + " ?x}", resource.getModel(), "subject", resource);
if ( ! rs.hasNext() )
return null;
List<RDFNode> results = new ArrayList<>();
@@ -118,49 +120,49 @@ public class FusekiBuildLib {
results.add(n);
}
});
- return results ;
+ return results;
}
// Node presentation
- public static String nodeLabel(RDFNode n) {
+ /*package*/ static String nodeLabel(RDFNode n) {
if ( n == null )
- return "<null>" ;
+ return "<null>";
if ( n instanceof Resource )
- return strForResource((Resource)n) ;
-
- Literal lit = (Literal)n ;
- return lit.getLexicalForm() ;
+ return strForResource((Resource)n);
+
+ Literal lit = (Literal)n;
+ return lit.getLexicalForm();
}
- public static String strForResource(Resource r) {
- return strForResource(r, r.getModel()) ;
+ /*package*/ static String strForResource(Resource r) {
+ return strForResource(r, r.getModel());
}
- public static String strForResource(Resource r, PrefixMapping pm) {
+ /*package*/ static String strForResource(Resource r, PrefixMapping pm) {
if ( r == null )
- return "NULL " ;
+ return "NULL ";
if ( r.hasProperty(RDFS.label) ) {
- RDFNode n = r.getProperty(RDFS.label).getObject() ;
+ RDFNode n = r.getProperty(RDFS.label).getObject();
if ( n instanceof Literal )
- return ((Literal)n).getString() ;
+ return ((Literal)n).getString();
}
-
+
if ( r.isAnon() )
- return "<<blank node>>" ;
-
+ return "<<blank node>>";
+
if ( pm == null )
- pm = r.getModel() ;
-
- return strForURI(r.getURI(), pm) ;
+ pm = r.getModel();
+
+ return strForURI(r.getURI(), pm);
}
- public static String strForURI(String uri, PrefixMapping pm) {
+ /*package*/ static String strForURI(String uri, PrefixMapping pm) {
if ( pm != null ) {
- String x = pm.shortForm(uri) ;
-
+ String x = pm.shortForm(uri);
+
if ( !x.equals(uri) )
- return x ;
+ return x;
}
- return "<" + uri + ">" ;
+ return "<" + uri + ">";
}
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/DatasetDescriptionRegistry.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/DatasetDescriptionMap.java
similarity index 74%
rename from jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/DatasetDescriptionRegistry.java
rename to jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/DatasetDescriptionMap.java
index b49c5be..c814a8f 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/DatasetDescriptionRegistry.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/DatasetDescriptionMap.java
@@ -21,30 +21,26 @@ package org.apache.jena.fuseki.build;
import java.util.HashMap;
import java.util.Map;
-import org.apache.jena.atlas.logging.Log ;
+import org.apache.jena.atlas.logging.Log;
import org.apache.jena.query.Dataset;
import org.apache.jena.rdf.model.Resource;
/**
- * Registry of Datasets created from descriptions.
- *
- * <p>
- * Provides a registry for use in building the Fuseki configuration to
- * ensure that each dataset description resource in configuration graphs
- * corresponds to one dataset object when multiple services refer to the
- * same dataset.
- * </p>
- *
+ * Record of datasets created from descriptions.
*
+ * Provides a registry for use in building one Fuseki configuration to
+ * ensure that each dataset description resource in configuration graphs
+ * corresponds to one dataset object when multiple services refer to the
+ * same dataset.
*/
-public class DatasetDescriptionRegistry {
+public class DatasetDescriptionMap {
private Map<Resource, Dataset> map = new HashMap<>();
- public DatasetDescriptionRegistry() {}
+ public DatasetDescriptionMap() {}
public void register(Resource node, Dataset ds) {
- Dataset dsCurrent = map.get(node) ;
+ Dataset dsCurrent = map.get(node);
if ( dsCurrent != null ) {
if ( ! dsCurrent.equals(ds) )
Log.warn(this.getClass(), "Replacing registered dataset for "+node);
@@ -55,7 +51,7 @@ public class DatasetDescriptionRegistry {
public Dataset get(Resource node) {
return map.get(node);
}
-
+
public void clear() {
map.clear();
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiBuilder.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiBuilder.java
deleted file mode 100644
index dfeb8fd..0000000
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiBuilder.java
+++ /dev/null
@@ -1,172 +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.fuseki.build;
-
-import static java.lang.String.format;
-import static java.util.stream.Collectors.toList;
-import static org.apache.jena.fuseki.server.FusekiVocab.pAllowedUsers;
-
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.jena.fuseki.FusekiConfigException;
-import org.apache.jena.fuseki.auth.Auth;
-import org.apache.jena.fuseki.auth.AuthPolicy;
-import org.apache.jena.fuseki.server.*;
-import org.apache.jena.graph.Node;
-import org.apache.jena.query.QuerySolution ;
-import org.apache.jena.query.ResultSet ;
-import org.apache.jena.rdf.model.*;
-import org.apache.jena.rdf.model.impl.Util;
-import org.apache.jena.shared.JenaException;
-import org.apache.jena.sparql.core.DatasetGraph ;
-import org.apache.jena.sparql.util.graph.GraphUtils;
-
-/**
- * Helper functions use to construct Fuseki servers.
- * @see FusekiConfig
- */
-public class FusekiBuilder
-{
- /** Build a DataService starting at Resource svc, with the standard (default) set of services. */
- public static DataService buildDataServiceStd(DatasetGraph dsg, boolean allowUpdate) {
- DataService dataService = new DataService(dsg) ;
- populateStdServices(dataService, allowUpdate);
- return dataService ;
- }
-
- /** Convenience operation to populate a {@link DataService} with the conventional default services. */
- public static void populateStdServices(DataService dataService, boolean allowUpdate) {
- addServiceEP(dataService, Operation.Query, "query") ;
- addServiceEP(dataService, Operation.Query, "sparql") ;
- if ( ! allowUpdate ) {
- addServiceEP(dataService, Operation.GSP_R, "data") ;
- addServiceEP(dataService, Operation.DatasetRequest_R, "") ;
- return;
- }
- addServiceEP(dataService, Operation.GSP_RW, "data") ;
- addServiceEP(dataService, Operation.GSP_R, "get") ;
- addServiceEP(dataService, Operation.Update, "update") ;
- addServiceEP(dataService, Operation.Upload, "upload") ;
- addServiceEP(dataService, Operation.DatasetRequest_RW, "") ;
- }
-
- /** Add an operation to a {@link DataService} with a given endpoint name */
- public static void addServiceEP(DataService dataService, Operation operation, String endpointName) {
- dataService.addEndpoint(operation, endpointName) ;
- }
-
- /** Add an operation to a {@link DataService} with a given endpoint name */
- public static void addServiceEP(DataService dataService, Operation operation, String endpointName, AuthPolicy requestAuth) {
- dataService.addEndpoint(operation, endpointName, requestAuth) ;
- }
-
- public static void addServiceEP(DataService dataService, Operation operation, Resource svc, Property property) {
- String p = "<"+property.getURI()+">" ;
- ResultSet rs = FusekiBuildLib.query("SELECT * { ?svc " + p + " ?ep}", svc.getModel(), "svc", svc) ;
- for ( ; rs.hasNext() ; ) {
- QuerySolution soln = rs.next() ;
- // No policy yet - set below if one is found.
- AuthPolicy requestAuth = null;
- RDFNode ep = soln.get("ep");
- String epName = null;
- if ( ep.isLiteral() )
- epName = soln.getLiteral("ep").getLexicalForm() ;
- else if ( ep.isResource() ) {
- Resource r = (Resource)ep;
- try {
- // Look for possible:
- // [ fuseki:name "" ; fuseki:allowedUsers ( "" "" ) ]
- epName = r.getProperty(FusekiVocab.pServiceName).getString();
- List<RDFNode> x = GraphUtils.multiValue(r, FusekiVocab.pAllowedUsers);
- if ( x.size() > 1 )
- throw new FusekiConfigException("Multiple fuseki:"+FusekiVocab.pAllowedUsers.getLocalName()+" for "+r);
- if ( ! x.isEmpty() )
- requestAuth = FusekiBuilder.allowedUsers(r);
- } catch(JenaException | ClassCastException ex) {
- throw new FusekiConfigException("Failed to parse endpoint: "+r);
- }
- } else {
- throw new FusekiConfigException("Unrecognized: "+ep);
- }
- addServiceEP(dataService, operation, epName, requestAuth);
- //log.info(" " + operation.name + " = " + dataAccessPoint.getName() + "/" + epName) ;
- }
- }
-
- public static void addDataService(DataAccessPointRegistry dataAccessPoints, String name, DataService dataService) {
- name = DataAccessPoint.canonical(name);
- if ( dataAccessPoints.isRegistered(name) )
- throw new FusekiConfigException("Data service name already registered: "+name);
- DataAccessPoint dap = new DataAccessPoint(name, dataService);
- dataAccessPoints.register(dap);
- }
-
- public static void addDataset(DataAccessPointRegistry dataAccessPoints, String name, DatasetGraph dsg, boolean withUpdate) {
- name = DataAccessPoint.canonical(name);
- if ( dataAccessPoints.isRegistered(name) )
- throw new FusekiConfigException("Data service name already registered: "+name);
- DataAccessPoint dap = buildDataAccessPoint(name, dsg, withUpdate);
- dataAccessPoints.register(dap);
- }
-
- private static DataAccessPoint buildDataAccessPoint(String name, DatasetGraph dsg, boolean withUpdate) {
- // See Builder. DRY.
- DataService dataService = FusekiBuilder.buildDataServiceStd(dsg, withUpdate);
- DataAccessPoint dap = new DataAccessPoint(name, dataService);
- return dap;
- }
-
- public static void removeDataset(DataAccessPointRegistry dataAccessPoints, String name) {
- name = DataAccessPoint.canonical(name);
- dataAccessPoints.remove(name);
- }
-
- /** Get the allowed users on a resource.
- * Returns null if the resource is null or if there were no settings.
- *
- * @param resource
- * @return RequestAuthorization
- */
- public static AuthPolicy allowedUsers(Resource resource) {
- if ( resource == null )
- return null;
- Collection<RDFNode> allowedUsers = FusekiBuildLib.getAll(resource, "fu:"+pAllowedUsers.getLocalName());
- if ( allowedUsers == null )
- // Indicate no settings.
- return null;
- // Check all values are simple strings
- List<String> bad = allowedUsers.stream()
- .map(RDFNode::asNode)
- .filter(rn -> ! Util.isSimpleString(rn))
- .map(rn->rn.toString())
- .collect(toList());
- if ( ! bad.isEmpty() ) {
- //Fuseki.configLog.error(format("User names must be a simple string: bad = %s", bad));
- throw new FusekiConfigException(format("User names should be a simple string: bad = %s", bad));
- }
- // RDFNodes/literals to strings.
- Collection<String> userNames = allowedUsers.stream()
- .map(RDFNode::asNode)
- .map(Node::getLiteralLexicalForm)
- .collect(toList());
- return Auth.policyAllowSpecific(userNames);
- }
-}
-
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiConfig.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiConfig.java
index b427f86..f790dd3 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiConfig.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiConfig.java
@@ -16,56 +16,173 @@
* limitations under the License.
*/
-package org.apache.jena.fuseki.build ;
+package org.apache.jena.fuseki.build;
import static java.lang.String.format;
+import static java.util.stream.Collectors.toList;
import static org.apache.jena.fuseki.server.FusekiVocab.*;
import static org.apache.jena.riot.RDFLanguages.filenameToLang;
import static org.apache.jena.riot.RDFParserRegistry.isRegistered;
-import java.io.File ;
-import java.io.IOException ;
-import java.lang.reflect.Method ;
-import java.nio.file.DirectoryStream ;
-import java.nio.file.Files ;
-import java.nio.file.Path ;
-import java.nio.file.Paths ;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.*;
+import org.apache.commons.lang3.StringUtils;
import org.apache.jena.assembler.Assembler;
-import org.apache.jena.assembler.JA ;
-import org.apache.jena.atlas.lib.IRILib ;
-import org.apache.jena.atlas.lib.StrUtils ;
+import org.apache.jena.assembler.JA;
+import org.apache.jena.atlas.lib.IRILib;
+import org.apache.jena.atlas.lib.StrUtils;
import org.apache.jena.datatypes.xsd.XSDDatatype;
-import org.apache.jena.fuseki.Fuseki ;
-import org.apache.jena.fuseki.FusekiConfigException ;
+import org.apache.jena.fuseki.Fuseki;
+import org.apache.jena.fuseki.FusekiConfigException;
+import org.apache.jena.fuseki.auth.Auth;
import org.apache.jena.fuseki.auth.AuthPolicy;
import org.apache.jena.fuseki.server.*;
-import org.apache.jena.query.Dataset ;
-import org.apache.jena.query.QuerySolution ;
-import org.apache.jena.query.ReadWrite ;
-import org.apache.jena.query.ResultSet ;
+import org.apache.jena.graph.Node;
+import org.apache.jena.query.*;
import org.apache.jena.rdf.model.*;
+import org.apache.jena.rdf.model.impl.Util;
import org.apache.jena.riot.Lang;
-import org.apache.jena.sparql.core.assembler.AssemblerUtils ;
+import org.apache.jena.shared.JenaException;
+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.FmtUtils;
import org.apache.jena.sparql.util.graph.GraphUtils;
import org.apache.jena.vocabulary.RDF;
-import org.slf4j.Logger ;
+import org.slf4j.Logger;
+/** Functions to setup and act onthe configuration of a Fuseki server */
public class FusekiConfig {
- static { Fuseki.init() ; }
-
- private static Logger log = Fuseki.configLog ;
+ static { Fuseki.init(); }
+
+ private static Logger log = Fuseki.configLog;
+ /** Build a DataService starting at Resource svc, with the standard (default) set of services. */
+ public static DataService buildDataServiceStd(DatasetGraph dsg, boolean allowUpdate) {
+ DataService dataService = new DataService(dsg);
+ populateStdServices(dataService, allowUpdate);
+ return dataService;
+ }
+
+ /** Convenience operation to populate a {@link DataService} with the conventional default services. */
+ public static void populateStdServices(DataService dataService, boolean allowUpdate) {
+ Set<Endpoint> endpoints = new HashSet<>();
+
+ accEndpoint(endpoints, Operation.Query, "query");
+ accEndpoint(endpoints, Operation.Query, "sparql");
+ if ( ! allowUpdate ) {
+ accEndpoint(endpoints, Operation.GSP_R, "data");
+ } else {
+ accEndpoint(endpoints, Operation.GSP_RW, "data");
+ accEndpoint(endpoints, Operation.GSP_R, "get");
+ accEndpoint(endpoints, Operation.Update, "update");
+ accEndpoint(endpoints, Operation.Upload, "upload");
+ }
+ // Dataset
+ accEndpoint(endpoints, Operation.Query);
+ accEndpoint(endpoints, Operation.GSP_R);
+ if ( allowUpdate ) {
+ accEndpoint(endpoints, Operation.Update);
+ accEndpoint(endpoints, Operation.GSP_RW);
+ }
+
+ // Add to DataService.
+ endpoints.forEach(dataService::addEndpoint);
+ }
+
+ /** Add an operation to a {@link DataService} for the dataset. */
+ public static void addDatasetEP(DataService dataService, Operation operation) {
+ addDatasetEP(dataService, operation, null);
+ }
+
+ /** Add an operation to a {@link DataService} for the dataset. */
+ public static void addDatasetEP(DataService dataService, Operation operation, AuthPolicy authPolicy) {
+ dataService.addEndpointNoName(operation, authPolicy);
+ }
+
+ /** Add an operation to a {@link DataService} with a given endpoint name */
+ public static void addServiceEP(DataService dataService, Operation operation, String endpointName) {
+ addServiceEP(dataService, operation, endpointName, null);
+ }
+
+ /** Add an operation to a {@link DataService} with a given endpoint name */
+ public static void addServiceEP(DataService dataService, Operation operation, String endpointName, AuthPolicy authPolicy) {
+ if ( StringUtils.isEmpty(endpointName) )
+ dataService.addEndpointNoName(operation, authPolicy);
+ else
+ dataService.addEndpoint(operation, endpointName, authPolicy);
+ }
+
+ public static void addDataService(DataAccessPointRegistry dataAccessPoints, String name, DataService dataService) {
+ name = DataAccessPoint.canonical(name);
+ if ( dataAccessPoints.isRegistered(name) )
+ throw new FusekiConfigException("Data service name already registered: "+name);
+ DataAccessPoint dap = new DataAccessPoint(name, dataService);
+ dataAccessPoints.register(dap);
+ }
+
+ public static void addDataset(DataAccessPointRegistry dataAccessPoints, String name, DatasetGraph dsg, boolean withUpdate) {
+ name = DataAccessPoint.canonical(name);
+ if ( dataAccessPoints.isRegistered(name) )
+ throw new FusekiConfigException("Data service name already registered: "+name);
+ DataAccessPoint dap = buildDataAccessPoint(name, dsg, withUpdate);
+ dataAccessPoints.register(dap);
+ }
+
+ private static DataAccessPoint buildDataAccessPoint(String name, DatasetGraph dsg, boolean withUpdate) {
+ // See Builder. DRY.
+ DataService dataService = buildDataServiceStd(dsg, withUpdate);
+ DataAccessPoint dap = new DataAccessPoint(name, dataService);
+ return dap;
+ }
+
+ public static void removeDataset(DataAccessPointRegistry dataAccessPoints, String name) {
+ name = DataAccessPoint.canonical(name);
+ dataAccessPoints.remove(name);
+ }
+
+ /** Get the allowed users on a resource.
+ * Returns null if the resource is null or if there were no settings.
+ *
+ * @param resource
+ * @return RequestAuthorization
+ */
+ public static AuthPolicy allowedUsers(Resource resource) {
+ if ( resource == null )
+ return null;
+ Collection<RDFNode> allowedUsers = BuildLib.getAll(resource, "fu:"+pAllowedUsers.getLocalName());
+ if ( allowedUsers == null )
+ // Indicate no settings.
+ return null;
+ // Check all values are simple strings
+ List<String> bad = allowedUsers.stream()
+ .map(RDFNode::asNode)
+ .filter(rn -> ! Util.isSimpleString(rn))
+ .map(rn->rn.toString())
+ .collect(toList());
+ if ( ! bad.isEmpty() ) {
+ //Fuseki.configLog.error(format("User names must be a simple string: bad = %s", bad));
+ throw new FusekiConfigException(format("User names should be a simple string: bad = %s", bad));
+ }
+ // RDFNodes/literals to strings.
+ Collection<String> userNames = allowedUsers.stream()
+ .map(RDFNode::asNode)
+ .map(Node::getLiteralLexicalForm)
+ .collect(toList());
+ return Auth.policyAllowSpecific(userNames);
+ }
+
/**
- * Process a configuration file and return the {@link DataAccessPoint
- * DataAccessPoints}; set the context provided for server-wide settings.
- *
+ * Process a configuration file and return the {@link DataAccessPoint DataAccessPoints};
+ * set the context provided for server-wide settings.
+ *
* This bundles together the steps:
* <ul>
* <li>{@link #findServer}
@@ -73,13 +190,13 @@ public class FusekiConfig {
* <li>{@link #processLoadClass} (legacy)
* <li>{@link #servicesAndDatasets}
* </ul>
- */
+ */
public static List<DataAccessPoint> processServerConfiguration(Model configuration, Context context) {
- Resource server = FusekiConfig.findServer(configuration);
- FusekiConfig.processContext(server, context);
- FusekiConfig.processLoadClass(server);
+ Resource server = findServer(configuration);
+ processContext(server, context);
+ processLoadClass(server);
// Process services, whether via server ja:services or, if absent, by finding by type.
- List<DataAccessPoint> x = FusekiConfig.servicesAndDatasets(configuration);
+ List<DataAccessPoint> x = servicesAndDatasets(configuration);
return x;
}
@@ -87,7 +204,7 @@ public class FusekiConfig {
* Process a configuration file, starting {@code server}.
* Return the {@link DataAccessPoint DataAccessPoints}
* set the context provided for server-wide settings.
- *
+ *
* This bundles together the steps:
* <ul>
* <li>{@link #findServer}
@@ -95,13 +212,13 @@ public class FusekiConfig {
* <li>{@link #processLoadClass} (legacy)
* <li>{@link #servicesAndDatasets}
* </ul>
- */
+ */
public static List<DataAccessPoint> processServerConfiguration(Resource server, Context context) {
Objects.requireNonNull(server);
- FusekiConfig.processContext(server, context);
- FusekiConfig.processLoadClass(server);
+ processContext(server, context);
+ processLoadClass(server);
// Process services, whether via server ja:services or, if absent, by finding by type.
- List<DataAccessPoint> x = FusekiConfig.servicesAndDatasets(server);
+ List<DataAccessPoint> x = servicesAndDatasets(server);
return x;
}
@@ -111,248 +228,288 @@ public class FusekiConfig {
* Raises {@link FusekiConfigException} is there are more than one.
*/
public static Resource findServer(Model model) {
- List<Resource> servers = GraphUtils.listResourcesByType(model, FusekiVocab.tServer) ;
+ List<Resource> servers = GraphUtils.listResourcesByType(model, FusekiVocab.tServer);
if ( servers.size() == 0 )
// "No server" is fine.
return null;
if ( servers.size() > 1 )
throw new FusekiConfigException(servers.size()
- + " servers found (must be exactly one in a configuration file)") ;
+ + " servers found (must be exactly one in a configuration file)");
// ---- Server
- Resource server = servers.get(0) ;
- return server ;
+ Resource server = servers.get(0);
+ return server;
}
-
+
/**
- * Process the configuration file declarations for {@link Context} settings.
+ * Process the configuration file declarations for {@link Context} settings.
*/
public static void processContext(Resource server, Context cxt) {
if ( server == null )
- return ;
- AssemblerUtils.setContext(server, cxt) ;
+ return;
+ AssemblerUtils.setContext(server, cxt);
}
-
+
/**
* Process any {@code ja:loadClass}
*/
public static void processLoadClass(Resource server) {
if ( server == null )
- return ;
- StmtIterator sIter = server.listProperties(JA.loadClass) ;
- for ( ; sIter.hasNext() ; ) {
- Statement s = sIter.nextStatement() ;
- RDFNode rn = s.getObject() ;
- String className = null ;
+ return;
+ StmtIterator sIter = server.listProperties(JA.loadClass);
+ for (; sIter.hasNext(); ) {
+ Statement s = sIter.nextStatement();
+ RDFNode rn = s.getObject();
+ String className = null;
if ( rn instanceof Resource ) {
- String uri = ((Resource)rn).getURI() ;
+ String uri = ((Resource)rn).getURI();
if ( uri == null ) {
- log.warn("Blank node for class to load") ;
- continue ;
+ log.warn("Blank node for class to load");
+ continue;
}
- String javaScheme = "java:" ;
+ String javaScheme = "java:";
if ( !uri.startsWith(javaScheme) ) {
- log.warn("Class to load is not 'java:': " + uri) ;
- continue ;
+ log.warn("Class to load is not 'java:': " + uri);
+ continue;
}
- className = uri.substring(javaScheme.length()) ;
+ className = uri.substring(javaScheme.length());
}
if ( rn instanceof Literal )
- className = ((Literal)rn).getLexicalForm() ;
- /* Loader. */loadAndInit(className) ;
+ className = ((Literal)rn).getLexicalForm();
+ /* Loader. */loadAndInit(className);
}
}
-
+
/** Find and process datasets and services in a configuration file.
* This can be a Fuseki server configuration file or a services-only configuration file.
- * It looks {@code fuseki:services ( .... )} then, if not found, all {@code rtdf:type fuseki:services}.
+ * It looks {@code fuseki:services ( .... )} then, if not found, all {@code rtdf:type fuseki:services}.
* @see #processServerConfiguration
*/
public static List<DataAccessPoint> servicesAndDatasets(Model model) {
Resource server = findServer(model);
return servicesAndDatasets$(server, model);
}
-
+
/** Find and process datasets and services in a configuration file
* starting from {@code server} which can have a {@code fuseki:services ( .... )}
- * but, if not found, all {@code rtdf:type fuseki:services} are processed.
+ * but, if not found, all {@code rtdf:type fuseki:services} are processed.
*/
public static List<DataAccessPoint> servicesAndDatasets(Resource server) {
Objects.requireNonNull(server);
return servicesAndDatasets$(server, server.getModel());
- }
-
- private static List<DataAccessPoint> servicesAndDatasets$(Resource server, Model model) {
- DatasetDescriptionRegistry dsDescMap = new DatasetDescriptionRegistry();
+ }
+
+ private static List<DataAccessPoint> servicesAndDatasets$(Resource server, Model model) {
+ DatasetDescriptionMap dsDescMap = new DatasetDescriptionMap();
// ---- Services
// Server to services.
- ResultSet rs = FusekiBuildLib.query("SELECT * { ?s fu:services [ list:member ?service ] }", model, "s", server) ;
- List<DataAccessPoint> accessPoints = new ArrayList<>() ;
+ ResultSet rs = BuildLib.query("SELECT * { ?s fu:services [ list:member ?service ] }", model, "s", server);
+ List<DataAccessPoint> accessPoints = new ArrayList<>();
// If none, look for services by type.
if ( ! rs.hasNext() )
// No "fu:services ( .... )" so try looking for services directly.
- // This means Fuseki2, service configuration files (no server section) work for --conf.
- rs = FusekiBuildLib.query("SELECT ?service { ?service a fu:Service }", model) ;
+ // This means Fuseki2, service configuration files (no server section) work for --conf.
+ rs = BuildLib.query("SELECT ?service { ?service a fu:Service }", model);
// rs is a result set of services to process.
- for ( ; rs.hasNext() ; ) {
- QuerySolution soln = rs.next() ;
- Resource svc = soln.getResource("service") ;
- DataAccessPoint acc = buildDataAccessPoint(svc, dsDescMap) ;
- accessPoints.add(acc) ;
+ for (; rs.hasNext(); ) {
+ QuerySolution soln = rs.next();
+ Resource svc = soln.getResource("service");
+ DataAccessPoint acc = buildDataAccessPoint(svc, dsDescMap);
+ accessPoints.add(acc);
}
- return accessPoints ;
+ return accessPoints;
}
-
+
private static void loadAndInit(String className) {
try {
- Class<? > classObj = Class.forName(className) ;
- log.info("Loaded " + className) ;
- Method initMethod = classObj.getMethod("init") ;
- initMethod.invoke(null) ;
+ Class<? > classObj = Class.forName(className);
+ log.info("Loaded " + className);
+ Method initMethod = classObj.getMethod("init");
+ initMethod.invoke(null);
}
catch (ClassNotFoundException ex) {
- log.warn("Class not found: " + className) ;
+ log.warn("Class not found: " + className);
}
catch (Exception e) {
- throw new FusekiConfigException(e) ;
+ throw new FusekiConfigException(e);
}
}
-
+
private static Model readAssemblerFile(String filename) {
- return AssemblerUtils.readAssemblerFile(filename) ;
+ return AssemblerUtils.readAssemblerFile(filename);
}
-
+
// ---- Directory of assemblers
-
- /** Read service descriptions in the given directory */
+
+ /** Read service descriptions in the given directory */
public static List<DataAccessPoint> readConfigurationDirectory(String dir) {
- Path pDir = Paths.get(dir).normalize() ;
- File dirFile = pDir.toFile() ;
+ Path pDir = Paths.get(dir).normalize();
+ File dirFile = pDir.toFile();
if ( ! dirFile.exists() ) {
- log.warn("Not found: directory for assembler files for services: '"+dir+"'") ;
- return Collections.emptyList() ;
+ log.warn("Not found: directory for assembler files for services: '"+dir+"'");
+ return Collections.emptyList();
}
if ( ! dirFile.isDirectory() ) {
- log.warn("Not a directory: '"+dir+"'") ;
- return Collections.emptyList() ;
+ log.warn("Not a directory: '"+dir+"'");
+ return Collections.emptyList();
}
// Files that are not hidden.
DirectoryStream.Filter<Path> filter = (entry)-> {
- File f = entry.toFile() ;
+ File f = entry.toFile();
final Lang lang = filenameToLang(f.getName());
- return ! f.isHidden() && f.isFile() && lang != null && isRegistered(lang) ;
- } ;
+ return ! f.isHidden() && f.isFile() && lang != null && isRegistered(lang);
+ };
- List<DataAccessPoint> dataServiceRef = new ArrayList<>() ;
+ List<DataAccessPoint> dataServiceRef = new ArrayList<>();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(pDir, filter)) {
for ( Path p : stream ) {
- DatasetDescriptionRegistry dsDescMap = new DatasetDescriptionRegistry() ;
- String fn = IRILib.filenameToIRI(p.toString()) ;
+ DatasetDescriptionMap dsDescMap = new DatasetDescriptionMap();
+ String fn = IRILib.filenameToIRI(p.toString());
log.info("Load configuration: "+fn);
- Model m = readAssemblerFile(fn) ;
- readConfiguration(m, dsDescMap, dataServiceRef) ;
+ Model m = readAssemblerFile(fn);
+ readConfiguration(m, dsDescMap, dataServiceRef);
}
} catch (IOException ex) {
log.warn("IOException:"+ex.getMessage(), ex);
}
- return dataServiceRef ;
+ return dataServiceRef;
}
/** Read a configuration in a model.
* Allow dataset descriptions to be carried over from another place.
- * Add to a list.
+ * Add to a list.
*/
- private static void readConfiguration(Model m, DatasetDescriptionRegistry dsDescMap, List<DataAccessPoint> dataServiceRef) {
- List<Resource> services = GraphUtils.listResourcesByType(m, FusekiVocab.fusekiService) ;
+ private static void readConfiguration(Model m, DatasetDescriptionMap dsDescMap, List<DataAccessPoint> dataServiceRef) {
+ List<Resource> services = GraphUtils.listResourcesByType(m, FusekiVocab.fusekiService);
if ( services.size() == 0 ) {
- log.error("No services found") ;
- throw new FusekiConfigException() ;
+ log.error("No services found");
+ throw new FusekiConfigException();
}
for ( Resource service : services ) {
- DataAccessPoint acc = buildDataAccessPoint(service, dsDescMap) ;
- dataServiceRef.add(acc) ;
+ DataAccessPoint acc = buildDataAccessPoint(service, dsDescMap);
+ dataServiceRef.add(acc);
}
}
-
- /** Build a DataAccessPoint, including DataService, from the description at Resource svc */
- public static DataAccessPoint buildDataAccessPoint(Resource svc, DatasetDescriptionRegistry dsDescMap) {
- RDFNode n = FusekiBuildLib.getOne(svc, "fu:name") ;
+
+ /** Build a DataAccessPoint, including DataService, from the description at Resource svc */
+ public static DataAccessPoint buildDataAccessPoint(Resource svc, DatasetDescriptionMap dsDescMap) {
+ RDFNode n = BuildLib.getOne(svc, "fu:name");
if ( ! n.isLiteral() )
throw new FusekiConfigException("Not a literal for access point name: "+FmtUtils.stringForRDFNode(n));
- Literal object = n.asLiteral() ;
-
+ Literal object = n.asLiteral();
+
if ( object.getDatatype() != null && ! object.getDatatype().equals(XSDDatatype.XSDstring) )
Fuseki.configLog.error(format("Service name '%s' is not a string", FmtUtils.stringForRDFNode(object)));
- String name = object.getLexicalForm() ;
- name = DataAccessPoint.canonical(name) ;
- DataService dataService = buildDataService(svc, dsDescMap) ;
- AuthPolicy allowedUsers = FusekiBuilder.allowedUsers(svc);
+ String name = object.getLexicalForm();
+ name = DataAccessPoint.canonical(name);
+ DataService dataService = buildDataService(svc, dsDescMap);
+ AuthPolicy allowedUsers = allowedUsers(svc);
dataService.setAuthPolicy(allowedUsers);
- DataAccessPoint dataAccess = new DataAccessPoint(name, dataService) ;
- return dataAccess ;
+ DataAccessPoint dataAccess = new DataAccessPoint(name, dataService);
+ return dataAccess;
}
-
+
/** Build a DatasetRef starting at Resource svc, having the services as described by the descriptions. */
- private static DataService buildDataService(Resource svc, DatasetDescriptionRegistry dsDescMap) {
- Resource datasetDesc = ((Resource)FusekiBuildLib.getOne(svc, "fu:dataset")) ;
-
+ private static DataService buildDataService(Resource svc, DatasetDescriptionMap dsDescMap) {
+ Resource datasetDesc = ((Resource)BuildLib.getOne(svc, "fu:dataset"));
+
Dataset ds = getDataset(datasetDesc, dsDescMap);
-
- // In case the assembler included ja:contents
- DataService dataService = new DataService(ds.asDatasetGraph()) ;
-
- FusekiBuilder.addServiceEP(dataService, Operation.Query, svc, pServiceQueryEP) ;
- FusekiBuilder.addServiceEP(dataService, Operation.Update, svc, pServiceUpdateEP) ;
- FusekiBuilder.addServiceEP(dataService, Operation.Upload, svc, pServiceUploadEP);
- FusekiBuilder.addServiceEP(dataService, Operation.GSP_R, svc, pServiceReadGraphStoreEP) ;
- FusekiBuilder.addServiceEP(dataService, Operation.GSP_RW, svc, pServiceReadWriteGraphStoreEP) ;
-
- FusekiBuilder.addServiceEP(dataService, Operation.Quads_R, svc, pServiceReadQuadsEP) ;
- FusekiBuilder.addServiceEP(dataService, Operation.Quads_RW, svc, pServiceReadWriteQuadsEP) ;
-
- // Quads - actions directly on the dataset URL are different.
- // In the config file they are also implicit when using GSP.
+ DataService dataService = new DataService(ds.asDatasetGraph());
+ Set<Endpoint> endpoints = new HashSet<>();
- if ( ! dataService.getEndpoints(Operation.GSP_RW).isEmpty() || ! dataService.getEndpoints(Operation.Quads_RW).isEmpty() ) {
- // ReadWrite available.
- // Dispatch needs introspecting on the HTTP request.
- dataService.addEndpoint(Operation.DatasetRequest_RW, "") ;
- } else if ( ! dataService.getEndpoints(Operation.GSP_R).isEmpty() || ! dataService.getEndpoints(Operation.Quads_R).isEmpty() ) {
- // Read-only available.
- // Dispatch needs introspecting on the HTTP request.
- dataService.addEndpoint(Operation.DatasetRequest_R, "") ;
- }
-
- // XXX
- // This needs sorting out -- here, it is only on the whole server, not per dataset or even per service.
+ accEndpoint(endpoints, Operation.Query, svc, pServiceQueryEP);
+ accEndpoint(endpoints, Operation.Update, svc, pServiceUpdateEP);
+ accEndpoint(endpoints, Operation.Upload, svc, pServiceUploadEP);
+ accEndpoint(endpoints, Operation.GSP_R, svc, pServiceReadGraphStoreEP);
+ accEndpoint(endpoints, Operation.GSP_RW, svc, pServiceReadWriteGraphStoreEP);
+
+ endpoints.forEach(dataService::addEndpoint);
+
+ // TODO
+ // Setting timeout. This needs sorting out -- here, it is only on the whole server, not per dataset or even per service.
// // Extract timeout overriding configuration if present.
// if ( svc.hasProperty(FusekiVocab.pAllowTimeoutOverride) ) {
-// sDesc.allowTimeoutOverride = svc.getProperty(FusekiVocab.pAllowTimeoutOverride).getObject().asLiteral().getBoolean() ;
+// sDesc.allowTimeoutOverride = svc.getProperty(FusekiVocab.pAllowTimeoutOverride).getObject().asLiteral().getBoolean();
// if ( svc.hasProperty(FusekiVocab.pMaximumTimeoutOverride) ) {
-// sDesc.maximumTimeoutOverride = (int)(svc.getProperty(FusekiVocab.pMaximumTimeoutOverride).getObject().asLiteral().getFloat() * 1000) ;
+// sDesc.maximumTimeoutOverride = (int)(svc.getProperty(FusekiVocab.pMaximumTimeoutOverride).getObject().asLiteral().getFloat() * 1000);
// }
// }
- return dataService ;
+ return dataService;
+ }
+
+ private static boolean endpointsContains(Collection<Endpoint> endpoints, Operation operation) {
+ return endpoints.stream().anyMatch(ep->operation.equals(ep.getOperation()));
+ }
+
+ private static void accEndpoint(Collection<Endpoint> endpoints, Operation operation, Resource svc, Property property) {
+ String p = "<"+property.getURI()+">";
+ ResultSet rs = BuildLib.query("SELECT * { ?svc " + p + " ?ep}", svc.getModel(), "svc", svc);
+ for (; rs.hasNext(); ) {
+ QuerySolution soln = rs.next();
+ // No policy yet - set below if one is found.
+ AuthPolicy authPolicy = null;
+ RDFNode ep = soln.get("ep");
+ String epName = null;
+ if ( ep.isLiteral() )
+ epName = soln.getLiteral("ep").getLexicalForm();
+ else if ( ep.isResource() ) {
+ Resource r = (Resource)ep;
+ try {
+ // Look for possible:
+ // [ fuseki:name ""; fuseki:allowedUsers ( "" "" ) ]
+ epName = r.getProperty(FusekiVocab.pServiceName).getString();
+ List<RDFNode> x = GraphUtils.multiValue(r, FusekiVocab.pAllowedUsers);
+ if ( x.size() > 1 )
+ throw new FusekiConfigException("Multiple fuseki:"+FusekiVocab.pAllowedUsers.getLocalName()+" for "+r);
+ if ( ! x.isEmpty() )
+ authPolicy = allowedUsers(r);
+ } catch(JenaException | ClassCastException ex) {
+ throw new FusekiConfigException("Failed to parse endpoint: "+r);
+ }
+ } else {
+ throw new FusekiConfigException("Unrecognized: "+ep);
+ }
+
+ if ( StringUtils.isEmpty(epName) )
+ epName = null;
+ Endpoint endpoint = new Endpoint(operation, epName, authPolicy);
+ endpoints.add(endpoint);
+ }
}
- public static Dataset getDataset(Resource datasetDesc, DatasetDescriptionRegistry dsDescMap) {
+ private static void accEndpoint(Collection<Endpoint> endpoints, Operation operation) {
+ accEndpoint(endpoints, operation, null);
+ }
+
+ private static void accEndpoint(Collection<Endpoint> endpoints, Operation operation, String endpointName) {
+ accEndpoint(endpoints, operation, endpointName, null);
+ }
+
+ private static void accEndpoint(Collection<Endpoint> endpoints, Operation operation, String endpointName, AuthPolicy authPolicy) {
+ if ( StringUtils.isEmpty(endpointName) )
+ endpointName = null;
+ Endpoint endpoint = new Endpoint(operation, endpointName, authPolicy);
+ endpoints.add(endpoint);
+ }
+
+ public static Dataset getDataset(Resource datasetDesc, DatasetDescriptionMap dsDescMap) {
// check if this one already built
Dataset ds = dsDescMap.get(datasetDesc);
if (ds == null) {
// Check if the description is in the model.
if ( !datasetDesc.hasProperty(RDF.type) )
- throw new FusekiConfigException("No rdf:type for dataset " + FusekiBuildLib.nodeLabel(datasetDesc)) ;
+ throw new FusekiConfigException("No rdf:type for dataset " + BuildLib.nodeLabel(datasetDesc));
- // Should have been done already. e.g. ActionDatasets.execPostContainer,
+ // Should have been done already. e.g. ActionDatasets.execPostContainer,
// Assemblerutils.readAssemblerFile < FusekiServer.parseConfigFile.
//AssemblerUtils.addRegistered(datasetDesc.getModel());
- ds = (Dataset)Assembler.general.open(datasetDesc) ;
+ ds = (Dataset)Assembler.general.open(datasetDesc);
}
- // Some kind of check that it is "the same" dataset.
+ // Some kind of check that it is "the same" dataset.
// It can be different if two descriptions in different files have the same URI.
dsDescMap.register(datasetDesc, ds);
return ds;
@@ -363,42 +520,42 @@ public class FusekiConfig {
/** Read the system database */
public static List<DataAccessPoint> readSystemDatabase(Dataset ds) {
// Webapp only.
- DatasetDescriptionRegistry dsDescMap = new DatasetDescriptionRegistry() ;
+ DatasetDescriptionMap dsDescMap = new DatasetDescriptionMap();
String qs = StrUtils.strjoinNL
- (FusekiConst.PREFIXES ,
+ (FusekiPrefixes.PREFIXES ,
"SELECT * {" ,
" GRAPH ?g {",
- " ?s fu:name ?name ;" ,
+ " ?s fu:name ?name;" ,
" fu:status ?status ." ,
" }",
"}"
- ) ;
-
- List<DataAccessPoint> refs = new ArrayList<>() ;
-
- ds.begin(ReadWrite.WRITE) ;
+ );
+
+ List<DataAccessPoint> refs = new ArrayList<>();
+
+ ds.begin(ReadWrite.WRITE);
try {
- ResultSet rs = FusekiBuildLib.query(qs, ds) ;
+ ResultSet rs = BuildLib.query(qs, ds);
- // ResultSetFormatter.out(rs);
+ // ResultSetFormatter.out(rs);
// ((ResultSetRewindable)rs).reset();
- for ( ; rs.hasNext() ; ) {
- QuerySolution row = rs.next() ;
- Resource s = row.getResource("s") ;
- Resource g = row.getResource("g") ;
- Resource rStatus = row.getResource("status") ;
- //String name = row.getLiteral("name").getLexicalForm() ;
- DataServiceStatus status = DataServiceStatus.status(rStatus) ;
+ for (; rs.hasNext(); ) {
+ QuerySolution row = rs.next();
+ Resource s = row.getResource("s");
+ Resource g = row.getResource("g");
+ Resource rStatus = row.getResource("status");
+ //String name = row.getLiteral("name").getLexicalForm();
+ DataServiceStatus status = DataServiceStatus.status(rStatus);
- Model m = ds.getNamedModel(g.getURI()) ;
+ Model m = ds.getNamedModel(g.getURI());
// Rebase the resource of the service description to the containing graph.
- Resource svc = m.wrapAsResource(s.asNode()) ;
- DataAccessPoint ref = buildDataAccessPoint(svc, dsDescMap) ;
- refs.add(ref) ;
+ Resource svc = m.wrapAsResource(s.asNode());
+ DataAccessPoint ref = buildDataAccessPoint(svc, dsDescMap);
+ refs.add(ref);
}
- ds.commit();
- return refs ;
- } finally { ds.end() ; }
+ ds.commit();
+ return refs;
+ } finally { ds.end(); }
}
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiConst.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiPrefixes.java
similarity index 95%
rename from jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiConst.java
rename to jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiPrefixes.java
index 8935029..a4689dd 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiConst.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiPrefixes.java
@@ -20,8 +20,8 @@ package org.apache.jena.fuseki.build;
import org.apache.jena.atlas.lib.StrUtils;
-/** Internal constants */
-public class FusekiConst {
+/** Convenience set of prefixes */
+public class FusekiPrefixes {
public static String PREFIXES = StrUtils.strjoinNL
("BASE <http://example/base#>",
@@ -37,6 +37,6 @@ public class FusekiConst {
"PREFIX apf: <http://jena.apache.org/ARQ/property#>",
"PREFIX afn: <http://jena.apache.org/ARQ/function#>",
"",
- "") ;
+ "");
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionAsyncTask.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionAsyncTask.java
index 4310c6f..2e72ddb 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionAsyncTask.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionAsyncTask.java
@@ -18,39 +18,37 @@
package org.apache.jena.fuseki.ctl;
-import org.apache.jena.atlas.json.JsonValue ;
-import org.apache.jena.atlas.lib.InternalErrorException ;
-import org.apache.jena.fuseki.async.AsyncPool ;
-import org.apache.jena.fuseki.async.AsyncTask ;
-import org.apache.jena.fuseki.servlets.HttpAction ;
-import org.apache.jena.fuseki.servlets.ServletOps ;
-
-/** Base helper class for creating async tasks on "items", based on POST */
+import org.apache.jena.atlas.json.JsonValue;
+import org.apache.jena.atlas.lib.InternalErrorException;
+import org.apache.jena.fuseki.async.AsyncPool;
+import org.apache.jena.fuseki.async.AsyncTask;
+import org.apache.jena.fuseki.servlets.HttpAction;
+
+/** Base helper class for creating async tasks on "items", based on POST */
public abstract class ActionAsyncTask extends ActionItem
{
- public ActionAsyncTask() { super() ; }
-
- @Override
- final
- protected void execGet(HttpAction action) {
- ServletOps.errorMethodNotAllowed(METHOD_GET);
+ private String name;
+
+ public ActionAsyncTask(String name) {
+ super();
+ this.name = name;
}
@Override
final
- protected JsonValue execGetItem(HttpAction action) {
- throw new InternalErrorException("GET for AsyncTask -- Should not be here!") ;
+ protected JsonValue execGetItem(HttpAction action) {
+ throw new InternalErrorException("GET for AsyncTask -- Should not be here!");
}
@Override
final
protected JsonValue execPostItem(HttpAction action) {
- Runnable task = createRunnable(action) ;
- AsyncTask aTask = Async.execASyncTask(action, AsyncPool.get(), "backup", task) ;
+ Runnable task = createRunnable(action);
+ AsyncTask aTask = Async.execASyncTask(action, AsyncPool.get(), name, task);
Async.setLocationHeader(action, aTask);
- return Async.asJson(aTask) ;
+ return Async.asJson(aTask);
}
-
- protected abstract Runnable createRunnable(HttpAction action) ;
+
+ protected abstract Runnable createRunnable(HttpAction action);
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionContainerItem.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionContainerItem.java
index 224c2f3..1d8c0e7 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionContainerItem.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionContainerItem.java
@@ -18,101 +18,95 @@
package org.apache.jena.fuseki.ctl;
-import javax.servlet.http.HttpServletRequest ;
-import javax.servlet.http.HttpServletResponse ;
+import static org.apache.jena.riot.web.HttpNames.METHOD_DELETE;
+import static org.apache.jena.riot.web.HttpNames.METHOD_GET;
+import static org.apache.jena.riot.web.HttpNames.METHOD_POST;
-import org.apache.jena.atlas.json.JsonValue ;
-import org.apache.jena.fuseki.servlets.HttpAction ;
-import org.apache.jena.fuseki.servlets.ServletOps ;
-import org.apache.jena.web.HttpSC ;
+import org.apache.jena.atlas.json.JsonValue;
+import org.apache.jena.fuseki.servlets.ActionLib;
+import org.apache.jena.fuseki.servlets.HttpAction;
+import org.apache.jena.fuseki.servlets.ServletOps;
+import org.apache.jena.web.HttpSC;
-/** Base for actions that are container and also have actions on items */
+/** Base for actions that are container and also have actions on items */
public abstract class ActionContainerItem extends ActionCtl {
-
- public ActionContainerItem() { super() ; }
- // Redirect operations so they dispatch to perform(HttpAction)
- @Override
- final protected void doGet(HttpServletRequest request, HttpServletResponse response) {
- doCommon(request, response);
- }
+ protected ActionContainerItem() { super(); }
@Override
- final protected void doPost(HttpServletRequest request, HttpServletResponse response) {
- doCommon(request, response);
- }
-
- @Override
- final protected void doHead(HttpServletRequest request, HttpServletResponse response) {
- doCommon(request, response);
- }
-
- @Override
- final protected void doDelete(HttpServletRequest request, HttpServletResponse response) {
- doCommon(request, response);
- }
-
- @Override
final
- protected void perform(HttpAction action) {
- String method = action.request.getMethod() ;
+ public void execute(HttpAction action) {
+ String method = action.request.getMethod();
if ( method.equals(METHOD_GET) )
- execGet(action) ;
+ performGet(action);
else if ( method.equals(METHOD_POST) )
- execPost(action) ;
+ performPost(action);
else if ( method.equals(METHOD_DELETE) )
- execDelete(action) ;
+ performDelete(action);
else
- ServletOps.error(HttpSC.METHOD_NOT_ALLOWED_405) ;
+ ServletOps.error(HttpSC.METHOD_NOT_ALLOWED_405);
+ }
+
+
+ @Override
+ public void execOptions(HttpAction action) {
+ ActionLib.doOptionsGetPostDeleteHead(action);
+ ServletOps.success(action);
}
- protected void execGet(HttpAction action) {
- JsonValue v ;
+ final
+ // Container action if the name used to route to the servlet has more path.
+ protected boolean isContainerAction(HttpAction action) {
+ return (getItemName(action) == null );
+ }
+
+ protected void performGet(HttpAction action) {
+ JsonValue v;
if ( isContainerAction(action) )
- v = execGetContainer(action) ;
+ v = execGetContainer(action);
else
- v = execGetItem(action) ;
-
+ v = execGetItem(action);
+
ServletOps.sendJsonReponse(action, v);
}
-
- /** GET request on the container - respond with JSON, or null for plain 200 */
- protected abstract JsonValue execGetContainer(HttpAction action) ;
- /** GET request on an item in the container - respond with JSON, or null for plain 200 */
- protected abstract JsonValue execGetItem(HttpAction action) ;
-
- protected void execPost(HttpAction action) {
- JsonValue v ;
+
+ /** GET request on the container - respond with JSON, or null for plain 200 */
+ protected abstract JsonValue execGetContainer(HttpAction action);
+ /** GET request on an item in the container - respond with JSON, or null for plain 200 */
+ protected abstract JsonValue execGetItem(HttpAction action);
+
+ protected void performPost(HttpAction action) {
+ JsonValue v;
if ( isContainerAction(action) )
- v = execPostContainer(action) ;
+ v = execPostContainer(action);
else
- v = execPostItem(action) ;
-
+ v = execPostItem(action);
+
ServletOps.sendJsonReponse(action, v);
}
-
- /** POST request on the container - respond with JSON, or null for plain 200 */
- protected abstract JsonValue execPostContainer(HttpAction action) ;
- /** POST request on an item in the container - respond with JSON, or null for plain 200 */
- protected abstract JsonValue execPostItem(HttpAction action) ;
-
+ /** POST request on the container - respond with JSON, or null for plain 200 */
+ protected abstract JsonValue execPostContainer(HttpAction action);
+ /** POST request on an item in the container - respond with JSON, or null for plain 200 */
+ protected abstract JsonValue execPostItem(HttpAction action);
+
+
/** DELETE request */
- protected void execDelete(HttpAction action) {
+ protected void performDelete(HttpAction action) {
if ( isContainerAction(action) )
- execDeleteContainer(action) ;
- else
- execDeleteItem(action) ;
- ServletOps.success(action) ;
+ execDeleteContainer(action);
+ else
+ execDeleteItem(action);
+ ServletOps.success(action);
}
-
+
/** DELETE request on an item in the container */
protected void execDeleteContainer(HttpAction action) {
- ServletOps.errorMethodNotAllowed(METHOD_DELETE, "DELETE applied to a container") ;
+ ServletOps.errorMethodNotAllowed(METHOD_DELETE, "DELETE applied to a container");
}
/** DELETE request on an item in the container */
protected void execDeleteItem(HttpAction action) {
- ServletOps.errorMethodNotAllowed(METHOD_DELETE) ;
+ ServletOps.errorMethodNotAllowed(METHOD_DELETE);
}
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionCtl.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionCtl.java
index 9ed6293..c887352 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionCtl.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionCtl.java
@@ -18,68 +18,80 @@
package org.apache.jena.fuseki.ctl;
-import org.apache.jena.fuseki.Fuseki ;
-import org.apache.jena.fuseki.server.DataAccessPoint ;
-import org.apache.jena.fuseki.servlets.ActionBase ;
-import org.apache.jena.fuseki.servlets.HttpAction ;
-import org.apache.jena.fuseki.servlets.ServletOps ;
+import org.apache.jena.fuseki.Fuseki;
+import org.apache.jena.fuseki.server.DataAccessPoint;
+import org.apache.jena.fuseki.servlets.ActionLifecycle;
+import org.apache.jena.fuseki.servlets.HttpAction;
+import org.apache.jena.fuseki.servlets.ServletProcessor;
+import org.apache.jena.sparql.core.DatasetGraph;
-/** Control/admin request lifecycle */
-public abstract class ActionCtl extends ActionBase {
+/**
+ * Base class for control actions. These are servlets and do not go through Fuseki
+ * dynamic dispatch. No statistics.
+ */
+public abstract class ActionCtl extends ServletProcessor implements ActionLifecycle {
+ protected ActionCtl() {
+ super(Fuseki.adminLog);
+ }
- protected ActionCtl() { super(Fuseki.adminLog) ; }
-
@Override
- final
- protected void execCommonWorker(HttpAction action) {
- DataAccessPoint dataAccessPoint ;
-
- String datasetUri = mapRequestToDatasetName(action) ;
- if ( datasetUri != null ) {
- dataAccessPoint = action.getDataAccessPointRegistry().get(datasetUri) ;
- if ( dataAccessPoint == null ) {
- ServletOps.errorNotFound("Not found: "+datasetUri) ;
- return ;
- }
- }
- else {
- // This is a placeholder when creating new DatasetRefs
- // and also if addressing a container, not a dataset
- dataAccessPoint = null ;
- }
-
- action.setControlRequest(dataAccessPoint, datasetUri) ;
- action.setEndpoint(null) ; // No operation or service name.
- executeAction(action) ;
+ final public void process(HttpAction action) {
+ executeLifecycle(action);
}
- protected String mapRequestToDatasetName(HttpAction action) {
- return extractItemName(action) ;
+ /**
+ * Simple execution lifecycle for a SPARQL Request. No statistics.
+ *
+ * @param action
+ */
+ protected void executeLifecycle(HttpAction action) {
+ validate(action);
+ execute(action);
}
- // Possible intercept point
- protected void executeAction(HttpAction action) {
- executeLifecycle(action) ;
+ /** Get the item name - the part after the URI for the servlet (which is the container). */
+ public static String getItemName(HttpAction action) {
+ return action.request.getPathInfo();
}
-
- // This is the service request lifecycle.
- final
- protected void executeLifecycle(HttpAction action) {
- perform(action) ;
+
+ /**
+ * Get the item name - the part after the URI for the servlet (which is
+ * the container) - treated as a dataset name.
+ */
+ public static String getItemDatasetName(HttpAction action) {
+ String x = getItemName(action);
+ if ( x == null )
+ return null;
+ while ( x.startsWith("//") )
+ x = x.substring(1);
+ return DataAccessPoint.canonical(x);
}
-
- final
- protected boolean isContainerAction(HttpAction action) {
- return (action.getDataAccessPoint() == null ) ;
+
+ /**
+ * Get the DataAccessPoint corresponding to the item name, or null.
+ * @see #getItemDatasetName
+ */
+ public static DataAccessPoint getItemDataAccessPoint(HttpAction action) {
+ String name = getItemDatasetName(action);
+ return getItemDataAccessPoint(action, name);
+ }
+
+ /**
+ * Get the DatasetGraph corresponding to the item name, or null.
+ * @see #getItemDatasetName
+ */
+ public static DatasetGraph getItemDataset(HttpAction action) {
+ DataAccessPoint dap = getItemDataAccessPoint(action);
+ if ( dap == null )
+ return null;
+ return dap.getDataService().getDataset();
}
-
- protected abstract void perform(HttpAction action) ;
-// /** Map request to uri in the registry.
-// * null means no mapping done (passthrough).
-// */
-// protected String mapRequestToDataset(HttpAction action)
-// {
-// return ActionLib.mapRequestToDataset(action.request.getRequestURI()) ;
-// }
+ /**
+ * Get the DataAccessPoint corresponding to the item name, or null.
+ * @see #getItemDatasetName
+ */
+ public static DataAccessPoint getItemDataAccessPoint(HttpAction action, String name) {
+ return action.getDataAccessPointRegistry().get(name);
+ }
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionDumpRequest.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionDumpRequest.java
index 88bbdc7..83ac976 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionDumpRequest.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionDumpRequest.java
@@ -50,7 +50,7 @@ public class ActionDumpRequest extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) {
doPrintInformation(req, resp);
}
-
+
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) {
doPrintInformation(req, resp);
@@ -106,7 +106,7 @@ public class ActionDumpRequest extends HttpServlet {
}
// ---- Library of things to report on.
-
+
static public void printRequest(PrintWriter pw, HttpServletRequest req) {
// ----Standard environment
pw.println("Method: " + req.getMethod());
@@ -128,9 +128,9 @@ public class ActionDumpRequest extends HttpServlet {
pw.println("getRemoteHost: " + req.getRemoteHost());
pw.println("getRequestedSessionId: " + req.getRequestedSessionId());
}
-
+
// ---- Library of things to report on.
-
+
static void printBody(PrintWriter pw, HttpServletRequest req) throws IOException {
// Destructive read of the request body.
BufferedReader in = req.getReader();
@@ -150,7 +150,7 @@ public class ActionDumpRequest extends HttpServlet {
if ( c == null )
pw.println("getCookies: <none>");
else {
- for ( int i = 0 ; i < c.length ; i++ ) {
+ for ( int i = 0; i < c.length; i++ ) {
pw.println();
pw.println("Cookie: " + c[i].getName());
pw.println(" value: " + c[i].getValue());
@@ -167,7 +167,7 @@ public class ActionDumpRequest extends HttpServlet {
static void printHeaders(PrintWriter pw, HttpServletRequest req) {
Enumeration<String> en = req.getHeaderNames();
- for ( ; en.hasMoreElements() ; ) {
+ for (; en.hasMoreElements(); ) {
String name = en.nextElement();
String value = req.getHeader(name);
pw.println("Head: " + name + " = " + value);
@@ -177,25 +177,24 @@ public class ActionDumpRequest extends HttpServlet {
// Note that doing this on a form causes the forms content (body) to be read
// and parsed as form variables.
static void printParameters(PrintWriter pw, HttpServletRequest req) {
- Enumeration<String> en = req.getParameterNames() ;
- for ( ; en.hasMoreElements() ; )
- {
- String name = en.nextElement() ;
- String value = req.getParameter(name) ;
- pw.println("Param: "+name + " = " + value) ;
+ Enumeration<String> en = req.getParameterNames();
+ for (; en.hasMoreElements(); ) {
+ String name = en.nextElement();
+ String value = req.getParameter(name);
+ pw.println("Param: " + name + " = " + value);
}
}
-
+
static void printQueryString(PrintWriter pw, HttpServletRequest req) {
- Multimap<String, String> map = FusekiNetLib.parseQueryString(req) ;
+ Multimap<String, String> map = FusekiNetLib.parseQueryString(req);
for ( String name : map.keys() )
for ( String value : map.get(name) )
- pw.println("Param: "+name + " = " + value) ;
+ pw.println("Param: "+name + " = " + value);
}
-
+
static void printLocales(PrintWriter pw, HttpServletRequest req) {
Enumeration<Locale> en = req.getLocales();
- for ( ; en.hasMoreElements() ; ) {
+ for (; en.hasMoreElements(); ) {
String name = en.nextElement().toString();
pw.println("Locale: " + name);
}
@@ -204,7 +203,7 @@ public class ActionDumpRequest extends HttpServlet {
/**
* <code>printEnvironment</code>
- *
+ *
* @return String that is the HTML of the System properties as name/value pairs. The
* values are with single quotes independent of whether or not the value has
* single quotes in it.
@@ -225,7 +224,7 @@ public class ActionDumpRequest extends HttpServlet {
return null;
}
}
-
+
public String printServletContext() {
try (StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw);) {
ServletContext sc = getServletContext();
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionItem.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionItem.java
index ea015e5..c2b4100 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionItem.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionItem.java
@@ -18,29 +18,29 @@
package org.apache.jena.fuseki.ctl;
-import org.apache.jena.atlas.json.JsonValue ;
+import org.apache.jena.atlas.json.JsonValue;
import org.apache.jena.fuseki.ctl.ActionContainerItem;
import org.apache.jena.fuseki.servlets.HttpAction;
import org.apache.jena.fuseki.servlets.ServletOps;
-import org.apache.jena.web.HttpSC ;
+import org.apache.jena.web.HttpSC;
-/** Action on items in a container, but not the container itself */
+/** Action on items in a container, but not the container itself */
public abstract class ActionItem extends ActionContainerItem
{
- public ActionItem() { super() ; }
-
+ public ActionItem() { super(); }
+
@Override
final
protected JsonValue execGetContainer(HttpAction action) {
- ServletOps.error(HttpSC.METHOD_NOT_ALLOWED_405) ;
- return null ;
+ ServletOps.error(HttpSC.METHOD_NOT_ALLOWED_405);
+ return null;
}
@Override
final
protected JsonValue execPostContainer(HttpAction action) {
- ServletOps.error(HttpSC.METHOD_NOT_ALLOWED_405) ;
- return null ;
+ ServletOps.error(HttpSC.METHOD_NOT_ALLOWED_405);
+ return null;
}
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionMetrics.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionMetrics.java
index cecf576..d488938 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionMetrics.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionMetrics.java
@@ -17,29 +17,32 @@
*/
package org.apache.jena.fuseki.ctl;
-import java.io.IOException;
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
import org.apache.jena.fuseki.metrics.MetricsProviderRegistry;
+import org.apache.jena.fuseki.servlets.ActionLib;
import org.apache.jena.fuseki.servlets.HttpAction;
+import org.apache.jena.fuseki.servlets.ServletOps;
public class ActionMetrics extends ActionCtl {
- @Override
- public void init(ServletConfig config) throws ServletException {
- super.init( config );
+ public ActionMetrics() { super(); }
+ @Override
+ public void execGet(HttpAction action) {
+ super.executeLifecycle(action);
}
@Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- super.doCommon(req, resp);
+ public void execOptions(HttpAction action) {
+ ActionLib.doOptionsGet(action);
+ ServletOps.success(action);
}
@Override
- protected void perform(HttpAction action) {
+ public void validate(HttpAction action) {}
+
+ @Override
+ public void execute(HttpAction action) {
MetricsProviderRegistry.get().scrape( action );
+ ServletOps.success(action);
}
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionPing.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionPing.java
index 2e43b22..8f3097f 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionPing.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionPing.java
@@ -18,55 +18,55 @@
package org.apache.jena.fuseki.ctl;
-import static org.apache.jena.riot.WebContent.charsetUTF8 ;
-import static org.apache.jena.riot.WebContent.contentTypeTextPlain ;
+import static org.apache.jena.riot.WebContent.charsetUTF8;
+import static org.apache.jena.riot.WebContent.contentTypeTextPlain;
-import java.io.IOException ;
+import java.io.IOException;
-import javax.servlet.ServletOutputStream ;
-import javax.servlet.http.HttpServlet ;
-import javax.servlet.http.HttpServletRequest ;
-import javax.servlet.http.HttpServletResponse ;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
-import org.apache.jena.atlas.lib.DateTimeUtils ;
-import org.apache.jena.fuseki.Fuseki ;
-import org.apache.jena.fuseki.servlets.ServletOps ;
-import org.apache.jena.web.HttpSC ;
+import org.apache.jena.atlas.lib.DateTimeUtils;
+import org.apache.jena.fuseki.Fuseki;
+import org.apache.jena.fuseki.servlets.ServletOps;
+import org.apache.jena.web.HttpSC;
/** The ping servlet provides a low cost, uncached endpoint that can be used
* to determine if this component is running and responding. For example,
- * a nagios check should use this endpoint.
+ * a nagios check should use this endpoint.
*/
public class ActionPing extends HttpServlet
{
// Ping is special.
// To avoid excessive logging and id allocation for a "noise" operation,
// this is a raw servlet.
- public ActionPing() { super() ; }
-
+ public ActionPing() { super(); }
+
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
- doCommon(req, resp);
+ doCommon(req, resp);
}
-
+
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
- doCommon(req, resp);
+ doCommon(req, resp);
}
-
+
@Override
protected void doHead(HttpServletRequest req, HttpServletResponse resp) {
- doCommon(req, resp);
+ doCommon(req, resp);
}
protected void doCommon(HttpServletRequest request, HttpServletResponse response) {
try {
- ServletOps.setNoCache(response) ;
+ ServletOps.setNoCache(response);
response.setContentType(contentTypeTextPlain);
- response.setCharacterEncoding(charsetUTF8) ;
+ response.setCharacterEncoding(charsetUTF8);
response.setStatus(HttpSC.OK_200);
- ServletOutputStream out = response.getOutputStream() ;
+ ServletOutputStream out = response.getOutputStream();
out.println(DateTimeUtils.nowAsXSDDateTimeString());
} catch (IOException ex) {
Fuseki.serverLog.warn("ping :: IOException :: "+ex.getMessage());
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionSleep.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionSleep.java
index 1857a05..2f2b3b9 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionSleep.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionSleep.java
@@ -18,75 +18,77 @@
package org.apache.jena.fuseki.ctl;
-import static java.lang.String.format ;
+import static java.lang.String.format;
-import javax.servlet.http.HttpServletRequest ;
-import javax.servlet.http.HttpServletResponse ;
-
-import org.apache.jena.atlas.json.JsonValue ;
-import org.apache.jena.atlas.lib.Lib ;
-import org.apache.jena.fuseki.async.AsyncPool ;
-import org.apache.jena.fuseki.async.AsyncTask ;
-import org.apache.jena.fuseki.servlets.HttpAction ;
-import org.apache.jena.fuseki.servlets.ServletOps ;
-import org.slf4j.Logger ;
+import org.apache.jena.atlas.json.JsonValue;
+import org.apache.jena.atlas.lib.Lib;
+import org.apache.jena.fuseki.async.AsyncPool;
+import org.apache.jena.fuseki.async.AsyncTask;
+import org.apache.jena.fuseki.servlets.ActionLib;
+import org.apache.jena.fuseki.servlets.HttpAction;
+import org.apache.jena.fuseki.servlets.ServletOps;
+import org.slf4j.Logger;
/** A task that kicks off a asynchronous operation that simply waits and exits. For testing. */
public class ActionSleep extends ActionCtl /* Not ActionAsyncTask - that is a container-item based. */
{
- public ActionSleep() { super() ; }
-
- // And only POST
+ public ActionSleep() { super(); }
+
+ @Override
+ public void execOptions(HttpAction action) {
+ ActionLib.doOptionsPost(action);
+ ServletOps.success(action);
+ }
+
@Override
- protected void doPost(HttpServletRequest request, HttpServletResponse response) {
- doCommon(request, response);
+ public void execPost(HttpAction action) {
+ super.executeLifecycle(action);
}
@Override
- protected void perform(HttpAction action) {
- Runnable task = createRunnable(action) ;
- AsyncTask aTask = Async.execASyncTask(action, AsyncPool.get(), "sleep", task) ;
- JsonValue v = Async.asJson(aTask) ;
+ public void validate(HttpAction action) {}
+
+ @Override
+ public void execute(HttpAction action) {
+ Runnable task = createRunnable(action);
+ AsyncTask aTask = Async.execASyncTask(action, AsyncPool.get(), "sleep", task);
+ JsonValue v = Async.asJson(aTask);
Async.setLocationHeader(action, aTask);
ServletOps.sendJsonReponse(action, v);
}
protected Runnable createRunnable(HttpAction action) {
- String name = action.getDatasetName() ;
- if ( name == null )
- name = "''" ;
-
- String interval = action.request.getParameter("interval") ;
- int sleepMilli = 5000 ;
+ String interval = action.request.getParameter("interval");
+ int sleepMilli = 5000;
if ( interval != null )
try {
- sleepMilli = Integer.parseInt(interval) ;
+ sleepMilli = Integer.parseInt(interval);
} catch (NumberFormatException ex) {
- action.log.error(format("[%d] NumberFormatException: %s", action.id, interval)) ;
+ action.log.error(format("[%d] NumberFormatException: %s", action.id, interval));
}
- action.log.info(format("[%d] Sleep %s %d ms", action.id, name, sleepMilli)) ;
- return new SleepTask(action, sleepMilli) ;
+ action.log.info(format("[%d] Sleep %d ms", action.id, sleepMilli));
+ return new SleepTask(action, sleepMilli);
}
static class SleepTask implements Runnable {
- private final Logger log ;
- private final long actionId ;
- private final int sleepMilli ;
-
+ private final Logger log;
+ private final long actionId;
+ private final int sleepMilli;
+
public SleepTask(HttpAction action, int sleepMilli ) {
- this.log = action.log ;
- this.actionId = action.id ;
- this.sleepMilli = sleepMilli ;
+ this.log = action.log;
+ this.actionId = action.id;
+ this.sleepMilli = sleepMilli;
}
@Override
public void run() {
try {
- log.info(format("[%d] >> Sleep start", actionId)) ;
- Lib.sleep(sleepMilli) ;
- log.info(format("[%d] << Sleep finish", actionId)) ;
+ log.info(format("[%d] >> Sleep start", actionId));
+ Lib.sleep(sleepMilli);
+ log.info(format("[%d] << Sleep finish", actionId));
} catch (Exception ex) {
- log.info(format("[%d] **** Exception", actionId), ex) ;
+ log.info(format("[%d] **** Exception", actionId), ex);
}
}
}
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 b6f7430..f3f8151 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
@@ -18,172 +18,189 @@
package org.apache.jena.fuseki.ctl;
-import static java.lang.String.format ;
-import static org.apache.jena.riot.WebContent.charsetUTF8 ;
-import static org.apache.jena.riot.WebContent.contentTypeTextPlain ;
+import static java.lang.String.format;
+import static org.apache.jena.riot.WebContent.charsetUTF8;
+import static org.apache.jena.riot.WebContent.contentTypeTextPlain;
-import java.io.IOException ;
-import java.util.Iterator ;
-import java.util.List ;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
-import javax.servlet.ServletOutputStream ;
-import javax.servlet.http.HttpServletResponse ;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
-import org.apache.jena.atlas.json.JsonBuilder ;
-import org.apache.jena.atlas.json.JsonObject ;
-import org.apache.jena.atlas.json.JsonValue ;
-import org.apache.jena.fuseki.server.* ;
-import org.apache.jena.fuseki.servlets.HttpAction ;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.jena.atlas.json.JsonBuilder;
+import org.apache.jena.atlas.json.JsonObject;
+import org.apache.jena.atlas.json.JsonValue;
+import org.apache.jena.fuseki.server.*;
+import org.apache.jena.fuseki.servlets.HttpAction;
+import org.apache.jena.fuseki.servlets.ServletOps;
public class ActionStats extends ActionContainerItem
{
- public ActionStats() { super() ; }
+ // For endpoint with "" as name.
+ private static String emptyNameKeyPrefix = "_";
+
+ public ActionStats() { super(); }
+
+ @Override
+ public void validate(HttpAction action) {}
// This does not consult the system database for dormant etc.
- protected JsonValue execCommonContainer(HttpAction action) {
- action.log.info(format("[%d] GET stats all", action.id)) ;
- return generateStats(action.getDataAccessPointRegistry()) ;
+ protected JsonValue execCommonContainer(HttpAction action) {
+ action.log.info(format("[%d] GET stats all", action.id));
+ return generateStats(action.getDataAccessPointRegistry());
}
public static JsonObject generateStats(DataAccessPointRegistry registry) {
- JsonBuilder builder = new JsonBuilder() ;
- builder.startObject("top") ;
- builder.key(ServerConst.datasets) ;
- builder.startObject("datasets") ;
+ JsonBuilder builder = new JsonBuilder();
+ builder.startObject("top");
+ builder.key(ServerConst.datasets);
+ builder.startObject("datasets");
registry.forEach((name, access)->statsDataset(builder, access));
- builder.finishObject("datasets") ;
- builder.finishObject("top") ;
- return builder.build().getAsObject() ;
+ builder.finishObject("datasets");
+ builder.finishObject("top");
+ return builder.build().getAsObject();
}
-
+
protected JsonValue execCommonItem(HttpAction action) {
- action.log.info(format("[%d] GET stats dataset %s", action.id, action.getDatasetName())) ;
-
- JsonBuilder builder = new JsonBuilder() ;
- String datasetPath = DataAccessPoint.canonical(action.getDatasetName()) ;
- builder.startObject("TOP") ;
-
- builder.key(ServerConst.datasets) ;
- builder.startObject("datasets") ;
- statsDataset(builder, datasetPath, action.getDataAccessPointRegistry()) ;
- builder.finishObject("datasets") ;
-
- builder.finishObject("TOP") ;
- return builder.build() ;
+ String datasetPath = getItemDatasetName(action);
+ action.log.info(format("[%d] GET stats dataset %s", action.id, datasetPath));
+
+ JsonBuilder builder = new JsonBuilder();
+ DataAccessPoint dap = getItemDataAccessPoint(action, datasetPath);
+ if ( dap == null )
+ ServletOps.errorNotFound(datasetPath);
+ builder.startObject("TOP");
+
+ builder.key(ServerConst.datasets);
+ builder.startObject("datasets");
+ statsDataset(builder, datasetPath, action.getDataAccessPointRegistry());
+ builder.finishObject("datasets");
+
+ builder.finishObject("TOP");
+ return builder.build();
}
-
+
public static JsonObject generateStats(DataAccessPoint access) {
- JsonBuilder builder = new JsonBuilder() ;
- statsDataset(builder, access) ;
- return builder.build().getAsObject() ;
+ JsonBuilder builder = new JsonBuilder();
+ statsDataset(builder, access);
+ return builder.build().getAsObject();
}
-
+
private void statsDataset(JsonBuilder builder, String name, DataAccessPointRegistry registry) {
- DataAccessPoint access = registry.get(name) ;
+ DataAccessPoint access = registry.get(name);
statsDataset(builder, access);
}
-
+
private static void statsDataset(JsonBuilder builder, DataAccessPoint access) {
// Object started
- builder.key(access.getName()) ;
- DataService dSrv = access.getDataService() ;
- builder.startObject("counters") ;
-
- builder.key(CounterName.Requests.getName()).value(dSrv.getCounters().value(CounterName.Requests)) ;
- builder.key(CounterName.RequestsGood.getName()).value(dSrv.getCounters().value(CounterName.RequestsGood)) ;
- builder.key(CounterName.RequestsBad.getName()).value(dSrv.getCounters().value(CounterName.RequestsBad)) ;
-
- builder.key(ServerConst.endpoints).startObject("endpoints") ;
-
+ builder.key(access.getName());
+ DataService dSrv = access.getDataService();
+ builder.startObject("counters");
+
+ builder.key(CounterName.Requests.getName()).value(dSrv.getCounters().value(CounterName.Requests));
+ builder.key(CounterName.RequestsGood.getName()).value(dSrv.getCounters().value(CounterName.RequestsGood));
+ builder.key(CounterName.RequestsBad.getName()).value(dSrv.getCounters().value(CounterName.RequestsBad));
+
+ builder.key(ServerConst.endpoints).startObject("endpoints");
+ int unique = 0;
for ( Operation operName : dSrv.getOperations() ) {
- List<Endpoint> endpoints = access.getDataService().getEndpoints(operName) ;
-
+ List<Endpoint> endpoints = access.getDataService().getEndpoints(operName);
+
for ( Endpoint endpoint : endpoints ) {
+ String k = endpoint.getName();
+ if ( StringUtils.isEmpty(k) )
+ k = emptyNameKeyPrefix+(++unique);
// Endpoint names are unique for a given service.
- builder.key(endpoint.getName()) ;
- builder.startObject() ;
-
+ builder.key(k);
+ builder.startObject();
+
operationCounters(builder, endpoint);
- builder.key(ServerConst.operation).value(operName.getName()) ;
+ builder.key(ServerConst.operation).value(operName.getName());
builder.key(ServerConst.description).value(operName.getDescription());
-
- builder.finishObject() ;
+
+ builder.finishObject();
}
}
- builder.finishObject("endpoints") ;
- builder.finishObject("counters") ;
+ builder.finishObject("endpoints");
+ builder.finishObject("counters");
}
private static void operationCounters(JsonBuilder builder, Endpoint operation) {
for (CounterName cn : operation.getCounters().counters()) {
- Counter c = operation.getCounters().get(cn) ;
- builder.key(cn.getName()).value(c.value()) ;
+ Counter c = operation.getCounters().get(cn);
+ builder.key(cn.getName()).value(c.value());
}
}
- private void statsTxt(HttpServletResponse resp, DataAccessPointRegistry registry) throws IOException
- {
- ServletOutputStream out = resp.getOutputStream() ;
+ private void statsTxt(HttpServletResponse resp, DataAccessPointRegistry registry) throws IOException {
+ ServletOutputStream out = resp.getOutputStream();
resp.setContentType(contentTypeTextPlain);
- resp.setCharacterEncoding(charsetUTF8) ;
-
- Iterator<String> iter = registry.keys().iterator() ;
- while(iter.hasNext())
- {
- String ds = iter.next() ;
- DataAccessPoint desc = registry.get(ds) ;
- statsTxt(out, desc) ;
+ resp.setCharacterEncoding(charsetUTF8);
+
+ Iterator<String> iter = registry.keys().iterator();
+ while (iter.hasNext()) {
+ String ds = iter.next();
+ DataAccessPoint desc = registry.get(ds);
+ statsTxt(out, desc);
if ( iter.hasNext() )
- out.println() ;
+ out.println();
}
- out.flush() ;
+ out.flush();
}
-
- private void statsTxt(ServletOutputStream out, DataAccessPoint desc) throws IOException
- {
- DataService dSrv = desc.getDataService() ;
- out.println("Dataset: "+desc.getName()) ;
- out.println(" Requests = "+dSrv.getCounters().value(CounterName.Requests)) ;
- out.println(" Good = "+dSrv.getCounters().value(CounterName.RequestsGood)) ;
- out.println(" Bad = "+dSrv.getCounters().value(CounterName.RequestsBad)) ;
-
- out.println(" SPARQL Query:") ;
- out.println(" Request = "+counter(dSrv, Operation.Query, CounterName.Requests)) ;
- out.println(" Good = "+counter(dSrv, Operation.Query, CounterName.RequestsGood)) ;
- out.println(" Bad requests = "+counter(dSrv, Operation.Query, CounterName.RequestsBad)) ;
- out.println(" Timeouts = "+counter(dSrv, Operation.Query, CounterName.QueryTimeouts)) ;
- out.println(" Bad exec = "+counter(dSrv, Operation.Query, CounterName.QueryExecErrors)) ;
- out.println(" IO Errors = "+counter(dSrv, Operation.Query, CounterName.QueryIOErrors)) ;
-
- out.println(" SPARQL Update:") ;
- out.println(" Request = "+counter(dSrv, Operation.Update, CounterName.Requests)) ;
- out.println(" Good = "+counter(dSrv, Operation.Update, CounterName.RequestsGood)) ;
- out.println(" Bad requests = "+counter(dSrv, Operation.Update, CounterName.RequestsBad)) ;
- out.println(" Bad exec = "+counter(dSrv, Operation.Update, CounterName.UpdateExecErrors)) ;
-
- out.println(" Upload:") ;
- out.println(" Requests = "+counter(dSrv, Operation.Upload, CounterName.Requests)) ;
- out.println(" Good = "+counter(dSrv, Operation.Upload, CounterName.RequestsGood)) ;
- out.println(" Bad = "+counter(dSrv, Operation.Upload, CounterName.RequestsBad)) ;
-
- out.println(" SPARQL Graph Store Protocol:") ;
- out.println(" GETs = "+gspValue(dSrv, CounterName.HTTPget) + " (good="+gspValue(dSrv, CounterName.HTTPgetGood)+"/bad="+gspValue(dSrv, CounterName.HTTPgetBad)+")") ;
- out.println(" PUTs = "+gspValue(dSrv, CounterName.HTTPput) + " (good="+gspValue(dSrv, CounterName.HTTPputGood)+"/bad="+gspValue(dSrv, CounterName.HTTPputBad)+")") ;
- out.println(" POSTs = "+gspValue(dSrv, CounterName.HTTPpost) + " (good="+gspValue(dSrv, CounterName.HTTPpostGood)+"/bad="+gspValue(dSrv, CounterName.HTTPpostBad)+")") ;
- out.println(" PATCHs = "+gspValue(dSrv, CounterName.HTTPpatch) + " (good="+gspValue(dSrv, CounterName.HTTPpatchGood)+"/bad="+gspValue(dSrv, CounterName.HTTPpatchBad)+")") ;
- out.println(" DELETEs = "+gspValue(dSrv, CounterName.HTTPdelete) + " (good="+gspValue(dSrv, CounterName.HTTPdeleteGood)+"/bad="+gspValue(dSrv, CounterName.HTTPdeleteBad)+")") ;
- out.println(" HEADs = "+gspValue(dSrv, CounterName.HTTPhead) + " (good="+gspValue(dSrv, CounterName.HTTPheadGood)+"/bad="+gspValue(dSrv, CounterName.HTTPheadBad)+")") ;
+
+ private void statsTxt(ServletOutputStream out, DataAccessPoint desc) throws IOException {
+ DataService dSrv = desc.getDataService();
+ out.println("Dataset: " + desc.getName());
+ out.println(" Requests = " + dSrv.getCounters().value(CounterName.Requests));
+ out.println(" Good = " + dSrv.getCounters().value(CounterName.RequestsGood));
+ out.println(" Bad = " + dSrv.getCounters().value(CounterName.RequestsBad));
+
+ out.println(" SPARQL Query:");
+ out.println(" Request = " + counter(dSrv, Operation.Query, CounterName.Requests));
+ out.println(" Good = " + counter(dSrv, Operation.Query, CounterName.RequestsGood));
+ out.println(" Bad requests = " + counter(dSrv, Operation.Query, CounterName.RequestsBad));
+ out.println(" Timeouts = " + counter(dSrv, Operation.Query, CounterName.QueryTimeouts));
+ out.println(" Bad exec = " + counter(dSrv, Operation.Query, CounterName.QueryExecErrors));
+ out.println(" IO Errors = " + counter(dSrv, Operation.Query, CounterName.QueryIOErrors));
+
+ out.println(" SPARQL Update:");
+ out.println(" Request = " + counter(dSrv, Operation.Update, CounterName.Requests));
+ out.println(" Good = " + counter(dSrv, Operation.Update, CounterName.RequestsGood));
+ out.println(" Bad requests = " + counter(dSrv, Operation.Update, CounterName.RequestsBad));
+ out.println(" Bad exec = " + counter(dSrv, Operation.Update, CounterName.UpdateExecErrors));
+
+ out.println(" Upload:");
+ out.println(" Requests = " + counter(dSrv, Operation.Upload, CounterName.Requests));
+ out.println(" Good = " + counter(dSrv, Operation.Upload, CounterName.RequestsGood));
+ out.println(" Bad = " + counter(dSrv, Operation.Upload, CounterName.RequestsBad));
+
+ out.println(" SPARQL Graph Store Protocol:");
+ out.println(" GETs = " + gspValue(dSrv, CounterName.HTTPget) + " (good=" + gspValue(dSrv, CounterName.HTTPgetGood)
+ + "/bad=" + gspValue(dSrv, CounterName.HTTPgetBad) + ")");
+ out.println(" PUTs = " + gspValue(dSrv, CounterName.HTTPput) + " (good=" + gspValue(dSrv, CounterName.HTTPputGood)
+ + "/bad=" + gspValue(dSrv, CounterName.HTTPputBad) + ")");
+ out.println(" POSTs = " + gspValue(dSrv, CounterName.HTTPpost) + " (good=" + gspValue(dSrv, CounterName.HTTPpostGood)
+ + "/bad=" + gspValue(dSrv, CounterName.HTTPpostBad) + ")");
+ out.println(" PATCHs = " + gspValue(dSrv, CounterName.HTTPpatch) + " (good=" + gspValue(dSrv, CounterName.HTTPpatchGood)
+ + "/bad=" + gspValue(dSrv, CounterName.HTTPpatchBad) + ")");
+ out.println(" DELETEs = " + gspValue(dSrv, CounterName.HTTPdelete) + " (good=" + gspValue(dSrv, CounterName.HTTPdeleteGood)
+ + "/bad=" + gspValue(dSrv, CounterName.HTTPdeleteBad) + ")");
+ out.println(" HEADs = " + gspValue(dSrv, CounterName.HTTPhead) + " (good=" + gspValue(dSrv, CounterName.HTTPheadGood)
+ + "/bad=" + gspValue(dSrv, CounterName.HTTPheadBad) + ")");
}
-
+
private long counter(DataService dSrv, Operation operation, CounterName cName) {
- return 0 ;
+ return 0;
}
-
+
private long gspValue(DataService dSrv, CounterName cn) {
return counter(dSrv, Operation.GSP_RW, cn) +
- counter(dSrv, Operation.GSP_R, cn) ;
+ counter(dSrv, Operation.GSP_R, cn);
}
-
+
@Override
protected JsonValue execPostContainer(HttpAction action) {
return execCommonContainer(action);
@@ -198,11 +215,11 @@ public class ActionStats extends ActionContainerItem
protected JsonValue execGetContainer(HttpAction action) {
return execCommonContainer(action);
}
-
+
@Override
protected JsonValue execGetItem(HttpAction action) {
return execCommonItem(action);
- }
+ }
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionTasks.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionTasks.java
index 23f786a..df60bf9 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionTasks.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/ActionTasks.java
@@ -17,109 +17,106 @@
*/
package org.apache.jena.fuseki.ctl;
-import static java.lang.String.format ;
-
-import javax.servlet.http.HttpServletRequest ;
-import javax.servlet.http.HttpServletResponse ;
-
-import org.apache.jena.atlas.json.JsonBuilder ;
-import org.apache.jena.atlas.json.JsonValue ;
-import org.apache.jena.fuseki.Fuseki ;
-import org.apache.jena.fuseki.async.AsyncPool ;
-import org.apache.jena.fuseki.async.AsyncTask ;
-import org.apache.jena.fuseki.servlets.ActionBase ;
-import org.apache.jena.fuseki.servlets.HttpAction ;
-import org.apache.jena.fuseki.servlets.ServletOps ;
-import org.apache.jena.web.HttpSC ;
-
-public class ActionTasks extends ActionBase //ActionContainerItem
+import static java.lang.String.format;
+import static org.apache.jena.riot.web.HttpNames.METHOD_GET;
+import static org.apache.jena.riot.web.HttpNames.METHOD_POST;
+
+import org.apache.jena.atlas.json.JsonBuilder;
+import org.apache.jena.atlas.json.JsonValue;
+import org.apache.jena.fuseki.async.AsyncPool;
+import org.apache.jena.fuseki.async.AsyncTask;
+import org.apache.jena.fuseki.servlets.ActionLib;
+import org.apache.jena.fuseki.servlets.HttpAction;
+import org.apache.jena.fuseki.servlets.ServletOps;
+import org.apache.jena.web.HttpSC;
+
+public class ActionTasks extends ActionCtl
{
- private static AsyncPool[] pools = { AsyncPool.get() } ;
-
- public ActionTasks() { super(Fuseki.serverLog) ; }
-
+ private static AsyncPool[] pools = { AsyncPool.get() };
+
+ public ActionTasks() { super(); }
+
@Override
- protected void doGet(HttpServletRequest request, HttpServletResponse response) {
- doCommon(request, response);
+ public void execOptions(HttpAction action) {
+ ActionLib.doOptionsGetPost(action);
+ ServletOps.success(action);
}
+ private static String prefix = "/";
+
@Override
- protected void doPost(HttpServletRequest request, HttpServletResponse response) {
- doCommon(request, response);
- }
+ public void validate(HttpAction action) { }
- private static String prefix = "/" ;
-
@Override
- protected void execCommonWorker(HttpAction action) {
- String name = extractItemName(action) ;
+ public void execute(HttpAction action) {
+ String name = ActionCtl.getItemName(action);
if ( name != null ) {
if ( name.startsWith(prefix))
- name = name.substring(prefix.length()) ;
+ name = name.substring(prefix.length());
else
- log.warn("Unexpected task name : "+name) ;
+ action.log.warn("Unexpected task name : "+name);
}
-
- String method = action.request.getMethod() ;
+
+ String method = action.request.getMethod();
if ( method.equals(METHOD_GET) )
- execGet(action, name) ;
+ execGet(action, name);
else if ( method.equals(METHOD_POST) )
- execPost(action, name) ;
+ execPost(action, name);
else
- ServletOps.error(HttpSC.METHOD_NOT_ALLOWED_405) ;
+ ServletOps.error(HttpSC.METHOD_NOT_ALLOWED_405);
}
private void execGet(HttpAction action, String name) {
if ( name == null )
- log.info(format("[%d] Tasks", action.id));
+ action.log.info(format("[%d] Tasks", action.id));
else
- log.info(format("[%d] Task %s", action.id, name));
+ action.log.info(format("[%d] Task %s", action.id, name));
+
+ JsonValue responseBody = null;
- JsonValue responseBody = null ;
-
if ( name == null ) {
- JsonBuilder builder = new JsonBuilder() ;
- builder.startArray() ;
-
+ JsonBuilder builder = new JsonBuilder();
+ builder.startArray();
+
for ( AsyncPool pool : pools ) {
for ( AsyncTask aTask : pool.tasks() ) {
- //builder.value(aTask.getTaskId()) ;
- descOneTask(builder, aTask) ;
+ //builder.value(aTask.getTaskId());
+ descOneTask(builder, aTask);
}
}
- builder.finishArray() ;
- responseBody = builder.build();
+ builder.finishArray();
+ responseBody = builder.build();
} else {
for ( AsyncPool pool : pools ) {
// Assumes first is only.
- AsyncTask aTask = pool.getTask(name) ;
+ AsyncTask aTask = pool.getTask(name);
if ( aTask != null ) {
- JsonBuilder builder = new JsonBuilder() ;
+ JsonBuilder builder = new JsonBuilder();
descOneTask(builder, aTask);
- responseBody = builder.build() ;
+ responseBody = builder.build();
}
}
}
-
+
if ( responseBody == null )
- ServletOps.errorNotFound("Task '"+name+"' not found") ;
- ServletOps.setNoCache(action) ;
- ServletOps.sendJsonReponse(action, responseBody);
+ ServletOps.errorNotFound("Task '"+name+"' not found");
+ ServletOps.setNoCache(action);
+ ServletOps.sendJsonReponse(action, responseBody);
}
private void execPost(HttpAction action, String name) {
-
+
}
-
+
private static void descOneTask(JsonBuilder builder, AsyncTask aTask) {
- builder.startObject("SingleTask") ;
- builder.key(JsonConstCtl.task).value(aTask.displayName()) ;
- builder.key(JsonConstCtl.taskId).value(aTask.getTaskId()) ;
+ builder.startObject("SingleTask");
+ builder.key(JsonConstCtl.task).value(aTask.displayName());
+ builder.key(JsonConstCtl.taskId).value(aTask.getTaskId());
if ( aTask.getStartPoint() != null )
- builder.key(JsonConstCtl.started).value(aTask.getStartPoint()) ;
+ builder.key(JsonConstCtl.started).value(aTask.getStartPoint());
if ( aTask.getFinishPoint() != null )
- builder.key(JsonConstCtl.finished).value(aTask.getFinishPoint()) ;
- builder.finishObject("SingleTask") ;
+ builder.key(JsonConstCtl.finished).value(aTask.getFinishPoint());
+ builder.finishObject("SingleTask");
}
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/Async.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/Async.java
index b3696c3..63262fe 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/Async.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/Async.java
@@ -18,44 +18,44 @@
package org.apache.jena.fuseki.ctl;
-import org.apache.http.HttpHeaders ;
-import org.apache.jena.atlas.json.JsonBuilder ;
-import org.apache.jena.atlas.json.JsonValue ;
-import org.apache.jena.fuseki.async.AsyncPool ;
-import org.apache.jena.fuseki.async.AsyncTask ;
-import org.apache.jena.fuseki.server.DataService ;
-import org.apache.jena.fuseki.servlets.HttpAction ;
+import org.apache.http.HttpHeaders;
+import org.apache.jena.atlas.json.JsonBuilder;
+import org.apache.jena.atlas.json.JsonValue;
+import org.apache.jena.fuseki.async.AsyncPool;
+import org.apache.jena.fuseki.async.AsyncTask;
+import org.apache.jena.fuseki.server.DataService;
+import org.apache.jena.fuseki.servlets.HttpAction;
public class Async
{
public static AsyncTask asyncTask(AsyncPool asyncPool, String displayName, DataService dataService, Runnable task, long requestId) {
- AsyncTask asyncTask = asyncPool.submit(task, displayName, dataService, requestId) ;
- return asyncTask ;
+ AsyncTask asyncTask = asyncPool.submit(task, displayName, dataService, requestId);
+ return asyncTask;
}
-
+
public static JsonValue asJson(AsyncTask asyncTask) {
- JsonBuilder builder = new JsonBuilder() ;
- builder.startObject("outer") ;
- builder.key(JsonConstCtl.taskId).value(asyncTask.getTaskId()) ;
+ JsonBuilder builder = new JsonBuilder();
+ builder.startObject("outer");
+ builder.key(JsonConstCtl.taskId).value(asyncTask.getTaskId());
if ( asyncTask.getOriginatingRequestId() > 0 )
- builder.key(JsonConstCtl.taskRequestId).value(asyncTask.getOriginatingRequestId()) ;
- builder.finishObject("outer") ;
- return builder.build() ;
+ builder.key(JsonConstCtl.taskRequestId).value(asyncTask.getOriginatingRequestId());
+ builder.finishObject("outer");
+ return builder.build();
}
-
+
public static void setLocationHeader(HttpAction action, AsyncTask asyncTask) {
- String x = action.getRequest().getRequestURI() ;
+ String x = action.getRequest().getRequestURI();
if ( ! x.endsWith("/") )
- x += "/" ;
- x += asyncTask.getTaskId() ;
- //String x = "/$/tasks/"+asyncTask.getTaskId() ;
- action.getResponse().setHeader(HttpHeaders.LOCATION, x) ;
+ x += "/";
+ x += asyncTask.getTaskId();
+ //String x = "/$/tasks/"+asyncTask.getTaskId();
+ action.getResponse().setHeader(HttpHeaders.LOCATION, x);
}
public static AsyncTask execASyncTask(HttpAction action, AsyncPool asyncPool, String displayName, Runnable runnable) {
- AsyncTask atask = Async.asyncTask(asyncPool, displayName, action.getDataService(), runnable, action.id) ;
- Async.setLocationHeader(action, atask);
- return atask ;
+ AsyncTask atask = Async.asyncTask(asyncPool, displayName, action.getDataService(), runnable, action.id);
+ Async.setLocationHeader(action, atask);
+ return atask;
}
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/JsonConstCtl.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/JsonConstCtl.java
index 7007098..6f439d6 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/JsonConstCtl.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/JsonConstCtl.java
@@ -20,10 +20,10 @@ package org.apache.jena.fuseki.ctl;
public class JsonConstCtl {
- public static final String taskId = "taskId" ;
- public static final String taskRequestId = "requestId" ;
- public static final String task = "task" ;
- public static final String finished = "finished" ;
- public static final String started = "started" ;
+ public static final String taskId = "taskId";
+ public static final String taskRequestId = "requestId";
+ public static final String task = "task";
+ public static final String finished = "finished";
+ public static final String started = "started";
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/JsonDescription.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/JsonDescription.java
index e74b0a4..b76cb76 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/JsonDescription.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/JsonDescription.java
@@ -18,56 +18,56 @@
package org.apache.jena.fuseki.ctl;
-import java.util.List ;
+import java.util.List;
-import org.apache.jena.atlas.json.JsonBuilder ;
-import org.apache.jena.fuseki.server.DataAccessPoint ;
-import org.apache.jena.fuseki.server.DataAccessPointRegistry ;
-import org.apache.jena.fuseki.server.Endpoint ;
-import org.apache.jena.fuseki.server.Operation ;
+import org.apache.jena.atlas.json.JsonBuilder;
+import org.apache.jena.fuseki.server.DataAccessPoint;
+import org.apache.jena.fuseki.server.DataAccessPointRegistry;
+import org.apache.jena.fuseki.server.Endpoint;
+import org.apache.jena.fuseki.server.Operation;
import org.apache.jena.fuseki.server.ServerConst;
/** Create a description of a service */
public class JsonDescription {
-
+
public static void arrayDatasets(JsonBuilder builder, DataAccessPointRegistry registry) {
- builder.startArray() ;
+ builder.startArray();
for ( String ds : registry.keys() ) {
- DataAccessPoint access = registry.get(ds) ;
- JsonDescription.describe(builder, access) ;
+ DataAccessPoint access = registry.get(ds);
+ JsonDescription.describe(builder, access);
}
- builder.finishArray() ;
+ builder.finishArray();
}
-
+
public static void describe(JsonBuilder builder, DataAccessPoint access) {
- builder.startObject() ;
- builder.key(ServerConst.dsName).value(access.getName()) ;
-
- builder.key(ServerConst.dsState).value(access.getDataService().isAcceptingRequests()) ;
-
- builder.key(ServerConst.dsService) ;
- builder.startArray() ;
-
+ builder.startObject();
+ builder.key(ServerConst.dsName).value(access.getName());
+
+ builder.key(ServerConst.dsState).value(access.getDataService().isAcceptingRequests());
+
+ builder.key(ServerConst.dsService);
+ builder.startArray();
+
for ( Operation operation : access.getDataService().getOperations() ) {
- List<Endpoint> endpoints = access.getDataService().getEndpoints(operation) ;
- describe(builder, operation, endpoints) ;
+ List<Endpoint> endpoints = access.getDataService().getEndpoints(operation);
+ describe(builder, operation, endpoints);
}
- builder.finishArray() ;
- builder.finishObject() ;
+ builder.finishArray();
+ builder.finishObject();
}
-
+
private static void describe(JsonBuilder builder, Operation operation, List<Endpoint> endpoints) {
- builder.startObject() ;
-
- builder.key(ServerConst.srvType).value(operation.getName()) ;
- builder.key(ServerConst.srvDescription).value(operation.getDescription()) ;
- builder.key(ServerConst.srvEndpoints) ;
- builder.startArray() ;
+ builder.startObject();
+
+ builder.key(ServerConst.srvType).value(operation.getName());
+ builder.key(ServerConst.srvDescription).value(operation.getDescription());
+ builder.key(ServerConst.srvEndpoints);
+ builder.startArray();
for ( Endpoint endpoint : endpoints )
- builder.value(endpoint.getName()) ;
- builder.finishArray() ;
+ builder.value(endpoint.getName());
+ builder.finishArray();
- builder.finishObject() ;
+ builder.finishObject();
}
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/TaskBase.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/TaskBase.java
index 8b73a98..60a5aee 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/TaskBase.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/ctl/TaskBase.java
@@ -18,26 +18,26 @@
package org.apache.jena.fuseki.ctl;
-import org.apache.jena.fuseki.servlets.HttpAction ;
-import org.apache.jena.sparql.core.DatasetGraph ;
-import org.apache.jena.sparql.core.Transactional ;
+import org.apache.jena.fuseki.servlets.HttpAction;
+import org.apache.jena.sparql.core.DatasetGraph;
+import org.apache.jena.sparql.core.Transactional;
/** Base of async tasks - this carries some useful information around, leaving the
* implementation of Callable.run() to the specific task.
*/
public abstract class TaskBase implements Runnable {
- public final long actionId ;
- public final DatasetGraph dataset ;
- public final String datasetName ;
- public final Transactional transactional ;
-
+ public final long actionId;
+ public final DatasetGraph dataset;
+ public final String datasetName;
+ public final Transactional transactional;
+
protected TaskBase(HttpAction action) {
// The action is closed as part of action processing so is not
// available in the async task. Anything from it that is needed,
// taken out here.
- this.actionId = action.id ;
- this.dataset = action.getDataset() ;
- this.transactional = action.getTransactional() ;
- this.datasetName = action.getDatasetName() ;
+ this.actionId = action.id;
+ this.dataset = ActionCtl.getItemDataset(action);
+ this.transactional = dataset;
+ this.datasetName = ActionCtl.getItemDatasetName(action);
}
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/jetty/FusekiErrorHandler.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/jetty/FusekiErrorHandler.java
index 84990cc..fd6bc03 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/jetty/FusekiErrorHandler.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/jetty/FusekiErrorHandler.java
@@ -18,21 +18,21 @@
package org.apache.jena.fuseki.jetty;
-import static java.lang.String.format ;
+import static java.lang.String.format;
-import java.io.* ;
+import java.io.*;
-import javax.servlet.http.HttpServletRequest ;
-import javax.servlet.http.HttpServletResponse ;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
-import org.apache.jena.atlas.io.IO ;
-import org.apache.jena.fuseki.servlets.ServletOps ;
-import org.apache.jena.web.HttpSC ;
-import org.eclipse.jetty.http.HttpMethod ;
-import org.eclipse.jetty.http.MimeTypes ;
-import org.eclipse.jetty.server.Request ;
-import org.eclipse.jetty.server.Response ;
-import org.eclipse.jetty.server.handler.ErrorHandler ;
+import org.apache.jena.atlas.io.IO;
+import org.apache.jena.fuseki.servlets.ServletOps;
+import org.apache.jena.web.HttpSC;
+import org.eclipse.jetty.http.HttpMethod;
+import org.eclipse.jetty.http.MimeTypes;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.server.handler.ErrorHandler;
/** The usual Fuseki error handler.
* Outputs a plain text message.
@@ -41,41 +41,37 @@ import org.eclipse.jetty.server.handler.ErrorHandler ;
public class FusekiErrorHandler extends ErrorHandler
{
public FusekiErrorHandler() {}
-
+
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
- {
+ public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException {
String method = request.getMethod();
-
+
if ( !method.equals(HttpMethod.GET.asString())
&& !method.equals(HttpMethod.POST.asString())
&& !method.equals(HttpMethod.HEAD.asString()) )
- return ;
-
- response.setContentType(MimeTypes.Type.TEXT_PLAIN_UTF_8.asString()) ;
- ServletOps.setNoCache(response) ;
-
- ByteArrayOutputStream bytes = new ByteArrayOutputStream(1024) ;
+ return;
+
+ response.setContentType(MimeTypes.Type.TEXT_PLAIN_UTF_8.asString());
+ ServletOps.setNoCache(response);
+
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream(1024);
try ( Writer writer = IO.asUTF8(bytes) ) {
String reason = (response instanceof Response) ? ((Response)response).getReason() : null;
- handleErrorPage(request, writer, response.getStatus(), reason) ;
+ handleErrorPage(request, writer, response.getStatus(), reason);
writer.flush();
- response.setContentLength(bytes.size()) ;
- response.getOutputStream().write(bytes.toByteArray()) ;
+ response.setContentLength(bytes.size());
+ response.getOutputStream().write(bytes.toByteArray());
}
}
-
+
@Override
- protected void handleErrorPage(HttpServletRequest request, Writer writer, int code, String message)
- throws IOException
- {
+ protected void handleErrorPage(HttpServletRequest request, Writer writer, int code, String message) throws IOException {
if ( message == null )
- message = HttpSC.getMessage(code) ;
- writer.write(format("Error %d: %s\n", code, message)) ;
-
+ message = HttpSC.getMessage(code);
+ writer.write(format("Error %d: %s\n", code, message));
+
Throwable th = (Throwable)request.getAttribute("javax.servlet.error.exception");
- while(th!=null)
- {
+ while (th != null) {
writer.write("\n");
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/jetty/FusekiErrorHandler1.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/jetty/FusekiErrorHandler1.java
index bc9eba0..7210afc 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/jetty/FusekiErrorHandler1.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/jetty/FusekiErrorHandler1.java
@@ -18,40 +18,39 @@
package org.apache.jena.fuseki.jetty;
-import static java.lang.String.format ;
+import static java.lang.String.format;
-import java.io.IOException ;
+import java.io.IOException;
-import javax.servlet.http.HttpServletRequest ;
-import javax.servlet.http.HttpServletResponse ;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
-import org.apache.jena.fuseki.servlets.ServletOps ;
-import org.apache.jena.web.HttpSC ;
-import org.eclipse.jetty.http.HttpMethod ;
-import org.eclipse.jetty.http.MimeTypes ;
-import org.eclipse.jetty.server.Request ;
-import org.eclipse.jetty.server.Response ;
-import org.eclipse.jetty.server.handler.ErrorHandler ;
+import org.apache.jena.fuseki.servlets.ServletOps;
+import org.apache.jena.web.HttpSC;
+import org.eclipse.jetty.http.HttpMethod;
+import org.eclipse.jetty.http.MimeTypes;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.server.handler.ErrorHandler;
/** One line Fuseki error handler */
public class FusekiErrorHandler1 extends ErrorHandler
{
public FusekiErrorHandler1() {}
-
+
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
- {
+ public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException {
String method = request.getMethod();
-
- if ( !method.equals(HttpMethod.GET.asString())
- && !method.equals(HttpMethod.POST.asString())
- && !method.equals(HttpMethod.HEAD.asString()) )
- return ;
-
- response.setContentType(MimeTypes.Type.TEXT_PLAIN_UTF_8.asString()) ;
- ServletOps.setNoCache(response) ;
- int code = response.getStatus() ;
- String message=(response instanceof Response)?((Response)response).getReason(): HttpSC.getMessage(code) ;
- response.getOutputStream().print(format("Error %d: %s\n", code, message)) ;
+
+ if ( !method.equals(HttpMethod.GET.asString())
+ && !method.equals(HttpMethod.POST.asString())
+ && !method.equals(HttpMethod.HEAD.asString()) )
+ return;
+
+ response.setContentType(MimeTypes.Type.TEXT_PLAIN_UTF_8.asString());
+ ServletOps.setNoCache(response);
+ int code = response.getStatus();
+ String message = (response instanceof Response) ? ((Response)response).getReason() : HttpSC.getMessage(code);
+ response.getOutputStream().print(format("Error %d: %s\n", code, message));
}
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/jetty/JettyHttps.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/jetty/JettyHttps.java
index 5ca3a91..5723445 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/jetty/JettyHttps.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/jetty/JettyHttps.java
@@ -30,7 +30,7 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
* It sets up "http" to redirect to "https".
*/
public class JettyHttps {
-
+
/*
* Useful documentation:
* http://www.eclipse.org/jetty/documentation/current/configuring-ssl.html
@@ -46,8 +46,8 @@ public class JettyHttps {
/**
* Create a HTTPS Jetty server for the {@link ServletContextHandler}
- * <p>
- * If httpPort is -1, don't add http otherwise make http redirect to https.
+ * <p>
+ * If httpPort is -1, don't add http otherwise make http redirect to https.
*/
public static Server jettyServerHttps(ServletContextHandler handler, String keystore, String certPassword, int httpPort, int httpsPort) {
// Server handling http and https.
@@ -61,10 +61,10 @@ public class JettyHttps {
JettyLib.addHandler(jettyServer, handler);
return jettyServer;
}
-
+
/** Build the server - http and https connectors.
* If httpPort is -1, don't add http.
- */
+ */
private static Server server(String keystore, String certPassword, int httpPort, int httpsPort) {
Server server = new Server();
if ( httpPort > 0 ) {
@@ -88,13 +88,13 @@ public class JettyHttps {
plainConnector.setPort(httpPort);
return plainConnector;
}
-
+
/** Add HTTPS to a {@link Server}. */
private static ServerConnector httpsConnector(Server server, int httpsPort, String keystore, String certPassword) {
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath(keystore);
sslContextFactory.setKeyStorePassword(certPassword);
-
+
SecureRequestCustomizer src = new SecureRequestCustomizer();
src.setStsMaxAge(2000);
src.setStsIncludeSubDomains(true);
@@ -112,7 +112,7 @@ public class JettyHttps {
return sslConnector;
}
- /** HTTP configuration with setting for Fuseki workload. No "secure" settings. */
+ /** HTTP configuration with setting for Fuseki workload. No "secure" settings. */
private static HttpConfiguration httpConfiguration() {
HttpConfiguration http_config = new HttpConfiguration();
// Some people do try very large operations ... really, should use POST.
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/jetty/JettyLib.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/jetty/JettyLib.java
index 005914c..7a940d4 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/jetty/JettyLib.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/jetty/JettyLib.java
@@ -43,14 +43,14 @@ import org.eclipse.jetty.util.security.Password;
* </pre>
*/
public class JettyLib {
-
+
/** Create a Jetty {@link SecurityHandler} for a specific pathSpace, e.g {@code /database}. */
public static SecurityHandler makeSecurityHandlerForPathspec(String pathSpec, String realm, UserStore userStore) {
ConstraintSecurityHandler sh = makeSecurityHandler(realm, userStore);
addPathConstraint(sh, pathSpec);
return sh;
}
-
+
// /** Create a Jetty {@link SecurityHandler} for basic authentication. */
// @Deprecated
// public static SecurityHandler makeSecurityHandlerForPathspec(String pathSpec, String realm, UserStore userStore, String role) {
@@ -59,7 +59,7 @@ public class JettyLib {
// addDatasetConstraint(securityHandler, pathSpec);
// return securityHandler;
// }
-
+
/**
* Digest requires an extra round trip so it is unfriendly to API
* or scripts that stream.
@@ -68,7 +68,7 @@ public class JettyLib {
/** Current auth mode */
public static AuthScheme authMode = dftAuthMode;
- /** Create a Jetty {@link SecurityHandler} for basic authentication.
+ /** Create a Jetty {@link SecurityHandler} for basic authentication.
* See {@linkplain #addPathConstraint(ConstraintSecurityHandler, String)}
* for adding the {@code pathspec} to apply it to.
*/
@@ -76,7 +76,7 @@ public class JettyLib {
return makeSecurityHandler(realm, userStore, "**", authMode);
}
- /** Create a Jetty {@link SecurityHandler} for basic authentication.
+ /** Create a Jetty {@link SecurityHandler} for basic authentication.
* See {@linkplain #addPathConstraint(ConstraintSecurityHandler, String)}
* for adding the {@code pathspec} to apply it to.
*/
@@ -84,7 +84,7 @@ public class JettyLib {
return makeSecurityHandler(realm, userStore, "**", authMode);
}
- /** Create a Jetty {@link SecurityHandler} for basic authentication.
+ /** Create a Jetty {@link SecurityHandler} for basic authentication.
* See {@linkplain #addPathConstraint(ConstraintSecurityHandler, String)}
* for adding the {@code pathspec} to apply it to.
*/
@@ -92,10 +92,10 @@ public class JettyLib {
// role can be "**" for any authenticated user.
Objects.requireNonNull(userStore);
Objects.requireNonNull(role);
-
+
if ( authMode == null )
authMode = dftAuthMode;
-
+
ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler();
IdentityService identService = new DefaultIdentityService();
@@ -105,22 +105,22 @@ public class JettyLib {
HashLoginService loginService = new HashLoginService(realm);
loginService.setUserStore(userStore);
loginService.setIdentityService(identService);
-
+
securityHandler.setLoginService(loginService);
securityHandler.setAuthenticator( authMode == AuthScheme.BASIC ? new BasicAuthenticator() : new DigestAuthenticator() );
if ( realm != null )
securityHandler.setRealmName(realm);
return securityHandler;
}
-
+
public static void addPathConstraint(ConstraintSecurityHandler securityHandler, String pathSpec) {
addPathConstraint(securityHandler, pathSpec, "**");
}
-
+
public static void addPathConstraint(ConstraintSecurityHandler securityHandler, String pathSpec, String role) {
Objects.requireNonNull(securityHandler);
Objects.requireNonNull(pathSpec);
-
+
ConstraintMapping mapping = new ConstraintMapping();
Constraint constraint = new Constraint();
String[] roles = new String[]{role};
@@ -134,7 +134,7 @@ public class JettyLib {
/**
* Make a {@link UserStore} from a password file.
- * {@link PropertyUserStore} for details.
+ * {@link PropertyUserStore} for details.
*/
public static UserStore makeUserStore(String passwordFile) {
PropertyUserStore propertyUserStore = new PropertyUserStore();
@@ -149,7 +149,7 @@ public class JettyLib {
public static UserStore makeUserStore(String user, String password) {
return makeUserStore(user, password, "**");
}
-
+
/** Make a {@link UserStore} for a single user,password,role*/
public static UserStore makeUserStore(String user, String password, String role) {
Objects.requireNonNull(user);
@@ -173,9 +173,9 @@ public class JettyLib {
return userStore;
}
-
-
-
+
+
+
/** Add or append a {@link Handler} to a Jetty {@link Server}. */
public static void addHandler(Server server, Handler handler) {
final Handler currentHandler = server.getHandler();
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/jetty/JettyServerConfig.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/jetty/JettyServerConfig.java
index b7de091..64596a1 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/jetty/JettyServerConfig.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/jetty/JettyServerConfig.java
@@ -26,31 +26,31 @@ package org.apache.jena.fuseki.jetty;
public class JettyServerConfig
{
public JettyServerConfig() {}
-
+
/** Port to run the server service on */
- public int port ;
-
+ public int port;
+
/** Path to run the server service under */
- public String contextPath ;
-
+ public String contextPath;
+
/** Jetty config file - if null, use the built-in configuration of Jetty */
- public String jettyConfigFile = null ;
-
+ public String jettyConfigFile = null;
+
/** Listen only on the loopback (localhost) interface */
- public boolean loopback = false ;
-
+ public boolean loopback = false;
+
/** Enable Accept-Encoding compression. Set to false by default.*/
- public boolean enableCompression = false ;
-
+ public boolean enableCompression = false;
+
/** Enable additional logging */
- public boolean verboseLogging = false ;
-
+ public boolean verboseLogging = false;
+
/** Authentication config file used to setup Jetty Basic auth,
* if a Jetty config file was set this is ignored since Jetty config
* allows much more complex auth methods to be implemented.
- * Using Apache Shiro is better as well.
+ * Using Apache Shiro is better as well.
*/
- public String authConfigFile ;
+ public String authConfigFile;
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/package-info.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/package-info.java
index 70bda0e..1cd88dc8 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/package-info.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/package-info.java
@@ -34,13 +34,13 @@
* <li><em>FusekiFilter</em> :: Routes requests to Fuseki (handles the dynamic nature dataset naming) by calling ServiceRouter.</li>
* <li><em>ServiceRouterServlet</em> :: Routes requests to the appropriate service (i.e. implementing servlet).</li>
* <li><em>ActionBase</em> :: Creates a basic {@code HttpAction} and defines {@code execCommonWorker}.</li>
- * <li><em>ActionService</em> :: Fills in {@code HttpAction} with dataset and endpoint. Calls {@code setRequest} on an {@code HttpAction}.
+ * <li><em>ActionService</em> :: Fills in {@code HttpAction} with dataset and endpoint. Calls {@code setRequest} on an {@code HttpAction}.
* It implements {@code execCommonWorker} as a lifecycle => {@code executeAction} => {@code executeLifecycle} => {@code validate - perform}
* <li><em>ServiceRouter</em> :: Routing of request to the cocrete servlet implementations.
- * </ul>
+ * </ul>
* <p>
* <pre>
- * ServiceDispatchServlet < ActionService < ActionBase
+ * ServiceDispatchServlet < ActionService < ActionBase
* Services < ActionService < ActionBase
* Admin operations < ActionCtl < ActionBase
* Task management < ActionTasks < ActionBase
@@ -52,7 +52,7 @@
* <ul>
* <li><em>ContentTypeToOperation</em>:: Map<content-type, Operation></li>
* <li><em>ContentTypeToOperation</em>:: Map<String, Operation></li>
- * <li><em>Dispatch</em> :: {@literal Map<Operation, ActionService>}</li>
+ * <li><em>Dispatch</em> :: {@literal Map<Operation, ActionService>}</li>
* </ul>
* <p>
*/
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Counter.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Counter.java
index 88d4d37..4196d6e 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Counter.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Counter.java
@@ -18,17 +18,17 @@
package org.apache.jena.fuseki.server;
-import java.util.concurrent.atomic.AtomicLong ;
+import java.util.concurrent.atomic.AtomicLong;
/** A statistics counter */
public class Counter
{
- private AtomicLong counter = new AtomicLong(0) ;
-
+ private AtomicLong counter = new AtomicLong(0);
+
public Counter() {}
-
- public void inc() { counter.incrementAndGet() ; }
- public void dec() { counter.decrementAndGet() ; }
- public long value() { return counter.get() ; }
+
+ public void inc() { counter.incrementAndGet(); }
+ public void dec() { counter.decrementAndGet(); }
+ public long value() { return counter.get(); }
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/CounterName.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/CounterName.java
index 7ad8cfd..1715548 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/CounterName.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/CounterName.java
@@ -20,24 +20,24 @@ package org.apache.jena.fuseki.server;
import java.util.Objects;
-/** Names for all counters */
+/** Names for all counters */
public class CounterName {
- // Create intern'ed symbols.
+ // Create intern'ed symbols.
static private NameMgr<CounterName> mgr = new NameMgr<>();
static public CounterName register(String name, String hierarchicalName) {
Objects.requireNonNull(name, "name");
Objects.requireNonNull(hierarchicalName, "hierarchicalName");
return mgr.register(name, (n)->new CounterName(name, hierarchicalName));
}
-
+
// The "name" is used as a JSON key string.
// Legacy from when this was an enum and the name() was used for the UI.
// The better hierarchicalName is not used but becuse this has
- // leaked to the jaavscript, we're a bit stuck.
+ // leaked to the jaavscript, we're a bit stuck.
+
+ private final String name;
+ private final String hierarchicalName;
- private final String name ;
- private final String hierarchicalName ;
-
// There are generic names - apply to all services and datasets.
// Total request received
public static final CounterName Requests = register("Requests", "requests");
@@ -91,16 +91,16 @@ public class CounterName {
public static final CounterName HTTPoptions = register("HTTPoptions", "http.options.requests");
public static final CounterName HTTPoptionsGood = register("HTTPoptionsGood", "http.options.requests.good");
public static final CounterName HTTPoptionsBad = register("HTTPoptionsBad", "http.options.requests.bad");
-
+
private CounterName(String name, String hierarchicalName) {
this.name = name;
this.hierarchicalName = hierarchicalName;
}
-
+
public String getName() {
return name;
}
-
+
public String getFullName() {
return hierarchicalName;
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/CounterSet.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/CounterSet.java
index 9b8231e..a5ae011 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/CounterSet.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/CounterSet.java
@@ -16,55 +16,52 @@
* limitations under the License.
*/
-package org.apache.jena.fuseki.server ;
+package org.apache.jena.fuseki.server;
-import java.util.Collection ;
-import java.util.HashMap ;
-import java.util.Map ;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
-import org.slf4j.Logger ;
-import org.slf4j.LoggerFactory ;
+import org.apache.jena.atlas.logging.Log;
/** A collection of counters */
public class CounterSet {
- private static Logger log = LoggerFactory.getLogger(CounterSet.class) ;
-
- private Map<CounterName, Counter> counters = new HashMap<>() ;
+ private Map<CounterName, Counter> counters = new HashMap<>();
public CounterSet() {}
public Collection<CounterName> counters() {
- return counters.keySet() ;
+ return counters.keySet();
}
public void inc(CounterName c) {
- get(c).inc() ;
+ get(c).inc();
}
public void dec(CounterName c) {
- get(c).dec() ;
+ get(c).dec();
}
public long value(CounterName c) {
- return get(c).value() ;
+ return get(c).value();
}
public void add(CounterName counterName) {
if ( counters.containsKey(counterName) ) {
- log.warn("Duplicate counter in counter set: " + counterName) ;
- return ;
+ Log.warn(CounterSet.class, "Duplicate counter in counter set: " + counterName);
+ return;
}
- counters.put(counterName, new Counter()) ;
+ counters.put(counterName, new Counter());
}
public boolean contains(CounterName cn) {
- return counters.containsKey(cn) ;
+ return counters.containsKey(cn);
}
public Counter get(CounterName cn) {
- Counter c = counters.get(cn) ;
+ Counter c = counters.get(cn);
if ( c == null )
- log.warn("No counter in counter set: " + cn) ;
- return c ;
+ Log.warn(CounterSet.class, "No counter in counter set: " + cn);
+ return c;
}
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Counters.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Counters.java
index 4e5ca4b..45f3996 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Counters.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Counters.java
@@ -18,8 +18,8 @@
package org.apache.jena.fuseki.server;
-/** Objects that have a counter set */
+/** Objects that have a counter set */
public interface Counters {
- public CounterSet getCounters() ;
+ public CounterSet getCounters();
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataAccessPoint.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataAccessPoint.java
index 9157353..43d8c6d 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataAccessPoint.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataAccessPoint.java
@@ -18,45 +18,52 @@
package org.apache.jena.fuseki.server;
-import java.util.concurrent.atomic.AtomicLong ;
+import java.util.concurrent.atomic.AtomicLong;
-import org.apache.jena.fuseki.servlets.HttpAction ;
+import org.apache.jena.fuseki.servlets.HttpAction;
-/** A name in the URL space of the server */
+/**
+ * A pairing of name and {@link DataService}, a dataset and its endpoints (which may
+ * in turn be named), in the URL space of the server
+ */
public class DataAccessPoint {
- private final String name ;
- private final DataService dataService ;
- private AtomicLong requests = new AtomicLong(0) ;
-
+ private final String name;
+ private final DataService dataService;
+ private AtomicLong requests = new AtomicLong(0);
+
public DataAccessPoint(String name, DataService dataService) {
- this.name = canonical(name) ;
- this.dataService = dataService ;
+ this.name = canonical(name);
+ this.dataService = dataService;
dataService.noteDataAccessPoint(this);
}
-
- public String getName() { return name ; }
-
+
+ public String getName() { return name; }
+
public static String canonical(String datasetPath) {
if ( datasetPath == null )
- return datasetPath ;
+ return datasetPath;
if ( datasetPath.equals("/") )
- datasetPath = "" ;
+ datasetPath = "";
else
if ( !datasetPath.startsWith("/") )
- datasetPath = "/" + datasetPath ;
+ datasetPath = "/" + datasetPath;
if ( datasetPath.endsWith("/") )
- datasetPath = datasetPath.substring(0, datasetPath.length() - 1) ;
- return datasetPath ;
+ datasetPath = datasetPath.substring(0, datasetPath.length() - 1);
+ return datasetPath;
}
public DataService getDataService() {
return dataService;
}
- public long requestCount() { return requests.get() ; }
-
- public void startRequest(HttpAction httpAction) { requests.incrementAndGet() ; }
+ public long requestCount() { return requests.get(); }
- public void finishRequest(HttpAction httpAction) { requests.getAndDecrement() ; }
+ public void startRequest(HttpAction httpAction) { requests.incrementAndGet(); }
+
+ public void finishRequest(HttpAction httpAction) { requests.getAndDecrement(); }
+
+ @Override public String toString() {
+ return "DataAccessPoint["+name+"]";
+ }
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataAccessPointRegistry.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataAccessPointRegistry.java
index 5fe5c82..eca7581 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataAccessPointRegistry.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataAccessPointRegistry.java
@@ -19,12 +19,12 @@
package org.apache.jena.fuseki.server;
import io.micrometer.core.instrument.MeterRegistry;
-import javax.servlet.ServletContext ;
+import javax.servlet.ServletContext;
-import org.apache.jena.atlas.lib.Registry ;
-import org.apache.jena.atlas.logging.Log ;
+import org.apache.jena.atlas.lib.Registry;
+import org.apache.jena.atlas.logging.Log;
import org.apache.jena.fuseki.Fuseki;
-import org.apache.jena.fuseki.FusekiException ;
+import org.apache.jena.fuseki.FusekiException;
import org.apache.jena.fuseki.metrics.FusekiRequestsMetrics;
public class DataAccessPointRegistry extends Registry<String, DataAccessPoint>
@@ -34,20 +34,20 @@ public class DataAccessPointRegistry extends Registry<String, DataAccessPoint>
public DataAccessPointRegistry(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}
-
+
public DataAccessPointRegistry(DataAccessPointRegistry other) {
other.forEach((name, accessPoint)->register(name, accessPoint));
this.meterRegistry = other.meterRegistry;
}
-
+
// Preferred way to register. Other method for legacy.
public void register(DataAccessPoint accessPt) {
register(accessPt.getName(), accessPt);
}
-
+
private void register(String name, DataAccessPoint accessPt) {
if ( isRegistered(name) )
- throw new FusekiException("Already registered: "+name) ;
+ throw new FusekiException("Already registered: "+name);
super.put(name, accessPt);
if (meterRegistry != null) {
new FusekiRequestsMetrics( accessPt ).bindTo( meterRegistry );
@@ -55,30 +55,30 @@ public class DataAccessPointRegistry extends Registry<String, DataAccessPoint>
}
// Debugging
public void print(String string) {
- System.out.flush() ;
+ System.out.flush();
if ( string == null )
- string = "DataAccessPointRegistry" ;
- System.out.println("== "+string) ;
+ string = "DataAccessPointRegistry";
+ System.out.println("== "+string);
this.forEach((k,ref)->{
- System.out.printf(" (key=%s, ref=%s)\n", k, ref.getName()) ;
+ System.out.printf(" (key=%s, ref=%s)\n", k, ref.getName());
ref.getDataService().getOperations().forEach((op)->{
ref.getDataService().getEndpoints(op).forEach(ep->{
- System.out.printf(" %s : %s\n", op, ep.getName()) ;
+ System.out.printf(" %s : %s\n", op, ep.getName());
});
});
- }) ;
+ });
}
// The server DataAccessPointRegistry is held in the ServletContext for the server.
-
+
public static DataAccessPointRegistry get(ServletContext cxt) {
- DataAccessPointRegistry registry = (DataAccessPointRegistry)cxt.getAttribute(Fuseki.attrNameRegistry) ;
+ DataAccessPointRegistry registry = (DataAccessPointRegistry)cxt.getAttribute(Fuseki.attrNameRegistry);
if ( registry == null )
- Log.warn(DataAccessPointRegistry.class, "No data access point registry for ServletContext") ;
- return registry ;
+ Log.warn(DataAccessPointRegistry.class, "No data access point registry for ServletContext");
+ return registry;
}
-
+
public static void set(ServletContext cxt, DataAccessPointRegistry registry) {
- cxt.setAttribute(Fuseki.attrNameRegistry, registry) ;
+ cxt.setAttribute(Fuseki.attrNameRegistry, registry);
}
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataService.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataService.java
index 9791b3e..192b412 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataService.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataService.java
@@ -22,13 +22,13 @@ import static java.lang.String.format;
import static org.apache.jena.fuseki.server.DataServiceStatus.*;
import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
-import org.apache.jena.atlas.logging.FmtLog;
import org.apache.jena.ext.com.google.common.collect.ArrayListMultimap;
import org.apache.jena.ext.com.google.common.collect.ListMultimap;
-import org.apache.jena.fuseki.Fuseki;
+import org.apache.jena.ext.com.google.common.collect.Multimaps;
import org.apache.jena.fuseki.FusekiException;
import org.apache.jena.fuseki.auth.AuthPolicy;
import org.apache.jena.query.TxnType;
@@ -37,9 +37,15 @@ import org.apache.jena.sparql.core.DatasetGraph;
public class DataService {
private DatasetGraph dataset;
-
- private ListMultimap<Operation, Endpoint> operations = ArrayListMultimap.create();
- private Map<String, Endpoint> endpoints = new HashMap<>();
+
+ private EndpointSet unnamedEndpoints = new EndpointSet(null);
+ private Map<String, EndpointSet> namedEndpoints = new ConcurrentHashMap<>();
+ private Map<String, Endpoint> endpoints = new HashMap<>();
+ // Keep a single multimap of operation->endpoints.
+ private ListMultimap<Operation, Endpoint> operationsMap = Multimaps.synchronizedListMultimap(ArrayListMultimap.create());
+
+
+ // Dataset-level authorization policy.
private AuthPolicy authPolicy = null;
/**
@@ -62,27 +68,14 @@ public class DataService {
counters.add(CounterName.Requests);
counters.add(CounterName.RequestsGood);
counters.add(CounterName.RequestsBad);
- // Start ACTIVE. Registration controls visibility.
+ // Start ACTIVE. Registration controls visibility.
goActive();
}
- /**
- * Create a {@code DataService} that has the same dataset, same operations and
- * endpoints as another {@code DataService}. Counters are not copied, not
- * DataAccessPoint associations.
- */
- private DataService(int dummy, DataService other) {
- // Copy non-counter state of 'other'.
- this.dataset = other.dataset;
- this.operations = ArrayListMultimap.create(other.operations);
- this.endpoints = new HashMap<>(other.endpoints);
- this.state = UNINITIALIZED;
- }
-
/*package*/ void noteDataAccessPoint(DataAccessPoint dap) {
this.dataAccessPoints.add(dap);
}
-
+
private String label() {
StringJoiner sj = new StringJoiner(", ", "[", "]");
dataAccessPoints.stream()
@@ -91,52 +84,98 @@ public class DataService {
.forEach(sj::add);
return sj.toString();
}
-
+
public DatasetGraph getDataset() {
- return dataset;
+ return dataset;
}
-
+
+ public void addEndpointNoName(Operation operation) {
+ addEndpointNoName(operation, null);
+ }
+
+ public void addEndpointNoName(Operation operation, AuthPolicy authPolicy) {
+ addEndpoint(operation, null, authPolicy);
+ }
+
public void addEndpoint(Operation operation, String endpointName) {
addEndpoint(operation, endpointName, null);
}
-
+
public void addEndpoint(Operation operation, String endpointName, AuthPolicy authPolicy) {
- if ( endpointName != null && endpoints.containsKey(endpointName) ) {
- Operation existing = endpoints.get(endpointName).getOperation();
- FmtLog.warn(Fuseki.configLog, "Duplicate use of name '%s'. Overwriting operation %s with %s",
- endpointName, operation, existing);
- }
+ // Operation -> endpoint.
Endpoint endpoint = new Endpoint(operation, endpointName, authPolicy);
- endpoints.put(endpointName, endpoint);
- operations.put(operation, endpoint);
+ addEndpoint(endpoint);
}
-
- public void removeEndpoint(Endpoint endpoint) {
- if ( endpoint.endpointName != null )
- endpoints.remove(endpoint.endpointName);
- operations.remove(endpoint.getOperation(), endpoint);
+
+ /** Return the {@linkplain EndpointSet} for the operations for named use. */
+ public EndpointSet getEndpointSet(String endpointName) {
+ return namedEndpoints.get(endpointName);
}
-
- public Endpoint getEndpoint(String endpointName) {
- return endpoints.get(endpointName);
+
+ /** Return the {@linkplain EndpointSet} for the operations for unnamed use. */
+ public EndpointSet getEndpointSet() {
+ return unnamedEndpoints;
}
+ /**
+ * Return a collection of all endpoints for this {@linkplain DataService}.
+ * This operation is for debug and development - it is not efficient.
+ */
public Collection<Endpoint> getEndpoints() {
- return operations.values();
+ // Keep separately?
+ Set<Endpoint> x = new HashSet<>();
+ unnamedEndpoints.forEach((op,ep)->x.add(ep));
+ namedEndpoints.forEach((k,eps)->{
+ eps.forEach((op,ep)->x.add(ep));
+ });
+ return x;
}
-
+
public List<Endpoint> getEndpoints(Operation operation) {
- List<Endpoint> x = operations.get(operation);
- if ( x == null )
- x = Collections.emptyList();
- return x;
+ List<Endpoint> x = operationsMap.get(operation);
+ return x;
}
/** Return the operations available here.
* @see #getEndpoints(Operation) to get the endpoint list
*/
public Collection<Operation> getOperations() {
- return operations.keySet();
+ return operationsMap.keySet();
+ }
+
+ /** Return the operations available here.
+ * @see #getEndpoints(Operation) to get the endpoint list
+ */
+ public boolean hasOperation(Operation operation) {
+ return operationsMap.keySet().contains(operation);
+ }
+
+ public void addEndpoint(Endpoint endpoint) {
+ addEndpoint$(endpoint);
+ }
+
+ private void addEndpoint$(Endpoint endpoint) {
+ if ( endpoint.isUnnamed() )
+ unnamedEndpoints.put(endpoint);
+ else {
+ EndpointSet eps = namedEndpoints.computeIfAbsent(endpoint.getName(), (k)->new EndpointSet(k));
+ eps.put(endpoint);
+ }
+ // Cleaner not to have duplicates. But nice to have a (short) list that keeps the create order.
+ if ( ! operationsMap.containsEntry(endpoint.getOperation(), endpoint) )
+ operationsMap.put(endpoint.getOperation(), endpoint);
+ }
+
+ private void removeEndpoint$(Endpoint endpoint) {
+ if ( endpoint.isUnnamed() )
+ unnamedEndpoints.remove(endpoint);
+ else {
+ EndpointSet eps = namedEndpoints.get(endpoint.getName());
+ if ( eps == null )
+ return;
+ eps.remove(endpoint);
+ }
+ operationsMap.remove(endpoint.getOperation(), endpoint);
}
//@Override
@@ -162,12 +201,12 @@ public class DataService {
public boolean isAcceptingRequests() {
return acceptingRequests.get();
}
-
+
//@Override
public CounterSet getCounters() { return counters; }
-
- //@Override
- public long getRequests() {
+
+ //@Override
+ public long getRequests() {
return counters.value(CounterName.Requests);
}
@@ -207,24 +246,23 @@ public class DataService {
public synchronized void shutdown() {
if ( state == CLOSING )
return;
- Fuseki.serverLog.info(format("Shutting down data service for %s", endpoints.keySet()));
expel(dataset);
- dataset = null;
+ dataset = null;
state = CLOSED;
}
-
+
private void expel(DatasetGraph database) {
// Text databases.
- // Close the in-JVM objects for Lucene index and databases.
+ // Close the in-JVM objects for Lucene index and databases.
if ( database instanceof DatasetGraphText ) {
DatasetGraphText dbtext = (DatasetGraphText)database;
database = dbtext.getBase();
dbtext.getTextIndex().close();
}
-
+
boolean isTDB1 = org.apache.jena.tdb.sys.TDBInternal.isTDB1(database);
boolean isTDB2 = org.apache.jena.tdb2.sys.TDBInternal.isTDB2(database);
-
+
if ( ( isTDB1 || isTDB2 ) ) {
// JENA-1586: Remove database from the process.
if ( isTDB1 )
@@ -236,9 +274,8 @@ public class DataService {
}
public void setAuthPolicy(AuthPolicy authPolicy) { this.authPolicy = authPolicy; }
-
+
/** Returning null implies no authorization control */
public AuthPolicy authPolicy() { return authPolicy; }
-
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataServiceStatus.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataServiceStatus.java
index 9b66a47..2004761 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataServiceStatus.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataServiceStatus.java
@@ -18,29 +18,29 @@
package org.apache.jena.fuseki.server;
-import org.apache.jena.rdf.model.Resource ;
+import org.apache.jena.rdf.model.Resource;
public enum DataServiceStatus {
-
+
UNINITIALIZED("Uninitialized"),
ACTIVE("Active"),
OFFLINE("Offline"),
CLOSING("Closing"),
- CLOSED("Closed") ;
-
- public final String name ;
- DataServiceStatus(String string) { name = string ; }
-
+ CLOSED("Closed");
+
+ public final String name;
+ DataServiceStatus(String string) { name = string; }
+
public static DataServiceStatus status(Resource r) {
if ( FusekiVocab.stateActive.equals(r) )
- return ACTIVE ;
+ return ACTIVE;
if ( FusekiVocab.stateOffline.equals(r) )
- return OFFLINE ;
+ return OFFLINE;
if ( FusekiVocab.stateClosing.equals(r) )
- return CLOSING ;
+ return CLOSING;
if ( FusekiVocab.stateClosed.equals(r) )
- return CLOSED ;
- return null ;
+ return CLOSED;
+ return null;
}
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DatasetMXBean.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DatasetMXBean.java
deleted file mode 100644
index bf38229..0000000
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DatasetMXBean.java
+++ /dev/null
@@ -1,35 +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.fuseki.server;
-
-public interface DatasetMXBean
-{
- String getName() ;
-
- long getRequests() ;
- long getRequestsGood() ;
- long getRequestsBad() ;
-
-// void enable() ;
-// void disable() ;
-// void setReadOnly() ;
-// boolean getReadOnly() ;
-
-}
-
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Endpoint.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Endpoint.java
index 9b95a78..7795baa 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Endpoint.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Endpoint.java
@@ -25,7 +25,7 @@ import org.apache.jena.fuseki.auth.AuthPolicy;
/*
* An {@code Endpoint} is an instance of an {@link Operation} within a {@link DataService} and has counters.
- * An {@code Endpoint} may have a name which is a path component.
+ * An {@code Endpoint} may have a name which is a path component.
*/
public class Endpoint implements Counters {
@@ -39,7 +39,7 @@ public class Endpoint implements Counters {
this.operation = Objects.requireNonNull(operation, "operation");
if ( operation == null )
throw new InternalErrorException("operation is null");
- this.endpointName = Objects.requireNonNull(endpointName, "endpointName");
+ this.endpointName = endpointName;
this.authPolicy = requestAuth;
// Standard counters - there may be others
counters.add(CounterName.Requests);
@@ -60,8 +60,12 @@ public class Endpoint implements Counters {
return operation.equals(operation);
}
+ public boolean isUnnamed() {
+ return endpointName == null || endpointName.isEmpty();
+ }
+
public String getName() {
- return endpointName;
+ return isUnnamed() ? "" : endpointName;
}
public AuthPolicy getAuthPolicy() {
@@ -80,4 +84,8 @@ public class Endpoint implements Counters {
return counters.value(CounterName.RequestsBad);
}
+ @Override
+ public String toString() {
+ return getName()+"["+operation+"]";
+ }
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/EndpointSet.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/EndpointSet.java
new file mode 100644
index 0000000..fe0edc9
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/EndpointSet.java
@@ -0,0 +1,119 @@
+/*
+ * 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.fuseki.server;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.StringJoiner;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.BiConsumer;
+
+import org.apache.jena.atlas.logging.Log;
+import org.apache.jena.fuseki.servlets.Dispatcher;
+import org.apache.jena.fuseki.servlets.HttpAction;
+
+/** Collection of endpoints for a dispatch point.
+ * A dispatch point is a URL name, without queyr string or content-type.
+ * {@linkplain Dispatcher#chooseOperation(HttpAction)} looks at request and decides which
+ * {@linkplain Operation} is being requested.
+ *
+ * {@linkplain Dispatcher#chooseEndpoint} looks at request,
+ * and a {@linkplain DataService}
+ * and decides the endpoint.
+ *
+ * There can be only be one endpoint for each operation in a {@code EndpointSet}.
+ */
+public class EndpointSet {
+ private final String name;
+ // Fast path for a set of one endpoint.
+ private Endpoint single;
+ private Map<Operation, Endpoint> endpoints = new ConcurrentHashMap<>();
+
+ public EndpointSet(String name) {
+ super();
+ this.name = name;
+ this.single = null;
+ }
+
+ public void put(Endpoint endpoint) {
+ if ( name != null ) {
+ if ( ! endpoint.getName().equals(name) )
+ Log.warn(EndpointSet.class, "Different endpoint name: set = '"+name+"' : endpoint = '"+endpoint.getName()+"'");
+ } else {
+ if ( ! endpoint.isUnnamed() )
+ Log.warn(EndpointSet.class, "Different endpoint name: set = '' : endpoint = '"+endpoint.getName()+"'");
+ }
+ Operation operation = endpoint.getOperation();
+ if ( endpoints.containsKey(operation) ) {
+ Log.warn(EndpointSet.class, "Redefining endpoint for "+operation);
+ }
+ Endpoint endpointPrev = endpoints.put(operation, endpoint);
+ resetSingle();
+ }
+
+ public void remove(Endpoint endpoint) {
+ endpoints.remove(endpoint.getOperation());
+ resetSingle();
+ }
+
+ public Endpoint get(Operation operation) {
+ return endpoints.get(operation);
+ }
+
+ public boolean contains(Operation operation) {
+ return endpoints.containsKey(operation);
+ }
+
+ public boolean isEmpty() {
+ return endpoints.isEmpty();
+ }
+
+ public int size() {
+ return endpoints.size();
+ }
+
+ public void forEach(BiConsumer<Operation, Endpoint> action) { endpoints.forEach(action); }
+
+ private void resetSingle() {
+ if ( endpoints.size() == 1 )
+ single = endpoints.values().iterator().next();
+ else {
+ // Set to null IFF not null. Debug point.
+ if ( single != null)
+ single = null;
+ }
+ }
+
+ public Collection<Endpoint> endpoints() { return endpoints.values(); }
+
+ public Collection<Operation> operations() { return endpoints.keySet(); }
+
+ /** Get the Endpoint for a singleton EndpointSet */
+ public Endpoint getOnly() {
+ return single;
+ }
+
+ @Override
+ public String toString() {
+ String x = (name==null)?"":name;
+ StringJoiner sj = new StringJoiner(", ", "[", "]");
+ operations().forEach(op->sj.add(op.toString()));
+ return x+sj.toString();
+ }
+}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiInfo.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiInfo.java
index 8312d1a..2800060 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiInfo.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiInfo.java
@@ -18,10 +18,10 @@
package org.apache.jena.fuseki.server;
-import java.util.ArrayList ;
-import java.util.LinkedHashMap ;
-import java.util.List ;
-import java.util.Map ;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
import java.util.function.Function;
import org.apache.jena.atlas.logging.FmtLog;
@@ -29,7 +29,7 @@ import org.apache.jena.fuseki.Fuseki;
import org.slf4j.Logger;
public class FusekiInfo {
-
+
public static void info(FusekiInitialConfig serverConfig, DataAccessPointRegistry registry) {
if ( ! serverConfig.verbose )
return;
@@ -38,21 +38,21 @@ public class FusekiInfo {
Logger log = Fuseki.serverLog;
FmtLog.info(log, "Apache Jena Fuseki");
-
+
// Dataset -> Endpoints
Map<String, List<String>> z = description(registry);
-
+
// if ( serverConfig.empty ) {
-// FmtLog.info(log, "No SPARQL datasets services");
+// FmtLog.info(log, "No SPARQL datasets services");
// } else {
// if ( serverConfig.datasetPath == null && serverConfig.serverConfig == null )
// log.error("No dataset path nor server configuration file");
// }
-
+
if ( serverConfig.datasetPath != null ) {
if ( z.size() != 1 )
log.error("Expected only one dataset");
- List<String> endpoints = z.get(serverConfig.datasetPath);
+ List<String> endpoints = z.get(serverConfig.datasetPath);
FmtLog.info(log, "Dataset Type = %s", serverConfig.datasetDescription);
FmtLog.info(log, "Path = %s; Services = %s", serverConfig.datasetPath, endpoints);
}
@@ -65,7 +65,7 @@ public class FusekiInfo {
}
FusekiInfo.logDetails(log);
}
-
+
private static Map<String, List<String>> description(DataAccessPointRegistry reg) {
Map<String, List<String>> desc = new LinkedHashMap<>();
reg.forEach((ds,dap)->{
@@ -77,13 +77,13 @@ public class FusekiInfo {
String x = ep.getName();
if ( x.isEmpty() )
x = "quads";
- endpoints.add(x);
+ endpoints.add(x);
});
});
});
return desc;
}
-
+
public static void logDetails(Logger log) {
long maxMem = Runtime.getRuntime().maxMemory();
long totalMem = Runtime.getRuntime().totalMemory();
@@ -97,7 +97,7 @@ public class FusekiInfo {
FmtLog.info(log, " Memory: max=%s", f.apply(maxMem));
FmtLog.info(log, " OS: %s %s %s", System.getProperty("os.name"), System.getProperty("os.version"), System.getProperty("os.arch"));
}
-
+
public static void logDetailsVerbose(Logger log) {
logDetails(log);
logOne(log, "java.vendor");
@@ -111,7 +111,7 @@ public class FusekiInfo {
logOne(log, "user.dir");
//logOne(log, "file.encoding");
}
-
+
private static void logOne(Logger log, String property) {
FmtLog.info(log, " %-20s = %s", property, System.getProperty(property));
}
@@ -129,7 +129,7 @@ public class FusekiInfo {
return String.format("%.1fG", x/(1024.0*1024*1024));
return String.format("%.1fT", x/(1024.0*1024*1024*1024));
}
-
+
/** Create a human-friendly string for a number based on Kilo/Mega/Giga/Tera (powers of 10) */
public static String strNum10(long x) {
@@ -143,7 +143,7 @@ public class FusekiInfo {
return String.format("%.1fG", x/(1000.0*1000*1000));
return String.format("%.1fT", x/(1000.0*1000*1000*1000));
}
-
+
/** Create a human-friendly string for a number based on Kibi/Mebi/Gibi/Tebi (powers of 2) */
public static String strNum2(long x) {
// https://en.wikipedia.org/wiki/Kibibyte
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiInitialConfig.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiInitialConfig.java
index 5c44802..2eb0ecb 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiInitialConfig.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiInitialConfig.java
@@ -18,45 +18,45 @@
package org.apache.jena.fuseki.server;
-import java.util.HashMap ;
-import java.util.Map ;
+import java.util.HashMap;
+import java.util.Map;
import org.apache.jena.fuseki.Fuseki;
-import org.apache.jena.sparql.core.DatasetGraph ;
+import org.apache.jena.sparql.core.DatasetGraph;
/** Dataset setup (command line, config file) for a dataset (or several if config file) */
public class FusekiInitialConfig {
- public boolean quiet = false ;
- public boolean verbose = Fuseki.verboseLogging ;
-
- // Priority order : --conf, templated
+ public boolean quiet = false;
+ public boolean verbose = Fuseki.verboseLogging;
+
+ // Priority order : --conf, templated
// through the command line processing should not allow --conf and a templated /dataset.
-
+
// Label for dataset setup (command line).
- public String datasetDescription = null ;
+ public String datasetDescription = null;
// Either this ... command line ...
- public String argTemplateFile = null ; // Command list args --mem, --loc, --memtdb
- public String datasetPath = null ; // Dataset name on the command line.
- public boolean allowUpdate = false ; // Command line --update.
+ public String argTemplateFile = null; // Command list args --mem, --loc, --memtdb
+ public String datasetPath = null; // Dataset name on the command line.
+ public boolean allowUpdate = false; // Command line --update.
// Special case - prebuilt dataset. Uses datasetPath.
- public DatasetGraph dsg = null ; // Embedded or command line --file)
-
- // Or configuration file from command line
- public String fusekiCmdLineConfigFile = null ; // Command line --conf.
+ public DatasetGraph dsg = null; // Embedded or command line --file)
+
+ // Or configuration file from command line
+ public String fusekiCmdLineConfigFile = null; // Command line --conf.
// Or configuration from run area (lowest priority)
- public String fusekiServerConfigFile = null ; // "run" area
-
+ public String fusekiServerConfigFile = null; // "run" area
+
// Additional information.
- public Map<String,String> params = new HashMap<>() ;
-
+ public Map<String,String> params = new HashMap<>();
+
public FusekiInitialConfig() {}
-
+
public void reset() {
- argTemplateFile = null ;
- datasetPath = null ;
- allowUpdate = false ;
- dsg = null ;
- fusekiCmdLineConfigFile = null ; // Command line --conf.
- fusekiServerConfigFile = null ;
+ argTemplateFile = null;
+ datasetPath = null;
+ allowUpdate = false;
+ dsg = null;
+ fusekiCmdLineConfigFile = null; // Command line --conf.
+ fusekiServerConfigFile = null;
}
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiVocab.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiVocab.java
index 54c1858..a2c0c55 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiVocab.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiVocab.java
@@ -34,12 +34,12 @@ public class FusekiVocab
public static final Property pServices = property("services");
public static final Property pServiceName = property("name");
-
+
public static final Property pAllowedUsers = property("allowedUsers");
public static final Property pPasswordFile = property("passwd");
public static final Property pRealm = property("realm");
public static final Property pAuth = property("auth");
-
+
// Server endpoints.
public static final Property pServerPing = property("pingEP");
public static final Property pServerStats = property("statsEP");
@@ -54,33 +54,32 @@ public class FusekiVocab
public static final Property pAllowTimeoutOverride = property("allowTimeoutOverride");
public static final Property pMaximumTimeoutOverride = property("maximumTimeoutOverride");
-
+
// Internal
-
+
private static final String stateNameActive = DataServiceStatus.ACTIVE.name;
private static final String stateNameOffline = DataServiceStatus.OFFLINE.name;
private static final String stateNameClosing = DataServiceStatus.CLOSING.name;
private static final String stateNameClosed = DataServiceStatus.CLOSED.name;
-
+
public static final Resource stateActive = resource(stateNameActive);
public static final Resource stateOffline = resource(stateNameOffline);
public static final Resource stateClosing = resource(stateNameClosing);
public static final Resource stateClosed = resource(stateNameClosed);
-
+
// public static final Property pStatus = property("status");
private static Resource resource(String localname) { return model.createResource(iri(localname)); }
private static Property property(String localname) { return model.createProperty(iri(localname)); }
-
- private static String iri(String localname)
- {
- String uri = NS+localname;
+
+ private static String iri(String localname) {
+ String uri = NS + localname;
IRI iri = IRIResolver.parseIRI(uri);
if ( iri.hasViolation(true) )
throw new FusekiException("Bad IRI: "+iri);
if ( ! iri.isAbsolute() )
throw new FusekiException("Bad IRI: "+iri);
-
+
return uri;
}
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/NameMgr.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/NameMgr.java
index d0d97d0..eddad0a 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/NameMgr.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/NameMgr.java
@@ -32,11 +32,11 @@ import java.util.function.Function;
*/
public class NameMgr<T> {
private final Map<String, T> registered = new ConcurrentHashMap<>();
-
+
/** register, creating an object is necessary */
public T register(String name, Function<String, T> maker) {
return registered.computeIfAbsent(name, maker);
}
-
+
public NameMgr() { }
}
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 f9afc8a..1d0694e 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,46 +18,41 @@
package org.apache.jena.fuseki.server;
-import org.apache.jena.fuseki.servlets.ServiceDispatchRegistry;
+import org.apache.jena.fuseki.servlets.OperationRegistry;
/**
- * Operations are symbol to look up in the {@link ServiceDispatchRegistry#operationToHandler} map. The name
+ * Operations are symbol to look up in the {@link OperationRegistry#operationToHandler} map. The name
* of an {@code Operation} is not related to the service name used to invoke the operation
* which is determined by the {@link Endpoint}.
*/
public class Operation {
-
- /** Create/intern. */
- static private NameMgr<Operation> mgr = new NameMgr<>();
+
+ /** Create/intern. */
+ static private NameMgr<Operation> mgr = new NameMgr<>();
static public Operation register(String name, String description) {
return mgr.register(name, (x)->create(x, description));
}
-
+
/** Create; not registered */
static private Operation create(String name, String description) {
return new Operation(name, description);
}
-
+
public static final Operation Query = register("Query", "SPARQL Query");
public static final Operation Update = register("Update", "SPARQL Update");
public static final Operation Upload = register("Upload", "File Upload");
+ public static final Operation Patch = register("Patch", "RDF Patch");
public static final Operation GSP_R = register("GSP_R", "Graph Store Protocol (Read)");
public static final Operation GSP_RW = register("GSP_RW", "Graph Store Protocol");
- public static final Operation Quads_R = register("Quads_R", "HTTP Quads (Read)");
- public static final Operation Quads_RW = register("Quads_RW", "HTTP Quads");
-
- // Plain REST operations on the dataset URL
- public static final Operation DatasetRequest_R = Quads_R;
- public static final Operation DatasetRequest_RW = Quads_RW;
-
- private final String description ;
- private final String name ;
+
+ private final String description;
+ private final String name;
private Operation(String name, String description) {
this.name = name;
this.description = description;
}
-
+
public String getName() {
return name;
}
@@ -65,7 +60,7 @@ public class Operation {
public String getDescription() {
return description;
}
-
+
@Override
public int hashCode() {
final int prime = 31;
@@ -73,10 +68,10 @@ public class Operation {
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
-
+
// Could be this == obj
// because we intern'ed the object
-
+
@Override
public boolean equals(Object obj) {
if ( this == obj )
@@ -93,7 +88,7 @@ public class Operation {
return false;
return true;
}
-
+
@Override
public String toString() {
return name;
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/RequestLog.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/RequestLog.java
index a5fc722..86a1ff3 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/RequestLog.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/RequestLog.java
@@ -18,20 +18,20 @@
package org.apache.jena.fuseki.server;
-import java.text.DateFormat ;
-import java.text.SimpleDateFormat ;
-import java.util.Collection ;
-import java.util.Date ;
-import java.util.Enumeration ;
-import java.util.TimeZone ;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.TimeZone;
-import javax.servlet.http.HttpServletRequest ;
-import javax.servlet.http.HttpServletResponse ;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
-import org.apache.jena.atlas.logging.Log ;
-import org.apache.jena.fuseki.servlets.HttpAction ;
+import org.apache.jena.atlas.logging.Log;
+import org.apache.jena.fuseki.servlets.HttpAction;
-/** Create standard request logs (NCSA etc) */
+/** Create standard request logs (NCSA etc) */
public class RequestLog {
/*
http://httpd.apache.org/docs/current/mod/mod_log_config.html
@@ -52,100 +52,102 @@ NCSA extended/combined log format
Headers.
%{}i for request header.
%{}o for response header.
- */
-
- private static DateFormat dateFormatter ;
+ */
+
+ private static DateFormat dateFormatter;
static {
- dateFormatter = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss Z") ;
+ dateFormatter = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss Z");
dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
}
- /** NCSA combined log format *
+ /**
+ * NCSA combined log format
+ *
* LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combinedfwd
- * XXX.XXX.XXX.XXX - - [01/Feb/2014:03:19:09 +0000] "GET / HTTP/1.1" 200 6190 "-" "check_http/v1.4.16 (nagios-plugins 1.4.16)"
+ * xxx.xxx.xxx.xxx - - [01/Feb/2014:03:19:09 +0000] "GET / HTTP/1.1" 200 6190 "-" "check_http/v1.4.16 (nagios-plugins 1.4.16)"
*/
public static String combinedNCSA(HttpAction action) {
- HttpServletRequest request = action.request ;
- HttpServletResponse response = action.response ;
- return combinedNCSA(request, response) ;
+ HttpServletRequest request = action.request;
+ HttpServletResponse response = action.response;
+ return combinedNCSA(request, response);
}
-
+
public static String combinedNCSA(HttpServletRequest request, HttpServletResponse response) {
- StringBuilder builder = new StringBuilder() ;
+ StringBuilder builder = new StringBuilder();
// Remote
- String remote = get(request, "X-Forwarded-For", request.getRemoteAddr()) ;
- builder.append(remote) ;
- builder.append(" ") ;
-
+ String remote = get(request, "X-Forwarded-For", request.getRemoteAddr());
+ builder.append(remote);
+ builder.append(" ");
+
// %l %u : User identity (unrelaible)
- builder.append("- - ") ;
-
+ builder.append("- - ");
+
// %t
- // Expensive?
+ // Expensive?
builder.append("[");
// Better?
- builder.append(dateFormatter.format(new Date())) ;
+ builder.append(dateFormatter.format(new Date()));
builder.append("] ");
-
+
// "%r"
- builder.append("\"") ;
- builder.append(request.getMethod()) ;
- builder.append(" ") ;
+ builder.append("\"");
+ builder.append(request.getMethod());
+ builder.append(" ");
// No query string - they are long and logged readably elsewhere
- builder.append(request.getRequestURI()) ;
- builder.append("\"") ;
+ builder.append(request.getRequestURI());
+ builder.append("\"");
//%>s -- Final request status
- builder.append(" ") ;
- builder.append(response.getStatus()) ;
-
+ builder.append(" ");
+ builder.append(response.getStatus());
+
//%b -- Size in bytes
- builder.append(" ") ;
+ builder.append(" ");
//String size = getField()
- String size = get(response, "Content-Length", "-") ;
- builder.append(size) ;
-
- // "%{Referer}i"
- builder.append(" \"") ;
- builder.append(get(request, "Referer", "")) ;
- builder.append("\"") ;
+ String size = get(response, "Content-Length", "-");
+ builder.append(size);
+
+ // "%{Referer}i"
+ builder.append(" \"");
+ builder.append(get(request, "Referer", ""));
+ builder.append("\"");
// "%{User-Agent}i"
- builder.append(" \"") ;
- builder.append(get(request, "User-Agent", "")) ;
- builder.append("\"") ;
-
- return builder.toString() ;
+ builder.append(" \"");
+ builder.append(get(request, "User-Agent", ""));
+ builder.append("\"");
+
+ return builder.toString();
}
-
+
private static String get(HttpServletRequest request, String name, String dft) {
- String x = get(request, name) ;
+ String x = get(request, name);
if ( x == null )
- x = dft ;
- return x ;
+ x = dft;
+ return x;
}
-
+
private static String get(HttpServletRequest request, String name) {
- Enumeration<String> en = request.getHeaders(name) ;
- if ( ! en.hasMoreElements() ) return null ;
- String x = en.nextElement() ;
+ Enumeration<String> en = request.getHeaders(name);
+ if ( ! en.hasMoreElements() ) return null;
+ String x = en.nextElement();
if ( en.hasMoreElements() ) {
- Log.warn(RequestLog.class, "Multiple request header values") ;
+ Log.warn(RequestLog.class, "Multiple request header values");
}
- return x ;
+ return x;
}
private static String get(HttpServletResponse response, String name, String dft) {
- String x = get(response, name) ;
+ String x = get(response, name);
if ( x == null )
- x = dft ;
- return x ;
+ x = dft;
+ return x;
}
-
+
private static String get(HttpServletResponse response, String name) {
- Collection<String> en = response.getHeaders(name) ;
- if ( en.isEmpty() )return null ;
- if ( en.size() != 1 ) Log.warn(RequestLog.class, "Multiple response header values") ;
- return response.getHeader(name) ;
+ Collection<String> en = response.getHeaders(name);
+ if ( en.isEmpty() )return null;
+ if ( en.size() != 1 ) Log.warn(RequestLog.class, "Multiple response header values");
+ return response.getHeader(name);
}
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/ServerConst.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/ServerConst.java
index f8b0f91..6c3ac6a 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/ServerConst.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/ServerConst.java
@@ -18,24 +18,24 @@
package org.apache.jena.fuseki.server;
-/** Various constants used in the API functions and JSON responses. */
+/** Various constants used in the API functions and JSON responses. */
public class ServerConst {
// Location under /$/
- public static final String opDump = "dump" ;
- public static final String opPing = "ping" ;
- public static final String opStats = "stats" ;
-
+ public static final String opDump = "dump";
+ public static final String opPing = "ping";
+ public static final String opStats = "stats";
+
// // JSON constants
- public static final String datasets = "datasets" ;
- public static final String operation = "operation" ;
- public static final String description = "description" ;
- public static final String endpoints = "endpoints" ;
+ public static final String datasets = "datasets";
+ public static final String operation = "operation";
+ public static final String description = "description";
+ public static final String endpoints = "endpoints";
- public static final String dsName = "ds.name" ;
- public static final String dsState = "ds.state" ;
- public static final String dsService = "ds.services" ;
- public static final String srvType = "srv.type" ;
- public static final String srvDescription = "srv.description" ;
- public static final String srvEndpoints = "srv.endpoints" ;
+ public static final String dsName = "ds.name";
+ public static final String dsState = "ds.state";
+ public static final String dsService = "ds.services";
+ public static final String srvType = "srv.type";
+ public static final String srvDescription = "srv.description";
+ public static final String srvEndpoints = "srv.endpoints";
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/ServiceOnly.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/ServiceOnly.java
deleted file mode 100644
index 857fdcd..0000000
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/ServiceOnly.java
+++ /dev/null
@@ -1,44 +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.fuseki.server;
-
-import org.apache.jena.fuseki.DEF;
-import org.apache.jena.sparql.core.DatasetGraph;
-import org.apache.jena.sparql.core.DatasetGraphSink;
-
-/** Configuration for a "no dataset" service */
-public class ServiceOnly {
-
- public static DataService dataService() {
- return serviceOnlyDataService;
- }
-
- public static DataAccessPoint dataAccessPoint() {
- return null;
- }
-
- private static final DataService serviceOnlyDataService;
- static {
- DatasetGraph dsg = new DatasetGraphSink();
- serviceOnlyDataService = new DataService(dsg);
- serviceOnlyDataService.addEndpoint(Operation.Query, DEF.ServiceQuery);
- serviceOnlyDataService.addEndpoint(Operation.Query, DEF.ServiceQueryAlt);
- }
- private static final DataAccessPoint serviceOnlyDataAccessPoint = new DataAccessPoint("", serviceOnlyDataService);
-}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionBase.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionBase.java
index 4ba0ede..a337eda 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionBase.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionBase.java
@@ -18,260 +18,49 @@
package org.apache.jena.fuseki.servlets;
-import static java.lang.String.format ;
-
-import java.io.IOException ;
-import java.util.Enumeration ;
-import java.util.Map ;
-
-import javax.servlet.http.HttpServletRequest ;
-import javax.servlet.http.HttpServletResponse ;
-
-import org.apache.jena.atlas.RuntimeIOException ;
-import org.apache.jena.atlas.web.HttpException;
-import org.apache.jena.query.QueryCancelledException ;
-import org.apache.jena.riot.web.HttpNames ;
-import org.apache.jena.web.HttpSC ;
-import org.slf4j.Logger ;
-
-/** General request lifecycle */
-public abstract class ActionBase extends ServletBase
-{
- protected final Logger log ;
-
- protected ActionBase(Logger log) {
- super() ;
- this.log = log ;
- }
-
- @Override
- public void init() {
-// log.info("["+Utils.className(this)+"] ServletContextName = "+getServletContext().getServletContextName()) ;
-// log.info("["+Utils.className(this)+"] ContextPath = "+getServletContext().getContextPath()) ;
- }
-
- /**
- * Common framework for handling HTTP requests.
- * @param request
- * @param response
- */
- protected void doCommon(HttpServletRequest request, HttpServletResponse response)
- {
- try {
- long id = allocRequestId(request, response);
-
- // Lifecycle
- HttpAction action = allocHttpAction(id, request, response) ;
-
- printRequest(action) ;
- action.setStartTime() ;
-
- // The response may be changed to a HttpServletResponseTracker
- response = action.response ;
- initResponse(request, response) ;
- try {
- startRequest(action);
- execCommonWorker(action) ;
- } catch (QueryCancelledException ex) {
- // To put in the action timeout, need (1) global, (2) dataset and (3) protocol settings.
- // See
- // global -- cxt.get(ARQ.queryTimeout)
- // dataset -- dataset.getContect(ARQ.queryTimeout)
- // protocol -- SPARQL_Query.setAnyTimeouts
-
- String message = String.format("Query timed out");
- // Possibility :: response.setHeader("Retry-after", "600") ; // 5 minutes
- ServletOps.responseSendError(response, HttpSC.SERVICE_UNAVAILABLE_503, message);
- } catch (ActionErrorException ex) {
- if ( ex.getCause() != null )
- ex.getCause().printStackTrace(System.err) ;
- // Log message done by printResponse in a moment.
- if ( ex.getMessage() != null )
- ServletOps.responseSendError(response, ex.getRC(), ex.getMessage()) ;
- else
- ServletOps.responseSendError(response, ex.getRC()) ;
- } catch (HttpException ex) {
- // Some code is passing up its own HttpException.
- if ( ex.getMessage() == null )
- ServletOps.responseSendError(response, ex.getResponseCode());
- else
- ServletOps.responseSendError(response, ex.getResponseCode(), ex.getMessage());
- } catch (RuntimeIOException ex) {
- log.warn(format("[%d] Runtime IO Exception (client left?) RC = %d : %s", id, HttpSC.INTERNAL_SERVER_ERROR_500, ex.getMessage()), ex) ;
- ServletOps.responseSendError(response, HttpSC.INTERNAL_SERVER_ERROR_500, ex.getMessage()) ;
- } catch (Throwable ex) {
- // This should not happen.
- //ex.printStackTrace(System.err) ;
- log.warn(format("[%d] RC = %d : %s", id, HttpSC.INTERNAL_SERVER_ERROR_500, ex.getMessage()), ex) ;
- ServletOps.responseSendError(response, HttpSC.INTERNAL_SERVER_ERROR_500, ex.getMessage()) ;
- } finally {
- action.setFinishTime() ;
- finishRequest(action);
- }
- printResponse(action) ;
- archiveHttpAction(action) ;
- } catch (Throwable th) {
- log.error("Internal error", th) ;
- }
- }
-
- // ---- Operation lifecycle
+/**
+ * Base of all implementations of service {@link HttpAction}. This class provides the
+ * two steps execution of "validate" and "perform".
+ *
+ * Subclasses choose which HTTP
+ * methods they handle by implementing "execGet(HttpAction)" etc. These often call
+ * {@link #executeLifecycle} for their normal {@code HttpAction} lifecycle, for example,
+ * when GET and POST do the same steps so common "validate" and "execute".
+ *
+ * See {@link ActionExecLib#execAction} for the common ActionProcessor execution with logging and error handling.
+ * This is used by {@link Dispatcher#dispatchAction(HttpAction)}.
+ *
+ * See {@link ActionService} which overrides {@link #executeLifecycle} to add statistics counters.
+ *
+ * Some operations like OPTIONS will implement differently.
+ *
+ * <pre>
+ * public void execGet(HttpAction action) { super.executeLifecycle(action); }
+ * </pre>
+ *
+ */
+public abstract class ActionBase implements ActionProcessor, ActionLifecycle {
+ protected ActionBase() { }
/**
- * Returns a fresh HTTP Action for this request.
- * @param id the Request ID
- * @param request HTTP request
- * @param response HTTP response
- * @return a new HTTP Action
+ * Subclasses must override {@code execGet}, {@code execPost} etc to say which
+ * methods they support.
+ * Typically, the implementation is a call to {@code executeLifecycle(action)}.
*/
- protected HttpAction allocHttpAction(long id, HttpServletRequest request, HttpServletResponse response) {
- // Need a way to set verbose logging on a per servlet and per request basis.
- return new HttpAction(id, log, request, response);
+ @Override
+ public void process(HttpAction action) {
+ // Enforce splitting to be "exec" for each HTTP method.
+ ActionProcessor.super.process(action);
}
/**
- * Begin handling an {@link HttpAction}
+ * Simple execution lifecycle for a SPARQL Request.
+ * No statistics.
+ *
* @param action
*/
- protected final void startRequest(HttpAction action) {
- action.startRequest() ;
- }
-
- /**
- * Stop handling an {@link HttpAction}
- */
- protected final void finishRequest(HttpAction action) {
- action.finishRequest() ;
- }
-
- /**
- * Archives the HTTP Action.
- * @param action HTTP Action
- * @see HttpAction#minimize()
- */
- private void archiveHttpAction(HttpAction action) {
- action.minimize() ;
- }
-
- /**
- * Execute this request, which maybe a admin operation or a client request.
- * @param action HTTP Action
- */
- protected abstract void execCommonWorker(HttpAction action) ;
-
- /**
- * Extract the name after the container name (servlet name).
- * @param action an HTTP action
- * @return item name as "/name" or {@code null}
- */
- protected static String extractItemName(HttpAction action) {
-// action.log.info("context path = "+action.request.getContextPath()) ;
-// action.log.info("pathinfo = "+action.request.getPathInfo()) ;
-// action.log.info("servlet path = "+action.request.getServletPath()) ;
- // if /name
- // request.getServletPath() otherwise it's null
- // if /*
- // request.getPathInfo() ; otherwise it's null.
-
- // PathInfo is after the servlet name.
- String x1 = action.request.getServletPath() ;
- String x2 = action.request.getPathInfo() ;
-
- String pathInfo = action.request.getPathInfo() ;
- if ( pathInfo == null || pathInfo.isEmpty() || pathInfo.equals("/") )
- // Includes calling as a container.
- return null ;
- String name = pathInfo ;
- // pathInfo starts with a "/"
- int idx = pathInfo.lastIndexOf('/') ;
- if ( idx > 0 )
- name = name.substring(idx) ;
- // Returns "/name"
- return name ;
- }
-
- protected void doPatch(HttpServletRequest request, HttpServletResponse response) throws IOException {
- response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "HTTP PATCH not supported");
- }
-
- private void printRequest(HttpAction action) {
- String url = ActionLib.wholeRequestURL(action.request) ;
- String method = action.request.getMethod() ;
-
- log.info(format("[%d] %s %s", action.id, method, url)) ;
- if ( action.verbose ) {
- Enumeration<String> en = action.request.getHeaderNames() ;
- for (; en.hasMoreElements();) {
- String h = en.nextElement() ;
- Enumeration<String> vals = action.request.getHeaders(h) ;
- if ( !vals.hasMoreElements() )
- log.info(format("[%d] => %s", action.id, h+":")) ;
- else {
- for (; vals.hasMoreElements();)
- log.info(format("[%d] => %-20s %s", action.id, h+":", vals.nextElement())) ;
- }
- }
- }
- }
-
- private void initResponse(HttpServletRequest request, HttpServletResponse response) {
- setCommonHeaders(response) ;
- String method = request.getMethod() ;
- // All GET and HEAD operations are sensitive to conneg so ...
- if ( HttpNames.METHOD_GET.equalsIgnoreCase(method) || HttpNames.METHOD_HEAD.equalsIgnoreCase(method) )
- setVaryHeader(response) ;
- }
-
- private void printResponse(HttpAction action) {
- long time = action.getTime() ;
-
- HttpServletResponseTracker response = action.response ;
- if ( action.verbose ) {
- if ( action.responseContentType != null )
- log.info(format("[%d] <= %-20s %s", action.id, HttpNames.hContentType+":", action.responseContentType)) ;
- if ( action.responseContentLength != -1 )
- log.info(format("[%d] <= %-20s %d", action.id, HttpNames.hContentLengh+":", action.responseContentLength)) ;
- for (Map.Entry<String, String> e : action.headers.entrySet()) {
- // Skip already printed.
- if ( e.getKey().equalsIgnoreCase(HttpNames.hContentType) && action.responseContentType != null)
- continue;
- if ( e.getKey().equalsIgnoreCase(HttpNames.hContentLengh) && action.responseContentLength != -1)
- continue;
- log.info(format("[%d] <= %-20s %s", action.id, e.getKey()+":", e.getValue())) ;
- }
- }
-
- String timeStr = fmtMillis(time) ;
-
- if ( action.message == null )
- log.info(String.format("[%d] %d %s (%s)", action.id, action.statusCode,
- HttpSC.getMessage(action.statusCode), timeStr)) ;
- else
- log.info(String.format("[%d] %d %s (%s)", action.id, action.statusCode, action.message, timeStr)) ;
-
- // See also HttpAction.finishRequest - request logging happens there.
- }
-
- /**
- * <p>Given a time point, return the time as a milli second string if it is less than 1000,
- * otherwise return a seconds string.</p>
- * <p>It appends a 'ms' suffix when using milli seconds,
- * and 's' for seconds.</p>
- * <p>For instance: </p>
- * <ul>
- * <li>10 emits 10 ms</li>
- * <li>999 emits 999 ms</li>
- * <li>1000 emits 1.000 s</li>
- * <li>10000 emits 10.000 s</li>
- * </ul>
- * @param time the time in milliseconds
- * @return the time as a display string
- */
-
- private static String fmtMillis(long time) {
- // Millis only? seconds only?
- if ( time < 1000 )
- return String.format("%,d ms", time) ;
- return String.format("%,.3f s", time / 1000.0) ;
+ protected void executeLifecycle(HttpAction action) {
+ validate(action);
+ execute(action);
}
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionErrorException.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionErrorException.java
index 0c8d57c..d3784cf 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionErrorException.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionErrorException.java
@@ -18,16 +18,14 @@
package org.apache.jena.fuseki.servlets;
-public class ActionErrorException extends RuntimeException
-{
- private final int rc ;
-
- public ActionErrorException(Throwable ex, String message, int rc)
- {
- super(message, ex) ;
- this.rc = rc ;
+public class ActionErrorException extends RuntimeException {
+ private final int rc;
+
+ public ActionErrorException(Throwable ex, String message, int rc) {
+ super(message, ex);
+ this.rc = rc;
}
-
+
public int getRC() {
return rc;
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionExecLib.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionExecLib.java
new file mode 100644
index 0000000..4a347c9
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionExecLib.java
@@ -0,0 +1,310 @@
+/*
+ * 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.fuseki.servlets;
+
+import java.util.Enumeration;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.Supplier;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.jena.atlas.RuntimeIOException;
+import org.apache.jena.atlas.logging.FmtLog;
+import org.apache.jena.atlas.logging.Log;
+import org.apache.jena.atlas.web.HttpException;
+import org.apache.jena.fuseki.Fuseki;
+import org.apache.jena.fuseki.server.*;
+import org.apache.jena.query.QueryCancelledException;
+import org.apache.jena.riot.web.HttpNames;
+import org.apache.jena.web.HttpSC;
+import org.slf4j.Logger;
+
+/**
+ * Functions relating to {@link HttpAction} objects, including the standard execute with logging process ({@link #execAction})
+ */
+public class ActionExecLib {
+
+ /**
+ * Returns a fresh HTTP Action for this request.
+ * @param dap
+ * @param request HTTP request
+ * @param response HTTP response
+ * @return a new HTTP Action
+ */
+ public static HttpAction allocHttpAction(DataAccessPoint dap, Logger log, HttpServletRequest request, HttpServletResponse response) {
+ long id = allocRequestId(request, response);
+ // Need a way to set verbose logging on a per servlet and per request basis.
+ HttpAction action = new HttpAction(id, log, request, response);
+ if ( dap != null ) {
+ // TODO remove setRequest?
+ DataService dataService = dap.getDataService();
+ action.setRequest(dap, dataService);
+ }
+ return action;
+ }
+
+ /**
+ * Standard execution lifecycle for a SPARQL Request.
+ * <ul>
+ * <li>{@link #startRequest(HttpAction)}</li>
+ * <li>initial statistics,</li>
+ * <li>{@link ActionLifecycle#validate(HttpAction)} request,</li>
+ * <li>{@link ActionLifecycle#execute(HttpAction)} request,</li>
+ * <li>completion/error statistics,</li>
+ * <li>{@link #finishRequest(HttpAction)}
+ * </ul>
+ * Common process for handling HTTP requests with logging and Java error handling.
+ * @param action
+ * @param processor
+ */
+ public static void execAction(HttpAction action, ActionProcessor processor) {
+ execAction(action, ()->processor);
+ }
+
+ /** execAction, allowing for a choice of {@link ActionProcessor} within the logging and error handling. */
+ public static void execAction(HttpAction action, Supplier<ActionProcessor> processor) {
+ try {
+ logRequest(action);
+ action.setStartTime();
+ initResponse(action);
+ HttpServletResponse response = action.response;
+
+ startRequest(action);
+
+ try {
+ // Get the processor inside the startRequest - error handling - finishRequest sequence.
+ ActionProcessor proc = processor.get();
+ proc.process(action);
+ } catch (QueryCancelledException ex) {
+ // To put in the action timeout, need (1) global, (2) dataset and (3) protocol settings.
+ // See
+ // global -- cxt.get(ARQ.queryTimeout)
+ // dataset -- dataset.getContect(ARQ.queryTimeout)
+ // protocol -- SPARQL_Query.setAnyTimeouts
+ String message = String.format("Query timed out");
+ ServletOps.responseSendError(response, HttpSC.SERVICE_UNAVAILABLE_503, message);
+ } catch (ActionErrorException ex) {
+ if ( ex.getCause() != null )
+ Log.warn(Fuseki.serverLog, "ActionErrorException with cause", ex);
+ // Log message done by printResponse in a moment.
+ if ( ex.getMessage() != null )
+ ServletOps.responseSendError(response, ex.getRC(), ex.getMessage());
+ else
+ ServletOps.responseSendError(response, ex.getRC());
+ } catch (HttpException ex) {
+ // Some code is passing up its own HttpException.
+ if ( ex.getMessage() == null )
+ ServletOps.responseSendError(response, ex.getStatusCode());
+ else
+ ServletOps.responseSendError(response, ex.getStatusCode(), ex.getMessage());
+ } catch (RuntimeIOException ex) {
+ FmtLog.warn(action.log, ex, "[%d] Runtime IO Exception (client left?) RC = %d : %s", action.id, HttpSC.INTERNAL_SERVER_ERROR_500, ex.getMessage());
+ ServletOps.responseSendError(response, HttpSC.INTERNAL_SERVER_ERROR_500, ex.getMessage());
+ } catch (Throwable ex) {
+ // This should not happen.
+ //ex.printStackTrace(System.err);
+ FmtLog.warn(action.log, ex, "[%d] RC = %d : %s", action.id, HttpSC.INTERNAL_SERVER_ERROR_500, ex.getMessage());
+ ServletOps.responseSendError(response, HttpSC.INTERNAL_SERVER_ERROR_500, ex.getMessage());
+ } finally {
+ action.setFinishTime();
+ finishRequest(action);
+ }
+ logResponse(action);
+ archiveHttpAction(action);
+ } catch (Throwable th) {
+ FmtLog.error(action.log, th, "Internal error");
+ }
+ }
+
+ /**
+ * Helper method which gets a unique request ID and appends it as a header to the
+ * response
+ *
+ * @param request HTTP Request
+ * @param response HTTP Response
+ * @return Request ID
+ */
+ public static long allocRequestId(HttpServletRequest request, HttpServletResponse response) {
+ long id = requestIdAlloc.incrementAndGet();
+ addRequestId(response, id);
+ return id;
+ }
+
+ private static AtomicLong requestIdAlloc = new AtomicLong(0);
+
+ /**
+ * Helper method for attaching a request ID to a response as a header
+ *
+ * @param response
+ * Response
+ * @param id
+ * Request ID
+ */
+ public static void addRequestId(HttpServletResponse response, long id) {
+ response.addHeader("Fuseki-Request-ID", Long.toString(id));
+ }
+
+ /**
+ * Begin handling an {@link HttpAction}
+ * @param action
+ */
+ private static void startRequest(HttpAction action) {
+ action.startRequest();
+ }
+
+ /**
+ * Stop handling an {@link HttpAction}
+ */
+ private static void finishRequest(HttpAction action) {
+ action.finishRequest();
+ }
+
+ /** Log an {@link HttpAction} request. */
+ public static void logRequest(HttpAction action) {
+ String url = ActionLib.wholeRequestURL(action.request);
+ String method = action.request.getMethod();
+
+ FmtLog.info(action.log, "[%d] %s %s", action.id, method, url);
+ if ( action.verbose ) {
+ Enumeration<String> en = action.request.getHeaderNames();
+ for (; en.hasMoreElements();) {
+ String h = en.nextElement();
+ Enumeration<String> vals = action.request.getHeaders(h);
+ if ( !vals.hasMoreElements() )
+ FmtLog.info(action.log, "[%d] => %s", action.id, h+":");
+ else {
+ for (; vals.hasMoreElements();)
+ FmtLog.info(action.log, "[%d] => %-20s %s", action.id, h+":", vals.nextElement());
+ }
+ }
+ }
+ }
+
+ /** Log an {@link HttpAction} response. */
+ public static void logResponse(HttpAction action) {
+ long time = action.getTime();
+
+ HttpServletResponseTracker response = action.response;
+ if ( action.verbose ) {
+ if ( action.responseContentType != null )
+ FmtLog.info(action.log,"[%d] <= %-20s %s", action.id, HttpNames.hContentType+":", action.responseContentType);
+ if ( action.responseContentLength != -1 )
+ FmtLog.info(action.log,"[%d] <= %-20s %d", action.id, HttpNames.hContentLengh+":", action.responseContentLength);
+ for (Map.Entry<String, String> e : action.headers.entrySet()) {
+ // Skip already printed.
+ if ( e.getKey().equalsIgnoreCase(HttpNames.hContentType) && action.responseContentType != null)
+ continue;
+ if ( e.getKey().equalsIgnoreCase(HttpNames.hContentLengh) && action.responseContentLength != -1)
+ continue;
+ FmtLog.info(action.log,"[%d] <= %-20s %s", action.id, e.getKey()+":", e.getValue());
+ }
+ }
+
+ String timeStr = fmtMillis(time);
+
+ if ( action.message == null )
+ FmtLog.info(action.log, "[%d] %d %s (%s)",
+ action.id, action.statusCode, HttpSC.getMessage(action.statusCode), timeStr);
+ else
+ FmtLog.info(action.log,"[%d] %d %s (%s)", action.id, action.statusCode, action.message, timeStr);
+
+ // See also HttpAction.finishRequest - request logging happens there.
+ }
+
+ /** Set headers for the response. */
+ public static void initResponse(HttpAction action) {
+ ServletBase.setCommonHeaders(action.response);
+ String method = action.request.getMethod();
+ // All GET and HEAD operations are sensitive to conneg so ...
+ if ( HttpNames.METHOD_GET.equalsIgnoreCase(method) || HttpNames.METHOD_HEAD.equalsIgnoreCase(method) )
+ ServletBase.setVaryHeader(action.response);
+ }
+
+ /**
+ * <p>Given a time point, return the time as a milli second string if it is less than 1000,
+ * otherwise return a seconds string.</p>
+ * <p>It appends a 'ms' suffix when using milli secoOnds,
+ * and 's' for seconds.</p>
+ * <p>For instance: </p>
+ * <ul>
+ * <li>10 emits 10 ms</li>
+ * <li>999 emits 999 ms</li>
+ * <li>1000 emits 1.000 s</li>
+ * <li>10000 emits 10.000 s</li>
+ * </ul>
+ * @param time the time in milliseconds
+ * @return the time as a display string
+ */
+ private static String fmtMillis(long time) {
+ // Millis only? seconds only?
+ if ( time < 1000 )
+ return String.format("%,d ms", time);
+ return String.format("%,.3f s", time / 1000.0);
+ }
+
+ /**
+ * Archives the HTTP Action.
+ * @param action HTTP Action
+ * @see HttpAction#minimize()
+ */
+ private static void archiveHttpAction(HttpAction action) {
+ action.minimize();
+ }
+
+ /** Increment counter */
+ public static void incCounter(Counters counters, CounterName name) {
+ if ( counters == null )
+ return;
+ incCounter(counters.getCounters(), name);
+ }
+
+ /** Decrement counter */
+ public static void decCounter(Counters counters, CounterName name) {
+ if ( counters == null )
+ return;
+ decCounter(counters.getCounters(), name);
+ }
+
+ public static void incCounter(CounterSet counters, CounterName name) {
+ if ( counters == null )
+ return;
+ try {
+ if ( counters.contains(name) )
+ counters.inc(name);
+ }
+ catch (Exception ex) {
+ Fuseki.serverLog.warn("Exception on counter inc", ex);
+ }
+ }
+
+ public static void decCounter(CounterSet counters, CounterName name) {
+ if ( counters == null )
+ return;
+ try {
+ if ( counters.contains(name) )
+ counters.dec(name);
+ }
+ catch (Exception ex) {
+ Fuseki.serverLog.warn("Exception on counter dec", ex);
+ }
+ }
+
+}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionLib.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionLib.java
index 33d51d6..171b4ab 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionLib.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionLib.java
@@ -21,15 +21,17 @@ package org.apache.jena.fuseki.servlets;
import java.io.InputStream;
import java.nio.charset.CharacterCodingException;
-import javax.servlet.http.HttpServletRequest ;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import org.apache.jena.atlas.RuntimeIOException;
-import org.apache.jena.atlas.web.AcceptList ;
+import org.apache.jena.atlas.web.AcceptList;
import org.apache.jena.atlas.web.ContentType;
-import org.apache.jena.atlas.web.MediaType ;
-import org.apache.jena.fuseki.DEF ;
-import org.apache.jena.fuseki.server.DataAccessPoint ;
-import org.apache.jena.fuseki.server.DataAccessPointRegistry ;
+import org.apache.jena.atlas.web.MediaType;
+import org.apache.jena.fuseki.DEF;
+import org.apache.jena.fuseki.Fuseki;
+import org.apache.jena.fuseki.server.DataAccessPoint;
+import org.apache.jena.fuseki.server.DataAccessPointRegistry;
import org.apache.jena.fuseki.system.ConNeg;
import org.apache.jena.fuseki.system.FusekiNetLib;
import org.apache.jena.riot.Lang;
@@ -39,85 +41,82 @@ import org.apache.jena.riot.RiotException;
import org.apache.jena.riot.system.ErrorHandler;
import org.apache.jena.riot.system.ErrorHandlerFactory;
import org.apache.jena.riot.system.StreamRDF;
+import org.apache.jena.riot.web.HttpNames;
/** Operations related to servlets */
public class ActionLib {
/**
- * A possible implementation for {@link ActionService#mapRequestToDataset}
+ * Get the datasets from an {@link HttpAction}
* that assumes the form /dataset/service.
* @param action the request
* @return the dataset
*/
public static String mapRequestToDataset(HttpAction action) {
- String uri = action.getActionURI() ;
- return mapActionRequestToDataset(uri) ;
+ String uri = action.getActionURI();
+ return mapActionRequestToDataset(uri);
}
-
+
/** Map request to uri in the registry.
* A possible implementation for mapRequestToDataset(String)
- * that assumes the form /dataset/service
+ * that assumes the form /dataset/service
* Returning null means no mapping found.
- * The URI must be the action URI (no contact path)
+ * The URI must be the action URI (no contact path)
*/
-
+
public static String mapActionRequestToDataset(String uri) {
// Chop off trailing part - the service selector
- // e.g. /dataset/sparql => /dataset
- int i = uri.lastIndexOf('/') ;
+ // e.g. /dataset/sparql => /dataset
+ int i = uri.lastIndexOf('/');
if ( i == -1 )
- return null ;
- if ( i == 0 )
- {
+ return null;
+ if ( i == 0 ) {
// started with '/' - leave.
- return uri ;
+ return uri;
}
-
- return uri.substring(0, i) ;
+
+ return uri.substring(0, i);
}
- /** Calculate the operation, given action and data access point */
+ /** Calculate the operation, given action and data access point */
public static String mapRequestToOperation(HttpAction action, DataAccessPoint dsRef) {
if ( dsRef == null )
- return "" ;
- String uri = action.getActionURI() ;
+ return "";
+ String uri = action.getActionURI();
String name = dsRef.getName();
if ( name.length() >= uri.length() )
- return "" ;
- return uri.substring(name.length()+1) ; // Skip the separating "/"
-
+ return "";
+ return uri.substring(name.length()+1); // Skip the separating "/"
+
}
-
- /** Implementation of mapRequestToDataset(String) that looks for
- * the longest match in the registry.
- * This includes use in direct naming GSP.
+
+ /**
+ * Implementation of mapRequestToDataset(String) that looks for the longest match
+ * in the registry. This includes use in direct naming GSP.
*/
- public static String mapRequestToDatasetLongest$(String uri, DataAccessPointRegistry registry)
- {
+ public static String mapRequestToDatasetLongest$(String uri, DataAccessPointRegistry registry) {
if ( uri == null )
- return null ;
-
+ return null;
+
// This covers local, using the URI as a direct name for
- // a graph, not just using the indirect ?graph= or ?default
+ // a graph, not just using the indirect ?graph= or ?default
// forms.
- String ds = null ;
+ String ds = null;
for ( String ds2 : registry.keys() ) {
if ( ! uri.startsWith(ds2) )
- continue ;
+ continue;
- if ( ds == null )
- {
- ds = ds2 ;
- continue ;
+ if ( ds == null ) {
+ ds = ds2;
+ continue;
}
- if ( ds.length() < ds2.length() )
- {
- ds = ds2 ;
- continue ;
+ if ( ds.length() < ds2.length() ) {
+ ds = ds2;
+ continue;
}
}
- return ds ;
+ return ds;
}
/** Calculate the fill URL including query string
@@ -126,16 +125,16 @@ public class ActionLib {
* @return String The full URL, including query string.
*/
public static String wholeRequestURL(HttpServletRequest request) {
- StringBuffer sb = request.getRequestURL() ;
- String queryString = request.getQueryString() ;
+ StringBuffer sb = request.getRequestURL();
+ String queryString = request.getQueryString();
if ( queryString != null ) {
- sb.append("?") ;
- sb.append(queryString) ;
+ sb.append("?");
+ sb.append(queryString);
}
- return sb.toString() ;
+ return sb.toString();
}
- /*
+ /*
* The context path can be:
* "" for the root context
* "/APP" for named contexts
@@ -145,60 +144,60 @@ public class ActionLib {
*/
public static String removeContextPath(HttpAction action) {
- return actionURI(action.request) ;
+ return actionURI(action.request);
}
-
+
/**
- * @return the URI without context path of the webapp.
+ * @return the URI without context path of the webapp and without query string.
*/
public static String actionURI(HttpServletRequest request) {
-// Log.info(this, "URI = '"+request.getRequestURI()) ;
-// Log.info(this, "Context Path = '"+request.getContextPath()+"'") ;
-// Log.info(this, "Servlet path = '"+request.getServletPath()+"'") ;
-// ServletContext cxt = this.getServletContext() ;
-// Log.info(this, "ServletContext path = '"+cxt.getContextPath()+"'") ;
-
- String contextPath = request.getServletContext().getContextPath() ;
- String uri = request.getRequestURI() ;
+// Log.info(this, "URI = '"+request.getRequestURI());
+// Log.info(this, "Context Path = '"+request.getContextPath()+"'");
+// Log.info(this, "Servlet path = '"+request.getServletPath()+"'");
+// ServletContext cxt = this.getServletContext();
+// Log.info(this, "ServletContext path = '"+cxt.getContextPath()+"'");
+
+ String contextPath = request.getServletContext().getContextPath();
+ String uri = request.getRequestURI();
if ( contextPath == null )
- return uri ;
+ return uri;
if ( contextPath.isEmpty())
- return uri ;
- String x = uri ;
+ return uri;
+ String x = uri;
if ( uri.startsWith(contextPath) )
- x = uri.substring(contextPath.length()) ;
- return x ;
+ x = uri.substring(contextPath.length());
+ return x;
}
- /** Negotiate the content-type and set the response headers */
+ /** Negotiate the content-type and set the response headers */
public static MediaType contentNegotation(HttpAction action, AcceptList myPrefs, MediaType defaultMediaType) {
- MediaType mt = ConNeg.chooseContentType(action.request, myPrefs, defaultMediaType) ;
+ MediaType mt = ConNeg.chooseContentType(action.request, myPrefs, defaultMediaType);
if ( mt == null )
- return null ;
+ return null;
if ( mt.getContentType() != null )
- action.response.setContentType(mt.getContentType()) ;
+ action.response.setContentType(mt.getContentType());
if ( mt.getCharset() != null )
- action.response.setCharacterEncoding(mt.getCharset()) ;
- return mt ;
+ action.response.setCharacterEncoding(mt.getCharset());
+ return mt;
}
-
- /** Negotiate the content-type for an RDF triples syntax and set the response headers */
+
+ /** Negotiate the content-type for an RDF triples syntax and set the response headers */
public static MediaType contentNegotationRDF(HttpAction action) {
- return contentNegotation(action, DEF.rdfOffer, DEF.acceptRDFXML) ;
+ return contentNegotation(action, DEF.rdfOffer, DEF.acceptRDFXML);
}
- /** Negotiate the content-type for an RDF quads syntax and set the response headers */
+ /** Negotiate the content-type for an RDF quads syntax and set the response headers */
public static MediaType contentNegotationQuads(HttpAction action) {
- return contentNegotation(action, DEF.quadsOffer, DEF.acceptNQuads) ;
+ return contentNegotation(action, DEF.quadsOffer, DEF.acceptNQuads);
}
- /**
+ /**
* Parse RDF content
*/
public static void parse(HttpAction action, StreamRDF dest, InputStream input, Lang lang, String base) {
try {
if ( ! RDFParserRegistry.isRegistered(lang) )
- ServletOps.errorBadRequest("No parser for language '"+lang.getName()+"'") ;
+ ServletOps.errorBadRequest("No parser for language '"+lang.getName()+"'");
ErrorHandler errorHandler = ErrorHandlerFactory.errorHandlerStd(action.log);
RDFParser.create()
.errorHandler(errorHandler)
@@ -211,7 +210,7 @@ public class ActionLib {
throw new RiotException("Character Coding Error: "+ex.getMessage());
throw ex;
}
- catch (RiotException ex) { ServletOps.errorBadRequest("Parse error: "+ex.getMessage()) ; }
+ catch (RiotException ex) { ServletOps.errorBadRequest("Parse error: "+ex.getMessage()); }
}
/** Get the content type of an action or return the default.
@@ -219,7 +218,88 @@ public class ActionLib {
* @return ContentType
*/
public static ContentType getContentType(HttpAction action) {
- return FusekiNetLib.getContentType(action.request) ;
+ return FusekiNetLib.getContentType(action.request);
+ }
+
+ public static void setCommonHeadersForOptions(HttpServletResponse httpResponse) {
+ if ( Fuseki.CORS_ENABLED )
+ httpResponse.setHeader(HttpNames.hAccessControlAllowHeaders, "X-Requested-With, Content-Type, Authorization");
+ setCommonHeaders(httpResponse);
+ }
+
+ public static void setCommonHeaders(HttpServletResponse httpResponse) {
+ if ( Fuseki.CORS_ENABLED )
+ httpResponse.setHeader(HttpNames.hAccessControlAllowOrigin, "*");
+ if ( Fuseki.outputFusekiServerHeader )
+ httpResponse.setHeader(HttpNames.hServer, Fuseki.serverHttpName);
+ }
+
+ /**
+ * Extract the name after the container name (servlet name).
+ * @param action an HTTP action
+ * @return item name as "/name" or {@code null}
+ */
+ private /*unused*/ static String extractItemName(HttpAction action) {
+// action.log.info("context path = "+action.request.getContextPath());
+// action.log.info("pathinfo = "+action.request.getPathInfo());
+// action.log.info("servlet path = "+action.request.getServletPath());
+ // if /name
+ // request.getServletPath() otherwise it's null
+ // if /*
+ // request.getPathInfo(); otherwise it's null.
+
+ // PathInfo is after the servlet name.
+ String x1 = action.request.getServletPath();
+ String x2 = action.request.getPathInfo();
+
+ String pathInfo = action.request.getPathInfo();
+ if ( pathInfo == null || pathInfo.isEmpty() || pathInfo.equals("/") )
+ // Includes calling as a container.
+ return null;
+ String name = pathInfo;
+ // pathInfo starts with a "/"
+ int idx = pathInfo.lastIndexOf('/');
+ if ( idx > 0 )
+ name = name.substring(idx);
+ // Returns "/name"
+ return name;
+ }
+
+ // Packing of OPTIONS.
+
+ public static void doOptionsGet(HttpAction action) {
+ ServletBase.setCommonHeadersForOptions(action.response);
+ action.response.setHeader(HttpNames.hAllow, "GET,OPTIONS");
+ }
+
+ public static void doOptionsGetHead(HttpAction action) {
+ ServletBase.setCommonHeadersForOptions(action.response);
+ action.response.setHeader(HttpNames.hAllow, "GET,HEAD,OPTIONS");
+ }
+
+ public static void doOptionsGetPost(HttpAction action) {
+ ServletBase.setCommonHeadersForOptions(action.response);
+ action.response.setHeader(HttpNames.hAllow, "GET,POST,OPTIONS");
+ }
+
+ public static void doOptionsGetPostHead(HttpAction action) {
+ ServletBase.setCommonHeadersForOptions(action.response);
+ action.response.setHeader(HttpNames.hAllow, "GET,POST,HEAD,OPTIONS");
+ }
+
+ public static void doOptionsGetPostDelete(HttpAction action) {
+ ServletBase.setCommonHeadersForOptions(action.response);
+ action.response.setHeader(HttpNames.hAllow, "GET,POST,DELETE,OPTIONS");
+ }
+
+ public static void doOptionsGetPostDeleteHead(HttpAction action) {
+ ServletBase.setCommonHeadersForOptions(action.response);
+ action.response.setHeader(HttpNames.hAllow, "GET,HEAD,POST,DELETE,OPTIONS");
+ }
+
+ public static void doOptionsPost(HttpAction action) {
+ ServletBase.setCommonHeadersForOptions(action.response);
+ action.response.setHeader(HttpNames.hAllow, "POST,OPTIONS");
}
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/CounterMXBean.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionLifecycle.java
similarity index 76%
rename from jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/CounterMXBean.java
rename to jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionLifecycle.java
index 2de7658..75fd7ef 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/CounterMXBean.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionLifecycle.java
@@ -1,4 +1,4 @@
-/**
+/*
* 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
@@ -16,10 +16,13 @@
* limitations under the License.
*/
-package org.apache.jena.fuseki.server;
+package org.apache.jena.fuseki.servlets;
-public interface CounterMXBean
-{
- long getValue() ;
-}
+public interface ActionLifecycle {
+
+ /** The validation step of a request */
+ public void validate(HttpAction action);
+ /** The perform step of a request */
+ public void execute(HttpAction action);
+}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionProcessor.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionProcessor.java
new file mode 100644
index 0000000..8c56b94
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionProcessor.java
@@ -0,0 +1,52 @@
+/*
+ * 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.fuseki.servlets;
+
+import static org.apache.jena.riot.web.HttpNames.*;
+
+/** Interface for executing {@link HttpAction}. */
+public interface ActionProcessor {
+ // c.f HttpServlet.
+ /**
+ * Execute this request.
+ *
+ * @param action HTTP Action
+ */
+ public default void process(HttpAction action) {
+ switch (action.getMethod() ) {
+ case METHOD_GET: execGet(action); break;
+ case METHOD_POST: execPost(action); break;
+ case METHOD_PATCH: execPatch(action); break;
+ case METHOD_PUT: execPut(action); break;
+ case METHOD_DELETE: execDelete(action); break;
+ case METHOD_HEAD: execHead(action); break;
+ case METHOD_OPTIONS: execOptions(action); break;
+ case METHOD_TRACE: execTrace(action); break;
+ }
+ }
+
+ public default void execHead(HttpAction action) { ServletOps.errorMethodNotAllowed(METHOD_HEAD); }
+ public default void execGet(HttpAction action) { ServletOps.errorMethodNotAllowed(METHOD_GET); }
+ public default void execPost(HttpAction action) { ServletOps.errorMethodNotAllowed(METHOD_POST); }
+ public default void execPatch(HttpAction action) { ServletOps.errorMethodNotAllowed(METHOD_PATCH); }
+ public default void execPut(HttpAction action) { ServletOps.errorMethodNotAllowed(METHOD_PUT); }
+ public default void execDelete(HttpAction action) { ServletOps.errorMethodNotAllowed(METHOD_DELETE); }
+ public default void execOptions(HttpAction action) { ServletOps.errorMethodNotAllowed(METHOD_OPTIONS); }
+ public default void execTrace(HttpAction action) { ServletOps.errorMethodNotAllowed(METHOD_TRACE); }
+}
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 e16e793..56f3592 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,35 +18,30 @@
package org.apache.jena.fuseki.servlets;
-import java.util.Locale ;
+import static org.apache.jena.fuseki.servlets.ActionExecLib.incCounter;
+import static org.apache.jena.riot.web.HttpNames.*;
-import javax.servlet.http.HttpServletRequest ;
-import javax.servlet.http.HttpServletResponse ;
+import java.util.Locale;
-import org.apache.jena.fuseki.server.CounterName ;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.jena.fuseki.server.CounterName;
import org.apache.jena.sparql.core.DatasetGraph;
-/** Common point for operations that are "REST"ish (use GET/PUT etc as operations). */
+/** Common point for operations that are "REST"ish (use GET/PUT etc as operations). */
public abstract class ActionREST extends ActionService
{
- public ActionREST()
- { super() ; }
-
- @Override
- protected void service(HttpServletRequest request, HttpServletResponse response) {
- // Direct all verbs to our common framework.
- doCommon(request, response) ;
- }
-
- @Override
- protected void perform(HttpAction action) {
- dispatch(action) ;
+ public ActionREST() {
+ super();
}
- private void dispatch(HttpAction action) {
- HttpServletRequest req = action.request ;
- HttpServletResponse resp = action.response ;
- String method = req.getMethod().toUpperCase(Locale.ROOT) ;
+ @Override
+ public void execute(HttpAction action) {
+ // Intercept to put counters around calls.
+ HttpServletRequest req = action.request;
+ HttpServletResponse resp = action.response;
+ String method = req.getMethod().toUpperCase(Locale.ROOT);
if (method.equals(METHOD_GET))
doGet$(action);
@@ -55,112 +50,123 @@ public abstract class ActionREST extends ActionService
else if (method.equals(METHOD_POST))
doPost$(action);
else if (method.equals(METHOD_PATCH))
- doPatch$(action) ;
+ doPatch$(action);
else if (method.equals(METHOD_OPTIONS))
- doOptions$(action) ;
+ doOptions$(action);
else if (method.equals(METHOD_TRACE))
- //doTrace(action) ;
- ServletOps.errorMethodNotAllowed("TRACE") ;
+ //doTrace(action);
+ ServletOps.errorMethodNotAllowed("TRACE");
else if (method.equals(METHOD_PUT))
- doPut$(action) ;
+ doPut$(action);
else if (method.equals(METHOD_DELETE))
- doDelete$(action) ;
+ doDelete$(action);
else
- ServletOps.errorNotImplemented("Unknown method: "+method) ;
+ ServletOps.errorNotImplemented("Unknown method: "+method);
}
/**
* Decide on the dataset to use for the operation. This can be overridden
- * by specialist subclasses e.g. data access control.
+ * by specialist subclasses e.g. data access control.
*/
protected DatasetGraph decideDataset(HttpAction action) {
- return action.getActiveDSG() ;
+ return action.getActiveDSG();
}
-
+
// Counter wrappers
-
+
private final void doGet$(HttpAction action) {
- incCounter(action.getEndpoint(), CounterName.HTTPget) ;
+ incCounter(action.getEndpoint(), CounterName.HTTPget);
try {
- doGet(action) ;
- incCounter(action.getEndpoint(), CounterName.HTTPgetGood) ;
+ doGet(action);
+ incCounter(action.getEndpoint(), CounterName.HTTPgetGood);
} catch ( ActionErrorException ex) {
- incCounter(action.getEndpoint(), CounterName.HTTPgetBad) ;
- throw ex ;
+ incCounter(action.getEndpoint(), CounterName.HTTPgetBad);
+ throw ex;
}
}
private final void doHead$(HttpAction action) {
- incCounter(action.getEndpoint(), CounterName.HTTPhead) ;
+ incCounter(action.getEndpoint(), CounterName.HTTPhead);
try {
- doHead(action) ;
- incCounter(action.getEndpoint(), CounterName.HTTPheadGood) ;
+ doHead(action);
+ incCounter(action.getEndpoint(), CounterName.HTTPheadGood);
} catch ( ActionErrorException ex) {
- incCounter(action.getEndpoint(), CounterName.HTTPheadBad) ;
- throw ex ;
+ incCounter(action.getEndpoint(), CounterName.HTTPheadBad);
+ throw ex;
}
}
private final void doPost$(HttpAction action) {
- incCounter(action.getEndpoint(), CounterName.HTTPpost) ;
+ incCounter(action.getEndpoint(), CounterName.HTTPpost);
try {
- doPost(action) ;
- incCounter(action.getEndpoint(), CounterName.HTTPpostGood) ;
+ doPost(action);
+ incCounter(action.getEndpoint(), CounterName.HTTPpostGood);
} catch ( ActionErrorException ex) {
- incCounter(action.getEndpoint(), CounterName.HTTPpostBad) ;
- throw ex ;
+ incCounter(action.getEndpoint(), CounterName.HTTPpostBad);
+ throw ex;
}
}
private final void doPatch$(HttpAction action) {
- incCounter(action.getEndpoint(), CounterName.HTTPpatch) ;
+ incCounter(action.getEndpoint(), CounterName.HTTPpatch);
try {
- doPatch(action) ;
- incCounter(action.getEndpoint(), CounterName.HTTPpatchGood) ;
+ doPatch(action);
+ incCounter(action.getEndpoint(), CounterName.HTTPpatchGood);
} catch ( ActionErrorException ex) {
- incCounter(action.getEndpoint(), CounterName.HTTPpatchBad) ;
- throw ex ;
+ incCounter(action.getEndpoint(), CounterName.HTTPpatchBad);
+ throw ex;
}
}
private final void doDelete$(HttpAction action) {
- incCounter(action.getEndpoint(), CounterName.HTTPdelete) ;
+ incCounter(action.getEndpoint(), CounterName.HTTPdelete);
try {
- doDelete(action) ;
- incCounter(action.getEndpoint(), CounterName.HTTPdeleteGood) ;
+ doDelete(action);
+ incCounter(action.getEndpoint(), CounterName.HTTPdeleteGood);
} catch ( ActionErrorException ex) {
- incCounter(action.getEndpoint(), CounterName.HTTPdeleteBad) ;
- throw ex ;
+ incCounter(action.getEndpoint(), CounterName.HTTPdeleteBad);
+ throw ex;
}
}
private final void doPut$(HttpAction action) {
- incCounter(action.getEndpoint(), CounterName.HTTPput) ;
+ incCounter(action.getEndpoint(), CounterName.HTTPput);
try {
- doPut(action) ;
- incCounter(action.getEndpoint(), CounterName.HTTPputGood) ;
+ doPut(action);
+ incCounter(action.getEndpoint(), CounterName.HTTPputGood);
} catch ( ActionErrorException ex) {
- incCounter(action.getEndpoint(), CounterName.HTTPputBad) ;
- throw ex ;
+ incCounter(action.getEndpoint(), CounterName.HTTPputBad);
+ throw ex;
}
}
private final void doOptions$(HttpAction action) {
- incCounter(action.getEndpoint(), CounterName.HTTPoptions) ;
+ incCounter(action.getEndpoint(), CounterName.HTTPoptions);
try {
- doOptions(action) ;
- incCounter(action.getEndpoint(), CounterName.HTTPoptionsGood) ;
+ doOptions(action);
+ incCounter(action.getEndpoint(), CounterName.HTTPoptionsGood);
} catch ( ActionErrorException ex) {
- incCounter(action.getEndpoint(), CounterName.HTTPoptionsBad) ;
- throw ex ;
+ incCounter(action.getEndpoint(), CounterName.HTTPoptionsBad);
+ throw ex;
}
}
-
- protected abstract void doGet(HttpAction action) ;
- protected abstract void doHead(HttpAction action) ;
- protected abstract void doPost(HttpAction action) ;
- protected abstract void doPatch(HttpAction action) ;
- protected abstract void doDelete(HttpAction action) ;
- protected abstract void doPut(HttpAction action) ;
- protected abstract void doOptions(HttpAction action) ;
+
+ protected abstract void doGet(HttpAction action);
+ protected abstract void doHead(HttpAction action);
+ protected abstract void doPost(HttpAction action);
+ protected abstract void doPut(HttpAction action);
+ protected abstract void doDelete(HttpAction action);
+ protected abstract void doPatch(HttpAction action);
+ protected abstract void doOptions(HttpAction action);
+
+ // If not final in ActionBase
+ //@Override public void process(HttpAction action) { executeLifecycle(action); }
+
+ @Override public void execHead(HttpAction action) { executeLifecycle(action); }
+ @Override public void execGet(HttpAction action) { executeLifecycle(action); }
+ @Override public void execPost(HttpAction action) { executeLifecycle(action); }
+ @Override public void execPatch(HttpAction action) { executeLifecycle(action); }
+ @Override public void execPut(HttpAction action) { executeLifecycle(action); }
+ @Override public void execDelete(HttpAction action) { executeLifecycle(action); }
+ @Override public void execOptions(HttpAction action) { executeLifecycle(action); }
}
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionService.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionService.java
index c329cda..881493a 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionService.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionService.java
@@ -18,232 +18,24 @@
package org.apache.jena.fuseki.servlets;
-import static java.lang.String.format;
import static org.apache.jena.fuseki.server.CounterName.Requests;
import static org.apache.jena.fuseki.server.CounterName.RequestsBad;
import static org.apache.jena.fuseki.server.CounterName.RequestsGood;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.function.BiFunction;
-
-import javax.servlet.ServletException;
+import static org.apache.jena.fuseki.servlets.ActionExecLib.incCounter;
import org.apache.jena.atlas.RuntimeIOException;
-import org.apache.jena.atlas.lib.InternalErrorException;
-import org.apache.jena.fuseki.Fuseki;
-import org.apache.jena.fuseki.auth.Auth;
-import org.apache.jena.fuseki.server.*;
+import org.apache.jena.fuseki.server.CounterSet;
import org.apache.jena.query.QueryCancelledException;
-import org.apache.jena.web.HttpSC;
-/** Service request lifecycle */
public abstract class ActionService extends ActionBase {
-
- private final BiFunction<HttpAction, Operation, ActionService> selectProcessor;
-
- /**
- * ActionService for a directly called serlvet. The request handler will be
- * {@code this.executeLifecycle}.
- */
- protected ActionService() {
- super(Fuseki.actionLog);
- selectProcessor = (action, operation)->this;
- }
-
- /**
- * ActionService to redirect to another ActionService to be request handler will be
- * {@code selectProcessor.executeLifecycle}.
- * @see ServiceRouter
- */
- protected ActionService(BiFunction<HttpAction, Operation, ActionService> selectProcessor) {
- super(Fuseki.actionLog);
- this.selectProcessor = selectProcessor;
- }
-
- protected abstract void validate(HttpAction action);
- protected abstract void perform(HttpAction action);
-
- /**
- * Executes common tasks, including mapping the request to the right dataset, setting
- * the dataset into the HTTP action, and retrieving the service for the dataset
- * requested. Finally, it calls the {@link #executeAction(HttpAction)} method, which
- * executes the HTTP Action life cycle.
- */
+ /** Add counters to the validate-execute lifecycle. */
@Override
- final
- protected void execCommonWorker(HttpAction action) {
- DataAccessPoint dataAccessPoint;
- DataService dSrv;
-
- String datasetUri = mapRequestToDataset(action);
- if ( datasetUri != null ) {
- dataAccessPoint = action.getDataAccessPointRegistry().get(datasetUri);
-
- if ( dataAccessPoint == null ) {
- ServletOps.errorNotFound("No dataset for URI: " + datasetUri);
- return;
- }
- dSrv = dataAccessPoint.getDataService();
-
- if ( !dSrv.isAcceptingRequests() ) {
- ServletOps.error(HttpSC.SERVICE_UNAVAILABLE_503, "Dataset not currently active");
- return;
- }
- } else {
- // Routed to this URL; no registered dataset on this URL.
- // e.g. General query servlet
- dSrv = ServiceOnly.dataService();
- dataAccessPoint = ServiceOnly.dataAccessPoint();
- }
-
- action.setRequest(dataAccessPoint, dSrv);
- // Endpoint Name is "" for GSP or quads.
- // Endpoint name is not "", but unknown for GSP direct naming (which is usually disabled).
- String endpointName = mapRequestToOperation(action, dataAccessPoint);
-
- // ServiceRouter dispatch
- Operation operation;
- if ( !endpointName.isEmpty() ) {
- operation = chooseOperation(action, dSrv, endpointName);
- if ( operation == null )
- if ( ! Fuseki.GSP_DIRECT_NAMING )
- ServletOps.errorBadRequest(format("dataset=%s, service=%s", dataAccessPoint.getName(), endpointName));
- else
- throw new InternalErrorException("Inconsistent: GSP_DIRECT_NAMING but no operation");
- } else {
- // Endpoint ""
- operation = chooseOperation(action, dSrv);
- }
-
- // ---- Auth checking.
- // -- Server-level authorization.
- // Checking was carried out by servlet filter AuthFilter.
- // Need to check Data service and endpoint authorization policies.
- String user = action.getUser();
- // -- Data service level authorization
- if ( dSrv.authPolicy() != null ) {
- if ( ! dSrv.authPolicy().isAllowed(user) )
- ServletOps.errorForbidden();
- }
-
- // -- Endpoint level authorization
- // Make sure all contribute authentication.
- if ( action.getEndpoint() != null ) {
- // Specific endpoint chosen.
- Auth.allow(user, action.getEndpoint().getAuthPolicy(), ServletOps::errorForbidden);
- } else {
- // No Endpoint name given; there may be several endpoints for the operation.
- // authorization is the AND of all endpoints.
- Collection<Endpoint> x = getEndpoints(dSrv, operation);
- if ( operation != null && x.isEmpty() )
- throw new InternalErrorException("Inconsistent: no endpoints for "+operation);
- x.forEach(ep->{
- Auth.allow(user, ep.getAuthPolicy(), ServletOps::errorForbidden);
- });
- }
- // ---- End auth checking.
-
- // Decide the code to execute the request.
- // For ServiceRouter, this involves a lookup in the service dispatch registry.
- // For directly called services, they override the operations called by this.executeLifecycle.
- ActionService handler = selectProcessor.apply(action, operation);
- if ( handler == null )
- ServletOps.errorBadRequest(format("dataset=%s: op=%s", dataAccessPoint.getName(), operation.getName()));
- handler.executeLifecycle(action);
- return;
- }
-
- // Find the endpoints for an operation.
- // This is GSP_R/GSP_RW and Quads_R/Quads_RW aware.
- // If asked for GSP_R and there are no endpoints for GSP_R, try GSP_RW.
- // Ditto Quads_R -> Quads_RW.
- private Collection<Endpoint> getEndpoints(DataService dSrv, Operation operation) {
- if ( operation == null )
- return Collections.emptySet();
- Collection<Endpoint> x = dSrv.getEndpoints(operation);
- if ( x == null || x.isEmpty() ) {
- if ( operation == Operation.GSP_R )
- x = dSrv.getEndpoints(Operation.GSP_RW);
- else if ( operation == Operation.Quads_R )
- x = dSrv.getEndpoints(Operation.Quads_RW);
- }
- return x;
- }
-
- /**
- * Return the operation that corresponds to the endpoint name for a given data service.
- * Side effect: This operation should set the selected endpoint in the HttpAction
- * if this operation is determined to be a specific endpoint.
- */
- protected Operation chooseOperation(HttpAction action, DataService dataService, String endpointName) {
- // Overridden by the ServiceRouter.
- // This default implementation is plain service name to operation based on the
- // DataService as would be used by operation servlets bound by web.xml
- // except Fuseki can add and delete mapping while running.
- Endpoint ep = dataService.getEndpoint(endpointName);
- Operation operation = ep.getOperation();
- action.setEndpoint(ep);
- return operation;
- }
-
- /**
- * Return the operation that corresponds to the request when there is no endpoint name.
- * This operation does not set the selected endpoint in the HttpAction.
- */
- protected Operation chooseOperation(HttpAction action, DataService dataService) {
- // No default implementation for directly bound services operation servlets.
- return null;
- }
-
- private void executeRequest(HttpAction action, ActionService servlet) {
- if ( true ) {
- // Execute an ActionService.
- // Bypasses HttpServlet.service to doMethod dispatch.
- servlet.executeLifecycle(action);
- return;
- }
- if ( false ) {
- // Execute by calling the whole servlet mechanism.
- // This causes HttpServlet.service to call the appropriate doMethod.
- // but the action, and the id, are not passed on and a ne one is created.
- try {
- servlet.service(action.request, action.response);
- }
- catch (ServletException | IOException e) {
- ServletOps.errorOccurred(e);
- }
- }
- }
-
- /**
- * Execute a SPARQL request. Statistics have not been adjusted at this point.
- *
- * @param action
- */
- protected void executeAction(HttpAction action) {
- executeLifecycle(action);
- }
-
- /**
- * Standard execution lifecycle for a SPARQL Request.
- * <ul>
- * <li>{@link #startRequest(HttpAction)}</li>
- * <li>initial statistics,</li>
- * <li>{@link #validate(HttpAction)} request,</li>
- * <li>{@link #perform(HttpAction)} request,</li>
- * <li>completion/error statistics,</li>
- * <li>{@link #finishRequest(HttpAction)}
- * </ul>
- *
- * @param action
- */
- // This is the service request lifecycle.
- final protected void executeLifecycle(HttpAction action) {
+ protected void executeLifecycle(HttpAction action) {
// And also HTTP counter
- CounterSet csService = action.getDataService().getCounters();
+
+ CounterSet csService =
+ (action.getDataService() == null) ? null : action.getDataService().getCounters();
CounterSet csOperation = null;
if ( action.getEndpoint() != null )
// Direct naming GSP does not have an "endpoint".
@@ -263,7 +55,7 @@ public abstract class ActionService extends ActionBase {
}
try {
- perform(action);
+ execute(action);
// Success
incCounter(csOperation, RequestsGood);
incCounter(csService, RequestsGood);
@@ -274,62 +66,4 @@ public abstract class ActionService extends ActionBase {
throw ex;
}
}
-
- /**
- * Map request {@link HttpAction} to uri in the registry. A return of {@code null}
- * means no mapping done (passthrough).
- *
- * @param uri
- * the URI
- * @return the dataset
- */
- protected String mapRequestToDataset(HttpAction action) {
- return ActionLib.mapRequestToDataset(action);
- }
-
- /**
- * Map request to uri in the registry. {@code null} means no mapping done
- * (passthrough).
- */
- protected String mapRequestToOperation(HttpAction action, DataAccessPoint dataAccessPoint) {
- return ActionLib.mapRequestToOperation(action, dataAccessPoint);
- }
-
- /** Increment counter */
- protected static void incCounter(Counters counters, CounterName name) {
- if ( counters == null )
- return;
- incCounter(counters.getCounters(), name);
- }
-
- /** Decrement counter */
- protected static void decCounter(Counters counters, CounterName name) {
- if ( counters == null )
- return;
- decCounter(counters.getCounters(), name);
- }
-
... 24421 lines suppressed ...