org.apache.jena.fuseki.servlets.SPARQL_REST Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jena-fuseki1 Show documentation
Show all versions of jena-fuseki1 Show documentation
Fuseki is a SPARQL 1.1 Server
/*
* 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.fuseki.HttpNames.* ;
import java.io.InputStream ;
import java.util.Enumeration ;
import java.util.Locale ;
import javax.servlet.http.HttpServletRequest ;
import javax.servlet.http.HttpServletResponse ;
import org.apache.jena.fuseki.HttpNames ;
import org.apache.jena.fuseki.server.CounterName ;
import org.apache.jena.graph.Graph ;
import org.apache.jena.graph.Node ;
import org.apache.jena.graph.NodeFactory ;
import org.apache.jena.riot.*;
import org.apache.jena.riot.system.ErrorHandler ;
import org.apache.jena.riot.system.ErrorHandlerFactory ;
import org.apache.jena.riot.system.IRIResolver ;
import org.apache.jena.riot.system.StreamRDF ;
import org.apache.jena.sparql.core.DatasetGraph ;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
public abstract class SPARQL_REST extends SPARQL_ServletBase
{
protected static Logger classLog = LoggerFactory.getLogger(SPARQL_REST.class) ;
protected static ErrorHandler errorHandler = ErrorHandlerFactory.errorHandlerStd(log) ;
protected final static Target determineTarget(HttpAction action) {
// Delayed until inside a transaction.
if ( action.getActiveDSG() == null )
errorOccurred("Internal error : No action graph (not in a transaction?)") ;
boolean dftGraph = getOneOnly(action.request, HttpNames.paramGraphDefault) != null ;
String uri = getOneOnly(action.request, HttpNames.paramGraph) ;
if ( !dftGraph && uri == null ) {
// Direct naming or error.
uri = action.request.getRequestURL().toString() ;
if ( action.request.getRequestURI().equals(action.getDatasetRef().name) )
// No name
errorBadRequest("Neither default graph nor named graph specified; no direct name") ;
}
if ( dftGraph )
return Target.createDefault(action.getActiveDSG()) ;
// Named graph
if ( uri.equals(HttpNames.valueDefault ) )
// But "named" default
return Target.createDefault(action.getActiveDSG()) ;
// Strictly, a bit naughty on the URI resolution. But more sensible.
// Base is dataset.
String base = action.request.getRequestURL().toString() ; //wholeRequestURL(request) ;
// Make sure it ends in "/", ie. dataset as container.
if ( action.request.getQueryString() != null && ! base.endsWith("/") )
base = base + "/" ;
String absUri = IRIResolver.resolveString(uri, base) ;
Node gn = NodeFactory.createURI(absUri) ;
return Target.createNamed(action.getActiveDSG(), absUri, gn) ;
}
// struct for target
protected static final class Target
{
final boolean isDefault ;
final DatasetGraph dsg ;
private Graph _graph ;
final String name ;
final Node graphName ;
static Target createNamed(DatasetGraph dsg, String name, Node graphName) {
return new Target(false, dsg, name, graphName) ;
}
static Target createDefault(DatasetGraph dsg) {
return new Target(true, dsg, null, null) ;
}
private Target(boolean isDefault, DatasetGraph dsg, String name, Node graphName) {
this.isDefault = isDefault ;
this.dsg = dsg ;
this._graph = null ;
this.name = name ;
this.graphName = graphName ;
if ( isDefault )
{
if ( name != null || graphName != null )
throw new IllegalArgumentException("Inconsistent: default and a graph name/node") ;
}
else
{
if ( name == null || graphName == null )
throw new IllegalArgumentException("Inconsistent: not default and/or no graph name/node") ;
}
}
/** Get a graph for the action - this may create a graph in the dataset - this is not a test for graph existence */
public Graph graph() {
if ( ! isGraphSet() )
{
if ( isDefault )
_graph = dsg.getDefaultGraph() ;
else
_graph = dsg.getGraph(graphName) ;
}
return _graph ;
}
public boolean exists()
{
if ( isDefault ) return true ;
return dsg.containsGraph(graphName) ;
}
public boolean isGraphSet()
{
return _graph != null ;
}
@Override
public String toString()
{
if ( isDefault ) return "default" ;
return name ;
}
}
public SPARQL_REST()
{ super() ; }
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) {
// Direct all verbs to our common framework.
doCommon(request, response) ;
}
private void maybeSetLastModified(HttpServletResponse resp, long lastModified) {
if (resp.containsHeader(HEADER_LASTMOD)) return ;
if (lastModified >= 0) resp.setDateHeader(HEADER_LASTMOD, lastModified);
}
@Override
protected void perform(HttpAction action) {
dispatch(action) ;
}
private void dispatch(HttpAction action) {
HttpServletRequest req = action.request ;
HttpServletResponse resp = action.response ;
String method = req.getMethod().toUpperCase(Locale.ROOT) ;
if (method.equals(METHOD_GET))
doGet$(action);
else if (method.equals(METHOD_HEAD))
doHead$(action);
else if (method.equals(METHOD_POST))
doPost$(action);
else if (method.equals(METHOD_PATCH))
doPatch$(action) ;
else if (method.equals(METHOD_OPTIONS))
doOptions$(action) ;
else if (method.equals(METHOD_TRACE))
//doTrace(action) ;
errorMethodNotAllowed("TRACE") ;
else if (method.equals(METHOD_PUT))
doPut$(action) ;
else if (method.equals(METHOD_DELETE))
doDelete$(action) ;
else
errorNotImplemented("Unknown method: "+method) ;
}
// Counter wrappers
protected void doGet$(HttpAction action) {
incCounter(action.srvRef, CounterName.GSPget) ;
try {
doGet(action) ;
incCounter(action.srvRef, CounterName.GSPgetGood) ;
} catch ( ActionErrorException ex) {
incCounter(action.srvRef, CounterName.GSPgetBad) ;
throw ex ;
}
}
protected void doHead$(HttpAction action) {
incCounter(action.srvRef, CounterName.GSPhead) ;
try {
doHead(action) ;
incCounter(action.srvRef, CounterName.GSPheadGood) ;
} catch ( ActionErrorException ex) {
incCounter(action.srvRef, CounterName.GSPheadBad) ;
throw ex ;
}
}
protected void doPost$(HttpAction action) {
incCounter(action.srvRef, CounterName.GSPpost) ;
try {
doPost(action) ;
incCounter(action.srvRef, CounterName.GSPpostGood) ;
} catch ( ActionErrorException ex) {
incCounter(action.srvRef, CounterName.GSPpostBad) ;
throw ex ;
}
}
protected void doPatch$(HttpAction action) {
incCounter(action.srvRef, CounterName.GSPpatch) ;
try {
doPatch(action) ;
incCounter(action.srvRef, CounterName.GSPpatchGood) ;
} catch ( ActionErrorException ex) {
incCounter(action.srvRef, CounterName.GSPpatchBad) ;
throw ex ;
}
}
protected void doDelete$(HttpAction action) {
incCounter(action.srvRef, CounterName.GSPdelete) ;
try {
doDelete(action) ;
incCounter(action.srvRef, CounterName.GSPdeleteGood) ;
} catch ( ActionErrorException ex) {
incCounter(action.srvRef, CounterName.GSPdeleteBad) ;
throw ex ;
}
}
protected void doPut$(HttpAction action) {
incCounter(action.srvRef, CounterName.GSPput) ;
try {
doPut(action) ;
incCounter(action.srvRef, CounterName.GSPputGood) ;
} catch ( ActionErrorException ex) {
incCounter(action.srvRef, CounterName.GSPputBad) ;
throw ex ;
}
}
protected void doOptions$(HttpAction action) {
incCounter(action.srvRef, CounterName.GSPoptions) ;
try {
doOptions(action) ;
incCounter(action.srvRef, CounterName.GSPoptionsGood) ;
} catch ( ActionErrorException ex) {
incCounter(action.srvRef, CounterName.GSPoptionsBad) ;
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) ;
// @@ Move to SPARQL_ServletBase
// Check for all RiotReader
public static void parse(HttpAction action, StreamRDF dest, InputStream input, Lang lang, String base) {
try {
if ( ! RDFLanguages.hasRegisteredParser(lang) ) {
errorBadRequest("No parser for language '"+lang.getName()+"'") ;
}
RDFParser.create()
.source(input)
.lang(lang)
.base(base)
.errorHandler(errorHandler)
.parse(dest);
}
catch (RiotException ex) { errorBadRequest("Parse error: "+ex.getMessage()) ; }
}
@Override
protected void validate(HttpAction action)
{
HttpServletRequest request = action.request ;
// Direct naming.
if ( request.getQueryString() == null )
//errorBadRequest("No query string") ;
return ;
String g = request.getParameter(HttpNames.paramGraph) ;
String d = request.getParameter(HttpNames.paramGraphDefault) ;
if ( g != null && d !=null )
errorBadRequest("Both ?default and ?graph in the query string of the request") ;
if ( g == null && d == null )
errorBadRequest("Neither ?default nor ?graph in the query string of the request") ;
int x1 = SPARQL_Protocol.countParamOccurences(request, HttpNames.paramGraph) ;
int x2 = SPARQL_Protocol.countParamOccurences(request, HttpNames.paramGraphDefault) ;
if ( x1 > 1 )
errorBadRequest("Multiple ?default in the query string of the request") ;
if ( x2 > 1 )
errorBadRequest("Multiple ?graph in the query string of the request") ;
Enumeration en = request.getParameterNames() ;
for ( ; en.hasMoreElements() ; )
{
String h = en.nextElement() ;
if ( ! HttpNames.paramGraph.equals(h) && ! HttpNames.paramGraphDefault.equals(h) )
errorBadRequest("Unknown parameter '"+h+"'") ;
// one of ?default and &graph
if ( request.getParameterValues(h).length != 1 )
errorBadRequest("Multiple parameters '"+h+"'") ;
}
}
protected static String getOneOnly(HttpServletRequest request, String name)
{
String[] values = request.getParameterValues(name) ;
if ( values == null )
return null ;
if ( values.length == 0 )
return null ;
if ( values.length > 1 )
errorBadRequest("Multiple occurrences of '"+name+"'") ;
return values[0] ;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy