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 2018/09/21 10:16:16 UTC
[65/70] [abbrv] jena git commit: Reorganise library code.
Reorganise library code.
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/0c218559
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/0c218559
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/0c218559
Branch: refs/heads/master
Commit: 0c218559beb8521a1ed5bf0ef9335056fd6684d1
Parents: 1d4a5f2
Author: Andy Seaborne <an...@apache.org>
Authored: Fri Sep 14 18:24:34 2018 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Fri Sep 14 18:24:34 2018 +0100
----------------------------------------------------------------------
.../java/org/apache/jena/atlas/web/WebLib.java | 12 +
.../access/AbstractTestSecurityAssembler.java | 4 +-
.../fuseki/access/TestSecurityFilterFuseki.java | 4 +-
.../java/org/apache/jena/fuseki/Fuseki.java | 76 ++++++
.../java/org/apache/jena/fuseki/FusekiLib.java | 238 -------------------
.../build/DatasetDescriptionRegistry.java | 17 +-
.../apache/jena/fuseki/build/FusekiBuilder.java | 139 +++--------
.../apache/jena/fuseki/build/FusekiConfig.java | 88 ++++++-
.../org/apache/jena/fuseki/conneg/ConNeg.java | 206 ----------------
.../org/apache/jena/fuseki/conneg/WebLib.java | 60 -----
.../apache/jena/fuseki/servlets/ActionLib.java | 12 +-
.../jena/fuseki/servlets/REST_Quads_RW.java | 4 +-
.../jena/fuseki/servlets/ResponseDataset.java | 6 +-
.../jena/fuseki/servlets/ResponseResultSet.java | 2 +-
.../jena/fuseki/servlets/SPARQL_GSP_RW.java | 8 +-
.../jena/fuseki/servlets/SPARQL_Query.java | 6 +-
.../jena/fuseki/servlets/SPARQL_Update.java | 5 +-
.../jena/fuseki/servlets/SPARQL_Upload.java | 6 +-
.../jena/fuseki/servlets/ServiceRouter.java | 2 +-
.../org/apache/jena/fuseki/system/ConNeg.java | 206 ++++++++++++++++
.../apache/jena/fuseki/system/FusekiNetLib.java | 179 ++++++++++++++
.../org/apache/jena/fuseki/system/Upload.java | 3 +-
.../jena/fuseki/validation/ValidatorBase.java | 2 +-
.../validation/html/DataValidatorHTML.java | 4 +-
.../org/apache/jena/fuseki/main/FusekiLib.java | 74 ++++++
.../apache/jena/fuseki/main/FusekiTestAuth.java | 4 +-
.../jena/fuseki/main/FusekiTestServer.java | 4 +-
.../jena/fuseki/main/TestEmbeddedFuseki.java | 20 +-
.../fuseki/main/TestFusekiCustomOperation.java | 4 +-
.../jena/fuseki/main/TestMultipleEmbedded.java | 16 +-
.../examples/ExtendFuseki_AddService_1.java | 4 +-
.../examples/ExtendFuseki_AddService_2.java | 4 +-
.../examples/ExtendFuseki_AddService_3.java | 4 +-
.../apache/jena/fuseki/mgt/ActionDatasets.java | 22 +-
.../apache/jena/fuseki/webapp/FusekiSystem.java | 2 +-
.../java/org/apache/jena/fuseki/ServerCtl.java | 5 +-
.../java/org/apache/jena/fuseki/TestAuth.java | 5 +-
.../org/apache/jena/fuseki/TestBuilder.java | 10 +-
.../TestRDFConnectionFusekiBinary.java | 9 +-
.../rdfconnection/TestRDFConnectionRemote.java | 4 +-
40 files changed, 771 insertions(+), 709 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-arq/src/main/java/org/apache/jena/atlas/web/WebLib.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/atlas/web/WebLib.java b/jena-arq/src/main/java/org/apache/jena/atlas/web/WebLib.java
index a062eca..5d2f4fe 100644
--- a/jena-arq/src/main/java/org/apache/jena/atlas/web/WebLib.java
+++ b/jena-arq/src/main/java/org/apache/jena/atlas/web/WebLib.java
@@ -18,6 +18,9 @@
package org.apache.jena.atlas.web;
+import java.io.IOException;
+import java.net.ServerSocket;
+
public class WebLib
{
/** Split a string, removing whitespace around the split string.
@@ -33,4 +36,13 @@ public class WebLib
return x ;
}
+ /** Choose an unused port for a server to listen on */
+ public static int choosePort() {
+ try (ServerSocket s = new ServerSocket(0)) {
+ return s.getLocalPort();
+ } catch (IOException ex) {
+ throw new RuntimeException("Failed to find a port");
+ }
+ }
+
}
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/AbstractTestSecurityAssembler.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/AbstractTestSecurityAssembler.java b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/AbstractTestSecurityAssembler.java
index 562e3e8..a7e5ac1 100644
--- a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/AbstractTestSecurityAssembler.java
+++ b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/AbstractTestSecurityAssembler.java
@@ -32,8 +32,8 @@ import org.apache.jena.atlas.iterator.Iter;
import org.apache.jena.atlas.lib.SetUtils;
import org.apache.jena.atlas.lib.StrUtils;
import org.apache.jena.atlas.web.HttpException;
-import org.apache.jena.fuseki.FusekiLib;
import org.apache.jena.fuseki.main.FusekiServer;
+import org.apache.jena.fuseki.system.FusekiNetLib;
import org.apache.jena.graph.Node;
import org.apache.jena.query.Dataset;
import org.apache.jena.query.QuerySolution;
@@ -102,7 +102,7 @@ public abstract class AbstractTestSecurityAssembler {
}
private static FusekiServer setup(String assembler, boolean sharedDatabase) {
- int port = FusekiLib.choosePort();
+ int port = FusekiNetLib.choosePort();
FusekiServer server = DataAccessCtl.fusekiBuilder((a)->user.get())
.port(port)
.parseConfigFile(assembler)
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityFilterFuseki.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityFilterFuseki.java b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityFilterFuseki.java
index 844b67e..fb236ab 100644
--- a/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityFilterFuseki.java
+++ b/jena-fuseki2/jena-fuseki-access/src/test/java/org/apache/jena/fuseki/access/TestSecurityFilterFuseki.java
@@ -34,9 +34,9 @@ import java.util.Set;
import org.apache.jena.atlas.iterator.Iter;
import org.apache.jena.atlas.lib.SetUtils;
import org.apache.jena.atlas.web.HttpException;
-import org.apache.jena.fuseki.FusekiLib;
import org.apache.jena.fuseki.jetty.JettyLib;
import org.apache.jena.fuseki.main.FusekiServer;
+import org.apache.jena.fuseki.system.FusekiNetLib;
import org.apache.jena.graph.Node;
import org.apache.jena.query.QuerySolution;
import org.apache.jena.rdf.model.Model;
@@ -81,7 +81,7 @@ public class TestSecurityFilterFuseki {
// Set up Fuseki with two datasets, "data1" backed by TDB and "data2" backed by TDB2.
@BeforeClass public static void beforeClass() {
- int port = FusekiLib.choosePort();
+ int port = FusekiNetLib.choosePort();
addTestData(testdsg1);
addTestData(testdsg2);
addTestData(testdsg3);
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/Fuseki.java
----------------------------------------------------------------------
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 4e5f1ac..dc5493b 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
@@ -18,17 +18,29 @@
package org.apache.jena.fuseki ;
+import java.io.IOException;
import java.util.Calendar ;
import java.util.TimeZone ;
import java.util.concurrent.TimeUnit ;
import javax.servlet.ServletContext;
+import org.apache.http.Header;
+import org.apache.http.HttpResponse;
+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.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.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.web.HttpOp;
import org.apache.jena.sparql.SystemARQ ;
import org.apache.jena.sparql.lib.Metadata ;
import org.apache.jena.sparql.mgt.SystemInfo ;
@@ -278,4 +290,68 @@ public class Fuseki {
static {
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
+ * the signature.
+ */
+ public static boolean isFuseki(String datasetURL) {
+ HttpOptions request = new HttpOptions(datasetURL);
+ HttpClient httpClient = HttpOp.getDefaultHttpClient();
+ if ( httpClient == null )
+ httpClient = HttpClients.createSystem();
+ return isFuseki(request, httpClient, null);
+ }
+
+ /**
+ * Test whether a {@link RDFConnectionRemote} connects to a Fuseki server. This
+ * operation can not guaranttee to detech a Fuseki server - for example, it may be
+ * behind a reverse proxy that masks the signature.
+ */
+ public static boolean isFuseki(RDFConnectionRemote connection) {
+ HttpOptions request = new HttpOptions(connection.getDestination());
+ HttpClient httpClient = connection.getHttpClient();
+ if ( httpClient == null )
+ httpClient = HttpClients.createSystem();
+ HttpContext httpContext = connection.getHttpContext();
+ return isFuseki(request, httpClient, httpContext);
+ }
+
+ private static boolean isFuseki(HttpOptions request, HttpClient httpClient, HttpContext httpContext) {
+ try {
+ 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"
+ String reqId = safeGetHeader(response, "Fuseki-Request-ID");
+ if ( reqId != null )
+ return true;
+
+ // If returning "Server"
+ String serverIdent = safeGetHeader(response, "Server");
+ if ( serverIdent != null ) {
+ Log.debug(ARQ.getHttpRequestLogger(), "Server: "+serverIdent);
+ boolean isFuseki = serverIdent.startsWith("Apache Jena Fuseki");
+ if ( !isFuseki )
+ isFuseki = serverIdent.toLowerCase().contains("fuseki");
+ return isFuseki;
+ }
+ return false;
+ } catch (IOException ex) {
+ throw new HttpException("Failed to check for a Fuseki server", ex);
+ }
+ }
+
+ static String safeGetHeader(HttpResponse response, String header) {
+ Header h = response.getFirstHeader(header);
+ if ( h == null )
+ return null;
+ return h.getValue();
+ }
}
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/FusekiLib.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/FusekiLib.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/FusekiLib.java
deleted file mode 100644
index e540a67..0000000
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/FusekiLib.java
+++ /dev/null
@@ -1,238 +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;
-
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.util.Iterator ;
-
-import javax.servlet.http.HttpServletRequest ;
-
-import org.apache.http.Header;
-import org.apache.http.HttpResponse;
-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.logging.Log;
-import org.apache.jena.atlas.web.ContentType ;
-import org.apache.jena.atlas.web.HttpException;
-import org.apache.jena.ext.com.google.common.collect.ArrayListMultimap;
-import org.apache.jena.ext.com.google.common.collect.Multimap;
-import org.apache.jena.fuseki.servlets.HttpAction ;
-import org.apache.jena.graph.Graph ;
-import org.apache.jena.graph.Node ;
-import org.apache.jena.graph.Triple ;
-import org.apache.jena.query.* ;
-import org.apache.jena.rdfconnection.RDFConnectionRemote;
-import org.apache.jena.riot.Lang ;
-import org.apache.jena.riot.RDFLanguages ;
-import org.apache.jena.riot.web.HttpOp;
-import org.apache.jena.shared.PrefixMapping ;
-import org.apache.jena.sparql.core.DatasetGraph ;
-import org.apache.jena.sparql.core.Quad ;
-import org.apache.jena.sparql.util.Convert ;
-
-public class FusekiLib {
- // ==> ActionLib
-
- /** Get the content type of an action or return the default.
- * @param action
- * @return ContentType
- */
- public static ContentType getContentType(HttpAction action) {
- return getContentType(action.request) ;
- }
-
- /** Get the content type of an action or return the default.
- * @param request
- * @return ContentType
- */
- public static ContentType getContentType(HttpServletRequest request) {
- String contentTypeHeader = request.getContentType() ;
- if ( contentTypeHeader == null )
- return null ;
- return ContentType.create(contentTypeHeader) ;
- }
-
- /** Get the incoming {@link Lang} based on Content-Type of an action.
- * @param action
- * @param dft Default if no "Content-Type:" found.
- * @return ContentType
- */
- public static Lang getLangFromAction(HttpAction action, Lang dft) {
- String contentTypeHeader = action.request.getContentType() ;
- if ( contentTypeHeader == null )
- return dft ;
- return RDFLanguages.contentTypeToLang(contentTypeHeader) ;
- }
-
- static String fmtRequest(HttpServletRequest request) {
- StringBuffer sbuff = new StringBuffer() ;
- sbuff.append(request.getMethod()) ;
- sbuff.append(" ") ;
- sbuff.append(Convert.decWWWForm(request.getRequestURL())) ;
-
- String qs = request.getQueryString() ;
- if ( qs != null ) {
- String tmp = request.getQueryString() ;
- tmp = Convert.decWWWForm(tmp) ;
- tmp = tmp.replace('\n', ' ') ;
- tmp = tmp.replace('\r', ' ') ;
- sbuff.append("?").append(tmp) ;
- }
- return sbuff.toString() ;
- }
-
- /** Parse the query string - do not process the body even for a form */
- public static Multimap<String, String> parseQueryString(HttpServletRequest req) {
- Multimap<String, String> map = ArrayListMultimap.create() ;
-
- // Don't use ServletRequest.getParameter or getParamterNames
- // as that reads form data. This code parses just the query string.
- if ( req.getQueryString() != null ) {
- String[] params = req.getQueryString().split("&") ;
- for (int i = 0; i < params.length; i++) {
- String p = params[i] ;
- String[] x = p.split("=", 2) ;
- String name = null ;
- String value = null ;
-
- if ( x.length == 0 ) { // No "="
- name = p ;
- value = "" ;
- } else if ( x.length == 1 ) { // param=
- name = x[0] ;
- value = "" ;
- } else { // param=value
- name = x[0] ;
- value = x[1] ;
- }
- map.put(name, value) ;
- }
- }
- return map ;
- }
-
- public static String safeParameter(HttpServletRequest request, String pName) {
- String value = request.getParameter(pName) ;
- if ( value == null )
- return null ;
- value = value.replace("\r", "") ;
- value = value.replace("\n", "") ;
- return value ;
- }
-
- // Do the addition directly on the dataset
- public static void addDataInto(Graph data, DatasetGraph dsg, Node graphName) {
- // Prefixes?
- if ( graphName == null )
- graphName = Quad.defaultGraphNodeGenerated ;
-
- Iterator<Triple> iter = data.find(Node.ANY, Node.ANY, Node.ANY) ;
- for (; iter.hasNext();) {
- Triple t = iter.next() ;
- dsg.add(graphName, t.getSubject(), t.getPredicate(), t.getObject()) ;
- }
-
- PrefixMapping pmapSrc = data.getPrefixMapping() ;
- PrefixMapping pmapDest = dsg.getDefaultGraph().getPrefixMapping() ;
- pmapDest.setNsPrefixes(pmapSrc) ;
- }
-
- public static void addDataInto(DatasetGraph src, DatasetGraph dest) {
- Iterator<Quad> iter = src.find(Node.ANY, Node.ANY, Node.ANY, Node.ANY) ;
- for (; iter.hasNext();) {
- Quad q = iter.next() ;
- dest.add(q) ;
- }
-
- PrefixMapping pmapSrc = src.getDefaultGraph().getPrefixMapping() ;
- PrefixMapping pmapDest = dest.getDefaultGraph().getPrefixMapping() ;
- pmapDest.withDefaultMappings(pmapSrc) ;
- }
-
- /** Choose an unused port for a server to listen on */
- public static int choosePort() {
- try (ServerSocket s = new ServerSocket(0)) {
- return s.getLocalPort();
- } catch (IOException ex) {
- throw new FusekiException("Failed to find a port");
- }
- }
-
- /**
- * 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
- * the signature.
- */
- public static boolean isFuseki(String datasetURL) {
- HttpOptions request = new HttpOptions(datasetURL);
- HttpClient httpClient = HttpOp.getDefaultHttpClient();
- if ( httpClient == null )
- httpClient = HttpClients.createSystem();
- return isFuseki(request, httpClient, null);
- }
-
- /**
- * Test whether a {@link RDFConnectionRemote} connects to a Fuseki server. This
- * operation can not guaranttee to detech a Fuseki server - for example, it may be
- * behind a reverse proxy that masks the signature.
- */
- public static boolean isFuseki(RDFConnectionRemote connection) {
- HttpOptions request = new HttpOptions(connection.getDestination());
- HttpClient httpClient = connection.getHttpClient();
- if ( httpClient == null )
- httpClient = HttpClients.createSystem();
- HttpContext httpContext = connection.getHttpContext();
- return isFuseki(request, httpClient, httpContext);
- }
-
- private static boolean isFuseki(HttpOptions request, HttpClient httpClient, HttpContext httpContext) {
- try {
- 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"
- String reqId = safeGetHeader(response, "Fuseki-Request-ID");
- if ( reqId != null )
- return true;
-
- // If returning "Server"
- String serverIdent = safeGetHeader(response, "Server");
- if ( serverIdent != null ) {
- Log.debug(ARQ.getHttpRequestLogger(), "Server: "+serverIdent);
- boolean isFuseki = serverIdent.startsWith("Apache Jena Fuseki");
- if ( !isFuseki )
- isFuseki = serverIdent.toLowerCase().contains("fuseki");
- return isFuseki;
- }
- return false;
- } catch (IOException ex) {
- throw new HttpException("Failed to check for a Fuseki server", ex);
- }
- }
-
- private static String safeGetHeader(HttpResponse response, String header) {
- Header h = response.getFirstHeader(header);
- if ( h == null )
- return null;
- return h.getValue();
- }
-}
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/DatasetDescriptionRegistry.java
----------------------------------------------------------------------
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/DatasetDescriptionRegistry.java
index 6443b55..b49c5be 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/DatasetDescriptionRegistry.java
@@ -18,6 +18,9 @@
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.query.Dataset;
import org.apache.jena.rdf.model.Resource;
@@ -36,27 +39,17 @@ import org.apache.jena.rdf.model.Resource;
*/
public class DatasetDescriptionRegistry {
- private RefCountingMap<Resource, Dataset> map = new RefCountingMap<>() ;
+ private Map<Resource, Dataset> map = new HashMap<>();
public DatasetDescriptionRegistry() {}
- /** Use a mapping. This will add a mapping or increment any reference counting. */
public void register(Resource node, Dataset ds) {
Dataset dsCurrent = map.get(node) ;
if ( dsCurrent != null ) {
if ( ! dsCurrent.equals(ds) )
Log.warn(this.getClass(), "Replacing registered dataset for "+node);
}
- map.add(node, ds);
- }
-
- /** Stop using a mapping. */
- public void unregister(Resource node) {
- map.remove(node);
- }
-
- public int refCount(Resource node) {
- return map.refCount(node);
+ map.put(node, ds);
}
public Dataset get(Resource node) {
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiBuilder.java
----------------------------------------------------------------------
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
index 2a673c7..c9fe706 100644
--- 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
@@ -18,113 +18,23 @@
package org.apache.jena.fuseki.build;
-import static java.lang.String.format ;
-import static org.apache.jena.fuseki.server.FusekiVocab.pServiceQueryEP;
-import static org.apache.jena.fuseki.server.FusekiVocab.pServiceReadGraphStoreEP;
-import static org.apache.jena.fuseki.server.FusekiVocab.pServiceReadQuadsEP;
-import static org.apache.jena.fuseki.server.FusekiVocab.pServiceReadWriteGraphStoreEP;
-import static org.apache.jena.fuseki.server.FusekiVocab.pServiceReadWriteQuadsEP;
-import static org.apache.jena.fuseki.server.FusekiVocab.pServiceUpdateEP;
-import static org.apache.jena.fuseki.server.FusekiVocab.pServiceUploadEP;
-
-import org.apache.jena.assembler.Assembler ;
-import org.apache.jena.datatypes.xsd.XSDDatatype ;
-import org.apache.jena.fuseki.Fuseki ;
-import org.apache.jena.fuseki.FusekiConfigException ;
-import org.apache.jena.fuseki.server.DataAccessPoint ;
+import org.apache.jena.fuseki.FusekiConfigException;
+import org.apache.jena.fuseki.server.DataAccessPoint;
+import org.apache.jena.fuseki.server.DataAccessPointRegistry;
import org.apache.jena.fuseki.server.DataService ;
import org.apache.jena.fuseki.server.Operation ;
-import org.apache.jena.query.Dataset ;
import org.apache.jena.query.QuerySolution ;
import org.apache.jena.query.ResultSet ;
-import org.apache.jena.rdf.model.Literal ;
import org.apache.jena.rdf.model.Property ;
-import org.apache.jena.rdf.model.RDFNode ;
import org.apache.jena.rdf.model.Resource ;
import org.apache.jena.sparql.core.DatasetGraph ;
-import org.apache.jena.sparql.util.FmtUtils ;
-import org.apache.jena.vocabulary.RDF ;
/**
* Helper functions use to construct Fuseki servers.
+ * @see FusekiConfig
*/
public class FusekiBuilder
{
- /** 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") ;
- if ( ! n.isLiteral() )
- throw new FusekiConfigException("Not a literal for access point name: "+FmtUtils.stringForRDFNode(n));
- 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 = buildDataServiceCustom(svc, dsDescMap) ;
- 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 buildDataServiceCustom(Resource svc, DatasetDescriptionRegistry dsDescMap) {
- Resource datasetDesc = ((Resource)getOne(svc, "fu:dataset")) ;
- Dataset ds = getDataset(datasetDesc, dsDescMap);
-
- // In case the assembler included ja:contents
- DataService dataService = new DataService(ds.asDatasetGraph()) ;
-
- addServiceEP(dataService, Operation.Query, svc, pServiceQueryEP) ;
- addServiceEP(dataService, Operation.Update, svc, pServiceUpdateEP) ;
- addServiceEP(dataService, Operation.Upload, svc, pServiceUploadEP);
- addServiceEP(dataService, Operation.GSP_R, svc, pServiceReadGraphStoreEP) ;
- addServiceEP(dataService, Operation.GSP_RW, svc, pServiceReadWriteGraphStoreEP) ;
-
- addServiceEP(dataService, Operation.Quads_R, svc, pServiceReadQuadsEP) ;
- 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.
-
- 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.
-// // Extract timeout overriding configuration if present.
-// if ( svc.hasProperty(FusekiVocab.pAllowTimeoutOverride) ) {
-// 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) ;
-// }
-// }
-
- return dataService ;
- }
-
- public static Dataset getDataset(Resource datasetDesc, DatasetDescriptionRegistry 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)) ;
- ds = (Dataset)Assembler.general.open(datasetDesc) ;
- }
- // 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;
- }
-
/** 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) ;
@@ -153,18 +63,7 @@ public class FusekiBuilder
dataService.addEndpoint(operation, endpointName) ;
}
- public static RDFNode getOne(Resource svc, String property) {
- String ln = property.substring(property.indexOf(':') + 1) ;
- ResultSet rs = FusekiBuildLib.query("SELECT * { ?svc " + property + " ?x}", svc.getModel(), "svc", svc) ;
- if ( !rs.hasNext() )
- throw new FusekiConfigException("No " + ln + " for service " + FusekiBuildLib.nodeLabel(svc)) ;
- RDFNode x = rs.next().get("x") ;
- if ( rs.hasNext() )
- throw new FusekiConfigException("Multiple " + ln + " for service " + FusekiBuildLib.nodeLabel(svc)) ;
- return x ;
- }
-
- private static void addServiceEP(DataService dataService, Operation operation, Resource svc, Property property) {
+ 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() ; ) {
@@ -174,5 +73,33 @@ public class FusekiBuilder
//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);
+ }
}
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiConfig.java
----------------------------------------------------------------------
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 9673cfa..7bf5ea0 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
@@ -18,6 +18,8 @@
package org.apache.jena.fuseki.build ;
+import static java.lang.String.format;
+import static org.apache.jena.fuseki.server.FusekiVocab.*;
import static org.apache.jena.riot.RDFLanguages.filenameToLang;
import static org.apache.jena.riot.RDFParserRegistry.isRegistered;
@@ -32,9 +34,11 @@ import java.util.ArrayList ;
import java.util.Collections ;
import java.util.List ;
+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.datatypes.xsd.XSDDatatype;
import org.apache.jena.fuseki.Fuseki ;
import org.apache.jena.fuseki.FusekiConfigException ;
import org.apache.jena.fuseki.server.* ;
@@ -45,7 +49,9 @@ import org.apache.jena.query.ResultSet ;
import org.apache.jena.rdf.model.* ;
import org.apache.jena.riot.Lang;
import org.apache.jena.sparql.core.assembler.AssemblerUtils ;
+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 ;
public class FusekiConfig {
@@ -117,7 +123,7 @@ public class FusekiConfig {
for ( ; rs.hasNext() ; ) {
QuerySolution soln = rs.next() ;
Resource svc = soln.getResource("service") ;
- DataAccessPoint acc = FusekiBuilder.buildDataAccessPoint(svc, dsDescMap) ;
+ DataAccessPoint acc = buildDataAccessPoint(svc, dsDescMap) ;
accessPoints.add(acc) ;
}
return accessPoints ;
@@ -191,10 +197,86 @@ public class FusekiConfig {
}
for ( Resource service : services ) {
- DataAccessPoint acc = FusekiBuilder.buildDataAccessPoint(service, dsDescMap) ;
+ 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") ;
+ if ( ! n.isLiteral() )
+ throw new FusekiConfigException("Not a literal for access point name: "+FmtUtils.stringForRDFNode(n));
+ 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 = buildDataServiceCustom(svc, dsDescMap) ;
+ 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 buildDataServiceCustom(Resource svc, DatasetDescriptionRegistry dsDescMap) {
+ Resource datasetDesc = ((Resource)FusekiBuildLib.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.
+
+ 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.
+// // Extract timeout overriding configuration if present.
+// if ( svc.hasProperty(FusekiVocab.pAllowTimeoutOverride) ) {
+// 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) ;
+// }
+// }
+
+ return dataService ;
+ }
+
+ public static Dataset getDataset(Resource datasetDesc, DatasetDescriptionRegistry 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)) ;
+ ds = (Dataset)Assembler.general.open(datasetDesc) ;
+ }
+ // 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;
+ }
+
// ---- System database
/** Read the system database */
@@ -230,7 +312,7 @@ public class FusekiConfig {
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 = FusekiBuilder.buildDataAccessPoint(svc, dsDescMap) ;
+ DataAccessPoint ref = buildDataAccessPoint(svc, dsDescMap) ;
refs.add(ref) ;
}
ds.commit();
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/conneg/ConNeg.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/conneg/ConNeg.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/conneg/ConNeg.java
deleted file mode 100644
index 672d2b9..0000000
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/conneg/ConNeg.java
+++ /dev/null
@@ -1,206 +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.conneg;
-
-import static org.apache.jena.riot.web.HttpNames.hAcceptCharset ;
-
-import javax.servlet.http.HttpServletRequest ;
-
-import org.apache.jena.atlas.web.AcceptList ;
-import org.apache.jena.atlas.web.MediaRange ;
-import org.apache.jena.atlas.web.MediaType ;
-import org.slf4j.Logger ;
-import org.slf4j.LoggerFactory ;
-
-/**
- * <p>Content negotiation is a mechanism defined in the HTTP specification
- * that makes it possible to serve different versions of a document
- * (or more generally, a resource representation) at the same URI, so that
- * user agents can specify which version fit their capabilities the best.</p>
- *
- * <p>ConNeg is used in Fuseki to help matching the content media type requested
- * by the user, against the list of offered media types.</p>
- *
- * @see <a href="http://en.wikipedia.org/wiki/Content_negotiation">http://en.wikipedia.org/wiki/Content_negotiation</a>
- * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1">http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1</a>
- */
-public class ConNeg
-{
- // Logger
- private static Logger log = LoggerFactory.getLogger(ConNeg.class) ;
- // See riot.ContentNeg (client side).
- // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
-
- /**
- * Parses the content type. It splits the string by semi-colon and finds the
- * other features such as the "q" quality factor. For a complete documentation
- * on how the parsing happens, see
- * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1">http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1</a>.
- *
- * @param contentType content type string
- * @return parsed media type
- */
- static public MediaType parse(String contentType)
- {
- try {
- return MediaType.create(contentType) ;
- } catch (RuntimeException ex) { return null ; }
- }
-
- /**
- * <p>Creates a {@link AcceptList} with the given HTTP header string and
- * uses the {@link AcceptList#match(MediaType)} method to decide which
- * media type matches the HTTP header string.</p>
- *
- * <p>The <em>q</em> quality factor is used to decide which choice is the best
- * match.</p>
- *
- * @param headerString HTTP header string
- * @param offerList accept list
- * @return matched media type
- */
- static public MediaType match(String headerString, AcceptList offerList)
- {
- AcceptList l = new AcceptList(headerString) ;
- return AcceptList.match(l, offerList) ;
- }
-
- /**
- * Match a single media type against a header string.
- *
- * @param headerString HTTP header string
- * @param mediaRangeStr Semi-colon separated list of media types
- * @return the matched media type or <code>null</code> if there was no match
- */
- public static String match(String headerString, String mediaRangeStr)
- {
- AcceptList l = new AcceptList(headerString) ;
- MediaRange aItem = new MediaRange(mediaRangeStr) ; // MediaType
- MediaType m = l.match(aItem) ;
- if ( m == null )
- return null ;
- return m.toHeaderString() ;
- }
-
- /**
- * Split and trims a string using a given regex.
- *
- * @param s string
- * @param splitStr given regex
- * @return an array with the trimmed strings found
- */
- /*package*/ static String[] split(String s, String splitStr)
- {
- String[] x = s.split(splitStr,2) ;
- for ( int i = 0 ; i < x.length ; i++ )
- {
- x[i] = x[i].trim() ;
- }
- return x ;
- }
-
- /**
- * <p>Chooses the charset by using the Accept-Charset HTTP header.</p>
- *
- * <p>See {@link ConNeg#choose(String, AcceptList, MediaType)}.</p>
- *
- * @param httpRequest HTTP request
- * @param myPrefs accept list
- * @param defaultMediaType default media type
- * @return media type chosen
- */
- public static MediaType chooseCharset(HttpServletRequest httpRequest,
- AcceptList myPrefs,
- MediaType defaultMediaType)
- {
- String a = httpRequest.getHeader(hAcceptCharset) ;
- if ( log.isDebugEnabled() )
- log.debug("Accept-Charset request: "+a) ;
-
- MediaType item = choose(a, myPrefs, defaultMediaType) ;
-
- if ( log.isDebugEnabled() )
- log.debug("Charset chosen: "+item) ;
-
- return item ;
- }
-
- /**
- * <p>Choose the content media type by extracting the Accept HTTP header from
- * the HTTP request and choosing
- * (see {@link ConNeg#choose(String, AcceptList, MediaType)}) a content media
- * type that matches the header.</p>
- *
- * @param httpRequest HTTP request
- * @param myPrefs accept list
- * @param defaultMediaType default media type
- * @return media type chosen
- */
- public static MediaType chooseContentType(HttpServletRequest httpRequest,
- AcceptList myPrefs,
- MediaType defaultMediaType)
- {
- String a = WebLib.getAccept(httpRequest) ;
- if ( log.isDebugEnabled() )
- log.debug("Accept request: "+a) ;
-
- MediaType item = choose(a, myPrefs, defaultMediaType) ;
-
- if ( log.isDebugEnabled() )
- log.debug("Content type chosen: "+item) ;
-
- return item ;
- }
-
- /**
- * <p>This method receives a HTTP header string, an {@link AcceptList} and a
- * default {@link MediaType}.</p>
- *
- * <p>If the header string is null, it returns the given default MediaType.</p>
- *
- * <p>Otherwise it builds an {@link AcceptList} object with the header string
- * and uses it to match against the given MediaType.</p>
- *
- * @param headerString HTTP header string
- * @param myPrefs accept list
- * @param defaultMediaType default media type
- * @return a media type or <code>null</code> if none matched or if the
- * HTTP header string and the default media type are <code>null</code>.
- */
- private static MediaType choose(String headerString, AcceptList myPrefs,
- MediaType defaultMediaType)
- {
- if ( headerString == null )
- return defaultMediaType ;
-
- AcceptList headerList = new AcceptList(headerString) ;
-
- if ( myPrefs == null )
- {
- MediaType i = headerList.first() ;
- if ( i == null ) return defaultMediaType ;
- return i ;
- }
-
- MediaType i = AcceptList.match(headerList, myPrefs) ;
- if ( i == null )
- return defaultMediaType ;
- return i ;
- }
-}
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/conneg/WebLib.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/conneg/WebLib.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/conneg/WebLib.java
deleted file mode 100644
index 38dc265..0000000
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/conneg/WebLib.java
+++ /dev/null
@@ -1,60 +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.conneg;
-
-import java.util.Enumeration ;
-
-import javax.servlet.http.HttpServletRequest ;
-
-import org.apache.jena.riot.web.HttpNames ;
-
-public class WebLib
-{
- /** Split a string, removing whitespace around the split string.
- * e.g. Use in splitting HTTP accept/content-type headers.
- */
- public static String[] split(String s, String splitStr)
- {
- String[] x = s.split(splitStr,2) ;
- for ( int i = 0 ; i < x.length ; i++ )
- {
- x[i] = x[i].trim() ;
- }
- return x ;
- }
-
- /** Migrate to WebLib */
- public static String getAccept(HttpServletRequest httpRequest)
- {
- // There can be multiple accept headers -- note many tools don't allow these to be this way (e.g. wget, curl)
- Enumeration<String> en = httpRequest.getHeaders(HttpNames.hAccept) ;
- if ( ! en.hasMoreElements() )
- return null ;
- StringBuilder sb = new StringBuilder() ;
- String sep = "" ;
- for ( ; en.hasMoreElements() ; )
- {
- String x = en.nextElement() ;
- sb.append(sep) ;
- sep = ", " ;
- sb.append(x) ;
- }
- return sb.toString() ;
- }
-}
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionLib.java
----------------------------------------------------------------------
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 e81b7ab..33d51d6 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
@@ -25,11 +25,13 @@ import javax.servlet.http.HttpServletRequest ;
import org.apache.jena.atlas.RuntimeIOException;
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.conneg.ConNeg ;
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;
import org.apache.jena.riot.RDFParser;
import org.apache.jena.riot.RDFParserRegistry;
@@ -211,5 +213,13 @@ public class ActionLib {
}
catch (RiotException ex) { ServletOps.errorBadRequest("Parse error: "+ex.getMessage()) ; }
}
+
+ /** Get the content type of an action or return the default.
+ * @param action
+ * @return ContentType
+ */
+ public static ContentType getContentType(HttpAction action) {
+ return FusekiNetLib.getContentType(action.request) ;
+ }
}
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/REST_Quads_RW.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/REST_Quads_RW.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/REST_Quads_RW.java
index 859ef95..6cf210b 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/REST_Quads_RW.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/REST_Quads_RW.java
@@ -18,7 +18,7 @@
package org.apache.jena.fuseki.servlets ;
-import org.apache.jena.fuseki.FusekiLib ;
+import org.apache.jena.fuseki.system.FusekiNetLib;
import org.apache.jena.fuseki.system.Upload;
import org.apache.jena.fuseki.system.UploadDetails;
import org.apache.jena.riot.RiotException ;
@@ -131,7 +131,7 @@ public class REST_Quads_RW extends REST_Quads_R {
DatasetGraph dsg = decideDataset(action);
if ( clearFirst )
dsg.clear() ;
- FusekiLib.addDataInto(dsgTmp, dsg) ;
+ FusekiNetLib.addDataInto(dsgTmp, dsg) ;
action.commit() ;
ServletOps.success(action) ;
} catch (Exception ex) {
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseDataset.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseDataset.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseDataset.java
index 99ed62c..9d86ee1 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseDataset.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseDataset.java
@@ -30,8 +30,8 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.jena.atlas.web.MediaType;
import org.apache.jena.fuseki.DEF;
import org.apache.jena.fuseki.Fuseki;
-import org.apache.jena.fuseki.conneg.ConNeg;
-import org.apache.jena.fuseki.conneg.WebLib;
+import org.apache.jena.fuseki.system.ConNeg;
+import org.apache.jena.fuseki.system.FusekiNetLib;
import org.apache.jena.query.Dataset;
import org.apache.jena.query.DatasetFactory ;
import org.apache.jena.rdf.model.Model ;
@@ -93,7 +93,7 @@ public class ResponseDataset
if ( mimeType == null )
{
Fuseki.actionLog.warn("Can't find MIME type for response") ;
- String x = WebLib.getAccept(request) ;
+ String x = FusekiNetLib.getAccept(request) ;
String msg ;
if ( x == null )
msg = "No Accept: header" ;
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseResultSet.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseResultSet.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseResultSet.java
index 464f5b8..8771629 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseResultSet.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseResultSet.java
@@ -34,7 +34,7 @@ import org.apache.jena.atlas.web.AcceptList ;
import org.apache.jena.atlas.web.MediaType ;
import org.apache.jena.fuseki.DEF ;
import org.apache.jena.fuseki.FusekiException ;
-import org.apache.jena.fuseki.conneg.ConNeg ;
+import org.apache.jena.fuseki.system.ConNeg;
import org.apache.jena.query.QueryCancelledException ;
import org.apache.jena.query.ResultSet ;
import org.apache.jena.query.ResultSetFormatter ;
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_GSP_RW.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_GSP_RW.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_GSP_RW.java
index 2b4952f..afe0a31 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_GSP_RW.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_GSP_RW.java
@@ -24,8 +24,8 @@ import static org.apache.jena.riot.WebContent.matchContentType ;
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.FusekiLib ;
-import org.apache.jena.fuseki.conneg.ConNeg ;
+import org.apache.jena.fuseki.system.ConNeg;
+import org.apache.jena.fuseki.system.FusekiNetLib;
import org.apache.jena.fuseki.system.Upload;
import org.apache.jena.fuseki.system.UploadDetails;
import org.apache.jena.fuseki.system.UploadDetails.PreState;
@@ -81,7 +81,7 @@ public class SPARQL_GSP_RW extends SPARQL_GSP_R
protected void doPost(HttpAction action) { doPutPost(action, false) ; }
private void doPutPost(HttpAction action, boolean overwrite) {
- ContentType ct = FusekiLib.getContentType(action) ;
+ ContentType ct = ActionLib.getContentType(action) ;
if ( ct == null )
ServletOps.errorBadRequest("No Content-Type:") ;
@@ -180,7 +180,7 @@ public class SPARQL_GSP_RW extends SPARQL_GSP_R
existedBefore = target.exists() ;
if ( overwrite && existedBefore )
clearGraph(target) ;
- FusekiLib.addDataInto(graphTmp, target.dsg, target.graphName) ;
+ FusekiNetLib.addDataInto(graphTmp, target.dsg, target.graphName) ;
details.setExistedBefore(existedBefore) ;
action.commit() ;
return details ;
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Query.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Query.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Query.java
index 931f27f..6bee41d 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Query.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Query.java
@@ -49,7 +49,7 @@ import org.apache.jena.atlas.json.JsonObject;
import org.apache.jena.atlas.web.ContentType ;
import org.apache.jena.fuseki.Fuseki ;
import org.apache.jena.fuseki.FusekiException ;
-import org.apache.jena.fuseki.FusekiLib ;
+import org.apache.jena.fuseki.system.FusekiNetLib;
import org.apache.jena.query.* ;
import org.apache.jena.rdf.model.Model ;
import org.apache.jena.riot.web.HttpNames ;
@@ -159,7 +159,7 @@ public abstract class SPARQL_Query extends SPARQL_Protocol
*/
protected void validateParams(HttpAction action, Collection<String> params) {
HttpServletRequest request = action.request ;
- ContentType ct = FusekiLib.getContentType(request) ;
+ ContentType ct = FusekiNetLib.getContentType(request) ;
boolean mustHaveQueryParam = true ;
if ( ct != null ) {
String incoming = ct.getContentType() ;
@@ -218,7 +218,7 @@ public abstract class SPARQL_Query extends SPARQL_Protocol
return ;
}
- ContentType ct = FusekiLib.getContentType(action) ;
+ ContentType ct = ActionLib.getContentType(action) ;
// POST application/x-www-form-url
// POST ?query= and no Content-Type
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Update.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Update.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Update.java
index 2b05907..cb327c8 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Update.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Update.java
@@ -48,7 +48,6 @@ import org.apache.jena.atlas.lib.Bytes ;
import org.apache.jena.atlas.lib.StrUtils ;
import org.apache.jena.atlas.web.ContentType ;
import org.apache.jena.fuseki.Fuseki ;
-import org.apache.jena.fuseki.FusekiLib ;
import org.apache.jena.graph.Node ;
import org.apache.jena.graph.NodeFactory ;
import org.apache.jena.iri.IRI ;
@@ -98,7 +97,7 @@ public class SPARQL_Update extends SPARQL_Protocol
@Override
protected void perform(HttpAction action) {
- ContentType ct = FusekiLib.getContentType(action) ;
+ ContentType ct = ActionLib.getContentType(action) ;
if ( ct == null )
ct = ctSPARQLUpdate ;
@@ -127,7 +126,7 @@ public class SPARQL_Update extends SPARQL_Protocol
if ( ! HttpNames.METHOD_POST.equalsIgnoreCase(request.getMethod()) )
ServletOps.errorMethodNotAllowed("SPARQL Update : use POST") ;
- ContentType ct = FusekiLib.getContentType(action) ;
+ ContentType ct = ActionLib.getContentType(action) ;
if ( ct == null )
ct = ctSPARQLUpdate ;
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Upload.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Upload.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Upload.java
index b87a7ce..2fc7d60 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Upload.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Upload.java
@@ -27,7 +27,7 @@ import javax.servlet.http.HttpServletResponse ;
import org.apache.commons.fileupload.servlet.ServletFileUpload ;
import org.apache.jena.fuseki.Fuseki ;
-import org.apache.jena.fuseki.FusekiLib ;
+import org.apache.jena.fuseki.system.FusekiNetLib;
import org.apache.jena.fuseki.system.Upload;
import org.apache.jena.fuseki.system.UploadDetailsWithName;
import org.apache.jena.graph.Node ;
@@ -138,9 +138,9 @@ public class SPARQL_Upload extends ActionService
action.beginWrite() ;
try {
if ( gn != null )
- FusekiLib.addDataInto(dataTmp.getDefaultGraph(), action.getActiveDSG(), gn) ;
+ FusekiNetLib.addDataInto(dataTmp.getDefaultGraph(), action.getActiveDSG(), gn) ;
else
- FusekiLib.addDataInto(dataTmp, action.getActiveDSG()) ;
+ FusekiNetLib.addDataInto(dataTmp, action.getActiveDSG()) ;
action.commit() ;
return count ;
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceRouter.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceRouter.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceRouter.java
index 9a3a2b2..8ec9cd1 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceRouter.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceRouter.java
@@ -27,10 +27,10 @@ import org.apache.jena.atlas.web.AcceptList;
import org.apache.jena.atlas.web.MediaType;
import org.apache.jena.fuseki.Fuseki;
import org.apache.jena.fuseki.FusekiException;
-import org.apache.jena.fuseki.conneg.ConNeg;
import org.apache.jena.fuseki.server.DataService;
import org.apache.jena.fuseki.server.Endpoint;
import org.apache.jena.fuseki.server.Operation;
+import org.apache.jena.fuseki.system.ConNeg;
import org.apache.jena.riot.web.HttpNames;
/**
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/ConNeg.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/ConNeg.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/ConNeg.java
new file mode 100644
index 0000000..364a803
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/ConNeg.java
@@ -0,0 +1,206 @@
+/*
+ * 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.system;
+
+import static org.apache.jena.riot.web.HttpNames.hAcceptCharset ;
+
+import javax.servlet.http.HttpServletRequest ;
+
+import org.apache.jena.atlas.web.AcceptList ;
+import org.apache.jena.atlas.web.MediaRange ;
+import org.apache.jena.atlas.web.MediaType ;
+import org.slf4j.Logger ;
+import org.slf4j.LoggerFactory ;
+
+/**
+ * <p>Content negotiation is a mechanism defined in the HTTP specification
+ * that makes it possible to serve different versions of a document
+ * (or more generally, a resource representation) at the same URI, so that
+ * user agents can specify which version fit their capabilities the best.</p>
+ *
+ * <p>ConNeg is used in Fuseki to help matching the content media type requested
+ * by the user, against the list of offered media types.</p>
+ *
+ * @see <a href="http://en.wikipedia.org/wiki/Content_negotiation">http://en.wikipedia.org/wiki/Content_negotiation</a>
+ * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1">http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1</a>
+ */
+public class ConNeg
+{
+ // Logger
+ private static Logger log = LoggerFactory.getLogger(ConNeg.class) ;
+ // See riot.ContentNeg (client side).
+ // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
+
+ /**
+ * Parses the content type. It splits the string by semi-colon and finds the
+ * other features such as the "q" quality factor. For a complete documentation
+ * on how the parsing happens, see
+ * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1">http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1</a>.
+ *
+ * @param contentType content type string
+ * @return parsed media type
+ */
+ static public MediaType parse(String contentType)
+ {
+ try {
+ return MediaType.create(contentType) ;
+ } catch (RuntimeException ex) { return null ; }
+ }
+
+ /**
+ * <p>Creates a {@link AcceptList} with the given HTTP header string and
+ * uses the {@link AcceptList#match(MediaType)} method to decide which
+ * media type matches the HTTP header string.</p>
+ *
+ * <p>The <em>q</em> quality factor is used to decide which choice is the best
+ * match.</p>
+ *
+ * @param headerString HTTP header string
+ * @param offerList accept list
+ * @return matched media type
+ */
+ static public MediaType match(String headerString, AcceptList offerList)
+ {
+ AcceptList l = new AcceptList(headerString) ;
+ return AcceptList.match(l, offerList) ;
+ }
+
+ /**
+ * Match a single media type against a header string.
+ *
+ * @param headerString HTTP header string
+ * @param mediaRangeStr Semi-colon separated list of media types
+ * @return the matched media type or <code>null</code> if there was no match
+ */
+ public static String match(String headerString, String mediaRangeStr)
+ {
+ AcceptList l = new AcceptList(headerString) ;
+ MediaRange aItem = new MediaRange(mediaRangeStr) ; // MediaType
+ MediaType m = l.match(aItem) ;
+ if ( m == null )
+ return null ;
+ return m.toHeaderString() ;
+ }
+
+ /**
+ * Split and trims a string using a given regex.
+ *
+ * @param s string
+ * @param splitStr given regex
+ * @return an array with the trimmed strings found
+ */
+ /*package*/ static String[] split(String s, String splitStr)
+ {
+ String[] x = s.split(splitStr,2) ;
+ for ( int i = 0 ; i < x.length ; i++ )
+ {
+ x[i] = x[i].trim() ;
+ }
+ return x ;
+ }
+
+ /**
+ * <p>Chooses the charset by using the Accept-Charset HTTP header.</p>
+ *
+ * <p>See {@link ConNeg#choose(String, AcceptList, MediaType)}.</p>
+ *
+ * @param httpRequest HTTP request
+ * @param myPrefs accept list
+ * @param defaultMediaType default media type
+ * @return media type chosen
+ */
+ public static MediaType chooseCharset(HttpServletRequest httpRequest,
+ AcceptList myPrefs,
+ MediaType defaultMediaType)
+ {
+ String a = httpRequest.getHeader(hAcceptCharset) ;
+ if ( log.isDebugEnabled() )
+ log.debug("Accept-Charset request: "+a) ;
+
+ MediaType item = choose(a, myPrefs, defaultMediaType) ;
+
+ if ( log.isDebugEnabled() )
+ log.debug("Charset chosen: "+item) ;
+
+ return item ;
+ }
+
+ /**
+ * <p>Choose the content media type by extracting the Accept HTTP header from
+ * the HTTP request and choosing
+ * (see {@link ConNeg#choose(String, AcceptList, MediaType)}) a content media
+ * type that matches the header.</p>
+ *
+ * @param httpRequest HTTP request
+ * @param myPrefs accept list
+ * @param defaultMediaType default media type
+ * @return media type chosen
+ */
+ public static MediaType chooseContentType(HttpServletRequest httpRequest,
+ AcceptList myPrefs,
+ MediaType defaultMediaType)
+ {
+ String a = FusekiNetLib.getAccept(httpRequest) ;
+ if ( log.isDebugEnabled() )
+ log.debug("Accept request: "+a) ;
+
+ MediaType item = choose(a, myPrefs, defaultMediaType) ;
+
+ if ( log.isDebugEnabled() )
+ log.debug("Content type chosen: "+item) ;
+
+ return item ;
+ }
+
+ /**
+ * <p>This method receives a HTTP header string, an {@link AcceptList} and a
+ * default {@link MediaType}.</p>
+ *
+ * <p>If the header string is null, it returns the given default MediaType.</p>
+ *
+ * <p>Otherwise it builds an {@link AcceptList} object with the header string
+ * and uses it to match against the given MediaType.</p>
+ *
+ * @param headerString HTTP header string
+ * @param myPrefs accept list
+ * @param defaultMediaType default media type
+ * @return a media type or <code>null</code> if none matched or if the
+ * HTTP header string and the default media type are <code>null</code>.
+ */
+ private static MediaType choose(String headerString, AcceptList myPrefs,
+ MediaType defaultMediaType)
+ {
+ if ( headerString == null )
+ return defaultMediaType ;
+
+ AcceptList headerList = new AcceptList(headerString) ;
+
+ if ( myPrefs == null )
+ {
+ MediaType i = headerList.first() ;
+ if ( i == null ) return defaultMediaType ;
+ return i ;
+ }
+
+ MediaType i = AcceptList.match(headerList, myPrefs) ;
+ if ( i == null )
+ return defaultMediaType ;
+ return i ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/FusekiNetLib.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/FusekiNetLib.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/FusekiNetLib.java
new file mode 100644
index 0000000..114b0dd
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/FusekiNetLib.java
@@ -0,0 +1,179 @@
+/*
+ * 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.system;
+
+import java.util.Enumeration;
+import java.util.Iterator ;
+
+import javax.servlet.http.HttpServletRequest ;
+
+import org.apache.jena.atlas.web.ContentType ;
+import org.apache.jena.atlas.web.WebLib;
+import org.apache.jena.ext.com.google.common.collect.ArrayListMultimap;
+import org.apache.jena.ext.com.google.common.collect.Multimap;
+import org.apache.jena.fuseki.FusekiException;
+import org.apache.jena.fuseki.servlets.HttpAction ;
+import org.apache.jena.graph.Graph ;
+import org.apache.jena.graph.Node ;
+import org.apache.jena.graph.Triple ;
+import org.apache.jena.riot.Lang ;
+import org.apache.jena.riot.RDFLanguages ;
+import org.apache.jena.riot.web.HttpNames;
+import org.apache.jena.shared.PrefixMapping ;
+import org.apache.jena.sparql.core.DatasetGraph ;
+import org.apache.jena.sparql.core.Quad ;
+import org.apache.jena.sparql.util.Convert ;
+
+public class FusekiNetLib {
+ /** Get the content type of an action or return the default.
+ * @param request
+ * @return ContentType
+ */
+ public static ContentType getContentType(HttpServletRequest request) {
+ String contentTypeHeader = request.getContentType() ;
+ if ( contentTypeHeader == null )
+ return null ;
+ return ContentType.create(contentTypeHeader) ;
+ }
+
+ /** Get the incoming {@link Lang} based on Content-Type of an action.
+ * @param action
+ * @param dft Default if no "Content-Type:" found.
+ * @return ContentType
+ */
+ public static Lang getLangFromAction(HttpAction action, Lang dft) {
+ String contentTypeHeader = action.request.getContentType() ;
+ if ( contentTypeHeader == null )
+ return dft ;
+ return RDFLanguages.contentTypeToLang(contentTypeHeader) ;
+ }
+
+ public static String getAccept(HttpServletRequest httpRequest)
+ {
+ // There can be multiple accept headers -- note many tools don't allow these to be this way (e.g. wget, curl)
+ Enumeration<String> en = httpRequest.getHeaders(HttpNames.hAccept) ;
+ if ( ! en.hasMoreElements() )
+ return null ;
+ StringBuilder sb = new StringBuilder() ;
+ String sep = "" ;
+ for ( ; en.hasMoreElements() ; )
+ {
+ String x = en.nextElement() ;
+ sb.append(sep) ;
+ sep = ", " ;
+ sb.append(x) ;
+ }
+ return sb.toString() ;
+ }
+
+
+ /** Helper function for displayign an HttpServletRequest */
+ public static String fmtRequest(HttpServletRequest request) {
+ StringBuffer sbuff = new StringBuffer() ;
+ sbuff.append(request.getMethod()) ;
+ sbuff.append(" ") ;
+ sbuff.append(Convert.decWWWForm(request.getRequestURL())) ;
+
+ String qs = request.getQueryString() ;
+ if ( qs != null ) {
+ String tmp = request.getQueryString() ;
+ tmp = Convert.decWWWForm(tmp) ;
+ tmp = tmp.replace('\n', ' ') ;
+ tmp = tmp.replace('\r', ' ') ;
+ sbuff.append("?").append(tmp) ;
+ }
+ return sbuff.toString() ;
+ }
+
+ /** Parse the query string - do not process the body even for a form */
+ public static Multimap<String, String> parseQueryString(HttpServletRequest req) {
+ Multimap<String, String> map = ArrayListMultimap.create() ;
+
+ // Don't use ServletRequest.getParameter or getParamterNames
+ // as that reads form data. This code parses just the query string.
+ if ( req.getQueryString() != null ) {
+ String[] params = req.getQueryString().split("&") ;
+ for (int i = 0; i < params.length; i++) {
+ String p = params[i] ;
+ String[] x = p.split("=", 2) ;
+ String name = null ;
+ String value = null ;
+
+ if ( x.length == 0 ) { // No "="
+ name = p ;
+ value = "" ;
+ } else if ( x.length == 1 ) { // param=
+ name = x[0] ;
+ value = "" ;
+ } else { // param=value
+ name = x[0] ;
+ value = x[1] ;
+ }
+ map.put(name, value) ;
+ }
+ }
+ return map ;
+ }
+
+ public static String safeParameter(HttpServletRequest request, String pName) {
+ String value = request.getParameter(pName) ;
+ if ( value == null )
+ return null ;
+ value = value.replace("\r", "") ;
+ value = value.replace("\n", "") ;
+ return value ;
+ }
+
+ // Do the addition directly on the dataset
+ public static void addDataInto(Graph data, DatasetGraph dsg, Node graphName) {
+ // Prefixes?
+ if ( graphName == null )
+ graphName = Quad.defaultGraphNodeGenerated ;
+
+ Iterator<Triple> iter = data.find(Node.ANY, Node.ANY, Node.ANY) ;
+ for (; iter.hasNext();) {
+ Triple t = iter.next() ;
+ dsg.add(graphName, t.getSubject(), t.getPredicate(), t.getObject()) ;
+ }
+
+ PrefixMapping pmapSrc = data.getPrefixMapping() ;
+ PrefixMapping pmapDest = dsg.getDefaultGraph().getPrefixMapping() ;
+ pmapDest.setNsPrefixes(pmapSrc) ;
+ }
+
+ public static void addDataInto(DatasetGraph src, DatasetGraph dest) {
+ Iterator<Quad> iter = src.find(Node.ANY, Node.ANY, Node.ANY, Node.ANY) ;
+ for (; iter.hasNext();) {
+ Quad q = iter.next() ;
+ dest.add(q) ;
+ }
+
+ PrefixMapping pmapSrc = src.getDefaultGraph().getPrefixMapping() ;
+ PrefixMapping pmapDest = dest.getDefaultGraph().getPrefixMapping() ;
+ pmapDest.withDefaultMappings(pmapSrc) ;
+ }
+
+ public static int choosePort() {
+ try {
+ return WebLib.choosePort();
+ } catch (RuntimeException ex) {
+ throw new FusekiException(ex.getMessage());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/Upload.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/Upload.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/Upload.java
index 0624afc..a956ae4 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/Upload.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/Upload.java
@@ -33,7 +33,6 @@ import org.apache.commons.fileupload.servlet.ServletFileUpload ;
import org.apache.commons.fileupload.util.Streams ;
import org.apache.jena.atlas.io.IO ;
import org.apache.jena.atlas.web.ContentType ;
-import org.apache.jena.fuseki.FusekiLib ;
import org.apache.jena.fuseki.servlets.ActionErrorException;
import org.apache.jena.fuseki.servlets.ActionLib;
import org.apache.jena.fuseki.servlets.HttpAction;
@@ -56,7 +55,7 @@ public class Upload {
* This function is used by GSP.
*/
public static UploadDetails incomingData(HttpAction action, StreamRDF dest) {
- ContentType ct = FusekiLib.getContentType(action) ;
+ ContentType ct = ActionLib.getContentType(action) ;
if ( ct == null ) {
ServletOps.errorBadRequest("No content type") ;
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/validation/ValidatorBase.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/validation/ValidatorBase.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/validation/ValidatorBase.java
index 7601f69..542a5d2 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/validation/ValidatorBase.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/validation/ValidatorBase.java
@@ -35,11 +35,11 @@ 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.Fuseki;
-import org.apache.jena.fuseki.conneg.ConNeg;
import org.apache.jena.fuseki.servlets.ActionErrorException;
import org.apache.jena.fuseki.servlets.ActionLib;
import org.apache.jena.fuseki.servlets.ServletBase;
import org.apache.jena.fuseki.servlets.ServletOps;
+import org.apache.jena.fuseki.system.ConNeg;
import org.apache.jena.fuseki.validation.json.ValidationAction;
import org.apache.jena.riot.web.HttpNames;
import org.apache.jena.web.HttpSC;
http://git-wip-us.apache.org/repos/asf/jena/blob/0c218559/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/validation/html/DataValidatorHTML.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/validation/html/DataValidatorHTML.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/validation/html/DataValidatorHTML.java
index 8017dbe..235108b 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/validation/html/DataValidatorHTML.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/validation/html/DataValidatorHTML.java
@@ -28,7 +28,7 @@ import javax.servlet.http.HttpServletRequest ;
import javax.servlet.http.HttpServletResponse ;
import org.apache.jena.atlas.io.IO ;
-import org.apache.jena.fuseki.FusekiLib ;
+import org.apache.jena.fuseki.system.FusekiNetLib;
import org.apache.jena.riot.Lang;
import org.apache.jena.riot.RDFLanguages;
import org.apache.jena.riot.RDFParser;
@@ -54,7 +54,7 @@ public class DataValidatorHTML
try {
// if ( log.isInfoEnabled() )
// log.info("data validation request") ;
- String syntax = FusekiLib.safeParameter(httpRequest, paramSyntax) ;
+ String syntax = FusekiNetLib.safeParameter(httpRequest, paramSyntax) ;
if ( syntax == null || syntax.equals("") )
syntax = RDFLanguages.NQUADS.getName() ;